BaseThread.cc

00001 // ----------------------------------------------------------------------^
00002 // Copyright (C) 2004, 2005, 2006, 2007, 2008 Giorgio Calderone
00003 // (mailto: <gcalderone@ifc.inaf.it>)
00004 // 
00005 // This file is part of MCS.
00006 // 
00007 // MCS is free software; you can redistribute it and/or modify
00008 // it under the terms of the GNU General Public License as published by
00009 // the Free Software Foundation; either version 2 of the License, or
00010 // (at your option) any later version.
00011 // 
00012 // MCS is distributed in the hope that it will be useful,
00013 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015 // GNU General Public License for more details.
00016 // 
00017 // You should have received a copy of the GNU General Public License
00018 // along with MCS; if not, write to the Free Software
00019 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00020 // 
00021 // ----------------------------------------------------------------------$
00022 
00023 
00024 #include "mcs.hh"
00025 using namespace mcs;
00026 
00027 
00028 //--------------------------------------------------------
00029 RetValue mcs::BaseThread::Log(Event e)
00030 {
00031   char buf[MCS_COMMBUFSIZE];
00032   char* p = buf;
00033   string str;
00034 
00035 
00036   const char *format="%Y%m%d %H%M%S ";   //Format time string
00037   const int lenfmt=strlen(format)+3;     //Three more for century and NULL
00038   time_t tp=time(NULL);
00039   p+=strftime(p, lenfmt, format, localtime(&tp));   //Time-stamp
00040   p+=sprintf(p, "%s ", tID);          //Thread id
00041 
00042   str = buf;
00043   str += e.msg();
00044 
00045   if (e.type() != OK) {
00046       str += " [";
00047       switch (e.type()) {
00048       case WARN:
00049           str += "W"; break;
00050       case ERROR:
00051           str += "E"; break;
00052       case FATAL:
00053           str += "F"; break;
00054       default:
00055           break;
00056       }
00057       str += " " + e.where() + "]";
00058   }
00059 
00060   if (env->cl_logstdout) cout << str << endl;
00061   if (env->cl_logfile) if (env->flog) (*(env->flog)) << str << endl;
00062 
00063   if ((env->local)                       &&
00064       (e.code() != MSG_THREAD_CREATE)    &&
00065       (e.code() != MSG_THREAD_DESTROY)   &&
00066       (id() > 0)                         ) {
00067 
00068       env->local->hk_log((UserThread*) this, e);
00069   }
00070 
00071   return e.type();
00072 }
00073 
00074 
00075 mcs::BaseThread::BaseThread(Thread* parent, int ID) : Thread(ID, parent)
00076 {
00077   sprintf(tID, "%03d", ID);
00078 }
00079 
00080 
00081 mcs::BaseThread::BaseThread(Thread* parent, const char *ltID) : Thread(-1, parent)
00082 {
00083   sprintf(tID, "%3s", ltID);
00084 }
00085 
00086 
00087 mcs::BaseThread::~BaseThread()
00088 {}
00089 
00090 const char* mcs::BaseThread::tid()
00091 {
00092   return tID;
00093 }
00094 
00095 
00096 
00097 
00098 Env* mcs::BaseThread::env;
00099 
00100 
00101 
00102 
00103 
00104 //--------------------------------------------------------
00105 #define FT_TEMPL_BATCH   "#BATCH"
00106 #define FT_TEMPL_SQL     "#SQL"
00107 #define FT_TEMPL_SCRIPT  "#SCRIPT"
00108 #define FT_TEMPL_BIN     "\177ELF"
00109 
00110 
00111 
00112 int mcs::BaseThread::fileType(string fn)
00113 {
00114   char buffer[10];
00115   buffer[9] = '\0';
00116 
00117   ifstream fin;
00118   fin.open(fn.csz);
00119   if (!(fin.is_open()))
00120     throw MCS_ERROR(MSG_CANT_OPEN_FILE, fn.csz);
00121 
00122   fin.read(buffer, 9);
00123   fin.close();
00124   if (0)
00125     ;
00126   else if (! memcmp(buffer, FT_TEMPL_BATCH,  strlen(FT_TEMPL_BATCH)))
00127     return MCS_FT_BATCH;
00128   else if (! memcmp(buffer, FT_TEMPL_SQL,    strlen(FT_TEMPL_SQL)))
00129     return MCS_FT_SQL;
00130   else if (! memcmp(buffer, FT_TEMPL_SCRIPT, strlen(FT_TEMPL_SCRIPT)))
00131     return MCS_FT_SCRIPT;
00132   else if (! memcmp(buffer, FT_TEMPL_BIN, strlen(FT_TEMPL_BIN)))
00133     return MCS_FT_BIN;
00134 
00135   return MCS_FT_UNKNOWN;
00136 }
00137 
00138 
00139 
00140 int mcs::BaseThread::chkExt(string& s)
00141 {
00142   int i;
00143   string fn = env->cnf->sval(env->appname + "_EXTERNAL" , s, "");
00144 
00145   if (! fn.empty()) {
00146     i = fileType(fn);  //Check file type
00147     if (i == MCS_FT_UNKNOWN)
00148       throw MCS_ERROR(MSG_UNKNOWN_FILE_TYPE, fn.csz);
00149   }
00150   else
00151     throw MCS_WARN(MSG_EXT_NOT_AVAILABLE, s.c_str());
00152 
00153   s = fn;
00154   return i;
00155 }
00156 
00157 
00158 
00159 int mcs::BaseThread::spawn(string fn, string pars,
00160                string wpath, string thrID,
00161                string user, string pass, string dbname,
00162                string fout, string ferr)
00163 {
00164   //We need to check for redirection operators '<', '>' and pipes
00165   //'|'. If one of these operators are present in the command line
00166   //we'll throw an error.
00167 
00168   static string bl = " ";
00169   string tmp;
00170   tmp = fn + bl + pars;
00171 
00172   if (strchr(tmp.c_str(), '>'))
00173     throw MCS_WARN(MSG_CHARACTER_NOT_ALLOWED, ">");
00174     
00175   if (strchr(tmp.c_str(), '<'))
00176     throw MCS_WARN(MSG_CHARACTER_NOT_ALLOWED, "<");
00177 
00178   if (strchr(tmp.c_str(), '|'))
00179     throw MCS_WARN(MSG_CHARACTER_NOT_ALLOWED, "|");
00180 
00181   int i = fileType(fn);   //Check file type
00182   if ((i != MCS_FT_SCRIPT)   &&
00183       (i != MCS_FT_BIN))
00184     throw MCS_ERROR(MSG_CANT_EXECUTE_FILE, fn);
00185 
00186 
00187   tmp  = BINDIR + string("/mcsexec ");        //external spawner, pars:
00188   tmp += thrID + bl;                          //client id
00189   tmp += user + bl + pass + bl + dbname + bl; //username, password, dbname,
00190   tmp += wpath + bl;                          //path to work directory
00191 
00192   if (i == MCS_FT_SCRIPT) //In this case the real executable is the shell
00193     tmp += "/bin/bash ";
00194 
00195   tmp += fn + bl + pars;                      //filename of executable
00196   tmp += " >  " + fout ;                      //redirect stdout
00197   tmp += " 2> " + ferr;                       //redirect stderr
00198 
00199   i=system(tmp.csz);
00200   if (WIFEXITED(i)) {
00201     i = WEXITSTATUS(i);
00202   }
00203   else
00204     throw MCS_ERROR( MSG_EXT_BIN_UNEXPECTED );
00205 
00206   return i;
00207 }
00208 
00209 

mcslogo

MCS (My Customizable Server) ver. 0.3.3-alpha3
Documentation generated on Thu Mar 22 13:22:23 UTC 2012