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 #define PIDFILE "mcs.pid" 00029 00030 00031 //-------------------------------------------------------- 00032 mcs::Server::Server(Env* lenv) : BaseThread(NULL, "MMM"), 00033 dispatch(true) 00034 { 00035 //Initialize to NULL all callback function pointers. 00036 cb_log = NULL; 00037 cb_connect = NULL; 00038 cb_auth = NULL; 00039 cb_exec = NULL; 00040 cb_postexec = NULL; 00041 cb_disconnect = NULL; 00042 cb_newClient = NULL; 00043 cbwa_log = NULL; 00044 cbwa_connect = NULL; 00045 cbwa_auth = NULL; 00046 cbwa_exec = NULL; 00047 cbwa_postexec = NULL; 00048 00049 pClient = NULL; 00050 env=lenv; //env is a static member of Thread 00051 00052 env->local = NULL; 00053 if (env->cl_logstdout) { 00054 //Print a banner 00055 cout << MCS_BANNER; 00056 cout << "\nYYYYMMDD HHMMSS thr MESSAGE" << endl; 00057 cout << 00058 "-------- ------ --- " << 00059 "------------------------------------------------------------" << 00060 endl; 00061 } 00062 } 00063 00064 00065 00066 00067 mcs::Server::~Server() 00068 { 00069 // env->server_running=false; 00070 00071 if (env->local) { 00072 Log(MCS_OK( MSG_KILLING_LOCAL )); 00073 env->cl_restartlocal = 0; 00074 env->local->stop(); //TESTING //env->local->exit(false); 00075 } 00076 00077 if (pClient) { 00078 killAllClients(); 00079 free(pClient); 00080 } 00081 00082 Log(MCS_OK( MSG_THREAD_DESTROY, "Server" )); 00083 } 00084 00085 00086 void mcs::Server::run() 00087 { 00088 int i; 00089 int newsock; 00090 00091 set_cancel_state(false); 00092 00093 try { 00094 Log(MCS_OK( MSG_THREAD_CREATE, "Server" )); 00095 00096 Log(MCS_OK( MSG_SERVER_DIR, env->path.csz )); 00097 00098 if (env->max_users <= 0) 00099 throw MCS_FATAL(MSG_ERROR, "max_users <= 0"); 00100 00101 pClient = (UserThread**) malloc(env->max_users * sizeof(UserThread*)); 00102 if (! pClient) 00103 throw MCS_FATAL(MSG_OUT_OF_MEMORY); 00104 00105 env->local=NULL; 00106 00107 for (i=0; i<env->max_users; i++) 00108 pClient[i]=NULL; 00109 00110 if (env->cl_createlocal) { 00111 Log(MCS_OK( MSG_CREATING_LOCAL )); 00112 env->local=newLocalThread(); 00113 env->local->start(); 00114 } 00115 00116 ServerSocket server(env->interface, env->port, 00117 env->cl_use_ssl, env->sslcert, env->sslpriv); 00118 env->ssl_ctx = server.getSSLContext(); //To be passed to UserThread objects 00119 00120 Log(MCS_OK( MSG_SERVER_RUNNING, server.ipaddress().c_str(), env->port )); 00121 00122 00123 //Write the PIDFILE 00124 { 00125 ofstream of(PIDFILE, ios::out); 00126 pid_t pid = getpid(); 00127 of << pid << endl; 00128 of.close(); 00129 } 00130 00131 00132 for(;;) { 00133 set_cancel_state(true); 00134 if (server.acceptConnection(newsock, 1000)) { 00135 set_cancel_state(false); 00136 newClient(newsock); 00137 } 00138 set_cancel_state(false); 00139 00140 if (! env->local) { 00141 if (env->cl_local_kills_mcs) { 00142 Log(MCS_OK( MSG_LOCAL_THREAD_DIED )); 00143 return; 00144 } 00145 00146 else if(env->cl_restartlocal) { 00147 Log(MCS_OK( MSG_CREATING_LOCAL )); 00148 env->local=newLocalThread(); 00149 env->local->start(); 00150 } 00151 } 00152 } 00153 } 00154 catch(Event e) { 00155 Log(e); 00156 if (e.type() == FATAL) 00157 return; 00158 } 00159 } 00160 00161 00162 00163 00164 void mcs::Server::notify(int id, Thread* ref) 00165 { 00166 #if ENABLE_DEBUG 00167 Thread::notify(id, ref); 00168 #endif 00169 00170 //ref->allowTermination(); 00171 00172 if (ref == env->local) { 00173 delete env->local; //TESTING 00174 env->local = NULL; 00175 } 00176 else { 00177 delete pClient[id]; //TESTING 00178 pClient[id]=NULL; 00179 } 00180 } 00181 00182 00183 00184 00185 int mcs::Server::find_free_id() 00186 { 00187 int i, res=-1; 00188 for (i=0; i<env->max_users; i++) 00189 if (pClient[i] == NULL) { 00190 res=i; 00191 break; 00192 } 00193 00194 return res; 00195 } 00196 00197 00198 00199 00200 void mcs::Server::newClient(int newsock) 00201 { 00202 int i=find_free_id(); 00203 if (i >= 0) { 00204 Log(MCS_OK( MSG_CREATING_CLIENT, i )); 00205 pClient[i] = newUserThread(i, newsock); 00206 pClient[i]->start(); 00207 hk_newClient(i); 00208 } 00209 else { 00210 close(newsock); 00211 Log(MCS_ERROR( MSG_NO_MORE_CLIENT_ALLOWED )); 00212 } 00213 } 00214 00215 00216 00217 void mcs::Server::killClient(int i) 00218 { 00219 if (i>=0 && i<env->max_users) 00220 if (pClient[i]) { 00221 Log(MCS_OK( MSG_KILLING_CLIENT, i )); 00222 pClient[i]->stop(); //TESTING //pClient[i]->exit(false); 00223 } 00224 } 00225 00226 00227 void mcs::Server::killAllClients() 00228 { 00229 if (pClient) { 00230 Log(MCS_OK( MSG_KILLING_ALL_CLIENTS )); 00231 for (int i=0; i<env->max_users; i++) 00232 killClient(i); 00233 } 00234 } 00235 00236 00237 RecordSet* mcs::Server::getAll_ClientInfo() 00238 { 00239 RecordSet* ret = new RecordSet(); 00240 00241 for (int i=0; i<env->max_users; i++) 00242 if (pClient[i]) 00243 ret->insert(pClient[i]->info()); 00244 00245 return ret; 00246 } 00247 00248 //vector<string> mcs::Server::clientsInfo() 00249 //{ 00250 // vector<string> ret; 00251 // string s; 00252 // static string tab = "\t"; 00253 // struct ClientInfo* info; 00254 // 00255 // 00256 // for (int i=0; i<env->max_users; i++) { 00257 // info = NULL; 00258 // if (pClient[i]) 00259 // info = pClient[i]->clientInfo(); 00260 // 00261 // if (info) { 00262 // s = itos(info->id) + tab; 00263 // s += info->ipaddress + tab; 00264 // s += info->hostname + tab; 00265 // s += info->timeConnetcted + tab; 00266 // s += info->username + tab; 00267 // s += info->lastCommand + tab; 00268 // s += info->timeLastCommand + tab; 00269 // s += itos(info->commandExecuted) + tab; 00270 // s += itos(info->logged); 00271 // ret.push_back(s); 00272 // } 00273 // } 00274 // return ret; 00275 //} 00276 00277 00278 00279 UserThread* mcs::Server::newUserThread(int lID, int newsock) 00280 { 00281 return new UserThread(this, lID, newsock); 00282 } 00283 00284 LocalThread* mcs::Server::newLocalThread() 00285 { 00286 return new LocalThread(this); 00287 } 00288 00289 00290 void mcs::Server::hk_newClient(int i) 00291 { 00292 if (cb_newClient) 00293 (*(cb_newClient))(i); 00294 } 00295 00296 00297 00298 00299 00300 00301 00302 00303 mcs::ClientInfo::ClientInfo() : Record() 00304 { 00305 addField(new Data (NULL, INT, "id" )); 00306 addField(new Data (NULL, STRING, "ipaddress" , 15)); 00307 addField(new Data (NULL, STRING, "hostname" , 30)); 00308 addField(new Data (NULL, TIME, "timeConnected" )); 00309 addField(new Data (NULL, STRING, "username" , 15)); 00310 addField(new Data (NULL, STRING, "lastCommand" , 30)); 00311 addField(new Data (NULL, TIME, "timeLastCommand" )); 00312 addField(new Data (NULL, INT, "commandExecuted" )); 00313 addField(new Data (NULL, TINY, "logged" )); 00314 } 00315 00316 00317 Data& mcs::ClientInfo::id() { return operator[](0); } 00318 Data& mcs::ClientInfo::ipaddress() { return operator[](1); } 00319 Data& mcs::ClientInfo::hostname() { return operator[](2); } 00320 Data& mcs::ClientInfo::timeConnetcted() { return operator[](3); } 00321 Data& mcs::ClientInfo::username() { return operator[](4); } 00322 Data& mcs::ClientInfo::lastCommand() { return operator[](5); } 00323 Data& mcs::ClientInfo::timeLastCommand() { return operator[](6); } 00324 Data& mcs::ClientInfo::commandExecuted() { return operator[](7); } 00325 Data& mcs::ClientInfo::logged() { return operator[](8); } 00326 00327 00328 00329 //mcs::ClientsInfo_set::ClientsInfo_set(UserThread** pClient, int max_users) : 00330 // RecordSet() 00331 //{ 00332 // this->pClient = pClient; 00333 // this->max_users = max_users; 00334 // lastpos = 0; 00335 // 00336 // ClientsInfo tmp; 00337 // metarec() = tmp; 00338 // init(0, true, true); 00339 //} 00340 // 00341 // 00342 //bool mcs::ClientsInfo_set::fetch(unsigned int newpos, bool random) 00343 //{ 00344 // ClientsInfo tmp; 00345 // 00346 // for (int i=lastpos; i<max_users; i++) 00347 // if (pClient[i]) { 00348 // rec() = pClient[i]->clientsInfo(); 00349 // rec().emptyName(); 00350 // lastpos = i; 00351 // return true; 00352 // } 00353 // 00354 // return false; 00355 //} 00356
![]() |
MCS (My Customizable Server) ver. 0.3.3-alpha3
|