server/bed.cxx File Reference

multi-user backend main More...

#include <errno.h>
#include <setjmp.h>
#include <stdlib.h>
#include <signal.h>
#include <sys/time.h>
#include <time.h>
#include "udanax.h"
#include "players.h"
#include "requests.h"

Include dependency graph for bed.cxx:

Include dependency graph

Go to the source code of this file.

Functions

bool getrequest (Session *sess, typerequest *requestptr)
 ???

void sendresultoutput (Session *session)
 ???

void xuputstring (char *string, FILE *fd)
 ???

void processrcfile ()
 ???

void crash (int)
 ???

void leave (PLAYER player[], int *xn_players)
 ???

int open_sock ()
 ???

void new_players (PLAYER player[], int *n_playersp, int block, Session *sess)
 ???

void logaccount (Tumbler *tp)
 ???

void xanadu (Session *sess)
 ???

void flagquitting (int)
 ???

int main (int argc, char *argv[])
 ???

bool establishprotocol (FILE *inp, FILE *outp)
 ???

void frontenddied ()
 ???

void setmaximumsetupsize (Session *sess)
 ???

void sourceunixcommand (Session *sess)
 ???

bool decrementusers ()
 ???


Variables

int backenddaemon
jmp_buf frontendeof
int user = 0
int errno
FILE * logfile
FILE * nulllog
FILE * reallog
char outputbuffer [BUFSIZ]
char inputbuffer [BUFSIZ]
bool logstuff
FILE * interfaceinput
FILE * febelog
timeval timeout
int main_socket
Tumbler currentaccount
bool quitafteruser = false
bool mightbeblocked = false


Detailed Description

multi-user backend main

(to be defined)

Definition in file bed.cxx.


Function Documentation

void crash int   ) 
 

???

(to be defined)

Definition at line 294 of file socketbe.cxx.

References L, and user.

Referenced by main().

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 }

bool decrementusers  ) 
 

???

(to be defined)

Definition at line 417 of file bed.cxx.

References n_players, player, and user.

00418 {
00419     if (n_players > 1) {
00420         player[user].wantsout = 1;
00421     }
00422     return (n_players > 1);
00423 }

bool establishprotocol FILE *  inp,
FILE *  outp
 

???

(to be defined)

Definition at line 335 of file bed.cxx.

References Session::errp, febelog, firstputforrequest, Session::inp, L, metachar, nulllog, Session::outp, pullc(), sendresultoutput(), and xuputstring().

Referenced by main(), and new_players().

00338 {
00339     L("Entering establishprotocol()\n");
00340 
00341     metachar ch;
00342 
00343 /* This is the metaprotocol for the time being */
00344     while ((ch = getc(inp)) != '\n')
00345         putc((ch > ' ' ? ch : '.'), stderr);
00346 
00347     while ((ch = getc(inp)) == '\n')
00348         putc(ch, stderr);
00349 
00350     L("establishprotocol: synced up\n");
00351 
00352     if (ch == 'P' && getc(inp) == '0' && getc(inp) == '~') {
00353         if (!feof(inp)) {              /* Don't send to a dead pipe */
00354             xuputstring("\nP0~", outp);
00355             fflush(outp);
00356             L("Leaving establishprotocol(), SUCCESS\n");
00357             return true;
00358         }
00359     } else {
00360         if (!feof(inp)) {              /* Don't send to a dead pipe */
00361             xuputstring("\nP?~", outp);
00362             fflush(outp);
00363         }
00364     }
00365     L("Leaving establishprotocol(), FAIL\n");
00366     return false;
00367 }

void flagquitting int   ) 
 

???

(to be defined)

Definition at line 180 of file bed.cxx.

References closediskfile(), interfaceinput, mightbeblocked, QUIT, quitafteruser, and writeenfilades().

Referenced by main().

00182 {
00183     signal(SIGINT, SIG_IGN);           /* Don't die too early */
00184     if (mightbeblocked) {
00185         if (interfaceinput) {
00186             fprintf(interfaceinput, "%d~\n", QUIT);
00187             fclose(interfaceinput);
00188         }
00189         writeenfilades();
00190         closediskfile();
00191         exit(0);
00192     } else
00193         quitafteruser = true;          /* Flag to stop backend after current request */
00194 }

void frontenddied  ) 
 

???

(to be defined)

Definition at line 377 of file bed.cxx.

References assert, diskexit(), frontendeof, and L.

00378 {
00379     longjmp(frontendeof, 1);
00380 }

bool getrequest Session sess,
typerequest *  requestptr
 

???

(to be defined)

Parameters:
sess  Input: User's session context

Definition at line 326 of file get2.cxx.

00327                                    : User's session context
00328     typerequest *requestptr)
00329 {
00330     prompt(sess, "\nrequest? ");
00331     int c = getc(sess->inp);
00332     if ((int) c == EOF) {
00333         L("endfile\n");
00334         sess->inp = stdin;
00335     }                                  /* else if (c == ':') { while ((c = * getc (sess->inp)) != '\n'); * return
00336                                         * (false); } */
00337     ungetc(c, sess->inp);
00338     return getnumber(sess, requestptr) && validrequest(sess, *requestptr);
00339 }

void leave PLAYER  player[],
int *  xn_players
 

???

(to be defined)

Definition at line 225 of file socketbe.cxx.

References inputfds, L, PLAYER, player, and _player::wantsout.

Referenced by main().

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 }

void logaccount Tumbler tp  ) 
 

???

(to be defined)

Definition at line 535 of file get1fe.cxx.

References interfaceinput, puttumbler(), and XACCOUNT.

Referenced by main().

00537 {
00538     if (interfaceinput) {
00539         fprintf(interfaceinput, "%d~", XACCOUNT);
00540         puttumbler(interfaceinput, tp);
00541     }
00542 }

int main int  argc,
char *  argv[]
 

???

(to be defined)

<Input: User's session context

Definition at line 204 of file bed.cxx.

References Session::account, assert, backenddaemon, closediskfile(), crash(), currentaccount, debug, diskflush(), errno, fdtoplayer, febelog, flagquitting(), init(), initsession(), Session::inp, inputbuffer, inputfds, interfaceinput, L, leave(), logaccount(), logfile, main_socket, mightbeblocked, n_players, new_players(), nfds, nsessorcommand, NULL, nulllog, open_sock(), Session::outp, outputbuffer, player, processrcfile(), QUIT, quitafteruser, reallog, timeout, tumblereq(), user, writeenfilades(), and xanadu().

00207 {                                      /* inside temporary */
00208     Session sess;    
00209     char buf[100];
00210     //UNUSED FILE *fd;
00211     struct tm *local;
00212     long clock;
00213 
00214 /* extern void crash();* *//* if broken pipe, release port (I hope) */
00215 
00216     //UNUSED int s;      /* for socket */
00217     fd_set inputfds2;
00218     int i;
00219 
00220     freopen("backenderror", "w", stderr);
00221     setbuf(stderr, NULL);
00222 
00223     backenddaemon = 1;
00224 
00225     FD_ZERO(&inputfds);
00226 
00227     processrcfile();
00228 
00229     signal(SIGPIPE, crash);
00230     signal(SIGHUP, crash);
00231     signal(SIGXCPU, SIG_IGN);
00232     signal(SIGINT, flagquitting);
00233 
00234     febelog = interfaceinput = reallog = logfile = nulllog = fopen("/dev/null", "a");
00235 
00236     clock = time(0);
00237     local = localtime(&clock);
00238     sprintf(buf, "ln%d.%d.%d:%d", local->tm_mon + 1, local->tm_mday, local->tm_hour, local->tm_min);
00239     interfaceinput = fopen(buf, "w");
00240 
00241 #ifndef DISTRIBUTION
00242     sprintf(buf, "febe%d.%d.%d:%d", local->tm_mon + 1, local->tm_mday, local->tm_hour, local->tm_min);
00243     febelog = fopen(buf, "w");
00244     setbuf(febelog, NULL);
00245 #endif
00246 
00247     setbuf(stdin, inputbuffer);
00248     setbuf(stdout, outputbuffer);
00249     debug = 0;
00250     init(1);
00251     //now uses a ctor:: inittask(&sess);
00252     errno = 0;
00253     initsession("enf.enf");
00254     main_socket = open_sock();
00255 
00256     if (n_players < 1) {
00257         mightbeblocked = true;
00258         new_players(player, &n_players, true, &sess);   /* wait for fe to talk to */
00259         mightbeblocked = false;
00260     }
00261 
00262     for (;;) {
00263         if (n_players < 1) {
00264             diskflush();               /* Write out everything when no one around */
00265             mightbeblocked = true;
00266             new_players(player, &n_players, true, &sess);       /* wait for fe to talk to */
00267             mightbeblocked = false;
00268         }
00269 
00270         inputfds2       = inputfds;
00271         timeout.tv_sec  = 2;                /* wait 2 seconds on a select, then look for a new user */
00272         timeout.tv_usec = 0;
00273 
00274         int nevents = select(nfds + 1, &inputfds2, 0, 0, &timeout);
00275         if (nevents < 0) {
00276             if (errno == EINTR) {
00277                 continue;
00278             }
00279             perror("select");
00280             assert(0); // select in main
00281         } else {
00282 
00283             if (nevents)
00284                 L("Somone connected to our main socket\n");
00285 
00286             for (i = 0; i <= nfds; i++) {
00287                 if (FD_ISSET(i, &inputfds2)) {
00288 //OBSOLETE                if ((1 << i) & inputfds2) {
00289                     L("Read-Event on socket %d\n", i);
00290 
00291                     user         = fdtoplayer[i];
00292                     sess.inp     = player[user].inp;
00293                     sess.outp    = player[user].outp;
00294                     sess.account = player[user].account;
00295 
00296                     if (!tumblereq(&currentaccount, &sess.account)) {
00297                         currentaccount = sess.account;
00298                         logaccount(&sess.account);
00299                     }
00300 
00301                     xanadu(&sess);
00302 
00303                     if (quitafteruser) {
00304                         if (interfaceinput) {
00305                             fprintf(interfaceinput, "%d~\n", QUIT);
00306                             fclose(interfaceinput);
00307                         }
00308                         writeenfilades();
00309                         closediskfile();
00310                         exit(0);
00311                     }
00312 /* testforreservedness("main"); */
00313 /* logfile = nulllog; */
00314                     nsessorcommand++;
00315                 }
00316             }
00317         }
00318 
00319         leave(player, &n_players);
00320         mightbeblocked = true;
00321         new_players(player, &n_players, false, &sess);
00322         mightbeblocked = false;
00323     }
00324     return 0;
00325 }

void new_players PLAYER  player[],
int *  n_playersp,
int  block,
Session sess
 

???

(to be defined)

Parameters:
sess  Input: User's session context

Definition at line 126 of file socketbe.cxx.

References ERROR, establishprotocol(), fdtoplayer, _player::inp, Session::inp, inputfds, L, main_socket, max, MAX_PLAYERS, nfds, NULL, open_sock(), Session::outp, _player::outp, PLAYER, player, _player::socket, and _player::wantsout.

Referenced by main().

00130                                : User's session context
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 }

int open_sock  ) 
 

???

(to be defined)

Definition at line 256 of file socketbe.cxx.

References L, and portname.

Referenced by main(), and new_players().

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 }

void processrcfile  ) 
 

???

(to be defined)

Definition at line 110 of file rcfile.cxx.

00111 {
00112     FILE *rcfd;
00113     static char buf[BUFSIZ];
00114     static char line[256];
00115     static char name[256];
00116     int temp;
00117 
00118     if ((rcfd = fopen(RCFILENAME, "r")) != NULL) {
00119         while (fgets(buf, BUFSIZ, rcfd)) {
00120             if (buf[0] != '#' && sscanf(buf, "%s = %s", name, line) == 2) {
00121 //UNUSED                if (!strcmp(name, BACKENDFILEMETANAME))
00122 //UNUSED                    strcpy(backendfilename, line);
00123 //UNUSED                else if (!strcmp(name, ACCOUNTFILEMETANAME))
00124 //UNUSED                     strcpy(accountfilename, line);
00125 //UNUSED                else
00126                 if (!strcmp(name, PORTMETANAME)) {
00127                     if (sscanf(line, "%d", &portname) < 1) {
00128                         L("Could not use port = %s, using %d\n", line, PORT);
00129                         portname = PORT;
00130                     }
00131                 } else if (!strcmp(name, HOSTMETANAME))
00132                     strcpy(hostname, line);
00133 //UNUSED                else if (!strcmp(name, BACKENDDIRECTORYMETANAME))
00134 //UNUSED                    strcpy(backenddirectoryname, line);
00135 //UNUSED                else if (!strcmp(name, BACKENDGLUEFILEMETANAME))
00136 //UNUSED                    strcpy(backendgluefilename, line);
00137 //UNUSED                else if (!strcmp(name, FRONTENDGLUEFILEMETANAME))
00138 //UNUSED                    strcpy(frontendgluefilename, line);
00139 //UNUSED                else if (!strcmp(name, FRONTENDFILEMETANAME))
00140 //UNUSED                    strcpy(frontendfilename, line);
00141                 else if (!strcmp(name, ALLOCSIZENAME)) {
00142                     temp = allocsize;
00143                     sscanf(line, "%d", &allocsize);
00144                     if (allocsize < 100000 || allocsize > 300000000) {  /* minimal sanity checking */
00145                         incrementalallocsize = temp;
00146                     }
00147                 } else if (!strcmp(name, INCREMENTALALLOCSIZENAME)) {
00148                     temp = incrementalallocsize;
00149                     sscanf(line, "%d", &incrementalallocsize);
00150                     if (incrementalallocsize < 10000 || incrementalallocsize > 100000000) {
00151                         incrementalallocsize = temp;
00152                     }
00153                 } else
00154                     L("Don't know about %s = %s\n", name, line);
00155             }
00156         }
00157         fclose(rcfd);
00158     }
00159 }

void sendresultoutput Session session  ) 
 

???

(to be defined)

Parameters:
session  Input: User's session context

Definition at line 192 of file putfe.cxx.

References Session::outp.

Referenced by establishprotocol(), and xanadu().

00193                                   : User's session context
00194 {
00195 /* FILE *fd; fd = session->outp; write (fd->_file, fd->_base, (int) (fd->_ptr - fd->_base)); fd->_ptr = fd->_base;
00196  * fd->_cnt = BUFSIZ; */
00197     fflush(session->outp);
00198 }

void setmaximumsetupsize Session sess  ) 
 

???

(to be defined)

Parameters:
sess  Input: User's session context

Definition at line 391 of file bed.cxx.

00392                                : User's session context
00393 {
00394 }

void sourceunixcommand Session sess  ) 
 

???

(to be defined)

Parameters:
sess  Input: User's session context

Definition at line 404 of file bed.cxx.

00405                                : User's session context
00406 {
00407 }

void xanadu Session sess  ) 
 

???

(to be defined)

Parameters:
sess  Input: User's session context

Definition at line 142 of file bed.cxx.

References closeberts(), Session::free(), frontendeof, getrequest(), interfaceinput, L, logstuff, nulllog, player, QUIT, requestfns, sendresultoutput(), typerequest, and user.

00143                                : User's session context
00144 {
00145     L("Entering xanadu()\n");
00146 
00147     typerequest request;
00148 
00149     logstuff = false;
00150     if (setjmp(frontendeof)) {
00151         closeberts(sess);
00152         player[user].wantsout = true;
00153 
00154     } else if (getrequest(sess, &request)) {
00155 
00156         (*requestfns[request]) (sess);
00157         sendresultoutput(sess);
00158 
00159         if (request == QUIT)
00160             player[user].wantsout = true;
00161     }
00162 
00163     sess->free();
00164 
00165     if (interfaceinput && interfaceinput != nulllog)
00166         fflush(interfaceinput);
00167 
00168     logstuff = false;
00169     L("Leaving xanadu()\n");
00170 }

void xuputstring char *  string,
FILE *  fd
 

???

(to be defined)

Definition at line 145 of file putfe.cxx.

Referenced by error(), establishprotocol(), and prompt().

00148 {
00149 /* while (*string) xuputc (*string++, fd); */
00150     fwrite(string, 1, strlen(string), fd);
00151 }


Variable Documentation

int backenddaemon
 

Definition at line 91 of file bed.cxx.

Tumbler currentaccount [static]
 

Definition at line 120 of file bed.cxx.

Referenced by main().

int errno
 

Definition at line 109 of file bed.cxx.

FILE* febelog
 

Definition at line 117 of file bed.cxx.

jmp_buf frontendeof
 

Definition at line 105 of file bed.cxx.

Referenced by frontenddied(), and xanadu().

char inputbuffer[BUFSIZ]
 

Definition at line 114 of file bed.cxx.

FILE* interfaceinput
 

Definition at line 116 of file bed.cxx.

FILE* logfile
 

Definition at line 110 of file bed.cxx.

bool logstuff
 

Definition at line 115 of file bed.cxx.

int main_socket
 

Definition at line 119 of file bed.cxx.

Referenced by main(), and new_players().

bool mightbeblocked = false
 

Definition at line 122 of file bed.cxx.

Referenced by flagquitting(), and main().

FILE* nulllog
 

Definition at line 111 of file bed.cxx.

char outputbuffer[BUFSIZ]
 

Definition at line 113 of file bed.cxx.

bool quitafteruser = false
 

Definition at line 121 of file bed.cxx.

Referenced by flagquitting(), and main().

FILE* reallog
 

Definition at line 112 of file bed.cxx.

struct timeval timeout
 

Definition at line 118 of file bed.cxx.

Referenced by main().

int user = 0
 

Definition at line 107 of file bed.cxx.


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