home *** CD-ROM | disk | FTP | other *** search
- /*++
- /* NAME
- /* startup 3
- /* SUMMARY
- /* startup/terminate network protocol
- /* PROJECT
- /* pc-mail
- /* PACKAGE
- /* cico
- /* SYNOPSIS
- /* startproto()
- /*
- /* endproto()
- /* DESCRIPTION
- /* startproto() should be called after a successfull login on a remote
- /* host. It performs the primary handshake with the other system
- /* (call accepted/locked) and negotiates a communications protocol.
- /* It then sets the function pointers Close/Read/Write to the
- /* appropriate values. Until endproto() is called, all i/o to the
- /* remote host should proceed through the functions pointed to by
- /* Read/Write.
- /*
- /* endproto() turns the protocol off, and sends the silly "OO" message
- /* to the remote system. It does not disconnect, nor does it change
- /* the state of the communications port.
- /* FUNCTIONS AND MACROS
- /* xgetc(), xwrite(), trap()
- /* DIAGNOSTICS
- /* The process of negotiation is shown when debugging is enabled.
- /* startproto() and endproto() return 0 in case of success, E_LOST
- /* if no response arrived and E_REJECT if the response differed
- /* from the expected response.
- /* BUGS
- /* startproto() assumes that the local system is the calling system.
- /* 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 13:43:00 GMT+1:00 1987
- /* LAST MODIFICATION
- /* 90/01/22 13:02:41
- /* VERSION/RELEASE
- /* 2.1
- /*--*/
-
- #include <stdio.h>
- #include <setjmp.h>
-
- #include "defs.h"
- #include "params.h"
- #include "comm.h"
- #include "logs.h"
- #include "status.h"
- #include "sysdep.h"
-
- /* forward declarations */
-
- hidden char *xpct(); /* expect a string */
- hidden char *send(); /* send a string */
-
- /* the functions that inplement the various protocols */
-
- extern kopen(), kclose(), kread(), kwrite(); /* k protocol */
- extern gopen(), gclose(), gread(), gwrite(); /* g protocol */
-
- typedef struct proto {
- char name; /* name of the protocol */
- int (*open) (); /* the open function */
- int (*close) (); /* the close function */
- int (*read) (); /* the read function */
- int (*write) (); /* the write function */
- };
-
- /* the order of protocols is significant! */
-
- hidden struct proto ptbl[] = {
- 'k', kopen, kclose, kread, kwrite, /* try this first */
- 'g', gopen, gclose, gread, gwrite, /* then this one */
- /* add your protocols at the appropriate place */
- 0, /* terminator! */
- };
-
- /* startproto - do primary handshake, establish protocol and turn it on */
-
- public startproto()
- {
- int *savetrap = systrap;
- jmp_buf mytrap;
- register struct proto *pp;
- register char *cp;
- int status;
-
- if (status = setjmp(systrap = mytrap)) { /* get here if expect fails */
- systrap = savetrap;
- return (status);
- }
- /* the primary handshake: who are we and is it ok we call right now */
-
- sscanf(xpct("Shere"), "Shere=%s", rmthost); /* try to get host name */
- log("SUCCEEDED (call to %s)", rmthost);
-
- /* some uucico implementations seem to have problems with debug level 0 */
-
- send(strcons("S%s -x%d", LOGIN_NAME, MAX(dflag, 1)));
- xpct("ROK"); /* we're accepted or rejected */
-
- /* choose a protocol from the list offered by the other side */
-
- for (cp = xpct("P") + 1, pp = ptbl; pp->name && !index(cp, pp->name); pp++)
- /* void */ ;
- if (pp->name == 0) { /* no common protocol */
- send("UN");
- trap(E_REJECT, "FAILED (no common protocol in \"%s\")", cp);
- /* NOTREACHED */
- }
- send(strcons("U%c", pp->name)); /* my choice of protocol */
-
- /* install protocol */
-
- Close = pp->close; /* for endproto() */
- Read = pp->read;
- Write = pp->write;
- if (pp->open && CALL(pp->open) (ttfd)) /* start up a protocol */
- trap(E_LOST, "FAILED (startup)");
-
- /* finish up */
-
- log("OK (startup)");
- systrap = savetrap; /* get here if expect wins */
- return (0);
- }
-
- /* endproto - terminate protocol */
-
- public endproto()
- {
- int *savetrap = systrap; /* save exception handler */
- jmp_buf mytrap;
- int status;
-
- if (Close) /* check there is one */
- CALL(Close) (ttfd); /* turn protocol off */
- send("OOOOOO"); /* byebye */
-
- /* Don\'t wait for the other side\'s OOOOOO, just sleep and quit. */
-
- (void) sleep(1);
- log("OK (conversation complete)");
- return (0);
- }
-
- /* send - write message to remote host and return pointer to message */
-
- hidden char *send(str)
- char *str;
- {
- xwrite(ttfd, "\020", 1); /* message header */
- xwrite(ttfd, str, strlen(str) + 1); /* include trailing null */
- debug(4) ("send: %S\n", str);
- return (str); /* return the message */
- }
-
- /* xpct - read message from host in "^Pmessage[\0\n]" format; trap on errors */
-
- hidden char *xpct(pat)
- char *pat;
- {
- register int c;
- register char *p = msgin;
- register int inmsg = 0;
-
- /*
- * Keep reading until we time out, or until a complete message has been
- * received. Consider the link as lost in case of time out. Assume we are
- * rejected if the received message differs from what was expected.
- */
-
- debug(4) ("xpct: %S\n", pat);
-
- for (;;) {
- if ((c = xgetc()) == EOF) {
- trap(E_LOST, "FAILED (protocol handshake)");
- /* NOTREACHED */
- } else if ((c &= 0177) == '\020') {
- debug(4) (" got sync\n"); /* got start of message */
- p = msgin; /* reset */
- inmsg = 1;
- } else if (inmsg == 0) {
- debug(4) ("%C", c); /* don\'t store, just debug */
- } else if (*p++ = ((c == '\n') ? '\0' : c)) {
- debug(4) ("%C", c); /* store and debug */
- if (p >= msgin + MSGBUF) { /* spurious Ctrl-P seen? */
- p = msgin; /* reset */
- inmsg = 0; /* reset */
- }
- } else if ((debug(4) ("\n")), strncmp(pat, msgin, strlen(pat)) == 0) {
- return (msgin); /* expect succeeded */
- } else {
- msgin[30] = '\0'; /* truncate to 30 */
- trap(E_REJECT, "FAILED (%S)", msgin);
- /* NOTREACHED */
- }
- }
- }
-