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 <errno.h>
00027 #include <unistd.h>
00028 #include <netdb.h>
00029 #include <sys/types.h>
00030 #include <sys/stat.h>
00031 #include <sys/socket.h>
00032 #include <sys/un.h>
00033 #include <sys/time.h>
00034 #include <netinet/in.h>
00035 #include <arpa/inet.h>
00036
00037 #include "Config.h"
00038 #include "SockServ.hh"
00039
00040
00041 clSockServ::clSockServ ()
00042 {
00043 iErrno = 0;
00044 iListenH = -1;
00045 }
00046
00047
00048 clSockServ::clSockServ (unsigned short usPort)
00049 {
00050 iErrno = 0;
00051 Bind(usPort);
00052 }
00053
00054
00055 clSockServ::clSockServ (const char *cpSockFile)
00056 {
00057 iErrno = 0;
00058 Bind(cpSockFile);
00059 }
00060
00061
00062
00063 bool clSockServ::Bind(unsigned short usPort)
00064 {
00065 int iFlag = 1;
00066 struct sockaddr_in sServAddr;
00067
00068 bLocal = false;
00069 iListenH = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
00070 if (iListenH < 0)
00071 {
00072 iErrno = errno;
00073 return false;
00074 }
00075 if (setsockopt(iListenH, SOL_SOCKET, SO_REUSEADDR,
00076 &iFlag, sizeof(iFlag)) < 0)
00077 {
00078 iErrno = errno;
00079 return false;
00080 }
00081 memset(&sServAddr, 0x00, sizeof(sServAddr));
00082 sServAddr.sin_family = AF_INET;
00083 sServAddr.sin_addr.s_addr = htonl(INADDR_ANY);
00084 sServAddr.sin_port = htons(usPort);
00085 if (bind(iListenH, (struct sockaddr *) &sServAddr, sizeof(sServAddr)) < 0)
00086 {
00087 iErrno = errno;
00088 return false;
00089 }
00090 if (listen(iListenH, SOCKSERV_LISTENQUEUE_LEN) < 0)
00091 {
00092 iErrno = errno;
00093 return false;
00094 }
00095 return true;
00096 }
00097
00098
00099 bool clSockServ::Bind(const char *cpAddress, unsigned short usPort)
00100 {
00101 int iFlag = 1;
00102 struct sockaddr_in sServAddr;
00103
00104 bLocal = false;
00105 iListenH = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
00106 if (iListenH < 0)
00107 {
00108 iErrno = errno;
00109 return false;
00110 }
00111 if (setsockopt(iListenH, SOL_SOCKET, SO_REUSEADDR,
00112 &iFlag, sizeof(iFlag)) < 0)
00113 {
00114 iErrno = errno;
00115 return false;
00116 }
00117 memset(&sServAddr, 0x00, sizeof(sServAddr));
00118 sServAddr.sin_family = AF_INET;
00119 if (cpAddress != NULL)
00120 {
00121 sServAddr.sin_addr.s_addr = inet_addr(cpAddress);
00122 }
00123 else
00124 {
00125 sServAddr.sin_addr.s_addr = htonl(INADDR_ANY);
00126 }
00127 sServAddr.sin_port = htons(usPort);
00128 if (bind(iListenH, (struct sockaddr *) &sServAddr, sizeof(sServAddr)) < 0)
00129 {
00130 iErrno = errno;
00131 return false;
00132 }
00133 if (listen(iListenH, SOCKSERV_LISTENQUEUE_LEN) < 0)
00134 {
00135 iErrno = errno;
00136 return false;
00137 }
00138 return true;
00139 }
00140
00141
00142 bool clSockServ::Bind(const char *cpSockFile)
00143 {
00144 #ifndef __QNX__
00145 int iFlag = 1;
00146 mode_t mtPrevMask;
00147 struct sockaddr_un sServAddr;
00148
00149 bLocal = true;
00150 if (access(cpSockFile, W_OK) == 0)
00151 {
00152 unlink(cpSockFile);
00153 }
00154 iListenH = socket(PF_UNIX, SOCK_STREAM, 0);
00155 if (iListenH < 0)
00156 {
00157 iErrno = errno;
00158 return false;
00159 }
00160 if (setsockopt(iListenH, SOL_SOCKET, SO_REUSEADDR,
00161 &iFlag, sizeof(iFlag)) < 0)
00162 {
00163 iErrno = errno;
00164 return false;
00165 }
00166 memset(&sServAddr, 0x00, sizeof(sServAddr));
00167 sServAddr.sun_family = AF_UNIX;
00168 if ((strlen(GLOBAL_SOCKET_PATH) + strlen(cpSockFile)) > UNIX_PATH_MAX)
00169 {
00170 iErrno = 0;
00171 return false;
00172 }
00173 sprintf(sServAddr.sun_path, "%s/%s", GLOBAL_SOCKET_PATH, cpSockFile);
00174 strcpy(cpLocalSockName, sServAddr.sun_path);
00175 mtPrevMask = umask(0111);
00176 if (bind(iListenH, (struct sockaddr *) &sServAddr, sizeof(sServAddr)) < 0)
00177 {
00178 umask(mtPrevMask);
00179 iErrno = errno;
00180 return false;
00181 }
00182 umask(mtPrevMask);
00183 if (listen(iListenH, SOCKSERV_LISTENQUEUE_LEN) < 0)
00184 {
00185 iErrno = errno;
00186 return false;
00187 }
00188 return true;
00189 #else
00190 return Bind(atoi(cpSockFile));
00191 #endif
00192 }
00193
00194
00195 clSockServ::~clSockServ()
00196 {
00197 Close();
00198 }
00199
00200
00201 int clSockServ::WaitForConnect()
00202 {
00203 int iClientH;
00204 socklen_t iAddrLen;
00205 struct sockaddr_un sClientAddrU;
00206 struct sockaddr_in sClientAddrI;
00207
00208 if (bLocal)
00209 {
00210 iAddrLen = sizeof(sClientAddrU);
00211 iClientH = accept(iListenH, (struct sockaddr *) &sClientAddrU,
00212 &iAddrLen);
00213 }
00214 else
00215 {
00216 iAddrLen = sizeof(sClientAddrI);
00217 iClientH = accept(iListenH, (struct sockaddr *) &sClientAddrI,
00218 &iAddrLen);
00219 }
00220 if (iClientH < 0)
00221 {
00222 iErrno = errno;
00223 return -1;
00224 }
00225 return iClientH;
00226 }
00227
00228
00229 int clSockServ::WaitForConnect(int iTimeout)
00230 {
00231 int iClientH;
00232 int iSelectResult;
00233 struct timeval sTimeout;
00234 struct sockaddr_un sClientAddrU;
00235 struct sockaddr_in sClientAddrI;
00236 socklen_t iAddrLen;
00237 fd_set fdsetListen;
00238
00239 sTimeout.tv_sec = iTimeout / 1000;
00240 sTimeout.tv_usec = iTimeout % 1000 * 1000;
00241 FD_ZERO(&fdsetListen);
00242 FD_SET(iListenH, &fdsetListen);
00243 iSelectResult = select(iListenH + 1, &fdsetListen, NULL, NULL, &sTimeout);
00244 if (iSelectResult > 0)
00245 {
00246 if (bLocal)
00247 {
00248 iAddrLen = sizeof(sClientAddrU);
00249 iClientH = accept(iListenH, (struct sockaddr *) &sClientAddrU,
00250 &iAddrLen);
00251 }
00252 else
00253 {
00254 iAddrLen = sizeof(sClientAddrI);
00255 iClientH = accept(iListenH, (struct sockaddr *) &sClientAddrI,
00256 &iAddrLen);
00257 }
00258 if (iClientH < 0)
00259 {
00260 iErrno = errno;
00261 return -1;
00262 }
00263 return iClientH;
00264 }
00265 else if (iSelectResult == 0)
00266 {
00267 iErrno = 0;
00268 return -1;
00269 }
00270 else
00271 {
00272 iErrno = errno;
00273 return -1;
00274 }
00275 }
00276
00277
00278 void clSockServ::Close ()
00279 {
00280 if (iListenH >= 0)
00281 {
00282 close(iListenH);
00283 if (bLocal)
00284 {
00285 unlink(cpLocalSockName);
00286 }
00287 }
00288 }
00289