Annotation of researchv10dc/lbin/kermit/ckuscr.c, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.