home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
misc
/
volume28
/
ldb
/
part01
/
readmail.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-03-15
|
5KB
|
157 lines
/* 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 */
}