home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / convergent / ctlogi.c < prev    next >
C/C++ Source or Header  |  2020-01-01  |  12KB  |  435 lines

  1. char *loginv = "Script login CTOS Version-2.00, Apr 1992";
  2.  
  3. /*  C K L O G I  --  Login script for logging onto remote system */
  4.  
  5. /*
  6.  The module expects a login string of the expect send [expect send] ...
  7.  format.  It is intended to operate similarly to the way the common
  8.  uucp "L.sys" login entries work.  Conditional responses are supported
  9.  expect[-send-expect[...]] as with uucp.  The send keyword EOT sends a
  10.  control-d, and the keyword BREAK sends a break.  Letters prefixed
  11.  by '~' are '~b' backspace, '~s' space, '~n' linefeed, '~r' return,
  12.  '~t' tab, '~q' ? (not allowed on kermit command lines), '~' ~, '~'', 
  13.  '~"', '~c' don't append return, '~o[o[o]]' octal character.  As with
  14.  some uucp systems, sent strings are followed by ~r (not ~n) unless they
  15.  end with ~c. Null expect strings (e.g., ~0 or --) cause a short
  16.  delay, and are useful for sending sequences requiring slight pauses.
  17.  
  18.  Author: Herm Fischer, Litton Data Systems, Van Nuys CA (HFISCHER@USC-ECLB)
  19.  
  20. */
  21.  
  22. /* modified for CTOS C2.0 by Joel Dunn, UNC-CH, October 1986 */
  23. /* modified to implement MS-DOS like INPUT, REINPUT, and OUTPUT  */
  24. /*          commands.  INPUT looks for a string of up to 7 bytes */
  25. /*          coming from the current line.  OUTPUT puts a string  */
  26. /*          out to the current line.  numerics up to 65535 that  */
  27. /*          are preceeded by "//" are converted to their ASCII   */
  28. /*          character equivalent. Numerics of greater than 65535 */
  29. /*          are sent verbatum.                                   */
  30. /*          D. Drury, E. Arnerich - ITT Federal Services 7/91    */
  31. /*  Modified RecvSeq to send exp_alrm value to use exp_alrm     */
  32. /*        value instead of 1 second for inter-character     */
  33. /*        timeout value.                     */
  34. /*          D. Drury, E. Arnerich - ITT Federal Services 4/92    */
  35.         
  36.  
  37. #include "ctermi.h"
  38.  
  39. extern int local, speed, flow, seslog, mdmtyp, techo, tlevel;
  40. extern char ttname[];
  41. static char * chstr();
  42.  
  43. int exp_alrm =     30;        /* Time to wait for expect string */
  44. #define NULL_EXP  2        /* Time to pause on null expect strg*/ 
  45. /* changed from 5 to 2, was 1 in Unix source, this change was 1.01 */
  46.  
  47. #define SBUFL 300            /* Login Sequence buffer */
  48. static char seq_buf[SBUFL], *s;
  49. static char savinput[SBUFL];
  50. static int got_it, no_cr;
  51.  
  52. /*
  53.  Sequence interpreter -- pick up next sequence from command string,
  54.  decode escapes and place into seq_buf
  55. */
  56. static 
  57. sequenc()  {
  58.  
  59.     int i;
  60.     char c, oct_char;
  61.  
  62.     no_cr = 0;                /* output needs cr appended */
  63.  
  64.     for (i=0; i<SBUFL; ) {        
  65.     if (*s == '\0' || *s == '-' || *s == ' ') { /* done */
  66.         seq_buf[i] = '\0';
  67.         return ;
  68.     }
  69.     if (*s == '~') {        /* escape character */
  70.         switch (c = *(++s) ) {
  71.         case 'n':    seq_buf[i++] = '\n'; break;
  72.         case 'r':    seq_buf[i++] = '\r'; break;
  73.         case 't':    seq_buf[i++] = '\t'; break;
  74.         case 'b':    seq_buf[i++] = '\b'; break;
  75.         case 'q':    seq_buf[i++] = '?';  break;
  76.         case '~':    seq_buf[i++] = '~';  break;
  77.         case '\'':    seq_buf[i++] = '\''; break;
  78.         case '\"':    seq_buf[i++] = '\"'; break;
  79.         case 's':    seq_buf[i++] = ' ';  break;
  80.         case 'c':    no_cr = 1; break;
  81.         default:
  82.             if ( isdigit(c) ) {            /* octal character */
  83.                 oct_char = (c & 7);    /* most significant digit */
  84.             if (isdigit( *(s+1) ) ) {
  85.                 oct_char = (oct_char<<3) | ( (*(++s)) & 7 ) ;
  86.                 if (isdigit( *(s+1) ) ) {
  87.                     oct_char = (oct_char<<3) | ( (*(++s)) & 7 ) ;
  88.                 }
  89.             }
  90.             seq_buf[i++] = oct_char;
  91.             break;
  92.             }
  93.         }
  94.     }
  95.     else seq_buf[i++] = *s;        /* plain old character */
  96.     s++;
  97.     }
  98.     seq_buf[i] = '\0';
  99.     return;            /* end of space, return anyway */
  100. }
  101.  
  102. /*
  103.  Receive sequence -- see if expected response comes return success
  104.  (or failure) in got_it
  105. */ 
  106. static 
  107. recvSeq()  {
  108.    
  109.     char *e, got[7], trace[SBUFL];
  110.     int i, l;
  111.     int exchwait;
  112.     int timerexit;
  113.     struct ctostimer trb1;
  114.     struct ctostimer *ptrb1;
  115.     int cterc;
  116.     
  117.     l = strlen(e=seq_buf);        /* no more than 7 chars allowed */
  118.     if (l > 7) {
  119.         e += l-7;
  120.         l = 7;
  121.     }
  122.  
  123.     tlog(F111,"expecting sequence",e,(long) l);
  124.     if (l == 0) {        /* null sequence, just delay a little */
  125.         delay (NULL_EXP*10);
  126.         got_it = 1;
  127.         tlog(F100,"got it (null sequence)","",0l);
  128.         return;
  129.     }
  130.     *trace = '\0';
  131.     for (i=0; i<7; i++) got[i]='\0';
  132.  
  133.     timerexit = 0;
  134.     allocexch(&exchwait);
  135.     trb1.ctt_counter = 10*exp_alrm;
  136.     trb1.ctt_reload = 0;
  137.     trb1.ctt_cevents = 0;
  138.     trb1.ctt_exchresp = exchwait;
  139.     trb1.ctt_ercret = 0;
  140.     trb1.ctt_rqcode = exchwait;
  141.     openrtclock(&trb1);
  142.     while ((!got_it) && (!timerexit))
  143.         {
  144.         for (i=0; i<(l-1); i++) got[i] = got[i+1]; /* shift over one */
  145.         got[l-1] = ttinc(1) & 0177;
  146.         while (got[l-1] == 023)                 /* ignore ctl-s */
  147.             got[l-1] = ttinc(exp_alrm) & 0177;        /* next char */
  148.         if (strlen(trace) < sizeof(trace)-2 ) 
  149.             strcat(trace,chstr(got[l-1]));
  150.         got_it = (!strncmp(seq_buf, got, l) ) ;
  151.         if (!check(exchwait, &ptrb1))
  152.             {
  153.             if (ptrb1->ctt_rqcode == exchwait)
  154.                 {
  155.                 timerexit = 1;
  156.                 got_it = 0;
  157.                 }
  158.             }
  159.         }
  160.     deallocexch(exchwait);
  161.     closertclock(&trb1);
  162.                          
  163.         for(i=0; i<SBUFL && trace[i] != '\0'; i++)   /* save what we got */
  164.             savinput[i] = trace[i];    /* regardless of success or failure */
  165.         if (i == SBUFL) i--;
  166.         savinput[i] = '\0';             /* make sure its null terminated */
  167.  
  168.     tlog(F110,"received sequence: ",trace,0l);
  169.     tlog(F101,"returning with got-it code","",(long) got_it);
  170.     return;
  171. }
  172.  
  173. /*
  174.  Output A Sequence starting at pointer s,
  175.  return 0 if okay,
  176.  1 if failed to read (modem hangup or whatever)
  177. */
  178. static int
  179. outSeq()  {
  180.     char *sb;
  181.     int l;
  182.  
  183.     l = strlen(seq_buf);
  184.     tlog(F111,"sending sequence ",seq_buf,(long) l);
  185.     if (!strcmp(seq_buf,"EOT")) ttoc(dopar('\004'));
  186.     else if (!strcmp(seq_buf,"BREAK")) ttsndb();
  187.      else {
  188.         if (l > 0) {
  189.         for ( sb=seq_buf; *sb; sb++) *sb = dopar(*sb);
  190.         ttol(seq_buf,l);        /* with parity */
  191.         }
  192.         if (!no_cr) ttoc( dopar('\r') );
  193.     }
  194.     return(0);
  195. }
  196.  
  197. /*  L O G I N  --  Process script to login or send commands remote system */
  198.  
  199. login(cmdstr) char *cmdstr; {
  200.  
  201.     char *e;
  202.         int  x;
  203.  
  204.     s = cmdstr;            /* make global to cklogi.c */
  205.  
  206.     tlog(F100,loginv,"",0l);                                             
  207.  
  208.         x = initline();
  209.         if (x != 0) return(x);          /* return error if initline failed */
  210.  
  211.        if((tlevel < 0) || techo)
  212.            printf("Logging on thru %s, speed %d.\r\n",ttname,speed);
  213.     *seq_buf=0;
  214.     for (e=s; *e; e++) strcat(seq_buf, chstr(*e) ); 
  215.         if ((tlevel < 0) || techo)
  216.         printf("The script string is: %s\r\n",seq_buf);
  217.     tlog(F110,"Script command string: ",seq_buf, 0l);
  218.  
  219. /* start expect - send sequence */
  220.  
  221.     while (*s) {        /* while not done with buffer */
  222.  
  223.     while (*s && *s == ' ') s++;    /* skip over separating blanks */
  224.                 /* gather up expect sequence */
  225.     got_it = 0;  
  226.         sequenc();
  227.     recvSeq();
  228.  
  229.     while (!got_it) {
  230.                 /* no, is there a conditional send */
  231.         if (*s++ != '-') goto failRet;        /* no -- return failure */
  232.         
  233.                 /* start of conditional send */
  234.         ttflui();                /* flush out input buffer */
  235.         sequenc();
  236.             if (outSeq()) goto failRet;     /* if unable to send! */
  237.  
  238.         if (*s++ != '-') goto failRet;     /* must have condit respon.*/
  239.             sequenc();
  240.         recvSeq();
  241.     }    /* loop back and check got_it */
  242.  
  243.     while (*s && *s++ != ' ') ;     /* skip over conditionals and spaces */
  244.     ttflui();            /* Flush */
  245.     if (*s) { 
  246.           sequenc();
  247.           if (outSeq()) goto failRet;     /* if any */
  248.         }
  249.     }     
  250.     if ((tlevel < 0) || techo)
  251.        printf("Script successful!\r\n");
  252.     tlog(F100,"Script successful!","",0l);
  253.     return(0);
  254.  
  255. failRet:  
  256.     if ((tlevel < 0) || techo)
  257.        printf("Sorry, script failed\r\n");
  258.     tlog(F100,"Script failed","",0l);
  259.     return(-2);
  260. }
  261.  
  262.  
  263. /*  C H S T R  --  Make printable string from a character */
  264.  
  265. static char *
  266. chstr(c) char c; {
  267.     static char sc[4];
  268.  
  269.     if (c < SP) sprintf(sc, "^%c",ctl(c) );
  270.     else sprintf(sc, "%c", c);
  271.   
  272.     return(sc);
  273. }
  274.  
  275. /* I N I T L I N E  -- initializes the line for login/input/output */
  276. /*                     return 0  if successful otherwise return -2 */
  277.  
  278. initline() {          
  279.  
  280.     if (!local) {
  281.         printf("Sorry, you must 'set line' first\n");
  282.         return(-2);
  283.     }
  284.     if (speed < 0) {
  285.         printf("Sorry, you must 'set speed' first\n");
  286.         return(-2);
  287.         }
  288.     if (ttopen(ttname,local,mdmtyp) < 0) {
  289.         sprintf(seq_buf,"Sorry, can't open %s",ttname);
  290.         perror(seq_buf);
  291.         return(-2);
  292.         }
  293. /* Condition console terminal and communication line */        
  294.  
  295.     if (ttvt(speed,flow) < 0) {
  296.         printf("Sorry, Can't condition communication line\n");
  297.         return(-2);
  298.         }
  299.  
  300. /*    ttflui();         flush stale input */
  301.         return (0);
  302. }
  303.  
  304. /* D O I N P U T  --  UNIX/DOS like input command                   */
  305. /*                the maximum input string length is 7              */
  306.  
  307. doinput (cmdstr, timeout) char *cmdstr; int timeout;
  308.     {
  309.     int x;
  310.     char *e;
  311.     s = cmdstr;
  312.     if (!local) {
  313.         printf("Sorry, you must 'set line' first\n");
  314.         return(-2);
  315.     }
  316.     if (speed < 0) {
  317.         printf("Sorry, you must 'set speed' first\n");
  318.         return(-2);
  319.         }
  320.                  
  321. /*    x = initline();
  322.     if(x != 0) return(x);   */
  323.      
  324.     *seq_buf = 0;
  325.     for (e = s; *e; e++)
  326.         strcat(seq_buf, chstr(*e));
  327.  
  328.     exp_alrm = timeout; 
  329.     got_it = 0;
  330.     recvSeq();
  331.     if (got_it == 0) return(-2);   /* return failure if not found */
  332.     return(0);                     /* otherwise return success */
  333. }
  334.  
  335. /* D O R E I N P U T  --  UNIX/DOS like reinput                     */
  336. /*                    not timeout value is used or required         */
  337.  
  338. dorinput(cmdstr) char *cmdstr;
  339. {       
  340.  
  341.     int rc = -2;        /* init result code to not found */
  342.     int i, len;
  343.     char *start;
  344.  
  345.     s = cmdstr;    
  346.     
  347.     while (*s != ' ')   /* get to spaces  */
  348.     s++;
  349.    while (*s == ' ')    /* get past spaces */
  350.     s++;
  351.     len = strlen(s);
  352.     start = savinput;                                
  353.     for(i = 0; i < SBUFL && (savinput[i] != '\0') && rc; i++) {
  354.         if (!strncmp(s, start, len))
  355.         rc = 0;     /* found it! */
  356.     start++;
  357.     }                                  
  358.     tlog(F110,"reinput searching for: ",s,0l);
  359.     tlog(F110,"received sequence: ",savinput,0l);
  360.     tlog(F101,"returning with result code","",(long) rc);
  361.     return(rc);   /* return result code */
  362.         
  363.  
  364. /* D O O U T P U T  --  UNIX/DOS like output command                   */
  365. /*  looks for '\', and if found processes following numerics as decimal */
  366. /*  to be converted to ASCII characters, then outputs the total length  */
  367. /*  of the input buffer - including any NULLs which may be generated by */
  368. /*  converting the numeric to ASCII.  This routine does not add cr      */
  369. /*  The maximum decimal value processed is 65535.  Anything larger is   */
  370. /*  put out as a character string                                       */
  371.  
  372. dooutput(cmdstr) char *cmdstr;
  373. {
  374. #define MAX_VALUE 65535L
  375.  
  376.     int x, y, len;
  377.     char e, *digitpos; 
  378.     unsigned long numbr; 
  379.     int j;
  380.    
  381.     numbr = 0;
  382.     s = cmdstr;
  383.     if (!local) {
  384.         printf("Sorry, you must 'set line' first\n");
  385.         return(-2);
  386.     }
  387.     if (speed < 0) {
  388.         printf("Sorry, you must 'set speed' first\n");
  389.         return(-2);
  390.         }
  391.     x = initline();
  392.     if (x != 0) return(-2);
  393.  
  394.     *seq_buf = 0;
  395.     len = strlen(s);     
  396.     x = 0;     
  397.     seq_buf[x] = '\0';
  398.     while (*s) {
  399.         digitpos = s; 
  400.     digitpos++;   
  401.         if (*s == '\\' && isdigit(*digitpos)) { /* quoted sequence? */
  402.         numbr = 0;
  403.         while (1) {
  404.         e = *digitpos;
  405.         if (isdigit(e)) {
  406.                     j = e & 0x0f;
  407.                     numbr = numbr*10 + (unsigned long) j;
  408.             digitpos++;
  409.                 }
  410.                 else
  411.             break;    /* exit while, on first non-digit */
  412.             }
  413.             if (numbr <= MAX_VALUE) { /* now that its a num make it str */
  414.                 seq_buf[x++] = (numbr & 0xff); /* get low order first */
  415.  
  416. /* followed by high order byte if high order byte > 0                     */
  417.  
  418.                 if (numbr > 256)
  419.             seq_buf[x++] = (numbr >> 8);
  420.         s = digitpos;
  421.         continue;  
  422.             }
  423.         }
  424.         seq_buf[x++] = *s++;
  425.     }
  426. /*        now put all x bytes out                                            */
  427.     tlog(F111, "sending output ", seq_buf, (long) x);
  428.     if (x > 0) {
  429.        for (y=0; y<x; y++) seq_buf[y] = dopar(seq_buf[y]);
  430.        ttol(seq_buf,x); 
  431.     }
  432.     return(0);                  
  433. }
  434.