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
![]() |
MCS (My Customizable Server) ver. 0.3.3-alpha3
|