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

SockServ.cc

Go to the documentation of this file.
00001 /*
00002 
00003     Socket server class
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 <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 

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