00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
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