Category : UNIX Files
Archive   : PC-MAIL2.ZIP
Filename : CONNECT.C

 
Output of file : CONNECT.C contained in archive : PC-MAIL2.ZIP

/*++
/* 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
#include
#include

#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);
}