Main Page | Namespace List | Class Hierarchy | Alphabetical List | Compound List | File List | Compound Members | File Members

UIServ.cc

Go to the documentation of this file.
00001 /*
00002 
00003     User interface server
00004     Copyright (C) 1999-2002 Jussi Laako
00005 
00006     This program is free software; you can redistribute it and/or modify
00007     it under the terms of the GNU General Public License as published by
00008     the Free Software Foundation; either version 2 of the License, or
00009     (at your option) any later version.
00010 
00011     This program is distributed in the hope that it will be useful,
00012     but WITHOUT ANY WARRANTY; without even the implied warranty of
00013     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014     GNU General Public License for more details.
00015 
00016     You should have received a copy of the GNU General Public License
00017     along with this program; if not, write to the Free Software
00018     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019 
00020 */
00021 
00022 
00023 #include <stdio.h>
00024 #include <stdlib.h>
00025 #include <string.h>
00026 #include <unistd.h>
00027 #include <signal.h>
00028 #include <fcntl.h>
00029 #include <sys/types.h>
00030 #include <sys/stat.h>
00031 #include <sys/wait.h>
00032 #include <sys/socket.h>
00033 #include <netinet/in.h>
00034 #include <arpa/inet.h>
00035 
00036 #include "Config.h"
00037 #include "UIServ.hh"
00038 #include "SockOp.hh"
00039 
00040 
00041 bool bRun = true;
00042 clUIServer *UIServer;
00043 clSockOp *SOp;
00044 
00045 
00046 void SigHandler(int iSigNum)
00047 {
00048     switch (iSigNum)
00049     {
00050         case SIGHUP:
00051         case SIGINT:
00052         case SIGTERM:
00053             bRun = false;
00054             break;
00055         default:
00056             bRun = false;
00057     }
00058 }
00059 
00060 
00061 int main(int argc, char *argv[])
00062 {
00063     int iArgCntr;
00064     int iClientH;
00065     int iTOS;
00066     socklen_t iTOSSize;
00067     bool bDaemon = false;
00068     bool bDebug = false;
00069     char cpMsg[GLOBAL_HEADER_LEN];
00070 
00071     signal(SIGPIPE, SIG_IGN);
00072     signal(SIGFPE, SIG_IGN);
00073     if (argc >= 2)
00074     {
00075         for (iArgCntr = 1; iArgCntr < argc; iArgCntr++)
00076         {
00077             if (strcmp(argv[iArgCntr], "-D") == 0)
00078             {
00079                 bDaemon = true;
00080             }
00081             if (strcmp(argv[iArgCntr], "--debug") == 0)
00082             {
00083                 bDebug = true;
00084             }
00085             if (strcmp(argv[iArgCntr], "--version") == 0)
00086             {
00087                 printf("UIServ v%i.%i.%i\n", UIS_VERSMAJ, UIS_VERSMIN,
00088                     UIS_VERSPL);
00089                 printf("Copyright (C) 1999-2001 Jussi Laako\n");
00090                 return 0;
00091             }
00092             if (strcmp(argv[iArgCntr], "--help") == 0)
00093             {
00094                 printf("%s [-D|--debug|--version|--help]\n\n", argv[0]);
00095                 printf("-D         start as daemon\n");
00096                 printf("--debug    emit debug output from servers\n");
00097                 printf("--version  display version information\n");
00098                 printf("--help     display this help\n");
00099                 return 0;
00100             }
00101         }
00102     }
00103     if (bDaemon)
00104     {
00105         signal(SIGHUP, SigHandler);
00106         if (fork() != 0)
00107         {
00108             exit(0);
00109         }
00110         setsid();
00111         freopen("/dev/null", "r+", stderr);
00112         freopen("/dev/null", "r+", stdin);
00113         freopen("/dev/null", "r+", stdout);
00114     }
00115     else
00116     {
00117         signal(SIGINT, SigHandler);
00118     }
00119     signal(SIGTERM, SigHandler);
00120     UIServer = new clUIServer();
00121     while (bRun)
00122     {
00123         if (bDebug) printf(" - Waiting for connections\n");
00124         iClientH = UIServer->Wait();
00125         if (iClientH >= 0)
00126         {
00127             if (fork() == 0)
00128             {
00129                 UIServer->NoLogShutdown();
00130                 delete UIServer;
00131                 dup2(iClientH, 3);
00132                 dup2(iClientH, 4);
00133                 SOp = new clSockOp(iClientH);
00134                 if (!SOp->ReadSelect(UIS_MSG_TIMEOUT))
00135                 {
00136                     exit(1);
00137                 }
00138                 if (SOp->ReadN(cpMsg, GLOBAL_HEADER_LEN) == GLOBAL_HEADER_LEN)
00139                 {
00140                     if (!SOp->DisableNagle())
00141                     {
00142                         if (bDebug) 
00143                             printf("clSockOp::DisableNagle() failed\n");
00144                     }
00145                     if (!SOp->SetTypeOfService(IPTOS_LOWDELAY))
00146                     {
00147                         if (bDebug)
00148                             printf("clSockOp::SetTypeOfService() failed\n");
00149                     }
00150                     iTOS = 0;
00151                     iTOSSize = sizeof(iTOS);
00152                     getsockopt(3, IPPROTO_IP, IP_TOS, &iTOS, &iTOSSize);
00153                     if (iTOS != IPTOS_LOWDELAY)
00154                     {
00155                         if (bDebug)
00156                             printf("Problem with socket options & dup2()!\n");
00157                     }
00158 
00159                     if (!bDebug)
00160                     {
00161                         if (!bDaemon)
00162                         {
00163                             execl(cpMsg, cpMsg, NULL);
00164                         }
00165                         else 
00166                         {
00167                             execl(cpMsg, cpMsg, "-D", NULL);
00168                         }
00169                     }
00170                     else
00171                     {
00172                         printf(" - execl(%s)\n", cpMsg);
00173                         execl(cpMsg, cpMsg, "--debug", NULL);
00174                     }
00175                     exit(1);
00176                 }
00177             }
00178             else
00179             {
00180                 close(iClientH);
00181             }
00182         }
00183         else
00184         {
00185             bRun = false;
00186         }
00187     }
00188     delete UIServer;
00189     if (bDebug) printf(" - Exit\n");
00190     return 0;
00191 }
00192 
00193 
00194 clUIServer::clUIServer()
00195 {
00196     int iPortNum;
00197     char cpLogBuf[UIS_CONV_BUF_SIZE];
00198     
00199     bLogShutdown = true;
00200     Cfg = new clCfgFile(UIS_CFGFILE);
00201     Log = new clLogFile(UIS_LOGFILE);
00202     if (Log->GetError() != LOGFILE_NOERROR)
00203     {
00204         printf("Logfile open failed!\n");
00205         exit(1);
00206     }
00207     Log->Add('*', "Starting");
00208     if (!Cfg->GetInt("Port", &iPortNum))
00209     {
00210         iPortNum = UIS_DEFAULT_PORT;
00211     }
00212     sprintf(cpLogBuf, "Listening for connections on port %i", iPortNum);
00213     Log->Add(' ', cpLogBuf);
00214     SServ = new clSockServ(iPortNum);
00215     if (SServ->GetErrno() != 0)
00216     {
00217         Log->Add('!', "clSockServ::clSockServ() error", SServ->GetErrno());
00218         return;
00219     }
00220 }
00221 
00222 
00223 clUIServer::~clUIServer()
00224 {
00225     if (bLogShutdown) Log->Add('*', "Shutdown");
00226     delete SServ;
00227     delete Log;
00228     delete Cfg;
00229 }
00230 
00231 
00232 int clUIServer::Wait()
00233 {
00234     int iHandle;
00235     char cpLogBuf[UIS_CONV_BUF_SIZE];
00236     socklen_t iPeerAddrLen;
00237     struct sockaddr_in sPeerAddr;
00238     clSockOp SOp;
00239     
00240     while (bRun)
00241     {
00242         if (access(UIS_SHUTDOWNFILE, F_OK) == 0)
00243         {
00244             unlink(UIS_SHUTDOWNFILE);
00245             bRun = false;
00246             break;
00247         }
00248         iHandle = SServ->WaitForConnect(UIS_TIMEOUT);
00249         if (iHandle >= 0)
00250         {
00251             SOp.SetHandle(iHandle);
00252             SOp.SetCloseOnDestruct(false);
00253             iPeerAddrLen = sizeof(sPeerAddr);
00254             SOp.GetPeerName((struct sockaddr *) &sPeerAddr, &iPeerAddrLen);
00255             sprintf(cpLogBuf, "Client connected from %s:%i",
00256                 inet_ntoa(sPeerAddr.sin_addr), ntohs(sPeerAddr.sin_port));
00257             Log->Add('+', cpLogBuf);
00258             return iHandle;
00259         }
00260         else
00261         {
00262             if (SServ->GetErrno() != 0)
00263             {
00264                 Log->Add('!', "clSockServ::WaitForConnect() error",
00265                     SServ->GetErrno());
00266                 return -1;
00267             }
00268         }
00269         waitpid(0, NULL, WNOHANG);
00270     }
00271     return -1;
00272 }
00273 

Generated on Sun Oct 26 19:11:23 2003 for HASAS by doxygen 1.3.3