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

  1. /*    rcv.c        8/7/91
  2.  *
  3.  * Copyright 1991  Perry R. Ross
  4.  *
  5.  * Permission to use, copy, modify, and distribute this software and its
  6.  * documentation without fee is hereby granted, subject to the restrictions
  7.  * detailed in the README file, which is included here by reference.
  8.  * Any other use requires written permission from the author.  This software
  9.  * is distributed "as is" without any warranty, including any implied
  10.  * warranties of merchantability or fitness for a particular purpose.
  11.  * The author shall not be liable for any damages resulting from the
  12.  * use of this software.  By using this software, the user agrees
  13.  * to these terms.
  14.  */
  15.  
  16. #include "ldb.h"
  17.  
  18.  
  19. /*----------------------------------------------------------------------
  20.  *    readmail -- read the incoming mail and process it
  21.  *
  22.  * This function extracts each packet from the mail file and applies it
  23.  * to the appropriate game structure.  Most packets are processed by
  24.  * calling the handler found in the func array, which is a 2-dimensional
  25.  * array indexed by the current game state and the received opcode.
  26.  * The handlers are responsible for transforming the game state as
  27.  * necessary.  The START and RSTART opcodes receive special processing,
  28.  * since they apply to games that do not exist and thus have no state.
  29.  * START packets result in the creation of a game, whose state is set
  30.  * such that the correct handler will be called.  The RSTART opcode
  31.  * is processed in the same way as the -start command line argument;
  32.  * the packet is then discarded.
  33.  *----------------------------------------------------------------------
  34.  */
  35.  
  36. readmail(file)
  37. char *file;
  38. {
  39. FILE *fp;
  40. int d, c1, c2;
  41.  
  42. if ( (fp = fopen(file,"r")) == NULL)
  43.     return;
  44. while (getpkt(fp) > 0) {    /* as long as we found a valid packet */
  45.     if (P.gameptr == NULL) {
  46.         if (P.opcode == START) {
  47.             P.gameptr = addgame(); /* init later in start() */
  48.             P.gameptr->gameid = P.gameid;
  49.             P.gameptr->state = ST_OPSTART;
  50.             }
  51.         else if (P.opcode == RSTART) {    /* remote start packet */
  52.             if (P.dir == NULL)    /* if no direction was given */
  53.                 d = cr_mydir;    /* use my default */
  54.             else            /* dir was given, grab it */
  55.                 d = (*P.dir == 'u') ? 1 : -1;
  56.             if (P.colors == NULL) {    /* if no colors were given */
  57.                 c1 = cr_mycolor;    /* use my defaults */
  58.                 c2 = cr_opcolor;
  59.                 }
  60.             else {                /* colors were given */
  61.                 c1 = *P.colors;        /* use them */
  62.                 c2 = P.colors[1];
  63.                 }
  64.             startgame(P.addr,d,c1,c2);    /* start a game */
  65.             continue;        /* discard this packet */
  66.             }
  67.         else {
  68.             fprintf(stderr,"ERROR: no such gameid: %s (ignored)\n",
  69.                 P.gameid);
  70.             continue;
  71.             }
  72.         }
  73.     if (P.gameptr->state >= OPSTATES) {    /* hey, it's still my turn */
  74.         fprintf(stderr,
  75.             "ERROR: move out of turn: %s (ignored)\n",P.gameid);
  76.         continue;
  77.         }
  78.     if (P.name != NULL)        /* snarf opponent's name */
  79.         P.gameptr->opname = P.name;
  80.     (*func[P.gameptr->state][P.opcode])(P.gameptr);    /* call handler */
  81.     }
  82. }
  83.  
  84.  
  85. /*---------------------------------------------------------------------------
  86.  *    getpkt -- read one packet from a file
  87.  *
  88.  * This function reads the next packet from the specified file.
  89.  * Getpkt() is passed a open file pointer to the file it is to scan.
  90.  * Lines are read and discarded until a line is found that contains only:
  91.  *        <<<===LDB===>>>
  92.  * Subsequent lines should contain name/value pairs as specified
  93.  * in nv_packet.  The packet ends with end of file or a line beginning
  94.  * with "end=".  Getpkt reads from the input file until one
  95.  * packet has been found and processed, then returns.  Subsequent calls
  96.  * to getpkt with the same file pointer will process additional packets.
  97.  * Getpkt returns 1 if a valid packet was read, 0 if EOF was encountered.
  98.  * Getpkt ignores incoming packets with the incorrect sequence number.
  99.  *---------------------------------------------------------------------------
  100.  */
  101.  
  102. getpkt(fp)
  103. FILE *fp;
  104. {
  105. static char buf[128];
  106. int i;
  107.  
  108. while (fgets(buf,sizeof(buf),fp) != NULL) {
  109.     if (strcmp(buf,"<<<===LDB===>>>\n"))/* skip all other lines */
  110.         continue;
  111.     P.gameid = NULL;    /* init P structure */
  112.     P.timestamp = 0L;
  113.     P.opcode = -1;
  114.     P.name = NULL;
  115.     P.addr = NULL;
  116.     P.comment = NULL;
  117.     P.comment2 = NULL;
  118.     P.seq = -1;
  119.     P.autodbl = NULL;
  120.     clearmvs(P.mvs);
  121.     P.gameptr = NULL;
  122.     nvscan(fp,nv_packet,&P,opcodes);    /* scan the packet into P */
  123.     if (P.gameid == NULL) {        /* didn't get a gameid */
  124.         fprintf(stderr,"ERROR: missing gameid in packet -- ignored\n");
  125.         continue;
  126.         }
  127.     if ( (P.gameptr = findgame(P.gameid)) == NULL)    /* doesn't exist */
  128.         i = 1;            /* initial seq == 1 */
  129.     else
  130.         i = P.gameptr->seq+1;    /* get current seq */
  131.     if (P.seq != i) {        /* sequence number is wrong */
  132.         if (P.seq > i)        /* rec'd seq # is too big */
  133.             fprintf(stderr,        /* shouldn't happen */
  134.             "WARNING: game %s, seq no. is %d, s/b %d -- ignored.\n"
  135.             ,P.gameid,P.seq,i);
  136.         continue;        /* ignore pkts with bad sequence #s */
  137.         }
  138.     if ( (P.opcode < 0) || (P.opcode >= NOP) ) {    /* bad opcode */
  139.         fprintf(stderr,
  140.             "ERROR: bad opcode for game %s: %d -- ignored.\n",
  141.             P.gameid,P.opcode);
  142.         continue;
  143.         }
  144.     if (P.gameptr != NULL) {
  145.         P.gameptr->seq += 2;    /* bump sequence number */
  146.         if (P.gameptr->opcmt != NULL)
  147.             free(P.gameptr->opcmt);    /* discard old comment */
  148.         P.gameptr->opcmt = P.comment;    /* copy new comment */
  149.         if (P.gameptr->opcmt2 != NULL)
  150.             free(P.gameptr->opcmt2);/* discard old comment */
  151.         P.gameptr->opcmt2 = P.comment2;    /* copy new comment */
  152.         }
  153.     return(1);            /* return success */
  154.     }
  155. return(0);        /* return this to mean end of file */
  156. }
  157.