char *loginv = "Login Command for Unix, V1.0(003) 28 Feb 85"; /* C K L O G I -- Login script for logging onto remote system */ /* This module should work under all versions of Unix. It calls externally defined system-depended functions for i/o. The module expects a login string of the expect send [expect send] ... format. It is intended to operate similarly to the way the common uucp "L.sys" login entries work. Conditional responses are supported expect[-send-expect[...]] as with uucp. The send keyword EOT sends a control-d, and the keyword BREAK sends a break. Letters prefixed by '~' are '~b' backspace, '~s' space, '~n' linefeed, '~r' return, '~t' tab, '~q' ? (not allowed on kermit command lines), '~' ~, '~'', '~"', '~c' don't append return, '~o[o[o]]' octal character. As with some uucp systems, sent strings are followed by ~r (not ~n) unless they end with ~c. Null expect strings (e.g., ~0 or --) cause a short delay, and are useful for sending sequences requiring slight pauses. Author: Herm Fischer, Litton Data Systems, Van Nuys CA (HFISCHER@USC-ECLB) */ #include "ckermi.h" #include #include extern int local, speed, flow, seslog, mdmtyp; extern char ttname[]; static char * chstr(); #define EXP_ALRM 15 /* Time to wait for expect string */ #define SND_ALRM 15 /* Time to allow for sending string */ #define NULL_EXP 2 /* Time to pause on null expect strg*/ #define SBUFL 300 /* Login Sequence buffer */ static char seq_buf[SBUFL], *s; static int got_it, no_cr; /* connect state parent/child communication signal handlers */ static jmp_buf alrmRng; /* Envir ptr for connect errors */ static timeInt() { /* modem read failure handler, */ longjmp(alrmRng,1); /* notifies parent process to stop */ } /* Sequence interpreter -- pick up next sequence from command string, decode escapes and place into seq_buf */ static sequenc() { int i; char c, oct_char; no_cr = 0; /* output needs cr appended */ for (i=0; i 7) { e += l-7; l = 7; } tlog(F111,"expecting sequence",e,(long) l); if (l == 0) { /* null sequence, just delay a little */ sleep (NULL_EXP); got_it = 1; tlog(F100,"got it (null sequence)","",0l); return; } *trace = '\0'; for (i=0; i<7; i++) got[i]='\0'; signal(SIGALRM,timeInt); /* did we get it? */ if (!setjmp(alrmRng)) { /* not timed out yet */ alarm(EXP_ALRM); while (!got_it) { for (i=0; i<(l-1); i++) got[i] = got[i+1]; /* shift over one */ got[l-1] = ttinc(0) & 0177; /* next char */ if (strlen(trace) < sizeof(trace)-2 ) strcat(trace,chstr(got[l-1])); got_it = (!strncmp(seq_buf, got, l) ) ; } } else got_it = 0; /* timed out here */ alarm(0); signal(SIGALRM,SIG_IGN); tlog(F110,"received sequence: ",trace,0l); tlog(F101,"returning with got-it code","",(long) got_it); return; } /* Output A Sequence starting at pointer s, return 0 if okay, 1 if failed to read (modem hangup or whatever) */ static int outSeq() { char *sb; int l; sequenc(); l = strlen(seq_buf); tlog(F111,"sending sequence ",seq_buf,(long) l); signal(SIGALRM,timeInt); if (!setjmp(alrmRng)) { alarm(SND_ALRM); if (!strcmp(seq_buf,"EOT")) ttoc(dopar('\004')); else if (!strcmp(seq_buf,"BREAK")) ttsndb(); else { if (l > 0) { for ( sb=seq_buf; *sb; sb++) *sb = dopar(*sb); ttol(seq_buf,l); /* with parity */ } if (!no_cr) ttoc( dopar('\r') ); } alarm(0); signal(SIGALRM,SIG_IGN); return(0); } alarm(0); /* else -- alarm rang */ signal(SIGALRM,SIG_IGN); return( -1 ); } /* L O G I N -- Login to remote system */ login(cmdstr) char *cmdstr; { int (*saveAlm)(); /* save incomming alarm function */ char *e; s = cmdstr; /* make global to cklogi.c */ tlog(F100,loginv,"",0l); if (!local) { printf("Sorry, you must 'set line' first\n"); return(-2); } if (speed < 0) { printf("Sorry, you must 'set speed' first\n"); return(-2); } if (ttopen(ttname,local,mdmtyp) < 0) { sprintf(seq_buf,"Sorry, can't open %s",ttname); perror(seq_buf); return(-2); } printf("Logging on thru %s, speed %d.\r\n",ttname,speed); *seq_buf=0; for (e=s; *e; e++) strcat(seq_buf, chstr(*e) ); printf("The logon string is: %s\r\n",seq_buf); tlog(F110,"Logon command string: ",seq_buf, 0l); /* Condition console terminal and communication line */ if (ttvt(speed,flow) < 0) { printf("Sorry, Can't condition communication line\n"); return(-2); } /* save initial timer interrupt value */ saveAlm = signal(SIGALRM,SIG_IGN); ttflui(); /* flush stale input */ /* cont'd... */ /* ...login, cont'd */ /* start expect - send sequence */ while (*s) { /* while not done with buffer */ while (*s && *s == ' ') s++; /* skip over separating blanks */ /* gather up expect sequence */ got_it = 0; recvSeq(); while (!got_it) { /* no, is there a conditional send */ if (*s++ != '-') goto failRet; /* no -- return failure */ /* start of conditional send */ ttflui(); /* flush out input buffer */ if (outSeq()) goto failRet; /* if unable to send! */ if (*s++ != '-') goto failRet; /* must have condit respon.*/ recvSeq(); } /* loop back and check got_it */ while (*s && *s++ != ' ') ; /* skip over conditionals and spaces */ ttflui(); /* Flush */ if (*s) if (outSeq()) goto failRet; /* if any */ } signal(SIGALRM,saveAlm); printf("Logged on!\r\n"); tlog(F100,"Logged on!","",0l); return(0); failRet: signal(SIGALRM,saveAlm); printf("Sorry, logon failed\r\n"); tlog(F100,"Logon failed","",0l); return(-2); } /* C H S T R -- Make printable string from a character */ static char * chstr(c) char c; { static char sc[4]; if (c < SP) sprintf(sc, "^%c",ctl(c) ); else sprintf(sc, "%c", c); return(sc); }