home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD2.mdf / c / library / dos / communic / pcmail / main / connect.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-06-05  |  7.0 KB  |  268 lines

  1. /*++
  2. /* NAME
  3. /*      connect 3
  4. /* SUMMARY
  5. /*      pre- and post protocol host access
  6. /* PROJECT
  7. /*      pc-mail
  8. /* PACKAGE
  9. /*      cico
  10. /* SYNOPSIS
  11. /*      int connect()
  12. /*
  13. /*      int disconnect()
  14. /* DESCRIPTION
  15. /*      connect() tries to make a connection to the remote host
  16. /*      and to log on, using the dial-up script and login-name
  17. /*    entries in the communications parameter file, and the password
  18. /*    provided as command-line parameter to the cico program.
  19. /*    A UUCP-like send/expect script facility is used. Thus a login
  20. /*    sequence might look like:
  21. /*
  22. /*    send expect send expect ...
  23. /*
  24. /*    The program will send the first "send" string, then expect the
  25. /*    first "expect" string, and so on.
  26. /*
  27. /*    Alternative expect/send sequences can be specified in the usual manner:
  28. /*
  29. /*    expect-send-expect-send-expect...
  30. /*
  31. /*    If the first expect string fails, the alternative send string is 
  32. /*    transmitted and the alternative expect is tried, and so on, until
  33. /*    an expect string succeeds, or until the list of alternatives is
  34. /*    exhausted.
  35. /*
  36. /*    After the dial-up script has completed the program
  37. /*    proceeds with the following build-in send/expect sequence:
  38. /*
  39. /*    ogin: your_login_name\\r ssword: your_password\\r
  40. /*
  41. /*      disconnect() tries to break a connection, using the disconnect
  42. /*      entry in the communications parameter file. Unlike connect()
  43. /*    this function is not driven by a send-expect script.
  44. /*
  45. /*    The following escape sequences are recognized in send or expect
  46. /*    strings:
  47. /*
  48. /* .nf
  49. /*    \\b    backspace
  50. /*    \\r    carriage return
  51. /*    \\n    newline
  52. /*    \\t    tab
  53. /*    \\s    space
  54. /*    \\f    form feed
  55. /*    \\nnn    octal character value
  56. /*    \\\\    a real backslash
  57. /* .fi
  58. /*
  59. /*    In addition, the following "send" strings are given special
  60. /*    treatment:
  61. /*
  62. /* .nf
  63. /*    BREAK    send a null character
  64. /*    EOT    send Control-D
  65. /* FUNCTIONS AND MACROS
  66. /*      xwrite(), xgetc(), trap(), debug(4)(), log(), split()
  67. /* FILES
  68. /*      $MAILDIR/s00000        communications parameter file
  69. /*    $MAILDIR/LOGFILE    system logfile
  70. /* SEE ALSO
  71. /*      params(5)       communications parameter file entries
  72. /* DIAGNOSTICS
  73. /*      connect() returns a status E_BADSETUP if the systems parameter
  74. /*    file contains bad data, and E_NOLINE if the login script fails.
  75. /* AUTHOR(S)
  76. /*      W.Z. Venema
  77. /*      Eindhoven University of Technology
  78. /*      Department of Mathematics and Computer Science
  79. /*      Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
  80. /* CREATION DATE
  81. /*      Fri Mar 27 17:11:12 GMT+1:00 1987
  82. /* LAST MODIFICATION
  83. /*    90/01/22 13:01:26
  84. /* VERSION/RELEASE
  85. /*    2.1
  86. /*--*/
  87.  
  88. #include <stdio.h>
  89. #include <setjmp.h>
  90. #include <ctype.h>
  91.  
  92. #include "defs.h"
  93. #include "params.h"
  94. #include "status.h"
  95. #include "comm.h"
  96. #include "logs.h"
  97. #include "sysdep.h"
  98.  
  99. hidden char *blnk = " \t";        /* send/expect separators */
  100.  
  101. /* forward declarations */
  102.  
  103. hidden void conn_send();
  104. hidden void conn_xpct();
  105. hidden char *escape();
  106.  
  107. /* connect - connect to remote system; simple script processing with retries */
  108.  
  109. public int connect()
  110. {
  111.     int    *savetrap = systrap;        /* save exception handler */
  112.     jmp_buf mytrap;            /* our exception handler */
  113.     int     retval;            /* completion code */
  114.     char   *seq = DIAL_SEQUENCE;
  115.     register char *cp;
  116.  
  117.     /* set up exception handler */
  118.  
  119.     if (retval = setjmp(systrap = mytrap)) {    /* get here if expect fails */
  120.     systrap = savetrap;            /* it just happened */
  121.     return (retval);
  122.     }
  123.     /* optional dial-up sequence */
  124.  
  125.     for (cp = split(&seq, blnk); cp; cp = split(&seq, blnk)) {
  126.     conn_send(escape(cp));
  127.     if (cp = split(&seq, blnk))
  128.         conn_xpct(escape(cp));
  129.     }
  130.  
  131.     /* mandatory login sequence; hack this for non-UNIX hosts */
  132.  
  133.     conn_xpct("ogin:");
  134.     conn_send(strcons("%s\r", LOGIN_NAME));
  135.     conn_xpct("ssword:");
  136.     conn_send(strcons("%s\r", password));
  137.  
  138.     /* restore exception handler */
  139.  
  140.     systrap = savetrap;                /* get here if expect wins */
  141.     return (0);                    /* say no problems... */
  142. }
  143.  
  144. /* disconnect - disconnect line */
  145.  
  146. public int disconnect()
  147. {
  148.     conn_send(escape(DISC_SEQUENCE));        /* send disconnect sequence */
  149.     return (0);                    /* always succeeds... */
  150. }
  151.  
  152. /* conn_send - send BREAK, EOT or string literal */
  153.  
  154. hidden void conn_send(s)
  155. register char *s;
  156. {
  157.     static char null = '\0';
  158.     static char eot = '\04';
  159.  
  160.     sleep(1);
  161.  
  162.     if (*s) {
  163.     debug(4) ("Sending: %S\n", s);
  164.     if (strcmp(s, "BREAK") == 0) {
  165.         xwrite(ttfd, &null, 1);
  166.     } else if (strcmp(s, "EOT") == 0) {
  167.         xwrite(ttfd, &eot, 1);
  168.     } else {
  169.         while (*s) {
  170.         delay();
  171.         xwrite(ttfd, s++, 1);
  172.         }
  173.     }
  174.     }
  175. }
  176.  
  177. /* conn_xpct - pattern matching without meta characters */
  178.  
  179. hidden void conn_xpct(s)
  180. char   *s;
  181. {
  182.     int     c;
  183.     int     i;
  184.     int     n;
  185.     char   *xp;
  186.     char   *sp;
  187.  
  188.     /*
  189.      * Keep listening until we time out or until we receive the expected
  190.      * string (thus, if the other end keeps sending garbage we will never
  191.      * terminate). Make sure that we do not overrun our buffer. Parity bits
  192.      * are ignored. If we do not succeed, try alternative sequences if they
  193.      * are specified.
  194.      */
  195.  
  196.     for (xp = split(&s, "-"); xp; xp = split(&s, "-")) {
  197.  
  198.     debug(4) ("Expecting: %S\nReceiving: ", xp);
  199.  
  200.     if (((n = strlen(xp)) > MSGBUF))
  201.         n = MSGBUF;
  202.     for (i = 0; (c = xgetc()) != EOF; /* void */ ) {
  203.         msgin[i++] = (c &= 0177);
  204.         debug(4) ("%C", c);
  205.         if (i >= n && strncmp(xp, &msgin[i - n], n) == 0) {
  206.         debug(4) (" ok!\n");
  207.         return;
  208.         } else if (i >= MSGBUF) {
  209.         strncpy(msgin, &msgin[i - (n - 1)], n - 1);
  210.         i = n - 1;
  211.         }
  212.     }
  213.     debug(4) (" failed!\n");
  214.  
  215.     /* try alternative sequence, if specified, else fail */
  216.  
  217.     if (sp = split(&s, "-")) {
  218.         conn_send(sp);
  219.     } else {
  220.         trap(E_NOLINE, "LOGIN FAILED (at \"%S\")", xp);
  221.     }
  222.     }
  223. }
  224.  
  225. /* escape - interpret backslash sequences */
  226.  
  227. hidden char *escape(s)
  228. register char *s;
  229. {
  230.     static char buf[BUFSIZ];
  231.     register char *cp = buf;
  232.     register char ch;
  233.     int     c;
  234.     int     i;
  235.  
  236.     while (*s && cp < buf + sizeof(buf) - 1) {    /* don't overflow the buffer */
  237.  
  238.     if (*s != '\\') {            /* ordinary character */
  239.         *cp++ = *s++;
  240.     } else if (isdigit(*++s) && *s < '8') {    /* \nnn octal code */
  241.         sscanf(s, "%3o", &c);
  242.         *cp++ = c;
  243.         i = 1;
  244.         s++;
  245.         while (i++ < 3 && isdigit(*s) && *s < '8')
  246.         s++;
  247.     } else if ((ch = *s++) == 0) {        /* at string terminator */
  248.         break;
  249.     } else if (ch == 'b') {            /* \b becomes backspace */
  250.         *cp++ = '\b';
  251.     } else if (ch == 'f') {            /* \f becomes formfeed */
  252.         *cp++ = '\f';
  253.     } else if (ch == 'n') {            /* \n becomes newline */
  254.         *cp++ = '\n';
  255.     } else if (ch == 'r') {            /* \r becomes carriage ret */
  256.         *cp++ = '\r';
  257.     } else if (ch == 's') {            /* \s becomes blank */
  258.         *cp++ = ' ';
  259.     } else if (ch == 't') {            /* \t becomes tab */
  260.         *cp++ = '\t';
  261.     } else {                /* \any becomes any */
  262.         *cp++ = ch;
  263.     }
  264.     }
  265.     *cp = '\0';                    /* terminate the result */
  266.     return (buf);
  267. }
  268.