char *loginv = "Script login CTOS Version-2.00, Apr 1992"; /* C K L O G I -- Login script for logging onto remote system */ /* 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) */ /* modified for CTOS C2.0 by Joel Dunn, UNC-CH, October 1986 */ /* modified to implement MS-DOS like INPUT, REINPUT, and OUTPUT */ /* commands. INPUT looks for a string of up to 7 bytes */ /* coming from the current line. OUTPUT puts a string */ /* out to the current line. numerics up to 65535 that */ /* are preceeded by "//" are converted to their ASCII */ /* character equivalent. Numerics of greater than 65535 */ /* are sent verbatum. */ /* D. Drury, E. Arnerich - ITT Federal Services 7/91 */ /* Modified RecvSeq to send exp_alrm value to use exp_alrm */ /* value instead of 1 second for inter-character */ /* timeout value. */ /* D. Drury, E. Arnerich - ITT Federal Services 4/92 */ #include "ctermi.h" extern int local, speed, flow, seslog, mdmtyp, techo, tlevel; extern char ttname[]; static char * chstr(); int exp_alrm = 30; /* Time to wait for expect string */ #define NULL_EXP 2 /* Time to pause on null expect strg*/ /* changed from 5 to 2, was 1 in Unix source, this change was 1.01 */ #define SBUFL 300 /* Login Sequence buffer */ static char seq_buf[SBUFL], *s; static char savinput[SBUFL]; static int got_it, no_cr; /* 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 */ delay (NULL_EXP*10); got_it = 1; tlog(F100,"got it (null sequence)","",0l); return; } *trace = '\0'; for (i=0; i<7; i++) got[i]='\0'; timerexit = 0; allocexch(&exchwait); trb1.ctt_counter = 10*exp_alrm; trb1.ctt_reload = 0; trb1.ctt_cevents = 0; trb1.ctt_exchresp = exchwait; trb1.ctt_ercret = 0; trb1.ctt_rqcode = exchwait; openrtclock(&trb1); while ((!got_it) && (!timerexit)) { for (i=0; i<(l-1); i++) got[i] = got[i+1]; /* shift over one */ got[l-1] = ttinc(1) & 0177; while (got[l-1] == 023) /* ignore ctl-s */ got[l-1] = ttinc(exp_alrm) & 0177; /* next char */ if (strlen(trace) < sizeof(trace)-2 ) strcat(trace,chstr(got[l-1])); got_it = (!strncmp(seq_buf, got, l) ) ; if (!check(exchwait, &ptrb1)) { if (ptrb1->ctt_rqcode == exchwait) { timerexit = 1; got_it = 0; } } } deallocexch(exchwait); closertclock(&trb1); for(i=0; i 0) { for ( sb=seq_buf; *sb; sb++) *sb = dopar(*sb); ttol(seq_buf,l); /* with parity */ } if (!no_cr) ttoc( dopar('\r') ); } return(0); } /* L O G I N -- Process script to login or send commands remote system */ login(cmdstr) char *cmdstr; { char *e; int x; s = cmdstr; /* make global to cklogi.c */ tlog(F100,loginv,"",0l); x = initline(); if (x != 0) return(x); /* return error if initline failed */ if((tlevel < 0) || techo) printf("Logging on thru %s, speed %d.\r\n",ttname,speed); *seq_buf=0; for (e=s; *e; e++) strcat(seq_buf, chstr(*e) ); if ((tlevel < 0) || techo) printf("The script string is: %s\r\n",seq_buf); tlog(F110,"Script command string: ",seq_buf, 0l); /* 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; sequenc(); 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 */ sequenc(); if (outSeq()) goto failRet; /* if unable to send! */ if (*s++ != '-') goto failRet; /* must have condit respon.*/ sequenc(); recvSeq(); } /* loop back and check got_it */ while (*s && *s++ != ' ') ; /* skip over conditionals and spaces */ ttflui(); /* Flush */ if (*s) { sequenc(); if (outSeq()) goto failRet; /* if any */ } } if ((tlevel < 0) || techo) printf("Script successful!\r\n"); tlog(F100,"Script successful!","",0l); return(0); failRet: if ((tlevel < 0) || techo) printf("Sorry, script failed\r\n"); tlog(F100,"Script 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); } /* I N I T L I N E -- initializes the line for login/input/output */ /* return 0 if successful otherwise return -2 */ initline() { 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); } /* Condition console terminal and communication line */ if (ttvt(speed,flow) < 0) { printf("Sorry, Can't condition communication line\n"); return(-2); } /* ttflui(); flush stale input */ return (0); } /* D O I N P U T -- UNIX/DOS like input command */ /* the maximum input string length is 7 */ doinput (cmdstr, timeout) char *cmdstr; int timeout; { int x; char *e; s = cmdstr; 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); } /* x = initline(); if(x != 0) return(x); */ *seq_buf = 0; for (e = s; *e; e++) strcat(seq_buf, chstr(*e)); exp_alrm = timeout; got_it = 0; recvSeq(); if (got_it == 0) return(-2); /* return failure if not found */ return(0); /* otherwise return success */ } /* D O R E I N P U T -- UNIX/DOS like reinput */ /* not timeout value is used or required */ dorinput(cmdstr) char *cmdstr; { int rc = -2; /* init result code to not found */ int i, len; char *start; s = cmdstr; while (*s != ' ') /* get to spaces */ s++; while (*s == ' ') /* get past spaces */ s++; len = strlen(s); start = savinput; for(i = 0; i < SBUFL && (savinput[i] != '\0') && rc; i++) { if (!strncmp(s, start, len)) rc = 0; /* found it! */ start++; } tlog(F110,"reinput searching for: ",s,0l); tlog(F110,"received sequence: ",savinput,0l); tlog(F101,"returning with result code","",(long) rc); return(rc); /* return result code */ } /* D O O U T P U T -- UNIX/DOS like output command */ /* looks for '\', and if found processes following numerics as decimal */ /* to be converted to ASCII characters, then outputs the total length */ /* of the input buffer - including any NULLs which may be generated by */ /* converting the numeric to ASCII. This routine does not add cr */ /* The maximum decimal value processed is 65535. Anything larger is */ /* put out as a character string */ dooutput(cmdstr) char *cmdstr; { #define MAX_VALUE 65535L int x, y, len; char e, *digitpos; unsigned long numbr; int j; numbr = 0; s = cmdstr; 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); } x = initline(); if (x != 0) return(-2); *seq_buf = 0; len = strlen(s); x = 0; seq_buf[x] = '\0'; while (*s) { digitpos = s; digitpos++; if (*s == '\\' && isdigit(*digitpos)) { /* quoted sequence? */ numbr = 0; while (1) { e = *digitpos; if (isdigit(e)) { j = e & 0x0f; numbr = numbr*10 + (unsigned long) j; digitpos++; } else break; /* exit while, on first non-digit */ } if (numbr <= MAX_VALUE) { /* now that its a num make it str */ seq_buf[x++] = (numbr & 0xff); /* get low order first */ /* followed by high order byte if high order byte > 0 */ if (numbr > 256) seq_buf[x++] = (numbr >> 8); s = digitpos; continue; } } seq_buf[x++] = *s++; } /* now put all x bytes out */ tlog(F111, "sending output ", seq_buf, (long) x); if (x > 0) { for (y=0; y