home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume3 / pcmail / part04 / startup.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-02-03  |  6.2 KB  |  196 lines

  1. /*++
  2. /* NAME
  3. /*      startup 3
  4. /* SUMMARY
  5. /*      startup/terminate network protocol 
  6. /* PROJECT
  7. /*      pc-mail
  8. /* PACKAGE
  9. /*      cico
  10. /* SYNOPSIS
  11. /*      startproto()
  12. /*
  13. /*      endproto()
  14. /* DESCRIPTION
  15. /*      startproto() should be called after a successfull login on a remote
  16. /*      host. It performs the primary handshake with the other system 
  17. /*      (call accepted/locked) and negotiates a communications protocol.
  18. /*      It then sets the function pointers Close/Read/Write to the
  19. /*      appropriate values. Until endproto() is called, all i/o to the
  20. /*      remote host should proceed through the functions pointed to by
  21. /*      Read/Write.
  22. /*
  23. /*      endproto() turns the protocol off, and sends the silly "OO" message
  24. /*      to the remote system. It does not disconnect, nor does it change
  25. /*      the state of the communications port.
  26. /* FUNCTIONS AND MACROS
  27. /*      xgetc(), xwrite(), trap()
  28. /* DIAGNOSTICS
  29. /*      The process of negotiation is shown when debugging is enabled.
  30. /*      startproto() and endproto() return 0 in case of success, E_LOST
  31. /*      if no response arrived and E_REJECT if the response differed
  32. /*      from the expected response.
  33. /* BUGS
  34. /*      startproto() assumes that the local system is the calling system.
  35. /* AUTHOR(S)
  36. /*      W.Z. Venema
  37. /*      Eindhoven University of Technology
  38. /*      Department of Mathematics and Computer Science
  39. /*      Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
  40. /* CREATION DATE
  41. /*      Fri Mar 27 13:43:00 GMT+1:00 1987
  42. /* LAST MODIFICATION
  43. /*    Wed Apr  6 00:22:51 MET 1988
  44. /* VERSION/RELEASE
  45. /*    1.4
  46. /*--*/
  47.  
  48. #include <setjmp.h>
  49. #include "defs.h"
  50. #include "params.h"
  51. #include "comm.h"
  52. #include "logs.h"
  53. #include "status.h"
  54. #include "sysdep.h"
  55.  
  56. /* forward declarations */
  57.  
  58. hidden char *xpct();                            /* expect a string */
  59. hidden char *send();                            /* send a string */
  60.  
  61. /* the functions that inplement the various protocols */
  62.  
  63. extern kopen(),kclose(),kread(),kwrite();       /* k protocol */
  64. extern gopen(),gclose(),gread(),gwrite();       /* g protocol */
  65.  
  66. typedef struct proto {
  67.     char name;                                  /* name of the protocol */
  68.     int (*open)();                              /* the open function */
  69.     int (*close)();                             /* the close function */
  70.     int (*read)();                              /* the read function */
  71.     int (*write)();                             /* the write function */
  72. };
  73.  
  74. /* the order of protocols is significant! */
  75.  
  76. hidden struct proto ptable[] = {
  77.     'k',        kopen,  kclose, kread,  kwrite, /* try this first */
  78.     'g',        gopen,  gclose, gread,  gwrite, /* then this one */
  79.     /* add your protocols at the appropriate place */
  80.     0,                                          /* terminator! */
  81. };
  82.  
  83. /* startproto - do primary handshake, establish protocol and turn it on */
  84.  
  85. public startproto()
  86. {
  87.     int *savetrap = systrap;
  88.     jmp_buf mytrap;
  89.     register struct proto *pp;
  90.     register char *cp;
  91.     int status;
  92.  
  93.     if (status = setjmp(systrap = mytrap)) {    /* get here if expect fails */
  94.     systrap = savetrap;
  95.     return(status);
  96.     }
  97.  
  98.     /* the primary handshake: who are we and is it ok we call right now */
  99.  
  100.     sscanf(xpct("Shere"),"Shere=%s",rmthost);   /* try to get host name */
  101.     log("SUCCEEDED (call to %s)",rmthost);
  102.     send(strcons("S%s -x%d",LOGIN_NAME,MAX(dflag,1))); /* name + debug level */
  103.     xpct("ROK");                                /* we're accepted or rejected */
  104.  
  105.     /* choose a protocol from the list offered by the other side */
  106.  
  107.     for (cp = xpct("P")+1,pp = ptable; pp->name && !index(cp,pp->name); pp++)
  108.     /* void */ ;
  109.     if (pp->name == 0) {                        /* no common protocol */
  110.     send("N");
  111.     trap(E_REJECT,"FAILED (no common protocol in \"%s\")",cp);
  112.     /* NOTREACHED */
  113.     }
  114.     send(strcons("U%c",pp->name));        /* my choice of protocol */
  115.  
  116.     /* install protocol */
  117.  
  118.     Close = pp->close;                          /* for endproto() */
  119.     Read  = pp->read;
  120.     Write = pp->write;
  121.     if (pp->open && CALL(pp->open)(ttfd))      /* start up a protocol */
  122.     trap(E_LOST,"FAILED (startup)");
  123.  
  124.     log("OK (startup)");
  125.     systrap = savetrap;                         /* get here if expect wins */
  126.     return(0);
  127. }
  128.  
  129. /* endproto - terminate protocol */
  130.  
  131. public endproto()
  132. {
  133.     int *savetrap = systrap;
  134.     jmp_buf mytrap;
  135.     int status;
  136.  
  137.     if (status = setjmp(systrap = mytrap)) {    /* get here if expect fails */
  138.     systrap = savetrap;
  139.     return(status);
  140.     }
  141.     if (Close)                                  /* check there is one */
  142.     CALL(Close)(ttfd);                      /* turn protocol off */
  143.     send("OOOOOO");                             /* byebye */
  144.     xpct("OO");                                 /* bye */
  145.     log("OK (conversation complete)");
  146.  
  147.     systrap = savetrap;                         /* get here if expect wins */
  148.     return(0);
  149. }
  150.  
  151. /* send - write message to remote host and return pointer to message */
  152.  
  153. hidden char *send(str)
  154. char *str;
  155. {
  156.     xwrite(ttfd,"\020",1);            /* message header */
  157.     xwrite(ttfd,str,strlen(str)+1);        /* include trailing null */
  158.     debug(4)("send: %S\n",str);
  159.     return(str);                /* return the message */
  160. }
  161.  
  162. /* xpct - read message from host in "^Pmessage[\0\n]" format; trap on errors */
  163.  
  164. hidden char *xpct(pat)
  165. char *pat;
  166. {
  167.     register int c;
  168.     register char *p = msgin;
  169.     register int inmsg = 0;
  170.  
  171.     /*
  172.     * Keep reading until we time out, the buffer is full, or until a 
  173.     * complete message has been received. Consider the link as lost
  174.     * in case of time out or buffer overflow. Assume we are rejected
  175.     * if the received message differs from what was expected.
  176.     */
  177.  
  178.     while (p < msgin+MSGBUF && (c = xgetc()) != EOF) {      
  179.     if ((c &= 0177) == '\020') {            /* got start of message */
  180.         debug(4)(" got sync\n");
  181.         p = msgin;                          /* clear msg buffer */
  182.         inmsg = 1;
  183.     } else if (inmsg == 0 || (*p++ = (c == '\n' ? 0 : c))) {
  184.         debug(4)("%C",c);
  185.     } else {                                /* message completed */
  186.         debug(4)("\n");
  187.         if (strncmp(pat,msgin,strlen(pat))) /* compare prefix only */
  188.         break;
  189.         return(msgin);
  190.     }
  191.     }
  192.     trap((c == EOF || p >= msgin+MSGBUF ? E_LOST : E_REJECT),
  193.     "FAILED (%s)",msgin);
  194.     /* NOTREACHED */
  195. }
  196.