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
- /* Wed Apr 6 00:22:51 MET 1988
- /* VERSION/RELEASE
- /* 1.4
- /*--*/
-
- #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 ptable[] = {
- '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);
- send(strcons("S%s -x%d",LOGIN_NAME,MAX(dflag,1))); /* name + debug level */
- xpct("ROK"); /* we're accepted or rejected */
-
- /* choose a protocol from the list offered by the other side */
-
- for (cp = xpct("P")+1,pp = ptable; pp->name && !index(cp,pp->name); pp++)
- /* void */ ;
- if (pp->name == 0) { /* no common protocol */
- send("N");
- 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)");
-
- log("OK (startup)");
- systrap = savetrap; /* get here if expect wins */
- return(0);
- }
-
- /* endproto - terminate protocol */
-
- public endproto()
- {
- int *savetrap = systrap;
- jmp_buf mytrap;
- int status;
-
- if (status = setjmp(systrap = mytrap)) { /* get here if expect fails */
- systrap = savetrap;
- return(status);
- }
- if (Close) /* check there is one */
- CALL(Close)(ttfd); /* turn protocol off */
- send("OOOOOO"); /* byebye */
- xpct("OO"); /* bye */
- log("OK (conversation complete)");
-
- systrap = savetrap; /* get here if expect wins */
- 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, the buffer is full, or until a
- * complete message has been received. Consider the link as lost
- * in case of time out or buffer overflow. Assume we are rejected
- * if the received message differs from what was expected.
- */
-
- while (p < msgin+MSGBUF && (c = xgetc()) != EOF) {
- if ((c &= 0177) == '\020') { /* got start of message */
- debug(4)(" got sync\n");
- p = msgin; /* clear msg buffer */
- inmsg = 1;
- } else if (inmsg == 0 || (*p++ = (c == '\n' ? 0 : c))) {
- debug(4)("%C",c);
- } else { /* message completed */
- debug(4)("\n");
- if (strncmp(pat,msgin,strlen(pat))) /* compare prefix only */
- break;
- return(msgin);
- }
- }
- trap((c == EOF || p >= msgin+MSGBUF ? E_LOST : E_REJECT),
- "FAILED (%s)",msgin);
- /* NOTREACHED */
- }
-