home *** CD-ROM | disk | FTP | other *** search
- /* rcv.c 8/7/91
- *
- * Copyright 1991 Perry R. Ross
- *
- * Permission to use, copy, modify, and distribute this software and its
- * documentation without fee is hereby granted, subject to the restrictions
- * detailed in the README file, which is included here by reference.
- * Any other use requires written permission from the author. This software
- * is distributed "as is" without any warranty, including any implied
- * warranties of merchantability or fitness for a particular purpose.
- * The author shall not be liable for any damages resulting from the
- * use of this software. By using this software, the user agrees
- * to these terms.
- */
-
- #include "ldb.h"
-
-
- /*----------------------------------------------------------------------
- * readmail -- read the incoming mail and process it
- *
- * This function extracts each packet from the mail file and applies it
- * to the appropriate game structure. Most packets are processed by
- * calling the handler found in the func array, which is a 2-dimensional
- * array indexed by the current game state and the received opcode.
- * The handlers are responsible for transforming the game state as
- * necessary. The START and RSTART opcodes receive special processing,
- * since they apply to games that do not exist and thus have no state.
- * START packets result in the creation of a game, whose state is set
- * such that the correct handler will be called. The RSTART opcode
- * is processed in the same way as the -start command line argument;
- * the packet is then discarded.
- *----------------------------------------------------------------------
- */
-
- readmail(file)
- char *file;
- {
- FILE *fp;
- int d, c1, c2;
-
- if ( (fp = fopen(file,"r")) == NULL)
- return;
- while (getpkt(fp) > 0) { /* as long as we found a valid packet */
- if (P.gameptr == NULL) {
- if (P.opcode == START) {
- P.gameptr = addgame(); /* init later in start() */
- P.gameptr->gameid = P.gameid;
- P.gameptr->state = ST_OPSTART;
- }
- else if (P.opcode == RSTART) { /* remote start packet */
- if (P.dir == NULL) /* if no direction was given */
- d = cr_mydir; /* use my default */
- else /* dir was given, grab it */
- d = (*P.dir == 'u') ? 1 : -1;
- if (P.colors == NULL) { /* if no colors were given */
- c1 = cr_mycolor; /* use my defaults */
- c2 = cr_opcolor;
- }
- else { /* colors were given */
- c1 = *P.colors; /* use them */
- c2 = P.colors[1];
- }
- startgame(P.addr,d,c1,c2); /* start a game */
- continue; /* discard this packet */
- }
- else {
- fprintf(stderr,"ERROR: no such gameid: %s (ignored)\n",
- P.gameid);
- continue;
- }
- }
- if (P.gameptr->state >= OPSTATES) { /* hey, it's still my turn */
- fprintf(stderr,
- "ERROR: move out of turn: %s (ignored)\n",P.gameid);
- continue;
- }
- if (P.name != NULL) /* snarf opponent's name */
- P.gameptr->opname = P.name;
- (*func[P.gameptr->state][P.opcode])(P.gameptr); /* call handler */
- }
- }
-
-
- /*---------------------------------------------------------------------------
- * getpkt -- read one packet from a file
- *
- * This function reads the next packet from the specified file.
- * Getpkt() is passed a open file pointer to the file it is to scan.
- * Lines are read and discarded until a line is found that contains only:
- * <<<===LDB===>>>
- * Subsequent lines should contain name/value pairs as specified
- * in nv_packet. The packet ends with end of file or a line beginning
- * with "end=". Getpkt reads from the input file until one
- * packet has been found and processed, then returns. Subsequent calls
- * to getpkt with the same file pointer will process additional packets.
- * Getpkt returns 1 if a valid packet was read, 0 if EOF was encountered.
- * Getpkt ignores incoming packets with the incorrect sequence number.
- *---------------------------------------------------------------------------
- */
-
- getpkt(fp)
- FILE *fp;
- {
- static char buf[128];
- int i;
-
- while (fgets(buf,sizeof(buf),fp) != NULL) {
- if (strcmp(buf,"<<<===LDB===>>>\n"))/* skip all other lines */
- continue;
- P.gameid = NULL; /* init P structure */
- P.timestamp = 0L;
- P.opcode = -1;
- P.name = NULL;
- P.addr = NULL;
- P.comment = NULL;
- P.comment2 = NULL;
- P.seq = -1;
- P.autodbl = NULL;
- clearmvs(P.mvs);
- P.gameptr = NULL;
- nvscan(fp,nv_packet,&P,opcodes); /* scan the packet into P */
- if (P.gameid == NULL) { /* didn't get a gameid */
- fprintf(stderr,"ERROR: missing gameid in packet -- ignored\n");
- continue;
- }
- if ( (P.gameptr = findgame(P.gameid)) == NULL) /* doesn't exist */
- i = 1; /* initial seq == 1 */
- else
- i = P.gameptr->seq+1; /* get current seq */
- if (P.seq != i) { /* sequence number is wrong */
- if (P.seq > i) /* rec'd seq # is too big */
- fprintf(stderr, /* shouldn't happen */
- "WARNING: game %s, seq no. is %d, s/b %d -- ignored.\n"
- ,P.gameid,P.seq,i);
- continue; /* ignore pkts with bad sequence #s */
- }
- if ( (P.opcode < 0) || (P.opcode >= NOP) ) { /* bad opcode */
- fprintf(stderr,
- "ERROR: bad opcode for game %s: %d -- ignored.\n",
- P.gameid,P.opcode);
- continue;
- }
- if (P.gameptr != NULL) {
- P.gameptr->seq += 2; /* bump sequence number */
- if (P.gameptr->opcmt != NULL)
- free(P.gameptr->opcmt); /* discard old comment */
- P.gameptr->opcmt = P.comment; /* copy new comment */
- if (P.gameptr->opcmt2 != NULL)
- free(P.gameptr->opcmt2);/* discard old comment */
- P.gameptr->opcmt2 = P.comment2; /* copy new comment */
- }
- return(1); /* return success */
- }
- return(0); /* return this to mean end of file */
- }
-