/* * mainServer.cpp * * Gouverneur Th. - Cuisinier Gi. * * Main routine&calls for the server of RMP and RMPA * protocols. * */ #include #include #include #include #include #include #include #include #include #include "libs/mysql.h" #include "mysqlQuery.h" using namespace std; void thread_client (void *); void thread_rmpa (void *); #ifdef TRU64 extern "C" { #endif int Arme (int, void (*)(int)); void Handler (int ); #ifdef TRU64 } #endif Sock_Server *serv; Sock_Server *serv_admin; int main(void) { /* signal stuff */ Arme(SIGINT, Handler); /* begining serious things ;) */ try { serv = new Sock_Server(ADDRESS_BIND, PORT_CHAMBRE); serv->setConnFct(thread_client); serv->setMainThreaded(false); serv->setBlock(false); serv_admin = new Sock_Server(ADDRESS_BIND, PORT_ADMIN); serv_admin->setConnFct(thread_rmpa); serv_admin->setMainThreaded(false); serv_admin->setBlock(false); /* Init rooms, users & reservations */ ServerProtocol::getRoomFromSql(); ServerProtocol::getUserFromSql(); ServerProtocol::refreshBooks(); /* ServerProtocol::listRoom.Push(new Room("001", "S")); // 001 - Standard ServerProtocol::listRoom.Push(new Room("002", "L")); // 002 - Luxe ServerProtocol::listRoom.Push(new Room("003", "S")); // 003 - Standard ServerProtocol::listRoom.Push(new Room("004", "S")); // 004 - Standard ServerProtocol::listRoom.Push(new Room("005", "S")); // 005 - Standard ServerProtocol::listUser.Push(new User("wildcat", "pass")); ServerProtocol::listUser.Push(new User("hikage", "pass")); */ /* start */ cout << "Starting main server" << endl; serv->start(); cout << "Starting Administration server" << endl; serv_admin->start(); while(1) { if (ServerProtocol::shutdown > -1) { if (time(0) > ServerProtocol::shutdown) // should shutdown now... { /* notify all client on udp port * that the server shutdown */ Sock_Base::sConn *tmp; for (int i = 0; i < serv->getListConn()->Size(); i++) { tmp = (*(serv->getListConn()))[i]; std::string ip = tmp->getIp(); Sock_Udp *sudp = new Sock_Udp(ip, PORT_NOTIFY); sudp->startNoBind(); *sudp << "SHUTDOWN\n"; sudp->stop(); } serv->stop(); serv_admin->stop(); ServerProtocol::cleanUpAll(); delete serv; delete serv_admin; return 0; } } // if (!ServerProtocol::suspended) serv->evolve(); serv_admin->evolve(); } } catch (Exception e) { cout << e << endl; } } void thread_rmpa(void *s) { Sock_Base::sConn *sSock= (Sock_Base::sConn *)s; Parser *p = new Parser(); p->setConn(*sSock); p->addCommand(Command("LCLIENTS", (void(*)(void*))RMPAProtocol::cmdLClients, 0)); p->addCommand(Command("SUSPS", (void(*)(void*))RMPAProtocol::cmdSusps, 0)); p->addCommand(Command("STOPS", (void(*)(void*))RMPAProtocol::cmdStops, 0)); sSock->readLen = 1000; /* max read len by line */ #ifdef DEBUG cout << "Nouveau client RMPA" << endl; #endif while (42) { try { string line; *sSock >> line; p->parseLine(line); } catch (Sock_Base::exRead e) { cout << e << endl; } catch (Sock_Base::exWrite e) { cout << e << endl; } catch (Sock_Base::exTimeout e) { #ifdef DEBUG cout << "Other side leaved, closing RMPA connection..." << endl; #endif ServerProtocol::cleanClient(sSock); delete sSock; pthread_exit(0); return; } catch (Exception e) { cout << e << endl; } } } void thread_client(void *s) { Sock_Base::sConn *sSock= (Sock_Base::sConn *)s; Parser *p = new Parser(); p->setConn(*sSock); p->addCommand(Command("LOGIN", (void(*)(void*))ServerProtocol::cmdLogin, 2)); /* args: nom, password */ p->addCommand(Command("BROOM", (void(*)(void*))ServerProtocol::cmdBRoom, 5)); /* args: type de chambre, date arrivee, nombre de nuit, nom client */ p->addCommand(Command("CROOM", (void(*)(void*))ServerProtocol::cmdCRoom, 2)); /* args: num chambre, nom client */ p->addCommand(Command("LROOMS", (void(*)(void*))ServerProtocol::cmdLRooms, 0)); /* args: -- */ sSock->readLen = 1000; /* max read len by line */ #ifdef DEBUG cout << "Nouveau client" << endl; #endif while (42) { try { // if (!ServerProtocol::suspended) // { string line; *sSock >> line; #ifdef DEBUG cout << "Ligne recue: " << line << "-" << endl; #endif // while (ServerProtocol::suspended) sleep(2); // if we were blocked in an I/O, now we wait here BEFORE parsing data received. if (!ServerProtocol::suspended) p->parseLine(line); else ServerProtocol::sendSusp(sSock); // tell client we are suspended.. // } else sleep(1); // we do NOT want to use all the CPU :) } catch (Sock_Base::exRead e) { cout << e << endl; } catch (Sock_Base::exWrite e) { cout << e << endl; } catch (Sock_Base::exTimeout e) { cout << "Other side leaved, closing connection..." << endl; ServerProtocol::cleanClient(sSock); delete sSock; pthread_exit(0); return; } catch (Exception e) { cout << e << endl; } } } #ifdef TRU64 extern "C" { #endif int Arme (int s, void (*f)(int)) { struct sigaction a; a.sa_flags = 0; a.sa_handler = f; return sigaction(s, &a, NULL); } void Handler (int s) { serv->stop(); exit(0); } #ifdef TRU64 } #endif