home *** CD-ROM | disk | FTP | other *** search
- /*++
- /* NAME
- /* connect 3
- /* SUMMARY
- /* pre- and post protocol host access
- /* PROJECT
- /* pc-mail
- /* PACKAGE
- /* cico
- /* SYNOPSIS
- /* int connect()
- /*
- /* int disconnect()
- /* DESCRIPTION
- /* connect() tries to make a connection to the remote host
- /* and to log on, using the dial-up script and login-name
- /* entries in the communications parameter file, and the password
- /* provided as command-line parameter to the cico program.
- /* A UUCP-like send/expect script facility is used. Thus a login
- /* sequence might look like:
- /*
- /* send expect send expect ...
- /*
- /* The program will send the first "send" string, then expect the
- /* first "expect" string, and so on.
- /*
- /* Alternative expect/send sequences can be specified in the usual manner:
- /*
- /* expect-send-expect-send-expect...
- /*
- /* If the first expect string fails, the alternative send string is
- /* transmitted and the alternative expect is tried, and so on, until
- /* an expect string succeeds, or until the list of alternatives is
- /* exhausted.
- /*
- /* After the dial-up script has completed the program
- /* proceeds with the following build-in send/expect sequence:
- /*
- /* ogin: your_login_name\\r ssword: your_password\\r
- /*
- /* disconnect() tries to break a connection, using the disconnect
- /* entry in the communications parameter file. Unlike connect()
- /* this function is not driven by a send-expect script.
- /*
- /* The following escape sequences are recognized in send or expect
- /* strings:
- /*
- /* .nf
- /* \\b backspace
- /* \\r carriage return
- /* \\n newline
- /* \\t tab
- /* \\s space
- /* \\f form feed
- /* \\nnn octal character value
- /* \\\\ a real backslash
- /* .fi
- /*
- /* In addition, the following "send" strings are given special
- /* treatment:
- /*
- /* .nf
- /* BREAK send a null character
- /* EOT send Control-D
- /* FUNCTIONS AND MACROS
- /* xwrite(), xgetc(), trap(), debug(4)(), log(), split()
- /* FILES
- /* $MAILDIR/s00000 communications parameter file
- /* $MAILDIR/LOGFILE system logfile
- /* SEE ALSO
- /* params(5) communications parameter file entries
- /* DIAGNOSTICS
- /* connect() returns a status E_BADSETUP if the systems parameter
- /* file contains bad data, and E_NOLINE if the login script fails.
- /* AUTHOR(S)
- /* W.Z. Venema
- /* Eindhoven University of Technology
- /* Department of Mathematics and Computer Science
- /* Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
- /* CREATION DATE
- /* Fri Mar 27 17:11:12 GMT+1:00 1987
- /* LAST MODIFICATION
- /* 90/01/22 13:01:26
- /* VERSION/RELEASE
- /* 2.1
- /*--*/
-
- #include <stdio.h>
- #include <setjmp.h>
- #include <ctype.h>
-
- #include "defs.h"
- #include "params.h"
- #include "status.h"
- #include "comm.h"
- #include "logs.h"
- #include "sysdep.h"
-
- hidden char *blnk = " \t"; /* send/expect separators */
-
- /* forward declarations */
-
- hidden void conn_send();
- hidden void conn_xpct();
- hidden char *escape();
-
- /* connect - connect to remote system; simple script processing with retries */
-
- public int connect()
- {
- int *savetrap = systrap; /* save exception handler */
- jmp_buf mytrap; /* our exception handler */
- int retval; /* completion code */
- char *seq = DIAL_SEQUENCE;
- register char *cp;
-
- /* set up exception handler */
-
- if (retval = setjmp(systrap = mytrap)) { /* get here if expect fails */
- systrap = savetrap; /* it just happened */
- return (retval);
- }
- /* optional dial-up sequence */
-
- for (cp = split(&seq, blnk); cp; cp = split(&seq, blnk)) {
- conn_send(escape(cp));
- if (cp = split(&seq, blnk))
- conn_xpct(escape(cp));
- }
-
- /* mandatory login sequence; hack this for non-UNIX hosts */
-
- conn_xpct("ogin:");
- conn_send(strcons("%s\r", LOGIN_NAME));
- conn_xpct("ssword:");
- conn_send(strcons("%s\r", password));
-
- /* restore exception handler */
-
- systrap = savetrap; /* get here if expect wins */
- return (0); /* say no problems... */
- }
-
- /* disconnect - disconnect line */
-
- public int disconnect()
- {
- conn_send(escape(DISC_SEQUENCE)); /* send disconnect sequence */
- return (0); /* always succeeds... */
- }
-
- /* conn_send - send BREAK, EOT or string literal */
-
- hidden void conn_send(s)
- register char *s;
- {
- static char null = '\0';
- static char eot = '\04';
-
- sleep(1);
-
- if (*s) {
- debug(4) ("Sending: %S\n", s);
- if (strcmp(s, "BREAK") == 0) {
- xwrite(ttfd, &null, 1);
- } else if (strcmp(s, "EOT") == 0) {
- xwrite(ttfd, &eot, 1);
- } else {
- while (*s) {
- delay();
- xwrite(ttfd, s++, 1);
- }
- }
- }
- }
-
- /* conn_xpct - pattern matching without meta characters */
-
- hidden void conn_xpct(s)
- char *s;
- {
- int c;
- int i;
- int n;
- char *xp;
- char *sp;
-
- /*
- * Keep listening until we time out or until we receive the expected
- * string (thus, if the other end keeps sending garbage we will never
- * terminate). Make sure that we do not overrun our buffer. Parity bits
- * are ignored. If we do not succeed, try alternative sequences if they
- * are specified.
- */
-
- for (xp = split(&s, "-"); xp; xp = split(&s, "-")) {
-
- debug(4) ("Expecting: %S\nReceiving: ", xp);
-
- if (((n = strlen(xp)) > MSGBUF))
- n = MSGBUF;
- for (i = 0; (c = xgetc()) != EOF; /* void */ ) {
- msgin[i++] = (c &= 0177);
- debug(4) ("%C", c);
- if (i >= n && strncmp(xp, &msgin[i - n], n) == 0) {
- debug(4) (" ok!\n");
- return;
- } else if (i >= MSGBUF) {
- strncpy(msgin, &msgin[i - (n - 1)], n - 1);
- i = n - 1;
- }
- }
- debug(4) (" failed!\n");
-
- /* try alternative sequence, if specified, else fail */
-
- if (sp = split(&s, "-")) {
- conn_send(sp);
- } else {
- trap(E_NOLINE, "LOGIN FAILED (at \"%S\")", xp);
- }
- }
- }
-
- /* escape - interpret backslash sequences */
-
- hidden char *escape(s)
- register char *s;
- {
- static char buf[BUFSIZ];
- register char *cp = buf;
- register char ch;
- int c;
- int i;
-
- while (*s && cp < buf + sizeof(buf) - 1) { /* don't overflow the buffer */
-
- if (*s != '\\') { /* ordinary character */
- *cp++ = *s++;
- } else if (isdigit(*++s) && *s < '8') { /* \nnn octal code */
- sscanf(s, "%3o", &c);
- *cp++ = c;
- i = 1;
- s++;
- while (i++ < 3 && isdigit(*s) && *s < '8')
- s++;
- } else if ((ch = *s++) == 0) { /* at string terminator */
- break;
- } else if (ch == 'b') { /* \b becomes backspace */
- *cp++ = '\b';
- } else if (ch == 'f') { /* \f becomes formfeed */
- *cp++ = '\f';
- } else if (ch == 'n') { /* \n becomes newline */
- *cp++ = '\n';
- } else if (ch == 'r') { /* \r becomes carriage ret */
- *cp++ = '\r';
- } else if (ch == 's') { /* \s becomes blank */
- *cp++ = ' ';
- } else if (ch == 't') { /* \t becomes tab */
- *cp++ = '\t';
- } else { /* \any becomes any */
- *cp++ = ch;
- }
- }
- *cp = '\0'; /* terminate the result */
- return (buf);
- }
-