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

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

unix.superglobalmegacorp.com

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