server/socketbe.cxx

Go to the documentation of this file.
00001 /**********************************************************************
00002  * Copyright 2002 Jeff Rush <jrush@taupro.com>
00003  * Original Copyright 1979-2002 Udanax.com
00004  *
00005  * This file is part of the Udanax xanalogical storage system.
00006  *
00007  * Udanax is free software; you can redistribute it and/or modify it
00008  * under the terms of the GNU General Public License as published by
00009  * the Free Software Foundation; either version 2 of the License, or
00010  * (at your option) any later version.
00011  *
00012  * Udanax is distributed in the hope that it will be useful, but
00013  * WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU General Public License
00018  * along with Udanax; if not, write to the Free Software Foundation,
00019  * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00020  **********************************************************************/
00021 
00030 /* Modification History:
00031  * $Log: socketbe.cxx,v $
00032  * Revision 1.15  2004/09/11 15:02:00  jrush
00033  * Fixed Doxygen tags on all Session parameter arguments.
00034  *
00035  * Revision 1.14  2004/09/11 13:59:21  jrush
00036  * Changed all fprintf's to stderr to use the Nana library L() macro.  Also
00037  * removed a 2-3 minor compiler warnings.
00038  *
00039  * Revision 1.13  2004/09/04 16:02:18  jrush
00040  * Added Doxygen headers before each and every function definition.
00041  *
00042  * Revision 1.12  2002/05/28 03:58:42  jrush
00043  * Sources modified to comply with GPL licensing.
00044  *
00045  * Revision 1.11  2002/04/12 11:48:51  jrush
00046  * Major reorganization of includes into a single base-include style.
00047  *
00048  * Revision 1.10  2002/04/09 21:45:47  jrush
00049  * Renamed class 'tumbler' to 'Tumbler', for consistency with Python sources,
00050  * and changed typeisa from typedef to a subclass, in preparation for cleaning
00051  * up the type/class tree.
00052  *
00053  * Revision 1.9  2002/04/07 14:04:37  jrush
00054  * Add ptr to Session to checkforopen() and isthisusersdocument() so that we
00055  * have session information available to make the decision.
00056  *
00057  * Revision 1.8  2002/04/06 19:51:30  jrush
00058  * Renamed TRUE/FALSE constant use to the C++ standard of true/false.
00059  *
00060  * Revision 1.7  2002/04/06 17:05:57  jrush
00061  * Switched from referring to 'task' for a client connection to 'session',
00062  * and converted the typetask typedef/struct into a Session C++ class.
00063  *
00064  * Revision 1.6  2002/04/06 15:01:45  jrush
00065  * Changed INT to just 'int'.
00066  *
00067  * Revision 1.5  2002/04/02 17:17:25  jrush
00068  * Fixed select() and FD_SET handling to work under Gnu C on Linux.
00069  *
00070  * Revision 1.4  2002/02/14 10:08:26  jrush
00071  * Cleaned up source:
00072  *
00073  * 1. ran thru the indent tool to achieve a standard look,
00074  * 2. added structured comments at top for use with DOxygen reporting
00075  *    as well as CVS keywords,
00076  * 3. centralized prototypes in protos.h, removing incomplete ones,
00077  * 4. cleaned up use of bool/BOOLEAN type to suit C++ type,
00078  * 5. fixed initializer nesting in tumbler constants,
00079  * 6. converted select() int bits into ANSI fd_set type,
00080  * 7. added Makefile.am for use by automake.
00081  *
00082  */
00083 
00084 #include <stdio.h>
00085 #include <stdlib.h>
00086 #include <errno.h>
00087 #include <sys/types.h>
00088 #include <sys/socket.h>
00089 #include <netinet/in.h>
00090 #include <sys/time.h>
00091 #include <netdb.h>
00092 #include <string.h>
00093 #include <unistd.h>
00094 #include "udanax.h"
00095 #include "players.h"
00096 #include "port.h"
00097 
00098 #define ERROR           -1
00099 #define typerequest int
00100 #define MAX_PLAYERS     25             /* max # concurrent players */
00101 
00102 /* These two are set in rcfile.c, possibly from the .backendrc file */
00103 extern char hostname[];
00104 extern int portname;
00105 
00106 int fdtoplayer[32];
00107 Tumbler defaultaccount = { 0, 0, 0, 0, { 1, 1, 0, 14, 0, 0, 0, 0, 0, 0, 0 } };
00108 
00109 PLAYER player[MAX_PLAYERS];     /* player information */
00110 int n_players = 0;
00111 fd_set inputfds;
00112 int nfds = 0;
00113 
00114 int main_socket = ERROR;        /* socket to accept connections on */
00115 
00116 extern bool establishprotocol(FILE *inp, FILE *outp);
00117 
00125     void
00126 new_players(
00127     PLAYER   player[],
00128     int     *n_playersp,
00129     int      block,
00130     Session *sess)    
00131     /* array of player info structures */
00132     /* number of players (incl comp) */
00133     /* if nobody wants to join, wait on socket until somebody * does. */
00134 {
00135     int s;      /* temp holder for new socket */
00136     int rc;     /* # ready selected sockets */
00137     struct sockaddr_in from;    /* connection acceptor */
00138     socklen_t fromlen = sizeof(from);
00139     struct timeval t;   /* don't let select() run forever */
00140     //UNUSED int i;
00141     //UNUSED FILE *temp;
00142     //UNUSED char devicename[100];
00143     //UNUSED int len;
00144     //UNUSED typerequest requestinstance;
00145     int open_sock();    /* to open main socket */
00146 
00147     if (main_socket == ERROR)
00148         main_socket = open_sock();
00149 
00150 /* set up 0 second timeout for use on select() calls */
00151 /* well it USED to be 0 seconds, but that seems too fast now !<reg sep 10 1999> */
00152     t.tv_sec = 0L;
00153     t.tv_usec = 3L;
00154     
00155     for (;;) {
00156         fd_set readfds;
00157         FD_ZERO(&readfds);
00158         FD_SET(main_socket, &readfds);
00159 //OBSOLETE        readfds = 1 << main_socket;
00160 
00161         t.tv_sec  = 0L;
00162         t.tv_usec = 3L;
00163         if ((rc = select(32, &readfds, 0, 0, &t)) == -1) { // Wait on Main Socket
00164             perror("new_players:select");
00165             fflush(stdout);
00166             break;
00167         }
00168         if (rc > 0 || block) {
00169             if ((s = accept(main_socket, (sockaddr *) &from, &fromlen)) < 0) {
00170                 perror("new_players:accept");
00171                 fflush(stdout);
00172                 break;
00173             }
00174             if (*n_playersp >= MAX_PLAYERS) {
00175                 L("TOOMANY frontends: won't log another one\n");
00176                 close(s);
00177             } else {
00178                 block = false;
00179 #ifndef DISTRIBUTION
00180                 L("accepted connection from %d ", s);
00181 #endif
00182 /* read ttyname and open socket for it; */
00183 
00184                 player[*n_playersp].socket = s;
00185                 if ((player[*n_playersp].inp = fdopen(s, "r")) == NULL) {
00186                     perror("fdopen(r)");
00187                     break;
00188                 }
00189                 if ((sess->outp = player[*n_playersp].outp = fdopen(s, "w")) == NULL) {
00190                     perror("fdopen(w)");
00191                     break;
00192                 }
00193                 sess->inp = player[*n_playersp].inp;
00194 
00195 #ifndef DISTRIBUTION
00196                 L("%s\n", (char *) &(player[*n_playersp].account));
00197 #endif
00198                 if (!establishprotocol(sess->inp, sess->outp)) {
00199                     break;
00200                 }
00201 // getrequest(sess, &requestinstance);
00202 // getxaccount(sess, &(player[*n_playersp].account));
00203 // logaccount(&(player[*n_playersp].account));
00204                 player[*n_playersp].wantsout = false;
00205 
00206                 fdtoplayer[s] = *n_playersp;
00207                 FD_SET(s, &inputfds);
00208                 nfds = max(s, nfds);
00209                 (*n_playersp)++;
00210                 break;
00211             }
00212         } else
00213             break;
00214     }
00215 }
00216 
00224     void
00225 leave(
00226     PLAYER  player[],
00227     int    *xn_players)
00228 {
00229     register int i;
00230 
00231     for (i = 0; i < *xn_players; i++)
00232         if (player[i].wantsout) {
00233             FD_CLR(player[i].socket, &inputfds);
00234 //OBSOLETE            inputfds ^= (1 << (player[i].socket));
00235 
00236             if (close(player[i].socket) != 0) {
00237                 L("user %d: ", i);
00238                 perror("close player.socket");
00239             }
00240             if (*xn_players > 1) {
00241                 player[i] = player[*xn_players - 1];
00242             }
00243             (*xn_players)--;
00244             --i;                       /* since this entry is new, test again */
00245         }
00246 }
00247 
00255     int
00256 open_sock()
00257 {                                      /* Open the main socket. */
00258     int s;
00259     struct sockaddr_in sockaddr;
00260     //UNUSED struct hostent *host;
00261 
00262     if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
00263         perror("socket()");
00264         exit(1);
00265     }
00266 /* 
00267  * if ((host = gethostbyname(hostname)) == NULL) { perror("gethostbyname()");
00268  * exit(1); } */
00269     sockaddr.sin_family = AF_INET;
00270     sockaddr.sin_port = htons(portname);
00271     sockaddr.sin_addr.s_addr = /* inetaddr */ INADDR_ANY;
00272 
00273     L("calling bind s = %d \n", s);
00274 
00275     if (bind(s, (struct sockaddr *) &sockaddr, sizeof(sockaddr)) < 0) {
00276         perror("bind()");
00277         exit(1);
00278     }
00279     if (listen(s, 0) < 0) {
00280         perror("listen()");
00281         exit(1);
00282     }
00283     return (s);
00284 }
00285 
00293     void
00294 crash(
00295     int /*sigarg*/)
00296 {
00297     int i;
00298 
00299     L("CRASH while dealing with user %d\n", user);
00300     for (i = 0; i < 32; i++)
00301         close(i);                      /* BOO HISS: too many closes */
00302     exit(9);
00303 }
00304 
00312     bool
00313 isthisusersdocument(
00314     Session *sess,    
00315     Tumbler *tp)
00316 {
00317     return tumbleraccounteq(tp, &(player[user].account));
00318 }

Generated on Sun Aug 21 04:18:15 2005 for Udanax-Green by doxygen1.3.4