Main Page | Data Structures | File List | Data Fields | Globals | Related Pages

nsnet.c

Go to the documentation of this file.
00001 
00004 /*
00005 NeuroServer
00006 
00007 A collection of programs to translate between EEG data and TCP network
00008 messages. This is a part of the OpenEEG project, see http://openeeg.sf.net
00009 for details.
00010 
00011 Copyright (C) 2003, 2004 Rudi Cilibrasi (cilibrar@ofb.net)
00012 
00013 This library is free software; you can redistribute it and/or
00014 modify it under the terms of the GNU Lesser General Public
00015 License as published by the Free Software Foundation; either
00016 version 2.1 of the License, or (at your option) any later version.
00017 
00018 This library is distributed in the hope that it will be useful,
00019 but WITHOUT ANY WARRANTY; without even the implied warranty of
00020 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00021 Lesser General Public License for more details.
00022 
00023 You should have received a copy of the GNU Lesser General Public
00024 License along with this library; if not, write to the Free Software
00025 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
00026 */
00027 
00028 
00029 
00030 #include <stdio.h>
00031 #include <fcntl.h>
00032 #include <string.h>
00033 #include <assert.h>
00034 #include <stdlib.h>
00035 #include <nsnet.h>
00036 #include <nsutil.h>
00037 #include <monitor.h>
00038 
00039 #ifndef __MINGW32__
00040 #include <signal.h>
00041 #endif
00042 
00043 #define NUM_WRITEN 1
00044 #define NUM_READN   2
00045 #define NUM_MYREAD   3
00046 #define NUM_READLINE   4
00047 #define NUM_WRITEN2 5
00048 
00049 #define NUM_MAX 6
00050 
00051 // output of debugging information (if not defined)
00052 #define NUM_QUIET
00053 
00054 unsigned int cur[NUM_MAX], last[NUM_MAX];
00055 
00056 void addCount(int where)
00057 {
00058         assert(where >= 0 && where < NUM_MAX);
00059         cur[where] += 1;
00060 }
00061 
00062 void showCounts()
00063 {
00064 #ifdef NUM_QUIET
00065         return;
00066 #else
00067         int i;
00068 
00069         for (i = 0; i < NUM_MAX; ++i)
00070                 rprintf("%d:%d\t", i, cur[i]);
00071         rprintf("\n");
00072 #endif
00073 }
00074 
00075 
00076 int isEOF(sock_t con, const struct InputBuffer *ib)
00077 {
00078         return ib->isEOF;
00079 }
00080 
00081 const char *stringifyErrorCode(int code)
00082 {
00083         static char buf[80];
00084 #if 0 && (defined(__MINGW32__) || defined(__CYGWIN__))
00085         switch (code) {
00086                 case WSAECONNRESET:
00087                         return "WSAECONNRESET";
00088                         break;
00089                 case WSAECONNREFUSED:
00090                         return "WSAECONNREFUSED";
00091                         break;
00092                 case WSAECONNABORTED:
00093                         return "WSAECONNABORTED";
00094                         break;
00095                 case WSAENOTSOCK:
00096                         return "WSAENOTSOCK";
00097                         break;
00098                 case WSAEINVAL:
00099                         return "WSAEINVAL";
00100                         break;
00101                 case WSAEISCONN:
00102                         return "WSAEISCONN";
00103                         break;
00104                 case WSAEALREADY:
00105                         return "WSAEALREADY";
00106                         break;
00107                 case WSAEWOULDBLOCK:
00108                         return "WSAEWOULDBLOCK";
00109                         break;
00110                 case WSAEINPROGRESS:
00111                         return "WSAEINPROGRESS";
00112                         break;
00113                 default:
00114                         sprintf(buf, "<unknown win:%d>", code);
00115                         return buf;
00116                         break;
00117         }
00118 #else
00119         sprintf(buf, "<unknown %s:%d>", OSTYPESTR, code);
00120         return buf;
00121 #endif
00122 }
00123 
00124 void rshutdown(sock_t fd)
00125 {
00126 #if 0 && (defined(__MINGW32__) || defined(__CYGWIN__))
00127         shutdown(fd, SD_BOTH);
00128 #else
00129         shutdown(fd, SHUT_RDWR);
00130 #endif
00131 }
00132 
00133 void setblocking(sock_t sock_fd)
00134 {
00135         int retval;
00136 #if 0 && (defined(__MINGW32__) || defined(__CYGWIN__))
00137         do {
00138                 u_long val;
00139                 val = 0;
00140                 retval = ioctlsocket(sock_fd, FIONBIO, &val);
00141                 if (retval != 0) {
00142                         int winerr;
00143                         winerr = WSAGetLastError();
00144                         monitorLog(PLACE_SETBLOCKING, winerr);
00145                         rexit(1);
00146                 }
00147         } while (0);
00148 #else
00149         do {
00150                 int flags;
00151                 flags = fcntl(sock_fd, F_GETFL, 0);
00152                 retval = fcntl(sock_fd, F_SETFL, flags & (~O_NONBLOCK));
00153 //              if (retval != 0) {
00154 //                      rprintf("Error clearing O_NONBLOCK\n");
00155 //                      rexit(1);
00156 //              }
00157         } while (0);
00158 #endif
00159 }
00160 void setnonblocking(sock_t sock_fd)
00161 {
00162         int retval;
00163 #if 0 && (defined(__MINGW32__) || defined(__CYGWIN__))
00164         do {
00165                 u_long val;
00166                 val = 1;
00167                 retval = ioctlsocket(sock_fd, FIONBIO, &val);
00168                 if (retval != 0) {
00169                         rprintf("Error setting FIONBIO\n");
00170                         rexit(1);
00171                 }
00172         } while (0);
00173 #else
00174         do {
00175                 int flags;
00176                 flags = fcntl(sock_fd, F_GETFL, 0);
00177                 retval = fcntl(sock_fd, F_SETFL, flags | O_NONBLOCK);
00178                 if (retval != 0) {
00179                         rprintf("Error setting O_NONBLOCK\n");
00180                         rexit(1);
00181                 }
00182         } while (0);
00183 #endif
00184 }
00185 
00186 sock_t rsocket(void) {
00187         sock_t sock_fd;
00188         sock_fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
00189         setnonblocking(sock_fd);
00190         return sock_fd;
00191 }
00192 
00193 #if 1 || (!defined(__MINGW32__) && !defined(__CYGWIN__))
00194 void sigPIPEHandler(int i) {
00195 }
00196 #endif
00197 
00198 int rinitNetworking(void) {
00199         static int mustInit = 1;
00200         if (mustInit) {
00201                 mustInit = 0;
00202 #if 0 && (defined(__MINGW32__) || defined(__CYGWIN__))
00203         WSADATA wsadata;
00204         WSAStartup(MAKEWORD(2,0), &wsadata);
00205         WSASetLastError(0);
00206 #else
00207         signal(SIGPIPE, sigPIPEHandler);
00208 #endif
00209         }
00210         return 0;
00211 }
00212 
00213 int rbindAll(sock_t sock_fd)
00214 {
00215         rsockaddr_t local;
00216         int retval;
00217         int one = 1;
00218 
00219         retval = setsockopt(sock_fd,SOL_SOCKET,SO_REUSEADDR,(char *)&one,sizeof(one));
00220 
00221         if (retval != 0) {
00222                 rprintf("setsockopt error\n");
00223                 rexit(1);
00224         }
00225 
00226         local.sin_family = AF_INET;
00227         local.sin_port = htons(DEFAULTPORT);
00228         local.sin_addr.s_addr = INADDR_ANY;
00229 
00230         retval = bind(sock_fd, (struct sockaddr *) &local, sizeof(local));
00231         if (retval != 0) {
00232                 rprintf("bind error\n");
00233                 rexit(1);
00234         }
00235         retval = listen(sock_fd, MAXCLIENTS);
00236         if (retval != 0) {
00237                 rprintf("listen error\n");
00238                 rexit(1);
00239         }
00240 
00241         return 0;
00242 }
00243 
00244 int rconnectName(sock_t sock_fd, const char *hostname, unsigned short portno)
00245 {
00246         int retval;
00247 #if 0 && (defined(__MINGW32__) || defined(__CYGWIN__))
00248         int winerr;
00249 #endif
00250         rsockaddr_t local;
00251         hostent_t host;
00252         host = gethostbyname(hostname);
00253         if(host == NULL) {
00254                 rprintf("Error looking up %s\n", hostname);
00255                 perror("gethostbyname");
00256                 rexit(1);
00257         }
00258         local.sin_family = AF_INET;
00259         local.sin_port = htons(portno);
00260 #if 0 && (defined(__MINGW32__) || defined(__CYGWIN__))
00261         local.sin_addr = *((LPIN_ADDR)*host->h_addr_list);
00262 #else
00263         local.sin_addr = *((struct in_addr *)host->h_addr);
00264 #endif
00265 
00266         rprintf("Connecting to %s at %s:%d\n", hostname, inet_ntoa(local.sin_addr), portno);
00267 
00268   while (1) {
00269                 retval = connect(sock_fd, (struct sockaddr *) &local, sizeof(local));
00270     if (retval != 0) {
00271       if (errno == EISCONN)
00272         return 0;
00273       else {
00274         if (errno == EINPROGRESS) {
00275           rsleep(5);
00276           continue;
00277         }
00278         perror("moreconnect");
00279       }
00280     }
00281                 monitorLog(PLACE_CONNECT, errno);
00282         }
00283 }
00284 
00285 sock_t raccept(sock_t sock_fd)
00286 {
00287 #if 0 && (defined(__MINGW32__) || defined(__CYGWIN__))
00288         int winerr;
00289 #endif
00290         rsockaddr_t modaddr;
00291         int modaddrsize = sizeof(modaddr);
00292 
00293         sock_t retval;
00294 
00295         do {
00296                 retval = accept(sock_fd, (struct sockaddr *) &modaddr, &modaddrsize);
00297 #if 0 && (defined(__MINGW32__) || defined(__CYGWIN__))
00298                 if (retval == SOCKET_ERROR) {
00299                         winerr = WSAGetLastError();
00300                         rprintf("Got error code %s\n", stringifyErrorCode(winerr));
00301                 }
00302         } while (retval == SOCKET_ERROR);
00303 #else
00304         } while (retval == -1);
00305 #endif
00306         rprintf("Received new connection from %s\n", inet_ntoa(modaddr.sin_addr));
00307         return retval;
00308 }
00309 
00310 int writeString(sock_t con, const char *buf, struct OutputBuffer *ob)
00311 {
00312         return writeBytes(con, buf, strlen(buf), ob);
00313 }
00314 
00315 int rrecv(sock_t fd, char *read_buf, size_t count)
00316 {
00317         int retval = -1;
00318         retval = recv(fd, read_buf, count, 0);
00319 #if 0 && (defined(__MINGW32__) || defined(__CYGWIN__))
00320         int winerr;
00321         if (retval == SOCKET_ERROR) {
00322                 winerr = WSAGetLastError();
00323                 if (winerr == WSAEISCONN || winerr == WSAEWOULDBLOCK)
00324                         retval = 0;
00325                 if (winerr == WSAENOTCONN || winerr == WSAECONNRESET)
00326                         retval = -1;
00327                 if (retval == -1)
00328                         monitorLog(PLACE_RRECV, winerr);
00329         }
00330 #endif
00331         return retval;
00332 }
00333 
00334 int writeBytes(sock_t con, const char *buf, int size, struct OutputBuffer *ob)
00335 {
00336         int retval;
00337         char obuf[MAXLEN];
00338         memcpy(obuf, buf, size);
00339         obuf[size] = 0;
00340 //      rprintf("Trying to write (%s) to socket %x\n", obuf, con);
00341         setblocking(con);
00342         retval = send(con, buf, size, 0);
00343         setnonblocking(con);
00344         if (retval != size) {
00345                 rprintf("send error: %d\n", retval);
00346 #if 0 && (defined(__MINGW32__) || defined(__CYGWIN__))
00347                 do {
00348                         int winerr;
00349                         winerr = WSAGetLastError();
00350                         monitorLog(PLACE_WRITEBYTES, winerr);
00351                 } while (0);
00352 #endif
00353         }
00354         return retval;
00355 }
00356 
00357 void initOutputBuffer(struct OutputBuffer *ob)
00358 {
00359         memset(ob, 0, sizeof(*ob));
00360 }
00361 
00362 void initInputBuffer(struct InputBuffer *ib)
00363 {
00364         memset(ib, 0, sizeof(*ib));
00365 }
00366 
00367 int my_read(sock_t fd, char *ptr, size_t maxlen, struct InputBuffer *ib)
00368 {
00369         addCount(NUM_MYREAD);
00370         showCounts();
00371         //setblocking(fd);
00372         //again:
00373         if (maxlen == 1) {
00374                 rprintf("Inefficient myread(%d)\n", maxlen);
00375         }
00376         if (ib->read_cnt <= 0) {
00377                         if ( (ib->read_cnt = rrecv(fd, ib->read_buf, maxlen)) < 0) {
00378 #if 0 && (defined(__MINGW32__) || defined(__CYGWIN__))
00379                                 int winerr;
00380                                 winerr = WSAGetLastError();
00381                                 if (winerr != WSAEWOULDBLOCK)
00382                                         monitorLog(PLACE_MYREAD, winerr);
00383                                 if (winerr == WSAECONNABORTED || winerr == WSAECONNRESET) {
00384                                         ib->isEOF = 1;
00385                                         return -1;
00386                                 }
00387                                 if (winerr == WSAEWOULDBLOCK)
00388                                         return 0;
00389 //                              if (winerr == WSAESHUTDOWN || winerr == WSAENOTCONN || winerr == WSAECONNRESET)
00390 #else
00391 #endif
00392                                 return -1;
00393                         } else {
00394                                 if (ib->read_cnt == 0) {
00395 #if defined(__MINGW32__) || defined(__CYGWIN__)
00396                                         ib->isEOF = 1;
00397 #endif
00398                                         return 0;
00399                                 }
00400                         }
00401                         ib->read_ptr = ib->read_buf;
00402         }
00403         
00404         ib->read_cnt--;
00405         *ptr = *ib->read_ptr++;
00406         return 1;
00407 }
00408         
00409 size_t readn(sock_t fd, void *vptr, size_t len, struct InputBuffer *ib)
00410 {
00411         size_t nleft;
00412         size_t nread;
00413         char *ptr;
00414         addCount(NUM_READN);
00415         showCounts();
00416         ptr = vptr;
00417         nleft = len;
00418         while (nleft > 0) {
00419                 if ( (nread = recv(fd, ptr, nleft, 0)) < 0) {
00420                         return -1;
00421                 } else if (nread == 0)
00422                                 break;
00423                 nleft -= nread;
00424                 ptr += nread;
00425         }
00426         printf("In readn, returning %d\n", len-nleft);
00427         return len - nleft;
00428 }
00429 
00430 size_t writen(sock_t fd, const void *vptr, size_t len, struct OutputBuffer *ob)
00431 {
00432         int nleft;
00433         int nwritten;
00434         const char *ptr;
00435         addCount(NUM_WRITEN);
00436         showCounts();
00437 
00438         ptr = vptr;
00439         nleft = len;
00440         while (nleft > 0) {
00441                 addCount(NUM_WRITEN2);
00442                 showCounts();
00443                 nwritten = send(fd, ptr, nleft, 0);
00444                 if (nwritten <= 0)
00445                         return -1;
00446                 nleft -= nwritten;
00447                 ptr += nwritten;
00448         }
00449         return len;
00450 }
00451 
00452 size_t readlinebuf(void **vptrptr, struct InputBuffer *ib)
00453 {
00454         if (ib->read_cnt)
00455                 *vptrptr = ib->read_ptr;
00456         return (ib->read_cnt);
00457 }
00458 
00459 int inputBufferEmpty(const struct InputBuffer *ib)
00460 {
00461         return ib->read_cnt == 0;
00462 }
00463 
00464 int getOK(sock_t sock_fd, struct InputBuffer *ib)
00465 {
00466         int retcode;
00467         rprintf("Waiting for OK\n");
00468         do {
00469                 retcode = getResponseCode(sock_fd, ib);
00470         } while (retcode == 0);
00471         if (retcode == -1) {
00472                 rprintf("nsnet.o: Server died, exitting.\n");
00473                 exit(0);
00474         }
00475         if (retcode != 200) {
00476                 printf("Got bad response: %d\n", retcode);
00477                 exit(1);
00478         }
00479         return 0;
00480 }
00481 
00482 int getResponseCode(sock_t sock_fd, struct InputBuffer *ib)
00483 {
00484         char linebuf[MAXLEN+1];
00485         int len;
00486         do {
00487                 len = readline(sock_fd, linebuf, MAXLEN, ib);
00488         } while (len == 0 && !isEOF(sock_fd, ib));
00489         if (isEOF(sock_fd, ib))
00490                 return -1;
00491         linebuf[len] = '\0';
00492 //      rprintf("Got response: <%s>\n", linebuf);
00493         strtok(linebuf, " ");
00494         return atoi(linebuf);
00495 }
00496 
00497 static int rselect_real(sock_t max_fd, fd_set *toread, fd_set *towrite, 
00498         fd_set *toerr,
00499         struct timeval *tv)
00500 {
00501         return select(max_fd, toread,towrite, toerr, tv);
00502 }
00503 
00504 int rselect_timed(sock_t max_fd, fd_set *toread, fd_set *towrite, 
00505         fd_set *toerr, struct timeval *tv)
00506 {
00507         int retval;
00508         retval = rselect_real(max_fd, toread, towrite, toerr, tv);
00509         return retval;
00510 }
00511         
00512 int rselect(sock_t max_fd, fd_set *toread, fd_set *towrite, fd_set *toerr)
00513 {
00514         int retval;
00515 
00516         retval = rselect_real(max_fd, toread, towrite, toerr, NULL);
00517 #if 0 && (defined(__MINGW32__) || defined(__CYGWIN__))
00518         if (retval == SOCKET_ERROR) {
00519                 int winerr;
00520                 winerr = WSAGetLastError();
00521                 monitorLog(PLACE_RSELECT, winerr);
00522         }
00523 #else
00524 #endif
00525 
00526         return retval;
00527 }
00528 
00529 int readline(sock_t fd, char *vptr, size_t maxlen, struct InputBuffer *ib)
00530 {
00531         size_t n;
00532         int rc;
00533         char c, *ptr;
00534 
00535         addCount(NUM_READLINE);
00536         showCounts();
00537 
00538         setblocking(fd);
00539         ptr = vptr;
00540         for (n = 1; n < maxlen; n++) {
00541                 rc = my_read(fd, &c, maxlen, ib);
00542                 if (rc == -1)
00543                         return -1;
00544                 if (rc == 0) {
00545                         *ptr = 0;
00546                         n -= 1;
00547                         break;
00548                 }
00549                 if (rc == 1) {
00550                         if (c != '\n' && c != '\r')
00551                                 *ptr++ = c;
00552                         if (c == '\n')
00553                                 break;
00554                 } 
00555         }
00556         *ptr = '\0';
00557         return n;
00558 }
00559 
00560 #define MAXHANDLER 1024
00561 struct FDHandlerEntry {
00562         sock_t fd;        
00563         void (*handler)(void *uobj, const char *data, size_t len); 
00564         void *uobj; 
00565 };
00566 
00567 struct FDHandlerEntry fdTable[MAXHANDLER]; 
00568 int handlerCount; 
00575 int findFdIndex(sock_t fd)
00576 {
00577         int i;
00578         for (i = 0; i < handlerCount; ++i)
00579                 if (fdTable[i].fd == fd)
00580                         return i;
00581         return -1;
00582 }
00583 
00584 int makeNewEntryForFD(sock_t fd, void (*handler)(void *uobj, const char *data, size_t len), void *uobj)
00585 {
00586         int newid = handlerCount;
00587         handlerCount += 1;
00588         if (handlerCount >= MAXHANDLER) {
00589                 rprintf("Error: ran out of FD table space at %d\n", handlerCount);
00590                 exit(1);
00591         }
00592         fdTable[newid].fd = fd;
00593         fdTable[newid].handler = handler;
00594         fdTable[newid].uobj = uobj;
00595         return newid;
00596 }
00597 
00598 int setFdHandler(sock_t fd, void (*handler)(void *uobj, const char *data, size_t len), void *uobj)
00599 {
00600         int id;
00601         id = findFdIndex(fd);
00602         if (id == -1)
00603                 id = makeNewEntryForFD(fd, handler, uobj);
00604         else {
00605                 fdTable[id].handler = handler;
00606                 fdTable[id].uobj = uobj;
00607         }
00608         return 0;
00609 }
00610 
00611 int removeFdHandler(sock_t fd)
00612 {
00613         int id;
00614         id = findFdIndex(fd);
00615         if (id == -1)
00616                 return 1;
00617         if (id < handlerCount-1)
00618                 memmove(&fdTable[id], &fdTable[id+1], (handlerCount-id-1) * sizeof(fdTable[0]));
00619         handlerCount -= 1;
00620         return 0;
00621 }
00622 
00623 #define MAXREAD 16384
00624 int handleReads(sock_t fd)
00625 {
00626         int have_read;
00627         char readbuf[MAXREAD];
00628         have_read = rrecv(fd, readbuf, MAXREAD);
00629         if (have_read > 0) {
00630                 int id = findFdIndex(fd);
00631                 if (id != -1 && fdTable[id].handler != NULL) {
00632                         fdTable[id].handler(fdTable[id].uobj, readbuf, have_read);
00633                 }
00634                 // TODO: Handle EOF
00635         }
00636         return 0;
00637 }

Generated on Tue Feb 8 00:05:16 2005 for Neuroserver by doxygen 1.3.3