|
|
1.1 ! root 1: char *loginv = "Script Command, V2.0(007) 3 Aug 87"; ! 2: ! 3: /* C K U S C R -- Login script for logging onto remote system */ ! 4: ! 5: /* ! 6: This module should work under all versions of Unix. It calls externally ! 7: defined system-depended functions for i/o. ! 8: ! 9: The module expects a login string of the expect send [expect send] ... ! 10: format. It is intended to operate similarly to the way the common ! 11: uucp "L.sys" login entries work. Conditional responses are supported ! 12: expect[-send-expect[...]] as with uucp. The send keyword EOT sends a ! 13: control-d, and the keyword BREAK sends a break. Letters prefixed ! 14: by '~' are '~b' backspace, '~s' space, '~n' linefeed, '~r' return, '~x' xon, ! 15: '~t' tab, '~q' ? (not allowed on kermit command lines), '~' ~, '~'', ! 16: '~"', '~c' don't append return, '~o[o[o]]' octal character. As with ! 17: some uucp systems, sent strings are followed by ~r (not ~n) unless they ! 18: end with ~c. Null expect strings (e.g., ~0 or --) cause a short ! 19: delay, and are useful for sending sequences requiring slight pauses. ! 20: ! 21: Author: Herm Fischer (HFISCHER@USC-ECLB) ! 22: Contributed to Columbia University for inclusion in C-Kermit. ! 23: Copyright (C) 1985, Herman Fischer, 16400 Ventura Blvd, Encino CA 91436 ! 24: Permission is granted to any individual or institution to use, copy, or ! 25: redistribute this software so long as it is not sold for profit, provided this ! 26: copyright notice is retained. ! 27: */ ! 28: ! 29: #include "ckcdeb.h" ! 30: #include <stdio.h> ! 31: #include <ctype.h> ! 32: #include <signal.h> ! 33: #include <setjmp.h> ! 34: #include "ckcker.h" ! 35: ! 36: extern int local, speed, flow, seslog, mdmtyp, quiet, duplex; ! 37: extern char ttname[]; ! 38: extern CHAR dopar(); ! 39: static char * chstr(); ! 40: ! 41: static int EXP_ALRM = 15; /* Time to wait for expect string */ ! 42: #define SND_ALRM 15 /* Time to allow for sending string */ ! 43: #define NULL_EXP 2 /* Time to pause on null expect strg*/ ! 44: #define DEL_MSEC 300 /* milliseconds to pause on ~d */ ! 45: ! 46: #define SBUFL 512 ! 47: static char seq_buf[SBUFL], *s; /* Login Sequence buffer */ ! 48: static char fls_buf[SBUFL]; /* Flush buffer */ ! 49: static int got_it, no_cr; ! 50: ! 51: /* connect state parent/child communication signal handlers */ ! 52: ! 53: static jmp_buf alrmRng; /* Envir ptr for connect errors */ ! 54: ! 55: scrtime() { /* modem read failure handler, */ ! 56: longjmp(alrmRng,1); /* notifies parent process to stop */ ! 57: } ! 58: ! 59: ! 60: /* ! 61: Sequence interpreter -- pick up next sequence from command string, ! 62: decode escapes and place into seq_buf ! 63: ! 64: If string contains a ~d (delay) then sequenc returns a 1 expecting ! 65: to be called again after the ~d executes. ! 66: */ ! 67: static ! 68: sequenc() { ! 69: ! 70: int i; ! 71: char c, oct_char; ! 72: ! 73: no_cr = 0; /* output needs cr appended */ ! 74: ! 75: for (i=0; i<SBUFL; ) { ! 76: if (*s == '\0' || *s == '-' || isspace(*s) ) { /* done */ ! 77: seq_buf[i] = '\0'; ! 78: return(0) ; ! 79: } ! 80: ! 81: if (*s == '~') { /* escape character */ ! 82: switch (c = *(++s) ) { ! 83: case 'n': seq_buf[i++] = '\n'; break; ! 84: case 'r': seq_buf[i++] = '\r'; break; ! 85: case 't': seq_buf[i++] = '\t'; break; ! 86: case 'b': seq_buf[i++] = '\b'; break; ! 87: case 'q': seq_buf[i++] = '?'; break; ! 88: case '~': seq_buf[i++] = '~'; break; ! 89: case '\'': seq_buf[i++] = '\''; break; ! 90: case '\"': seq_buf[i++] = '\"'; break; ! 91: case 's': seq_buf[i++] = ' '; break; ! 92: case 'x': seq_buf[i++] = '\021'; break; ! 93: case 'c': no_cr = 1; break; ! 94: case 'd': { /* send what we have & then */ ! 95: seq_buf[i] = '\0'; /* expect to send rest after */ ! 96: no_cr = 1; /* sender delays a little */ ! 97: s++; ! 98: return(1); ! 99: } ! 100: case 'w': { /* wait count */ ! 101: EXP_ALRM = 15; /* default to 15 sec */ ! 102: if ( isdigit( *(s+1) ) ) { ! 103: EXP_ALRM = (*(++s)) & 15; ! 104: if ( isdigit( *(s+1) ) ) { ! 105: EXP_ALRM = EXP_ALRM*10 + ( (*(++s)) & 15 ); ! 106: } ! 107: } ! 108: break; ! 109: } ! 110: default: ! 111: if ( isdigit(c) ) { /* octal character */ ! 112: oct_char = (c & 7); /* most significant digit */ ! 113: if (isdigit( *(s+1) ) ) { ! 114: oct_char = (oct_char<<3) | ( (*(++s)) & 7 ) ; ! 115: if (isdigit( *(s+1) ) ) { ! 116: oct_char = (oct_char<<3) | ( (*(++s)) & 7 ) ; ! 117: } ! 118: } ! 119: seq_buf[i++] = oct_char; ! 120: break; ! 121: } ! 122: } ! 123: } ! 124: else seq_buf[i++] = *s; /* plain old character */ ! 125: s++; ! 126: } ! 127: seq_buf[i] = '\0'; ! 128: return(0); /* end of space, return anyway */ ! 129: } ! 130: ! 131: ! 132: /* ! 133: Receive sequence -- see if expected response comes return success ! 134: (or failure) in got_it ! 135: */ ! 136: static ! 137: recvSeq() { ! 138: ! 139: char *e, got[7], trace[SBUFL]; ! 140: int i, l; ! 141: ! 142: sequenc(); ! 143: l = strlen(e=seq_buf); /* no more than 7 chars allowed */ ! 144: if (l > 7) { ! 145: e += l-7; ! 146: l = 7; ! 147: } ! 148: tlog(F111,"expecting sequence",e,(long) l); ! 149: if (l == 0) { /* null sequence, just delay a little */ ! 150: sleep (NULL_EXP); ! 151: got_it = 1; ! 152: tlog(F100,"got it (null sequence)","",0l); ! 153: return; ! 154: } ! 155: *trace = '\0'; ! 156: for (i=0; i<7; i++) got[i]='\0'; ! 157: ! 158: signal(SIGALRM,scrtime); /* did we get it? */ ! 159: if (!setjmp(alrmRng)) { /* not timed out yet */ ! 160: alarm(EXP_ALRM); ! 161: while (!got_it) { ! 162: for (i=0; i<(l-1); i++) got[i] = got[i+1]; /* shift over one */ ! 163: got[l-1] = ttinc(0) & 0177; /* next char */ ! 164: if (seslog) /* Log in session log */ ! 165: zchout(ZSFILE,got[l-1]); ! 166: if (strlen(trace) < sizeof(trace)-2 ) ! 167: strcat(trace,chstr(got[l-1])); ! 168: got_it = (!strncmp(seq_buf, got, l) ) ; ! 169: } ! 170: } else got_it = 0; /* timed out here */ ! 171: ! 172: alarm(0); ! 173: signal(SIGALRM,SIG_IGN); ! 174: tlog(F110,"received sequence: ",trace,0l); ! 175: tlog(F101,"returning with got-it code","",(long) got_it); ! 176: return; ! 177: } ! 178: ! 179: ! 180: /* ! 181: Output A Sequence starting at pointer s, ! 182: return 0 if okay, ! 183: 1 if failed to read (modem hangup or whatever) ! 184: */ ! 185: static int ! 186: outSeq() { ! 187: char *sb; ! 188: int l; ! 189: int delay; ! 190: int retCode = 0; ! 191: ! 192: while(1) { ! 193: delay = sequenc(); ! 194: l = strlen(seq_buf); ! 195: tlog(F111,"sending sequence ",seq_buf,(long) l); ! 196: signal(SIGALRM,scrtime); ! 197: if (!setjmp(alrmRng)) { ! 198: alarm(SND_ALRM); ! 199: if (!strcmp(seq_buf,"EOT")) { ! 200: ttoc(dopar('\004')); ! 201: if (seslog && duplex) zsout(ZSFILE,"{EOT}"); ! 202: } else if (!strcmp(seq_buf,"BREAK")) { ! 203: ttsndb(); ! 204: zsout(ZSFILE,"{BREAK}"); ! 205: } else { ! 206: if (l > 0) { ! 207: for ( sb=seq_buf; *sb; sb++) *sb = dopar(*sb); ! 208: ttol(seq_buf,l); /* with parity */ ! 209: if (seslog && duplex) zsout(ZSFILE,seq_buf); ! 210: } ! 211: if (!no_cr) { ! 212: ttoc( dopar('\r') ); ! 213: if (seslog && duplex) zchout(ZSFILE,dopar('\r')); ! 214: } ! 215: } ! 216: } ! 217: else retCode |= -1; /* else -- alarm rang */ ! 218: alarm(0); ! 219: signal(SIGALRM,SIG_IGN); ! 220: if (!delay) return ( retCode ); ! 221: msleep(DEL_MSEC); /* delay, and loop to next stuff to send */ ! 222: } ! 223: } ! 224: ! 225: ! 226: /* L O G I N -- Login to remote system */ ! 227: ! 228: login(cmdstr) char *cmdstr; { ! 229: ! 230: SIGTYP (*saveAlm)(); /* save incoming alarm function */ ! 231: char *e; ! 232: ! 233: s = cmdstr; /* make global to ckuscr.c */ ! 234: ! 235: tlog(F100,loginv,"",0l); ! 236: ! 237: if (!local) { ! 238: printf("Sorry, you must 'set line' first\n"); ! 239: return(-2); ! 240: } ! 241: if (speed < 0) { ! 242: printf("Sorry, you must 'set speed' first\n"); ! 243: return(-2); ! 244: } ! 245: if (ttopen(ttname,&local,mdmtyp) < 0) { ! 246: sprintf(seq_buf,"Sorry, can't open %s",ttname); ! 247: perror(seq_buf); ! 248: return(-2); ! 249: } ! 250: if (!quiet) ! 251: printf("Executing script thru %s, speed %d.\r\n",ttname,speed); ! 252: *seq_buf=0; ! 253: for (e=s; *e; e++) strcat(seq_buf, chstr(*e) ); ! 254: if (!quiet) printf("Script string: %s\r\n",seq_buf); ! 255: tlog(F110,"Script string: ",seq_buf, 0l); ! 256: ! 257: /* Condition console terminal and communication line */ ! 258: ! 259: if (ttvt(speed,flow) < 0) { ! 260: printf("Sorry, Can't condition communication line\n"); ! 261: return(-2); ! 262: } ! 263: /* save initial timer interrupt value */ ! 264: saveAlm = signal(SIGALRM,SIG_IGN); ! 265: ! 266: flushi(); /* flush stale input */ ! 267: ! 268: /* cont'd... */ ! 269: ! 270: ! 271: /* ...login, cont'd */ ! 272: ! 273: /* start expect - send sequence */ ! 274: ! 275: while (*s) { /* while not done with buffer */ ! 276: ! 277: while (*s && isspace(*s)) s++; /* skip over separating whitespaces */ ! 278: /* gather up expect sequence */ ! 279: got_it = 0; ! 280: recvSeq(); ! 281: ! 282: while (!got_it) { ! 283: /* no, is there a conditional send */ ! 284: if (*s++ != '-') goto failRet; /* no -- return failure */ ! 285: ! 286: /* start of conditional send */ ! 287: flushi(); /* flush out input buffer */ ! 288: if (outSeq()) goto failRet; /* if unable to send! */ ! 289: ! 290: if (*s++ != '-') goto failRet; /* must have condit respon.*/ ! 291: recvSeq(); ! 292: } /* loop back and check got_it */ ! 293: ! 294: while (*s && !isspace(*s++) ) ; /* Skip over conditionals */ ! 295: while (*s && isspace(*s)) s++; /* Skip over separating whitespaces */ ! 296: flushi(); /* Flush */ ! 297: if (*s) if (outSeq()) goto failRet; /* If any */ ! 298: } ! 299: signal(SIGALRM,saveAlm); ! 300: if (!quiet) printf("Script successful.\r\n"); ! 301: tlog(F100,"Script successful.","",0l); ! 302: return(0); ! 303: ! 304: failRet: ! 305: signal(SIGALRM,saveAlm); ! 306: printf("Sorry, script failed\r\n"); ! 307: tlog(F100,"Script failed","",0l); ! 308: return(-2); ! 309: } ! 310: ! 311: ! 312: /* C H S T R -- Make printable string from a character */ ! 313: ! 314: static char * ! 315: chstr(c) char c; { ! 316: static char sc[4]; ! 317: ! 318: if (c < SP) sprintf(sc, "^%c",ctl(c) ); ! 319: else sprintf(sc, "%c", c); ! 320: ! 321: return(sc); ! 322: } ! 323: ! 324: /* F L U S H I -- Flush, but log, input buffer */ ! 325: ! 326: flushi() { ! 327: int n; ! 328: if (seslog) { /* Logging session? */ ! 329: n = ttchk(); /* Yes, anything in buffer? */ ! 330: if (n > 0) { /* If so, */ ! 331: if (n > SBUFL) n = SBUFL; /* make sure not too much, */ ! 332: n = ttxin(n,fls_buf); /* then read it, */ ! 333: zsout(ZSFILE,fls_buf); /* and log it. */ ! 334: } ! 335: } else ttflui(); /* Otherwise just flush. */ ! 336: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.