Annotation of coherent/e/bin/cku179/ckuscr.c, revision 1.1.1.1

1.1       root        1: #ifndef NOICP
                      2: #ifndef NOSCRIPT
                      3: char *loginv = "Script Command, 5A(012) 25 Dec 91";
                      4: 
                      5: /*  C K U S C R  --  Login script for logging onto remote system */
                      6: 
                      7: /*
                      8:  This module should work under all versions of Unix.  It calls externally
                      9:  defined system-depended functions for i/o.
                     10: 
                     11:  The module expects a login string of the expect send [expect send] ...
                     12:  format.  It is intended to operate similarly to the way the common
                     13:  uucp "L.sys" login entries work.  Conditional responses are supported
                     14:  expect[-send-expect[...]] as with uucp.  The send keyword EOT sends a
                     15:  control-d, and the keyword BREAK sends a break.  Letters prefixed
                     16:  by '~' are '~b' backspace, '~s' space, '~n' linefeed, '~r' return, '~x' xon,
                     17:  '~t' tab, '~q' ? (not allowed on kermit command lines), '~' ~, '~'', 
                     18:  '~"', '~c' don't append return, '~o[o[o]]' octal character.  As with
                     19:  some uucp systems, sent strings are followed by ~r (not ~n) unless they
                     20:  end with ~c. Null expect strings (e.g., ~0 or --) cause a short
                     21:  delay, and are useful for sending sequences requiring slight pauses.
                     22: 
                     23:  Author: Herm Fischer (HFISCHER@USC-ECLB)
                     24:  Contributed to Columbia University for inclusion in C-Kermit.
                     25:  Copyright (C) 1985, Herman Fischer, 16400 Ventura Blvd, Encino CA 91436
                     26:  Permission is granted to any individual or institution to use, copy, or
                     27:  redistribute this software so long as it is not sold for profit, provided this
                     28:  copyright notice is retained. 
                     29: 
                     30:  Modifications added 1985-1991, F. da Cruz, Columbia University.
                     31: */
                     32: 
                     33: #include "ckcdeb.h"
                     34: #include <signal.h>
                     35: #include <setjmp.h>
                     36: #include "ckcasc.h"
                     37: #include "ckcker.h"
                     38: #include "ckuusr.h"
                     39: #include "ckcnet.h"
                     40: 
                     41: _PROTOTYP( VOID flushi, (void) );
                     42: 
                     43: #ifdef MAC
                     44: #define SIGALRM (1<<10)
                     45: #undef SIGTYP                          /* put in ckcdeb.h later */
                     46: #define SIGTYP void
                     47: #endif /* MAC */
                     48: 
                     49: extern int local, flow, seslog, mdmtyp, quiet, duplex, backgrd, secho;
                     50: #ifdef NETCONN
                     51: extern int network, ttnproto;
                     52: #endif /* NETCONN */
                     53: extern long speed;
                     54: extern char ttname[];
                     55: 
                     56: #ifndef NOSPL
                     57: extern struct cmdptr cmdstk[];
                     58: extern int techo, cmdlvl;
                     59: extern int mecho;
                     60: #endif /* NOSPL */
                     61: 
                     62: static int scr_echo;                   /* Whether to echo script commands */
                     63: 
                     64: static int exp_alrm = 15;              /* Time to wait for expect string */
                     65: #define SND_ALRM 15                    /* Time to allow for sending string */
                     66: #define NULL_EXP 2                     /* Time to pause on null expect strg*/ 
                     67: #define DEL_MSEC 300                   /* milliseconds to pause on ~d */
                     68: 
                     69: #define SBUFL 512              
                     70: static char seq_buf[SBUFL], *s;                /* Login Sequence buffer */
                     71: static char fls_buf[SBUFL];            /* Flush buffer */
                     72: static int got_it, no_cr;
                     73: 
                     74: /*  connect state parent/child communication signal handlers */
                     75: 
                     76: static jmp_buf alrmrng;                        /* Envir ptr for connect errors */
                     77: 
                     78: SIGTYP
                     79: scrtime(foo) int foo; {                        /* modem read failure handler, */
                     80:     longjmp(alrmrng,1);                        /* notifies parent process to stop */
                     81: }
                     82: 
                     83: /*
                     84:  Sequence interpreter -- pick up next sequence from command string,
                     85:  decode escapes and place into seq_buf.
                     86: 
                     87:  If string contains a ~d (delay) then sequenc returns a 1 expecting
                     88:  to be called again after the ~d executes.
                     89: */
                     90: static int
                     91: sequenc() {
                     92:     int i;
                     93:     char c, oct_char;
                     94: 
                     95:     no_cr = 0;                         /* output needs cr appended */
                     96:     for (i = 0; i < SBUFL; ) {         
                     97:        if (*s == '\0' || *s == '-' || isspace(*s) ) { /* done */
                     98:            seq_buf[i] = '\0';
                     99:            return(0) ;
                    100:        }
                    101:        if (*s == '~') {                /* escape character */
                    102:            s++;
                    103:            switch (c = *s) {
                    104:                case 'n':  seq_buf[i++] = LF; break;
                    105:                case 'r':  seq_buf[i++] = CR; break;
                    106:                case 't':  seq_buf[i++] = '\t'; break;
                    107:                case 'b':  seq_buf[i++] = '\b'; break;
                    108:                case 'q':  seq_buf[i++] = '?';  break;
                    109: #ifdef COMMENT
                    110: /* The default case should catch these now... */
                    111:                case '~':  seq_buf[i++] = '~';  break;
                    112:                case '-':  seq_buf[i++] = '-';  break;
                    113: #endif /* COMMENT */
                    114:                case '\'': seq_buf[i++] = '\''; break;
                    115:                case '\"': seq_buf[i++] = '\"'; break;
                    116:                case 's':  seq_buf[i++] = ' ';  break;
                    117:                case 'x':  seq_buf[i++] = '\021'; break;
                    118:                case 'c':  no_cr = 1; break;
                    119:                case 'd': {                     /* send what we have & then */
                    120:                    seq_buf[i] = '\0';          /* expect to send rest after */
                    121:                    no_cr = 1;                  /* sender delays a little */
                    122:                    s++;
                    123:                    return(1);
                    124:                }
                    125:                case 'w': {                     /* wait count */
                    126:                    exp_alrm = 15;              /* default to 15 sec */
                    127:                    if (isdigit(*(s+1))) { 
                    128:                        s++;
                    129:                        exp_alrm = *s & 15;
                    130:                        if (isdigit(*(s+1)) ) {
                    131:                            s++;
                    132:                            exp_alrm = exp_alrm * 10 + (*s & 15);
                    133:                        }
                    134:                    }
                    135:                    break;
                    136:                }
                    137:                default:
                    138:                    if ( isdigit(c) ) {         /* octal character */
                    139:                        oct_char = (c & 7);     /* most significant digit */
                    140:                        if (isdigit( *(s+1) ) ) {
                    141:                            s++;
                    142:                            oct_char = (oct_char<<3) | ( *s & 7 ) ;
                    143:                            if (isdigit( *(s+1) ) ) {
                    144:                                s++;
                    145:                                oct_char = (oct_char<<3) | ( *s & 7 ) ;
                    146:                            }
                    147:                        }
                    148:                        seq_buf[i++] = oct_char;
                    149:                        break;
                    150:                    } else seq_buf[i++] = *s; /* Treat ~ as quote */
                    151:              }
                    152:        } else seq_buf[i++] = *s;       /* Plain old character */
                    153:        s++;
                    154:     }
                    155:     seq_buf[i] = '\0';
                    156:     return(0);                         /* end of space, return anyway */
                    157: }
                    158: 
                    159: /*
                    160:  Receive sequence -- see if expected response comes,
                    161:  return success (or failure) in got_it.
                    162: */ 
                    163: static VOID
                    164: recvseq()  {
                    165:    
                    166:     char *e, got[7], trace[SBUFL];
                    167:     int i, l, x;
                    168:     
                    169:        sequenc();
                    170:        l = (int)strlen(e=seq_buf);     /* no more than 7 chars allowed */
                    171:        if (l > 7) {
                    172:            e += l-7;
                    173:            l = 7;
                    174:        }
                    175:        tlog(F111,"expecting sequence",e,(long) l);
                    176:        if (l == 0) {           /* null sequence, just delay a little */
                    177:            sleep (NULL_EXP);
                    178:            got_it = 1;
                    179:            tlog(F100,"got it (null sequence)","",0L);
                    180:            return;
                    181:        }
                    182:        *trace = '\0';
                    183:        for (i = 0; i < 7; i++) got[i]='\0';
                    184: 
                    185:        signal(SIGALRM,scrtime);        /* did we get it? */
                    186:        if (!setjmp(alrmrng)) {         /* not timed out yet */
                    187:            alarm(exp_alrm);
                    188:            while (!got_it) {
                    189:                for (i = 0; i < l-1; i++) got[i] = got[i+1]; /* Shift over */
                    190:                x = ttinc(0);           /* Read a character */
                    191:                debug(F101,"recvseq","",x);
                    192:                if (x < 0) goto rcvx;   /* Check for error */
                    193: #ifdef NETCONN
                    194: /* Check for telnet protocol negotiation */
                    195:                if (network &&
                    196:                    (ttnproto == NP_TELNET) &&
                    197:                    ( (x & 0xff) == IAC) ) {
                    198:                    switch (tn_doop((CHAR)(x & 0xff),duplex)) {
                    199:                      case 2: duplex = 0; continue;
                    200:                      case 1: duplex = 1;
                    201:                      default: continue;
                    202:                    }
                    203:                }
                    204: #endif /* NETCONN */
                    205:                got[l-1] = x & 0x7f;    /* Got a character */
                    206:                if (scr_echo) conoc(got[l-1]); /* Echo it */
                    207:                if (seslog)             /* Log it in session log */
                    208:                  if (zchout(ZSFILE,got[l-1]) < 0) seslog = 0;
                    209:                if ((int)strlen(trace) < sizeof(trace)-2 ) 
                    210:                  strcat(trace,dbchr(got[l-1]));
                    211:                got_it = (!strncmp(e, got, l));
                    212:            }
                    213:        } else got_it = 0;              /* timed out here */
                    214: rcvx:
                    215:        alarm(0);
                    216:        signal(SIGALRM,SIG_IGN);
                    217:        tlog(F110,"received sequence: ",trace,0L);
                    218:        tlog(F101,"returning with got-it code","",(long) got_it);
                    219:        return;
                    220: }
                    221: 
                    222: /*
                    223:  Output A Sequence starting at pointer s,
                    224:  return 0 if okay,
                    225:  1 if failed to read (modem hangup or whatever)
                    226: */
                    227: static int
                    228: outseq() {
                    229:     char *sb;
                    230:     int l;
                    231:     int delay;
                    232:     int retcode = 0;
                    233: 
                    234:     while(1) {
                    235:        delay = sequenc();  
                    236:        l = (int)strlen(seq_buf);
                    237:        tlog(F111,"sending sequence ",seq_buf,(long) l);
                    238:        signal(SIGALRM,scrtime);
                    239:        if (!setjmp(alrmrng)) {
                    240:            alarm(SND_ALRM);
                    241:            if (!strcmp(seq_buf,"EOT")) {
                    242:                ttoc(dopar('\004'));
                    243:                if (scr_echo) conol("<EOT>");
                    244:                if (seslog && duplex) if (zsout(ZSFILE,"<EOT>") < 0)
                    245:                  seslog = 0;
                    246:            } else if (!strcmp(seq_buf,"BREAK") ||
                    247:                       !strcmp(seq_buf,"\\b") ||
                    248:                       !strcmp(seq_buf,"\\B")) {
                    249:                ttsndb();
                    250:                if (scr_echo) conol("<BREAK>");
                    251:                if (seslog) if (zsout(ZSFILE,"{BREAK}") < 0) seslog = 0;
                    252:            } else {
                    253:                if (l > 0) {
                    254:                    for ( sb = seq_buf; *sb; sb++)
                    255:                      *sb = dopar(*sb); /* add parity */
                    256:                    ttol((CHAR *)seq_buf,l); /* send it */
                    257:                    if (scr_echo && duplex) conxo(l,seq_buf);
                    258:                    if (seslog && duplex) /* log it */
                    259:                      if (zsout(ZSFILE,seq_buf) < 0)
                    260:                        seslog=0;
                    261:                }
                    262:                if (!no_cr) {
                    263:                    ttoc( dopar(CR) );
                    264:                    if (seslog && duplex)
                    265:                      if (zchout(ZSFILE,dopar(CR)) < 0)
                    266:                        seslog = 0;
                    267:                }
                    268:            }
                    269:        } else retcode |= -1;           /* else -- alarm rang */
                    270:        alarm(0);
                    271:        signal(SIGALRM,SIG_IGN);
                    272:        if (!delay) return(retcode);
                    273: #ifndef MAC
                    274:        msleep(DEL_MSEC);               /* delay, loop to next send */
                    275: #endif /* MAC */
                    276:     }
                    277: }
                    278: 
                    279: /*  L O G I N  --  Login to remote system */
                    280: 
                    281: int
                    282: dologin(cmdstr) char *cmdstr; {
                    283: 
                    284:        SIGTYP (*savealm)();            /* save incoming alarm function */
                    285:        char *e;
                    286: 
                    287:        s = cmdstr;                     /* make global to ckuscr.c */
                    288: 
                    289:        tlog(F100,loginv,"",0L);
                    290: 
                    291:        if (speed < 0L) speed = ttgspd();
                    292:        if (ttopen(ttname,&local,mdmtyp,0) < 0) {
                    293:            sprintf(seq_buf,"Sorry, can't open %s",ttname);
                    294:            perror(seq_buf);
                    295:            return(0);
                    296:        }
                    297:        /* Whether to echo script cmds */
                    298:        scr_echo = (!quiet && !backgrd && secho);
                    299: #ifndef NOSPL
                    300:        if (scr_echo && cmdlvl > 1) {
                    301:            if (cmdstk[cmdlvl].src == CMD_TF)
                    302:              scr_echo = techo;
                    303:            if (cmdstk[cmdlvl].src == CMD_MD)
                    304:              scr_echo = mecho;
                    305:        }
                    306: #endif /* NOSPL */
                    307:        if (scr_echo) {
                    308: #ifdef NETCONN
                    309:            if (network)
                    310:              printf("Executing SCRIPT to host %s.\n",ttname);
                    311:            else
                    312: #endif /* NETCONN */
                    313:              printf("Executing SCRIPT through %s, speed %ld.\n",ttname,speed);
                    314:        }
                    315:        *seq_buf=0;
                    316:        for (e = s; *e; e++) strcat(seq_buf, dbchr(*e) );
                    317: #ifdef COMMENT
                    318: /* Skip this because it tends to contain a password... */
                    319:        if (scr_echo) printf("SCRIPT string: %s\n",seq_buf);
                    320: #endif /* COMMENT */
                    321:        tlog(F110,"SCRIPT string: ",seq_buf, 0L);
                    322: 
                    323: /* Condition console terminal and communication line */            
                    324: 
                    325:        if (ttvt(speed,flow) < 0) {
                    326:            printf("Sorry, Can't condition communication line\n");
                    327:            return(0);
                    328:        }
                    329:        /* Save initial timer interrupt value */
                    330:        savealm = signal(SIGALRM,SIG_IGN);
                    331: 
                    332:        flushi();               /* flush stale input */
                    333: 
                    334: /* start expect - send sequence */
                    335: 
                    336:     while (*s) {               /* while not done with buffer */
                    337: 
                    338:        while (*s && isspace(*s)) s++;  /* skip over separating whitespaces */
                    339:                                        /* gather up expect sequence */
                    340:        got_it = 0;
                    341:        recvseq();
                    342: 
                    343:        while (!got_it) {               /* Have it yet? */
                    344:            if (*s++ != '-')            /* No, is there a conditional send? */
                    345:              goto failret;             /* No, return failure */
                    346:            flushi();                   /* Yes, flush out input buffer */
                    347:            if (outseq())               /* If unable to send, */
                    348:              goto failret;             /* return failure. */
                    349:            if (*s++ != '-')            /* If no conditional response here, */
                    350:              goto failret;             /* return failure. */
                    351:            recvseq();                  /* All OK, read response from host. */
                    352:        }                               /* Loop back and check got_it */
                    353: 
                    354:        while (*s && !isspace(*s++) ) ; /* Skip over conditionals */
                    355:        while (*s && isspace(*s)) s++;  /* Skip over separating whitespaces */
                    356:        flushi();                       /* Flush */
                    357:        if (*s) if (outseq()) goto failret; /* If any */
                    358:     }
                    359:     signal(SIGALRM,savealm);
                    360:     if (scr_echo) printf("Script successful.\n");
                    361:     tlog(F100,"Script successful.","",0L);
                    362:     return(1);
                    363: 
                    364: failret:
                    365:     signal(SIGALRM,savealm);
                    366:     if (scr_echo) printf("Sorry, script failed\n");
                    367:     tlog(F100,"Script failed","",0L);
                    368:     return(0);
                    369: }
                    370: 
                    371: /*  F L U S H I  --  Flush, but log, input buffer  */
                    372: 
                    373: VOID
                    374: flushi() {
                    375:     int n;
                    376:     if (seslog) {                      /* Logging session? */
                    377:         n = ttchk();                   /* Yes, anything in buffer? */
                    378:         if (n > 0) {                   /* If so, */
                    379:            if (n > SBUFL) n = SBUFL;   /* make sure not too much, */
                    380:            n = ttxin(n,(CHAR *)fls_buf); /* then read it, */
                    381:            if (n > 0) if (zsout(ZSFILE,fls_buf) < 0) seslog = 0;
                    382:        }
                    383:     } else ttflui();                   /* Otherwise just flush. */
                    384: }
                    385: 
                    386: #ifdef MAC
                    387: alarm (s) int s; {                     /* Fix this later */
                    388: }
                    389: #endif /* MAC */
                    390: #else
                    391: char *loginv = "Script Command Disabled";
                    392: #endif /* NOSCRIPT */
                    393: #endif /* NOICP */

unix.superglobalmegacorp.com

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