home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / games / volume14 / okbridge2 / part09 / protocol.c < prev   
C/C++ Source or Header  |  1993-01-27  |  20KB  |  874 lines

  1. /* command.c -- Command processor for communications between client
  2.  * and server.
  3.  *
  4.  ! Copyright (C) 1990-1992 by Matthew Clegg.  All Rights Reserved
  5.  ! 
  6.  ! OKbridge is made available as a free service to the Internet.
  7.  ! Accordingly, the following restrictions are placed on its use:
  8.  ! 
  9.  ! 1.  OKbridge may not be modified in any way without the explicit 
  10.  !     permission of Matthew Clegg.  
  11.  ! 
  12.  ! 2.  OKbridge may not be used in any way for commercial advantage.
  13.  !     It may not be placed on for-profit networks or on for-profit
  14.  !     computer systems.  It may not be bundled as part of a package
  15.  !     or service provided by a for-profit organization.
  16.  ! 
  17.  ! If you have questions about restrictions on the use of OKbridge,
  18.  ! write to mclegg@cs.ucsd.edu.
  19.  ! 
  20.  ! DISCLAIMER:  The user of OKbridge accepts full responsibility for any
  21.  ! damage which may be caused by OKbridge.
  22.  *
  23.  */
  24.  
  25. #include <stdio.h>
  26. #include <string.h>
  27. #include <ctype.h>
  28.  
  29. #define PROTOCOL
  30. #include "types.h"
  31. #include "protocol.h"
  32. #include "state.h"
  33. #include "parser.h"
  34.  
  35. #ifdef GCC
  36. extern sscanf ();
  37. #endif
  38.  
  39. void 
  40.   Parse_ack (), 
  41.   Parse_alert (), 
  42.   Parse_begin (), 
  43.   Parse_bid (), 
  44.   Parse_board (),
  45.   Parse_claim (),
  46.   Parse_claimreq (),
  47.   Parse_claimresp (),
  48.   Parse_cc (), 
  49.   Parse_comment (), 
  50.   Parse_connerr (), 
  51.   Parse_deal (),
  52.   Parse_echo (), 
  53.   Parse_email (),
  54.   Parse_end (), 
  55.   Parse_fullname (),
  56.   Parse_hello (), 
  57.   Parse_mode (),
  58.   Parse_name (), 
  59.   Parse_ping (), 
  60.   Parse_play (), 
  61.   Parse_playreq (),
  62.   Parse_quit (), 
  63.   Parse_reconnect (),
  64.   Parse_record (),
  65.   Parse_registry (),
  66.   Parse_reset (),
  67.   Parse_seat (), 
  68.   Parse_seaterr (), 
  69.   Parse_seatpos (), 
  70.   Parse_seatreq (),
  71.   Parse_servereq (),
  72.   Parse_score (), 
  73.   Parse_skip (), 
  74.   Parse_skipack (),
  75.   Parse_spec (),
  76.   Parse_table (),
  77.   Parse_tablereq (),
  78.   Parse_talk (), 
  79.   Parse_userec (),
  80.   Parse_wakeup (),
  81.   Parse_who (), 
  82.   Parse_whois (), 
  83.   Parse_whoresp ();
  84.  
  85. static Command_Descriptor Commands [] = {
  86.   {"ACK",    {{F_NAME, "<player-name>"}, 
  87.           {F_KEYWORD | F_OPTIONAL, PARSER_SEATS}, NOP},  Parse_ack},
  88.   {"ALERT",  C_KEY("OPP|ALL"), Parse_alert},
  89.   {"BEGIN",  C_EMPTY, Parse_begin},
  90.   {"BID",    {{F_BID, "<bid-name>"}, {F_KEYWORD | F_OPTIONAL, "ALERT"},
  91.         NOP}, Parse_bid},
  92.   {"BOARD",  {{F_NAME, "<board-name>"}, {F_INT, "<board-number>"}, NOP},
  93.               Parse_board},
  94.  
  95.   {"CC",     C_PARAM(F_STRING, "<convention-card>"), Parse_cc},
  96.   {"CLAIM",  C_INT("<no-tricks>"), Parse_claim},
  97.   {"CLAIMREQ",  C_INT("<no-tricks>"), Parse_claimreq},
  98.   {"CLAIMRESP", C_KEY("REJECT|ACCEPT"), Parse_claimresp},
  99.   {"COMMENT",C_STRING("<message>"), Parse_comment},
  100.  
  101.   {"CONNERR",C_STRING("<error-message>"), Parse_connerr},
  102.   {"DEAL",   C_EMPTY, Parse_deal},
  103.   {"ECHO",   C_PARAM(F_NAME, "<ping-source>"), Parse_echo},
  104.   {"EMAIL",  C_STRING("<email-address>"), Parse_email},
  105.   {"END",    C_EMPTY, Parse_end},
  106.  
  107.   {"FULLNAME", C_STRING("<full-name>"), Parse_fullname},
  108.   {"HELLO",  {{F_NAME, "<version>"}, {F_NAME, "<player-name>"}, 
  109.           {F_KEYWORD | F_OPTIONAL, PARSER_SEATS}}, Parse_hello},
  110.   {"MODE",   C_KEY("CLUB|PRACTICE|FORMAL"), Parse_mode},
  111.   {"NAME",   C_PARAM(F_NAME, "<new-player-name>"), Parse_name},
  112.   {"PING",   C_EMPTY, Parse_ping},
  113.  
  114.   {"PLAY",   C_PARAM(F_CARD, "<card-name>"), Parse_play},
  115.   {"PLAYREQ", {{F_CARD, "<card-name>"}, {F_INT, "<sequence-number>"}, NOP}, 
  116.      Parse_play},
  117.   {"QUIT",   C_EMPTY, Parse_quit},
  118.   {"RECONNECT", {{F_NAME, "<ip-number>"}, {F_INT, "<port-number>"},
  119.            {F_KEYWORD, PARSER_SEATS}}, Parse_reconnect},
  120.   {"RECORD", {{F_NAME, "<board-name>"}, {F_INT, "<board-number>"}, NOP}, 
  121.               Parse_record},
  122.  
  123.   {"REGISTRY", C_PARAM(F_NAME, "<identification>"), Parse_registry},
  124.   {"RESET",  C_EMPTY, Parse_reset},
  125.   {"SCORE",  {{F_STRING, "<current-scores>"}, NOP, NOP}, Parse_score},
  126.   {"SEAT",   {{F_KEYWORD, PARSER_SEATS}, {F_KEYWORD, PARSER_SEATS},
  127.         {F_NAME, "<player-name>"}}, Parse_seat},
  128.   {"SEATERR",{{F_KEYWORD | F_OPTIONAL, PARSER_SEATS},
  129.               {F_KEYWORD | F_OPTIONAL, PARSER_SEATS},
  130.           {F_KEYWORD | F_OPTIONAL, PARSER_SEATS}}, Parse_seaterr},
  131.  
  132.   {"SEATPOS", {{F_KEYWORD, PARSER_SEATS}, NOP, NOP}, Parse_seatpos},
  133.   {"SEATREQ", C_SEAT, Parse_seatreq},
  134.   {"SERVEREQ",C_PARAM(F_STRING, "<server-command>"), Parse_servereq},
  135.   {"SKIP",    C_EMPTY, Parse_skip},
  136.   {"SKIPACK",C_EMPTY, Parse_skipack},
  137.  
  138.   {"SPEC",   C_EMPTY, Parse_spec},
  139.   {"TABLE",    C_INT("<table-number>"), Parse_table},
  140.   {"TABLEREQ", C_INT("<requested-table-number>"), Parse_tablereq},
  141.   {"TALK",   {{F_KEYWORD, "LHO|RHO|OPPS|SPEC|ALL"}, {F_STRING, "<message>"}, 
  142.         NOP}, Parse_talk},
  143.   {"USEREC", {{F_STRING, "<player-names>"}, NOP, NOP}, Parse_userec},
  144.  
  145.   {"WAKEUP", C_PARAM(F_NAME, "<player-name> | ALL"), Parse_wakeup},
  146.   {"WHO",    C_EMPTY, Parse_who},
  147.   {"WHOIS",  C_PARAM(F_NAME, "<player-name>"), Parse_whois},
  148.   {"WHORESP",{{F_NAME, "<recipient>"}, {F_STRING, "<ident>"}, NOP},
  149.      Parse_whoresp},
  150.   END_PARSE_TABLE
  151. };
  152.  
  153.  
  154. static char send_buffer [132];
  155. static player_command p;
  156.  
  157. void Send_ack (t, player_name, pos)
  158.      Table_ptr t; name_buffer player_name; int pos;
  159. {
  160.   sprintf (send_buffer, "ACK %s %s", player_name,
  161.        (pos < 4)? seat_names[pos]: "");
  162.   send_message (t, CMD_ACK, send_buffer);
  163. }
  164.  
  165. void Send_alert (t, notify_partner)
  166.      Table_ptr t; int notify_partner;
  167. {
  168.   sprintf (send_buffer, "ALERT %s", notify_partner? "ALL": "OPP");
  169.   send_message (t, CMD_ALERT, send_buffer);
  170. }
  171.  
  172. void Send_begin (t)
  173.      Table_ptr t;
  174. {
  175.   send_message (t, CMD_BEGIN, "BEGIN");
  176. }
  177.  
  178. void Send_bid (t, bid, alert)
  179.      Table_ptr t;
  180.      int bid;
  181.      int alert;
  182. {
  183.   sprintf (send_buffer, "BID %s %s", bid_names[bid],  alert? "ALERT": "");
  184.   send_message (t, CMD_BID, send_buffer);
  185. }
  186.  
  187. void Send_board (t, b)
  188.      Table_ptr t; board_ptr b;
  189. {
  190.   Message m;
  191.  
  192.   sprintf (send_buffer, "BOARD %s %d", b->source, b->serial_no);
  193.   m = send_message (t, CMD_BOARD, send_buffer);
  194.   m->p.data.board.record = b;
  195.   if (client_mode) 
  196.     Transmit_board (t, b);
  197.   
  198. }
  199.  
  200. void Send_claim (t, no_tricks)
  201.      Table_ptr t; int no_tricks;
  202. {
  203.   sprintf (send_buffer, "CLAIM %d", no_tricks);
  204.   send_message (t, CMD_CLAIM, send_buffer);
  205. }
  206.  
  207. void Send_claimreq (t, no_tricks)
  208.      Table_ptr t; int no_tricks;
  209. {
  210.   sprintf (send_buffer, "CLAIMREQ %d", no_tricks);
  211.   send_message (t, CMD_CLAIMREQ, send_buffer);
  212. }
  213.  
  214. void Send_claimresp (t, resp)
  215.      Table_ptr t; int resp;
  216. {
  217.   sprintf (send_buffer, "CLAIMRESP %s", resp? "ACCEPT": "REJECT");
  218.   send_message (t, CMD_CLAIMRESP, send_buffer);
  219. }
  220.  
  221. void Send_cc (t, convention_card)
  222.      Table_ptr t; char *convention_card;
  223. {
  224.   sprintf (send_buffer, "CC %s", convention_card);
  225.   send_message (t, CMD_CC, send_buffer);
  226. }
  227.  
  228. void Send_comment (t, comment)
  229.      Table_ptr t; message_buffer comment;
  230. {
  231.   sprintf (send_buffer, "COMMENT %s", comment);
  232.   send_message (t, CMD_COMMENT, send_buffer);
  233. }
  234.  
  235. void Send_deal (t)
  236.      Table_ptr t;
  237. {
  238.   send_message (t, CMD_DEAL, "DEAL");
  239. }
  240.  
  241. void Send_echo (t, ping_source)
  242.      Table_ptr t; name_buffer ping_source;
  243. {
  244.   sprintf (send_buffer, "ECHO %s", ping_source);
  245.   send_message (t, CMD_ECHO, send_buffer);
  246. }
  247.  
  248. void Send_email (t, email_addr)
  249.      Table_ptr t; char *email_addr;
  250. {
  251.   sprintf (send_buffer, "EMAIL %s", email_addr);
  252.   send_message (t, CMD_EMAIL, send_buffer);
  253. }
  254.  
  255. void Send_end (t)
  256.      Table_ptr t;
  257. {
  258.   send_message (t, CMD_END, "END");
  259. }
  260.  
  261. void Send_fullname (t, fullname)
  262.      Table_ptr t; message_buffer fullname;
  263. {
  264.   sprintf (send_buffer, "FULLNAME %s", fullname);
  265.   send_message (t, CMD_FULLNAME, send_buffer);
  266. }
  267.  
  268. void Send_hello (t, version, player_name, seat_pos)
  269.      Table_ptr t; name_buffer version, player_name; int seat_pos;
  270. {
  271.   sprintf (send_buffer, "HELLO %s %s %s", version, player_name,
  272.        (seat_pos < 4)? seat_names[seat_pos]: "OBS");
  273.   send_message (t, CMD_HELLO, send_buffer);
  274. }
  275.  
  276. void Send_mode (t, m)
  277.      Table_ptr t; int m;
  278. {
  279.   switch (m) {
  280.   case CLUB_PLAYING_MODE: 
  281.     send_message (t, CMD_MODE, "MODE CLUB");
  282.     break;
  283.   case PRACTICE_PLAYING_MODE:
  284.     send_message (t, CMD_MODE, "MODE PRACTICE");
  285.     break;
  286.   case FORMAL_PLAYING_MODE:
  287.     send_message (t, CMD_MODE, "MODE FORMAL");
  288.     break;
  289.   }
  290. }
  291.  
  292. void Send_name (t, n)
  293.      Table_ptr t; char *n;
  294. {
  295.   sprintf (send_buffer, "NAME %s", n);
  296.   send_message (t, CMD_NAME, send_buffer);
  297. }
  298.  
  299. void Send_ping (t)
  300.      Table_ptr t;
  301. {
  302.   send_message (t, CMD_PING, "PING");
  303. }
  304.  
  305. void Send_play (t, play)
  306.      Table_ptr t; int play;
  307. {
  308.   sprintf (send_buffer, "PLAY %s", card_names[play]);
  309.   send_message (t, CMD_PLAY, send_buffer);
  310. }
  311.  
  312. void Send_playreq (t, play, playno)
  313.      Table_ptr t; int play, playno;
  314. {
  315.   sprintf (send_buffer, "PLAYREQ %s %d", card_names[play], playno);
  316.   send_message (t, CMD_PLAYREQ, send_buffer);
  317. }
  318.  
  319. void Send_quit (t)
  320.      Table_ptr t;
  321. {
  322.   send_message (t, CMD_QUIT, "QUIT");
  323. }
  324.  
  325. void Send_reconnect (t, c, ip, port, seat)
  326.      Table_ptr t;
  327.      Connection c;
  328.      char *ip;
  329.      int port;
  330.      int seat;
  331. {
  332.   sprintf (send_buffer, "RECONNECT %s %d %s", ip, port, seat_names[seat]);
  333.   send_private_message (c, send_buffer);
  334. }
  335.  
  336. void Send_record (t, b, p)
  337.      Table_ptr t;
  338.      board_ptr b;
  339.      play_ptr p;
  340. {
  341.   Message m;
  342.  
  343.   sprintf (send_buffer, "RECORD %s %d", b->source, b->serial_no);
  344.   m = send_message (t, CMD_RECORD, send_buffer);
  345.   m->p.data.record.play = p;
  346.   if (client_mode)
  347.     Transmit_play_record (t, p);
  348.  
  349. }
  350.  
  351. void Send_registry (t, id)
  352.      Table_ptr t; char *id;
  353. {
  354.   sprintf (send_buffer, "REGISTRY %s", id);
  355.   send_message (t, CMD_REGISTRY, send_buffer);
  356. }
  357.  
  358. void Send_reset (t)
  359.      Table_ptr t;
  360. {
  361.   send_message (t, CMD_RESET, "RESET");
  362. }
  363.  
  364. void Send_score (t, above, below)
  365.      Table_ptr t; int above[]; int below[];
  366. {
  367.   sprintf (send_buffer, "SCORE %d %d %d %d",
  368.        above[0], above[1], below[0], below[1]);
  369.   send_server_message (t, CMD_SCORE, send_buffer);
  370. }
  371.  
  372. void Send_seat (t, oldseat, newseat, name)
  373.      Table_ptr t; int oldseat, newseat; char *name; 
  374. {
  375.   sprintf (send_buffer, "SEAT %s %s %s", seat_names[oldseat], 
  376.        seat_names[newseat], name);
  377.   send_message (t, CMD_SEAT, send_buffer);
  378. }
  379.  
  380. void Send_seaterr (t, message)
  381.      Table_ptr t; message_buffer message;
  382. {
  383.   sprintf (send_buffer, "SEATERR %s", message);
  384.   send_message (t, CMD_SEATERR, send_buffer);
  385. }
  386.  
  387. void Send_seatreq (t, seat)
  388.      Table_ptr t; int seat;
  389. {
  390.   sprintf (send_buffer, "SEATREQ %s", seat_names[seat]);
  391.   send_message (t, CMD_SEAT, send_buffer);
  392. }
  393.  
  394. void Send_servereq (t, request)
  395.      Table_ptr t; char *request;
  396. {
  397.   sprintf (send_buffer, "SERVEREQ %s", request);
  398.   send_message (t, CMD_SERVEREQ, send_buffer);
  399. }
  400.  
  401. void Send_skip (t)
  402.      Table_ptr t;
  403. {
  404.   send_message (t, CMD_SKIP, "SKIP");
  405. }
  406.  
  407. void Send_skipack (t)
  408.      Table_ptr t;
  409. {
  410.   send_message (t, CMD_SKIPACK, "SKIPACK");
  411. }
  412.  
  413. void Send_spec (t)
  414.      Table_ptr t;
  415. {
  416.   send_message (t, CMD_SPEC, "SPEC");
  417. }
  418.  
  419. void Send_table (t, c, table_no)
  420.      Table_ptr t;
  421.      Connection c;
  422.      int table_no;
  423. {
  424.   sprintf (send_buffer, "TABLE %d", table_no);
  425.   send_private_message (c, send_buffer);
  426. }
  427.  
  428. void Send_tablereq (t, table_no)
  429.      Table_ptr t;
  430.      int table_no;
  431. {
  432.   sprintf (send_buffer, "TABLEREQ %d", table_no);
  433.   send_message (t, CMD_TABLEREQ, send_buffer);
  434. }
  435.  
  436. static char *talk_rcpts [] = {"LHO", "RHO", "OPPS", "SPEC", "ALL"};
  437.  
  438. void Send_talk (t, destination, message)
  439.      Table_ptr t; int destination; message_buffer message;
  440. {
  441.  
  442.   sprintf (send_buffer, "TALK %s %s", talk_rcpts[destination], message);
  443.   send_message (t, CMD_TALK, send_buffer);
  444. }
  445.  
  446. void Send_userec (t, n, e, s, w)
  447.      Table_ptr t;
  448.      char *n;
  449.      char *e;
  450.      char *s;
  451.      char *w;
  452. {
  453.   sprintf (send_buffer, "USEREC %s %s %s %s", n, e, s, w);
  454.   send_message (t, CMD_USEREC, send_buffer);
  455. }
  456.  
  457. void Send_wakeup (t, p)
  458.      Table_ptr t; char *p;
  459. {
  460.   sprintf (send_buffer, "WAKEUP %s", p);
  461.   send_message (t, CMD_WAKEUP, send_buffer);
  462. }
  463.  
  464. void Send_who (t)
  465.      Table_ptr t;
  466. {
  467.   send_message (t, CMD_WHO, "WHO");
  468. }
  469.  
  470. void Send_whois (t, p)
  471.      Table_ptr t; char *p;
  472. {
  473.   sprintf (send_buffer, "WHOIS %s", p);
  474.   send_message (t, CMD_WHOIS, send_buffer);
  475. }
  476.  
  477. void Send_whoresp (t, r, i)
  478.      Table_ptr t; char *r, *i;
  479. {
  480.   sprintf (send_buffer, "WHORESP %s %s", r, i);
  481.   send_message (t, CMD_WHORESP, send_buffer);
  482. }
  483.  
  484. void Parse_ack (player_name, pos)
  485.      char *player_name; int *pos;
  486. {
  487.   p->command = CMD_ACK;
  488.   Lcopy (player_name, p->data.ack.player_name, NAME_LENGTH);
  489.   p->data.ack.position = (pos == NULL)? 4: *pos;
  490. }
  491.  
  492. void Parse_alert (notify_all)
  493.      int *notify_all;
  494. {
  495.   p->command = CMD_ALERT;
  496.   p->data.alert = *notify_all;
  497. }
  498.  
  499. void Parse_begin ()
  500. {
  501.   p->command = CMD_BEGIN;
  502. }
  503.  
  504. void Parse_bid (bid, alert)
  505.      int *bid, *alert;
  506. {
  507.   p->command = CMD_BID;
  508.   p->data.bid.level = *bid;
  509.   p->data.bid.alert = (alert == NULL)? 0: 1;
  510. }
  511.  
  512. void Parse_board (name, no)
  513.      char *name; int *no;
  514. {
  515.   p->command = CMD_BOARD;
  516.   Lcopy (name, p->data.board.board_name, NAME_LENGTH);
  517.   p->data.board.board_no = *no;
  518. }
  519.  
  520. void Parse_cc (convention_card)
  521.      char *convention_card;
  522. {
  523.   p->command = CMD_CC;
  524.   Lcopy (convention_card, p->data.cc, MESSAGE_LENGTH);
  525. }
  526.  
  527. void Parse_claim (no_tricks)
  528.      int *no_tricks;
  529. {
  530.   p->command = CMD_CLAIM;
  531.   p->data.claim.no_tricks = *no_tricks;
  532. }
  533.  
  534. void Parse_claimreq (no_tricks)
  535.      int *no_tricks;
  536. {
  537.   p->command = CMD_CLAIMREQ;
  538.   p->data.claimreq.no_tricks = *no_tricks;
  539. }
  540.  
  541. void Parse_claimresp (resp)
  542.      int *resp;
  543. {
  544.   p->command = CMD_CLAIMRESP;
  545.   p->data.claimresp = *resp;
  546. }
  547.  
  548. void Parse_comment (message)
  549.      char *message;
  550. {
  551.   p->command = CMD_COMMENT;
  552.   Lcopy (message, p->data.comment, MESSAGE_LENGTH);
  553. }
  554.  
  555. void Parse_connerr (message)
  556.      char *message;
  557. {
  558.   p->command = CMD_CONNERR;
  559.   Lcopy (message, p->data.connerr, MESSAGE_LENGTH);
  560. }
  561.  
  562. void Parse_deal ()
  563. {
  564.   p->command = CMD_DEAL;
  565. }
  566.  
  567. void Parse_echo (ping_source)
  568.      char *ping_source;
  569. {
  570.   p->command = CMD_ECHO;
  571.   Lcopy (ping_source, p->data.echo.ping_source, NAME_LENGTH);
  572. }
  573.  
  574. void Parse_email (email_addr)
  575.      char *email_addr;
  576. {
  577.   p->command = CMD_EMAIL;
  578.   Lcopy (email_addr, p->data.email.addr, MESSAGE_LENGTH);
  579. }
  580.  
  581. void Parse_end ()
  582. {
  583.   p->command = CMD_END;
  584. }
  585.  
  586. void Parse_fullname (fullname)
  587.      char *fullname;
  588. {
  589.   p->command = CMD_FULLNAME;
  590.   Lcopy (fullname, p->data.fullname.name, MESSAGE_LENGTH);
  591. }
  592.  
  593. void Parse_hello (version, player_name, pos)
  594.      char *version, *player_name; int *pos;
  595. {
  596.   p->command = CMD_HELLO;
  597.   Lcopy (version, p->data.hello.version, NAME_LENGTH);
  598.   Lcopy (player_name, p->data.hello.player_name, NAME_LENGTH);
  599.   p->data.hello.seat_req = (pos == NULL)? 4: *pos;
  600. }
  601.  
  602. void Parse_mode (m)
  603.      int *m;
  604. {
  605.   p->command = CMD_MODE;
  606.   p->data.mode = *m;
  607. }
  608.  
  609. void Parse_name (c)
  610.      char *c;
  611. {
  612.   p->command = CMD_NAME;
  613.   Lcopy (c, p->data.name.new_name, NAME_LENGTH);
  614. }
  615.  
  616. void Parse_ping ()
  617. {
  618.   p->command = CMD_PING;
  619. }
  620.  
  621. void Parse_play (play)
  622.      int *play;
  623. {
  624.   p->command = CMD_PLAY;
  625.   p->data.play = *play;
  626. }
  627.  
  628. void Parse_playreq (play, seqno)
  629.      int *play, *seqno;
  630. {
  631.   p->command = CMD_PLAYREQ;
  632.   p->data.playreq.card = *play;
  633.   p->data.playreq.play_no = *seqno;
  634. }
  635.  
  636. void Parse_quit ()
  637. {
  638.   p->command = CMD_QUIT;
  639. }
  640.  
  641. void Parse_reconnect (ip, port, seat)
  642.      char *ip; int *port; int *seat;
  643. {
  644.   p->command = CMD_RECONNECT;
  645.   Lcopy (ip, p->data.reconnect.ip, NAME_LENGTH);
  646.   p->data.reconnect.port = *port;
  647.   p->data.reconnect.seat = *seat;
  648. }
  649.  
  650.  
  651. void Parse_record (name, no)
  652.      char *name; int *no;
  653. {
  654.   p->command = CMD_RECORD;
  655.   Lcopy (name, p->data.record.board_name, NAME_LENGTH);
  656.   p->data.record.board_no = *no;
  657.   p->data.record.play = NULL;
  658. }
  659.  
  660. void Parse_registry (id)
  661.      char *id;
  662. {
  663.   p->command = CMD_REGISTRY;
  664.   Lcopy (id, p->data.registry.id, MESSAGE_LENGTH);
  665. }
  666.  
  667. void Parse_reset ()
  668. {
  669.   p->command = CMD_RESET;
  670. }
  671.  
  672. void Parse_seat (old, new, name)
  673.      int *old, *new; char *name;
  674. {
  675.   p->command = CMD_SEAT;
  676.   p->data.seat.old_pos = *old;
  677.   p->data.seat.new_pos = *new;
  678.   Lcopy (name, p->data.seat.player_name, NAME_LENGTH);
  679. }
  680.  
  681. void Parse_seaterr (free0, free1, free2)
  682.      int *free0, *free1, *free2;
  683. {
  684.   p->command = CMD_SEATERR;
  685.   p->data.seaterr.free_seats[0] = (free0 == NULL)? 4: *free0;
  686.   p->data.seaterr.free_seats[1] = (free1 == NULL)? 4: *free1;
  687.   p->data.seaterr.free_seats[2] = (free2 == NULL)? 4: *free2;
  688. }
  689.  
  690. void Parse_seatpos (s)
  691.      int *s;
  692. {
  693.   p->command = CMD_SEATPOS;
  694.   p->data.seatpos = *s;
  695. }
  696.  
  697. void Parse_seatreq (s)
  698.      int *s;
  699. {
  700.   p->command = CMD_SEATREQ;
  701.   p->data.seatreq = *s;
  702. }
  703.  
  704. void Parse_score (current_scores)
  705.      char *current_scores;
  706. {
  707.   p->command = CMD_SCORE;
  708.   sscanf (current_scores, "%d %d %d %d", 
  709.       p->data.score.above + 0, p->data.score.above + 1,
  710.       p->data.score.below + 0, p->data.score.below + 1);
  711. }
  712.  
  713. void Parse_servereq (request)
  714.      char *request;
  715. {
  716.   p->command = CMD_SERVEREQ;
  717.   Lcopy (request, p->data.servereq.command, MESSAGE_LENGTH);
  718. }
  719.  
  720. void Parse_skip ()
  721. {
  722.   p->command = CMD_SKIP;
  723. }
  724.  
  725. void Parse_skipack ()
  726. {
  727.   p->command = CMD_SKIPACK;
  728. }
  729.  
  730. void Parse_spec ()
  731. {
  732.   p->command = CMD_SPEC;
  733. }
  734.  
  735. void Parse_table (table_no)
  736.      int *table_no;
  737. {
  738.   p->command = CMD_TABLE;
  739.   p->data.table = *table_no;
  740. }
  741.  
  742. void Parse_tablereq (table_no)
  743.      int *table_no;
  744. {
  745.   p->command = CMD_TABLEREQ;
  746.   p->data.tablereq = *table_no;
  747. }
  748.  
  749. void Parse_talk (recpts, message)
  750.      int *recpts; char *message;
  751. {
  752.   p->command = CMD_TALK;
  753.   p->data.talk.recipients = *recpts;
  754.   Lcopy (message, p->data.talk.message, MESSAGE_LENGTH);
  755. }
  756.  
  757. void Parse_userec (player_names)
  758.      char *player_names;
  759. {
  760.   char north_buf[80], east_buf[80], south_buf[80], west_buf[80];
  761.  
  762.   p->command = CMD_USEREC;
  763.   sscanf (player_names, "%s %s %s %s", north_buf, east_buf, 
  764.       south_buf, west_buf);
  765.   Lcopy (north_buf, p->data.userec.north, NAME_LENGTH);
  766.   Lcopy (east_buf,  p->data.userec.east,  NAME_LENGTH);
  767.   Lcopy (south_buf, p->data.userec.south, NAME_LENGTH);
  768.   Lcopy (west_buf,  p->data.userec.west,  NAME_LENGTH);
  769. }
  770.  
  771. void Parse_wakeup (c)
  772.      char *c;
  773. {
  774.   p->command = CMD_WAKEUP;
  775.   Lcopy (c, p->data.wakeup.recipient, NAME_LENGTH);
  776. }
  777.  
  778. void Parse_who ()
  779. {
  780.   p->command = CMD_WHO;
  781. }
  782.  
  783. void Parse_whois (n)
  784.      char *n;
  785. {
  786.   p->command = CMD_WHOIS;
  787.   Lcopy (n, p->data.whois.name, NAME_LENGTH);
  788. }
  789.  
  790. void Parse_whoresp (r, i)
  791.      char *r, *i;
  792. {
  793.   p->command = CMD_WHORESP;
  794.   Lcopy (r, p->data.whoresp.recipient, NAME_LENGTH);
  795.   Lcopy (i, p->data.whoresp.message, MESSAGE_LENGTH);
  796. }
  797.  
  798. int Parse_Command_for_Client (pc)
  799.      player_command pc;
  800. {
  801.   int i, n;
  802.   p = pc;
  803.  
  804.   switch (p->command_text[0]) {
  805.   case 'N':
  806.     p->player_no = PLAYER_NORTH; break;
  807.   case 'E':
  808.     p->player_no = PLAYER_EAST;  break;
  809.   case 'S':
  810.     p->player_no = PLAYER_SOUTH; break;
  811.   case 'W':
  812.     p->player_no = PLAYER_WEST;  break;
  813.   case 'M':
  814.     p->player_no = PLAYER_SERVER; break;
  815.   case 'O':
  816.     p->player_no = PLAYER_OBS;   break;
  817.   default:
  818.     p->command = CMD_ERROR;
  819.     sprintf (p->data.error.message, 
  820.          "ERROR IN MESSAGE SOURCE");
  821.     return (-1);
  822.   }
  823.  
  824.   i = 2;
  825.   while ((p->command_text[i] != '\0') && !isspace(p->command_text[i])) i++;
  826.   while ((p->command_text[i] != '\0') && isspace(p->command_text[i])) i++;
  827.   n = 0;
  828.   while (p->command_text[i] && !isspace(p->command_text[i])) {
  829.     if (n < NAME_LENGTH-1)
  830.       p->player_name[n++] = p->command_text[i];
  831.     i++;
  832.   }
  833.   p->player_name[n] = '\0';
  834.  
  835.   if (Parse_Command (Commands, CMD_MAX-1, p->command_text+i)) {
  836.     p->command = CMD_ERROR;
  837.     Lcopy (Parser_Error_Buf, p->data.error.message, MESSAGE_LENGTH);
  838.     return (-1);
  839.   }
  840.   return (0);
  841.  
  842. }
  843.  
  844. int Parse_Command_for_Server (pc)
  845.      player_command pc;
  846. {
  847.   int i, n;
  848.   p = pc;
  849.  
  850.   i = 0;
  851.   while ((p->command_text[i] != '\0') && isspace(p->command_text[i])) i++;
  852.   n = 0;
  853.   while (p->command_text[i] && !isspace(p->command_text[i])) {
  854.     if (n < NAME_LENGTH-1)
  855.       p->player_name[n++] = p->command_text[i];
  856.     i++;
  857.   }
  858.   p->player_name[n] = '\0';
  859.  
  860.   if (Parse_Command (Commands, CMD_MAX-1, p->command_text+i)) {
  861.     p->command = CMD_ERROR;
  862.     Lcopy (Parser_Error_Buf, p->data.error.message, MESSAGE_LENGTH);
  863.     return (-1);
  864.   }
  865.   return (0);
  866.  
  867. }
  868.  
  869. void Initialize_protocols ()
  870. /* Initializes the array of message attributes. */
  871. {
  872.   ;
  873. }
  874.