home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD2.mdf / c / library / dos / communic / pcmail / main / startup.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-06-05  |  6.2 KB  |  207 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. /*    90/01/22 13:02:41
  44. /* VERSION/RELEASE
  45. /*    2.1
  46. /*--*/
  47.  
  48. #include <stdio.h>
  49. #include <setjmp.h>
  50.  
  51. #include "defs.h"
  52. #include "params.h"
  53. #include "comm.h"
  54. #include "logs.h"
  55. #include "status.h"
  56. #include "sysdep.h"
  57.  
  58. /* forward declarations */
  59.  
  60. hidden char *xpct();            /* expect a string */
  61. hidden char *send();            /* send a string */
  62.  
  63. /* the functions that inplement the various protocols */
  64.  
  65. extern  kopen(), kclose(), kread(), kwrite();    /* k protocol */
  66. extern  gopen(), gclose(), gread(), gwrite();    /* g protocol */
  67.  
  68. typedef struct proto {
  69.     char    name;            /* name of the protocol */
  70.     int     (*open) ();            /* the open function */
  71.     int     (*close) ();        /* the close function */
  72.     int     (*read) ();            /* the read function */
  73.     int     (*write) ();        /* the write function */
  74. };
  75.  
  76. /* the order of protocols is significant! */
  77.  
  78. hidden struct proto ptbl[] = {
  79.     'k', kopen, kclose, kread, kwrite,    /* try this first */
  80.     'g', gopen, gclose, gread, gwrite,    /* then this one */
  81.     /* add your protocols at the appropriate place */
  82.     0,                    /* terminator! */
  83. };
  84.  
  85. /* startproto - do primary handshake, establish protocol and turn it on */
  86.  
  87. public  startproto()
  88. {
  89.     int    *savetrap = systrap;
  90.     jmp_buf mytrap;
  91.     register struct proto *pp;
  92.     register char *cp;
  93.     int     status;
  94.  
  95.     if (status = setjmp(systrap = mytrap)) {    /* get here if expect fails */
  96.     systrap = savetrap;
  97.     return (status);
  98.     }
  99.     /* the primary handshake: who are we and is it ok we call right now */
  100.  
  101.     sscanf(xpct("Shere"), "Shere=%s", rmthost);    /* try to get host name */
  102.     log("SUCCEEDED (call to %s)", rmthost);
  103.  
  104.     /* some uucico implementations seem to have problems with debug level 0 */
  105.  
  106.     send(strcons("S%s -x%d", LOGIN_NAME, MAX(dflag, 1)));
  107.     xpct("ROK");                /* we're accepted or rejected */
  108.  
  109.     /* choose a protocol from the list offered by the other side */
  110.  
  111.     for (cp = xpct("P") + 1, pp = ptbl; pp->name && !index(cp, pp->name); pp++)
  112.      /* void */ ;
  113.     if (pp->name == 0) {            /* no common protocol */
  114.     send("UN");
  115.     trap(E_REJECT, "FAILED (no common protocol in \"%s\")", cp);
  116.     /* NOTREACHED */
  117.     }
  118.     send(strcons("U%c", pp->name));        /* my choice of protocol */
  119.  
  120.     /* install protocol */
  121.  
  122.     Close = pp->close;                /* for endproto() */
  123.     Read = pp->read;
  124.     Write = pp->write;
  125.     if (pp->open && CALL(pp->open) (ttfd))    /* start up a protocol */
  126.     trap(E_LOST, "FAILED (startup)");
  127.  
  128.     /* finish up */
  129.  
  130.     log("OK (startup)");
  131.     systrap = savetrap;                /* get here if expect wins */
  132.     return (0);
  133. }
  134.  
  135. /* endproto - terminate protocol */
  136.  
  137. public  endproto()
  138. {
  139.     int    *savetrap = systrap;            /* save exception handler */
  140.     jmp_buf mytrap;
  141.     int     status;
  142.  
  143.     if (Close)                    /* check there is one */
  144.     CALL(Close) (ttfd);            /* turn protocol off */
  145.     send("OOOOOO");                /* byebye */
  146.  
  147.     /* Don\'t wait for the other side\'s OOOOOO, just sleep and quit. */
  148.  
  149.     (void) sleep(1);
  150.     log("OK (conversation complete)");
  151.     return (0);
  152. }
  153.  
  154. /* send - write message to remote host and return pointer to message */
  155.  
  156. hidden char *send(str)
  157. char   *str;
  158. {
  159.     xwrite(ttfd, "\020", 1);            /* message header */
  160.     xwrite(ttfd, str, strlen(str) + 1);        /* include trailing null */
  161.     debug(4) ("send: %S\n", str);
  162.     return (str);                /* return the message */
  163. }
  164.  
  165. /* xpct - read message from host in "^Pmessage[\0\n]" format; trap on errors */
  166.  
  167. hidden char *xpct(pat)
  168. char   *pat;
  169. {
  170.     register int c;
  171.     register char *p = msgin;
  172.     register int inmsg = 0;
  173.  
  174.     /*
  175.      * Keep reading until we time out, or until a complete message has been
  176.      * received. Consider the link as lost in case of time out. Assume we are
  177.      * rejected if the received message differs from what was expected.
  178.      */
  179.  
  180.     debug(4) ("xpct: %S\n", pat);
  181.  
  182.     for (;;) {
  183.     if ((c = xgetc()) == EOF) {
  184.         trap(E_LOST, "FAILED (protocol handshake)");
  185.         /* NOTREACHED */
  186.     } else if ((c &= 0177) == '\020') {
  187.         debug(4) (" got sync\n");        /* got start of message */
  188.         p = msgin;                /* reset */
  189.         inmsg = 1;
  190.     } else if (inmsg == 0) {    
  191.         debug(4) ("%C", c);            /* don\'t store, just debug */
  192.     } else if (*p++ = ((c == '\n') ? '\0' : c)) {
  193.         debug(4) ("%C", c);            /* store and debug */
  194.         if (p >= msgin + MSGBUF) {        /* spurious Ctrl-P seen? */
  195.         p = msgin;            /* reset */
  196.         inmsg = 0;            /* reset */
  197.         }
  198.     } else if ((debug(4) ("\n")), strncmp(pat, msgin, strlen(pat)) == 0) {
  199.         return (msgin);            /* expect succeeded */
  200.     } else {
  201.         msgin[30] = '\0';            /* truncate to 30 */
  202.         trap(E_REJECT, "FAILED (%S)", msgin);
  203.         /* NOTREACHED */
  204.     }
  205.     }
  206. }
  207.