home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / pub / uniflex / ufkerm.uue / ufkerm.arc / UFUTIL.C < prev   
C/C++ Source or Header  |  1989-01-09  |  17KB  |  622 lines

  1. #include "ufk.h"
  2. #include <pwd.h>
  3. #include <sgtty.h>
  4. #include <signal.h>
  5. #include <setjmp.h>
  6. #include <stat.h>
  7.  
  8. /*
  9.  * split command line into seperate strings
  10.  */
  11.  
  12. split(cmd_str, cmds)
  13. char  *cmd_str[],
  14.       *cmds[];
  15. {
  16.    char  *malloc();
  17.    char  *p,
  18.          *q,
  19.          result[128];
  20.  
  21.    numprm = 0;                         /* no parameters yet */
  22.    p = &cmd_str[0];                    /* setup pointer to input string */
  23.    while (*p && (*p != COMMENT))       /* do till end of string */
  24.    {
  25.       if (numprm == MAXPRM)            /* no more space */
  26.       {
  27.          prterr(ER_TOOMPRM);
  28.          return(FALSE);
  29.       }
  30.       while (isspace(*p))              /* strip leading white space */
  31.          p++;
  32.       sscanf(p, "%s", result);         /* get part of input string */
  33.       if ((q = malloc(strlen(result) + 1)) == NULL) /* allocate string space */
  34.       {
  35.          prterr(ER_NOMEM);
  36.          kerm_exit();
  37.       }
  38.       strcpy(q, result);               /* copy part to allocated memory */
  39.       cmds[numprm++] = q;              /* save pointer to string */
  40.       while ((!isspace(*p)) && *p)     /* skip to end of this string */
  41.          p++;
  42.    }
  43.    return (TRUE);
  44. }
  45.  
  46. /*
  47.  * parse command components
  48.  */
  49.  
  50. parse(command_string, table)
  51. char *command_string;
  52. TABLE table[];
  53. {
  54.    char  i = 0,
  55.          j;
  56.    int   mstat,
  57.          cmd_num = 0,
  58.          tv = 0,
  59.          unique = FALSE;
  60.  
  61.    make_lower(command_string);         /* convert to lower case */
  62.    while (*table[i].string)            /* do until end of command table */
  63.    {
  64.       mstat = match(table[i].string, command_string); /* do compare */
  65.       if (mstat == -1)
  66.          return (table[i].funcadr);    /* exact match found */
  67.       if (mstat != 0)                  /* some characters did match */
  68.       {
  69.          if (mstat > tv)               /* longer than so far ? */
  70.          {
  71.             tv = mstat;                /* save longest length */
  72.             cmd_num = i;               /* remember which command */
  73.             unique = TRUE;             /* it's unique so far */
  74.          }
  75.          j = i;
  76.          while (*table[++j].string)    /* start new search from next entry */
  77.          {
  78.             mstat = match(table[j].string, command_string); /* other match ? */
  79.             if (mstat == -1)
  80.                return (table[j].funcadr); /* exact match */
  81.             if (mstat != 0)            /* some characters did match */
  82.             {
  83.                if (mstat > tv)         /* longer than so far ? */
  84.                {
  85.                   tv = mstat;          /* save greatest length */
  86.                   cmd_num = i;         /* remember which command */
  87.                   unique = TRUE;       /* it's unique so far */
  88.                }
  89.                if (mstat == tv)        /* another one of the same length ? */
  90.                   unique = FALSE;      /* yes, it's not unique anymore */
  91.             }
  92.          }
  93.          if (!unique)                  /* if it was'nt unique it's ambiguous */
  94.             return (NULL);
  95.          else
  96.             return (table[cmd_num].funcadr); /* else it's a valid command */
  97.       }
  98.       i++;                             /* try next entry */
  99.    }
  100.    if (cmd_num == 0)
  101.       return (ERROR);                  /* no such command */
  102.    else return (table[cmd_num].funcadr); /* return command number */
  103. }
  104.  
  105. match(s, t)
  106. char *s, *t;
  107. {
  108.    int   len = 0,
  109.          inputlen;
  110.  
  111.    inputlen = strlen(t);               /* length of input command */
  112.    while (*s)                          /* do until end of string */
  113.    {
  114.       if (*s++ != *t++)                /* if no match */
  115.       {
  116.          if (inputlen == 0)            /* total command checked */
  117.             return (len);              /* return matched length */
  118.          else
  119.             return (0);                /* no match for this command */
  120.       }
  121.       len++;                           /* one more character done */
  122.       --inputlen;                      /* count down input string length */
  123.    }
  124.    return (-1);                        /* full match found */
  125. }
  126.  
  127. /*
  128.  *  m a k e _ u p p e r
  129.  *
  130.  *  Convert string to upper case
  131.  */
  132.  
  133. make_upper(p)
  134. char  *p;
  135. {
  136.    while (*p)
  137.    {
  138.       if (islower(*p))
  139.          *p = toupper(*p);
  140.       p++;
  141.    }
  142. }
  143.  
  144. /*
  145.  *  m a k e _ l o w e r
  146.  *
  147.  *  Convert string to lower case
  148.  */
  149.  
  150. make_lower(p)
  151. char *p;
  152. {
  153.    while (*p)
  154.    {
  155.       if (isupper(*p))
  156.          *p = tolower(*p);
  157.       p++;
  158.    }
  159. }
  160.  
  161. /*
  162.  *  p r e r r p k t
  163.  *
  164.  *  Print contents of error packet received from remote host.
  165.  */
  166. prerrpkt(msg)
  167. char  *msg;
  168. {
  169.    if (!nooutput)
  170.    {
  171.       disp(0,19,"Kermit aborting with following error from remote host:");
  172.       foreground();
  173.       disp(0,20,msg);
  174.       background();
  175.       beep();
  176.    }
  177. }
  178.  
  179. /*
  180.  * send ASCII file to remote without protocol.
  181.  * handshake is used.
  182.  */
  183.  
  184. jmp_buf trn_env;
  185.  
  186. trnsmit()
  187. {
  188.    FILE *xmitfp;
  189.    char c1;
  190.    int  c, trnsm_int();
  191.    struct sgttyb mode;
  192.  
  193.    if (numprm <= 1)                       /* check for parameters */
  194.       prterr(ER_FSPCREQ);
  195.    else
  196.    {
  197.       if ((xmitfp = fopen(params[1], "r")) == NULL)
  198.          prterr(ER_OPENERR);
  199.       else
  200.       {
  201.          if (!open_port(FALSE,FALSE))
  202.             prterr(ER_POPNERR);
  203.          else
  204.          {
  205.             signal(SIGINT,trnsm_int);
  206.             if (!setjmp(trn_env))
  207.                while ((c = getc(xmitfp)) != EOF) /* get character from file */
  208.                {
  209.                   if (debug)
  210.                      putc(c, stdout);         /* send to console as well */
  211.                   gtty(ttyfd,&mode);
  212.                   if (mode.sg_speed & INCHR)
  213.                   {
  214.                      read(ttyfd,&c1,1);       /* Check received character */
  215.                      if ((c1 & 0177) == dstop && dstop != 0)/* Stop chr ? */
  216.                         do                    /* Yes */
  217.                            read(ttyfd,&c1,1); /* Wait for next character */
  218.                         while ((c1 & 0177) != dstart);/* Wait for start chr */
  219.                   }
  220.                   c1 = c;       /* Only high byte of int would be send (=0) */
  221.                   write(ttyfd,&c1,1);         /* Send to output port */
  222.                }
  223.             else
  224.                if (debug)
  225.                   fputs("\n",stdout);
  226.             fclose(xmitfp);
  227.             kdelay(1);                      /* Give the port time to finish */
  228.             close_port(FALSE,FALSE);
  229.          }
  230.       }
  231.    }
  232. }
  233.  
  234. trnsm_int()
  235. {
  236.    longjmp(trn_env,TRUE);               /* Transmit interrupted... */
  237. }
  238.  
  239.  
  240. /*
  241.  * Read KERMIT commands from file
  242.  */
  243.  
  244. take(startup,echo)
  245. char startup, echo;
  246. {
  247.    FILE *tfp;
  248.    char  data[133],                       /* Command input */
  249.          fname[132];
  250.  
  251.    if (startup)
  252.       strcpy(fname, INITFILE);            /* Use default name at startup */
  253.    else
  254.    {
  255.       if (numprm <= 1)                    /* Filename must be given */
  256.       {
  257.          prterr(ER_FSPCREQ);
  258.          return;
  259.       }
  260.       else
  261.          strcpy(fname, params[1]);
  262.    }
  263.    if ((tfp = fopen(fname,"r")) != NULL)    /* Look for command file */
  264.    {                                        /* Found file, read commands */
  265.       while (fgets(data,132,tfp))
  266.       {
  267.          if (echo)
  268.          {
  269.             fputs(prompt,stdout);           /* Echo prompt */
  270.             fputs(data,stdout);             /* Echo command */
  271.          }
  272.          data[strlen(data) - 1] = '\0';     /* Zap newline */
  273.          if (data[0] && data[0] != COMMENT) /* Not a blank line */
  274.             kerm_command(data);             /* Do command */
  275.       }
  276.       fclose(tfp);
  277.    }
  278.    else
  279.       if (!startup)
  280.          prterr(ER_OPENERR);
  281. }
  282.  
  283. /*
  284.  * call UniFLEX to perform external command
  285.  */
  286.  
  287. do_uniflex()
  288. {
  289.    static char *shell = { "/bin/shell" };
  290.    static char *opt = { "+xc" };
  291.    char *prm[4],
  292.         *p,
  293.         cmdline[256];
  294.    int i,
  295.        kerm_exit();
  296.  
  297.    prm[0] = &shell[5];                  /* setup program name */
  298.    prm[1] = prm[3] = 0;                 /* end of parameters pointer */
  299.    if (numprm > 1)
  300.    {
  301.       prm[1] = opt;                     /* one shot option */
  302.       prm[2] = p = cmdline;             /* pointers to start of commandline */
  303.       for (i = 1; i < numprm; i++)
  304.       {
  305.          strcpy(p,params[i]);           /* copy params into one line */
  306.          p += strlen(p);                /* point after command */
  307.          *p++ = ' ';                    /* separator */
  308.       }
  309.       *p = '\0';                        /* end of string */
  310.    }
  311.    if (!fork())                         /* duplicate myself */
  312.    {
  313.       execvp(shell,prm);                /* execute command in child */
  314.       prterr(ER_SPAWN);                 /* should not come here */
  315.    }
  316.    else
  317.    {
  318.       signal(SIGTERM,SIG_IGN);          /* Ignore this signals */
  319.       signal(SIGHUP,SIG_IGN);
  320.       signal(SIGQUIT,SIG_IGN);
  321.       signal(SIGINT,SIG_IGN);
  322.       wait(0);                          /* wait for child to die */
  323.       signal(SIGTERM,kerm_exit);        /* Set signals again */
  324.       signal(SIGHUP,kerm_exit);
  325.       signal(SIGQUIT,SIG_DFL);          /* Make these default */
  326.       signal(SIGINT,SIG_DFL);
  327.    }
  328. }
  329.  
  330. disk_free()
  331. {
  332.    char dev[30];
  333.    long size;
  334.  
  335.    if (numprm <= 1)
  336.       strcpy(dev,".");               /* use current place if not specified */
  337.    else
  338.       strcpy(dev,params[1]);         /* use specified place */
  339.    if ((size = get_free(dev)) != -1l)/* if no error... */
  340.       printf("Number of free blocks: %ld (%ld bytes)\n",size, size * 512);
  341. }
  342.  
  343.  
  344. chd()
  345. {
  346.    struct passwd *p;
  347.  
  348.    if (numprm <= 1)
  349.    {
  350.       if ((p = getpwuid(getuid())) == NULL)
  351.          prterr(ER_GETPWDID);
  352.       chdir(p->pw_dir);
  353.       set_dir(p->pw_dir);
  354.    }
  355.    else
  356.    {
  357.       if (chdir(params[1]) == ERROR)
  358.          prterr(ER_INVDIR);
  359.       else
  360.          set_dir(params[1]);
  361.    }
  362. }
  363.  
  364.  
  365. /*
  366.  * show statistics about connection
  367.  */
  368.  
  369. statistics()
  370. {
  371.    static char s1[] = "Characters sent:\t\t%ld\n";
  372.    static char s2[] = "Data characters sent:\t\t%ld\n";
  373.    static char s3[] = "NAK's sent:\t\t\t%d\n";
  374.    static char s4[] = "Packets sent:\t\t\t%d\n";
  375.    static char s5[] = "Characters received:\t\t%ld\n";
  376.    static char s6[] = "Data characters received:\t%ld\n";
  377.    static char s7[] = "NAK's received:\t\t\t%d\n";
  378.    static char s8[] = "Packets received:\t\t%d\n";
  379.  
  380.    printf("Totals for the last transfer:\n\n");
  381.    printf(s1, chr_sent);
  382.    printf(s2, dchr_sent);
  383.    printf(s3, nak_sent);
  384.    printf(s4, pack_sent);
  385.    printf(s5, chr_rec);
  386.    printf(s6, dchr_rec);
  387.    printf(s7, nak_rec);
  388.    printf(s8, pack_rec);
  389.    printf("Effective data rate:\t\t%d baud\n", data_rate);
  390.    printf("\nTotals since KERMIT was started:\n\n");
  391.    printf(s1, t_chr_sent);
  392.    printf(s2, t_dchr_sent);
  393.    printf(s3, t_nak_sent);
  394.    printf(s4, t_pack_sent);
  395.    printf(s5, t_chr_rec);
  396.    printf(s6, t_dchr_rec);
  397.    printf(s7, t_nak_rec);
  398.    printf(s8, t_pack_rec);
  399.    printf("Mean effective data rate:\t%d baud\n", t_data_rate);
  400. }
  401.  
  402. #define  POLYIT  0x8408       /* Polynomial for CRC-CCITT */
  403. #define  POLY16  0xa001       /* Polynomial for CRC-16 (not used here) */
  404.  
  405. unsigned int crc_value, crc[256];    /* Global accessible variables */
  406.  
  407. init_crc_table()
  408. {
  409.    int count, nr;
  410.    unsigned int accum, crcch;
  411.  
  412.    for (count = 0; count < 256; count++)     /* Build CRC lookup table */
  413.    {
  414.       accum = 0;
  415.       crcch = count;
  416.       for (nr = 0; nr < 8; nr++)
  417.       {
  418.          if (((accum & 0xff) ^ crcch) & 1)
  419.             accum = (accum / 2) ^ POLYIT;
  420.          else
  421.             accum = (accum / 2);
  422.          crcch = (crcch / 2);
  423.       }
  424.       crc[count] = accum;                 /* Save calculated value in table */
  425.    }
  426. }
  427.  
  428. zero_crc()
  429. {
  430.    crc_value = 0;                         /* Initial value is zero */
  431. }
  432.  
  433. unsigned int calc_crc(value)
  434. unsigned char value;
  435. {
  436.    crc_value = crc[value ^ (crc_value & 0xff)] ^ ((crc_value >> 8) & 0xff);
  437.    return crc_value;                      /* Return accumulated value so far */
  438. }
  439.  
  440. beep()
  441. {
  442.    if (!remote && !nooutput)
  443.       putc(BELL,stdout);
  444. }
  445.  
  446. disp(x,y,string)
  447. int x,y;
  448. char *string;
  449. {
  450.    if (!remote)
  451.    {
  452.       posit(x,y);
  453.       fputs(string,stdout);
  454.       if (!screen && !nooutput)
  455.          fputs("\n",stdout);
  456.    }
  457. }
  458.  
  459. set_frame()
  460. {
  461.    if (screen && !remote && !nooutput)
  462.    {
  463.       clear_screen();
  464.       posit(28,0);
  465.       foreground();
  466.       fprintf(stdout," KERMIT version %s ",VERSION);
  467.       background();
  468.       if (sflg || rflg)
  469.       {
  470.          disp(0,4,"Transferred:");
  471.          disp(27,4,"Percentage:");
  472.       }
  473.       disp(0,6,"Packet received:");
  474.       disp(0,7,"Packet transmitted:");
  475.       if (debug >= 1)
  476.       {
  477.          disp(0,9,"Data received:");
  478.          disp(0,11,"Data transmitted:");
  479.          disp(0,13,"Receive state:");
  480.          disp(36,13,"Send state:");
  481.          disp(27,6,"Type:");
  482.          disp(27,7,"Type:");
  483.          disp(37,6,"Length:");
  484.          disp(37,7,"Length:");
  485.          disp(50,6,"Checksum:");
  486.          disp(50,7,"Checksum:");
  487.       }
  488.       curs_off();                       /* Turn off cursor */
  489.    }
  490. }
  491.  
  492. disp_state(x,y,state)
  493. int x,y;
  494. char state;
  495. {
  496.    static char sa[] = "Attribute   ";
  497.    static char sb[] = "Break       ";
  498.    static char sc[] = "Complete    ";
  499.    static char sd[] = "Data        ";
  500.    static char sf[] = "Filename    ";
  501.    static char sq[] = "Abort       ";
  502.    static char sr[] = "Receive init";
  503.    static char ss[] = "Send init   ";
  504.    static char st[] = "Timeout     ";
  505.    static char sz[] = "End of file ";
  506.    static char un[] = "Unknown     ";
  507.    char dsc[5];
  508.  
  509.    if (debug == 2)
  510.       strcpy(dsc,"%s\r");
  511.    else
  512.       strcpy(dsc,"%s\r\l");
  513.    posit(x,y);
  514.    switch(state)
  515.    {
  516.       case 'A':
  517.                   prtdbg(dsc,sa);
  518.                   break;
  519.       case 'B':
  520.                   prtdbg(dsc,sb);
  521.                   break;
  522.       case 'C':
  523.                   prtdbg(dsc,sc);
  524.                   break;
  525.       case 'D':
  526.                   prtdbg(dsc,sd);
  527.                   break;
  528.       case 'F':
  529.                   prtdbg(dsc,sf);
  530.                   break;
  531.       case 'Q':
  532.                   prtdbg(dsc,sq);
  533.                   break;
  534.       case 'R':
  535.                   prtdbg(dsc,sr);
  536.                   break;
  537.       case 'S':
  538.                   prtdbg(dsc,ss);
  539.                   break;
  540.       case 'T':
  541.                   prtdbg(dsc,st);
  542.                   break;
  543.       case 'Z':
  544.                   prtdbg(dsc,sz);
  545.                   break;
  546.       default:
  547.                   prtdbg(dsc,un);
  548.    }
  549. }
  550.  
  551. prtdbg(fmt, a1, a2, a3, a4, a5, a6)
  552. char *fmt;
  553. {
  554.    if ((debug >= 1) && !remote)
  555.       fprintf(stdout,fmt,a1,a2,a3,a4,a5,a6);
  556.    if (debug == 2)
  557.       fprintf(dbgfil,fmt,a1,a2,a3,a4,a5,a6);
  558. }
  559.  
  560. prtdbgf(fmt, a1, a2, a3, a4, a5, a6)
  561. char *fmt;
  562. {
  563.    if (debug == 2)
  564.       fprintf(dbgfil,fmt,a1,a2,a3,a4,a5,a6);
  565. }
  566.  
  567. map_case(name,mode)
  568. char *name;
  569. int mode;
  570. {
  571.    if (mapping)
  572.    {
  573.       if (mode == IN)
  574.          make_lower(name);
  575.       else if (mode == OUT)
  576.          make_upper(name);
  577.    }
  578. }
  579.  
  580. new_name(s)
  581. char *s;
  582. {
  583.    struct stat buf;
  584.    int num;
  585.    char new_str[15],
  586.         num_str[5];
  587.  
  588.    num = 0;
  589.    do                                   /* Construct new filename */
  590.    {                                    /* until new name not found */
  591.       if (num++ > 4095)                 /* Bump counter */
  592.       {
  593.          error(PER_CREATE,"%s",new_str);/* FATAL error */
  594.          kerm_exit();                   /* More than 4096 files ??? */
  595.       }
  596.       strncpy(new_str,s,10);            /* Copy 10 characters at most */
  597.       new_str[10] = '\0';               /* Truncate at position 10 */
  598.       sprintf(num_str,".%03x",num);     /* Format new filename */
  599.       strcat(new_str,num_str);
  600.    }
  601.    while (!stat(new_str,&buf));         /* If it exists, try again */
  602.    strcpy(s,new_str);                   /* Save new filename */
  603. }
  604.  
  605. synerr(threshold)
  606. int threshold;
  607. {
  608.    if ((threshold != 0) && (numprm >= threshold))
  609.       return FALSE;
  610.    prterr(ER_SYNERR);
  611.    return TRUE;
  612. }
  613.  
  614. check_bg()
  615. {
  616.    int oldsig;
  617.  
  618.    oldsig = signal(SIGINT,SIG_IGN);     /* Get old KBD signal */
  619.    signal(SIGINT,oldsig);               /* Restore */
  620.    bg = oldsig;                         /* TRUE if we're in the background */
  621. }
  622.