home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / archival / ftp / BFTP.312 / ucb_cp.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-06-29  |  6.3 KB  |  361 lines

  1. /*
  2.  * Copyright (c) 1985, 1989 Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms are permitted
  6.  * provided that the above copyright notice and this paragraph are
  7.  * duplicated in all such forms and that any documentation,
  8.  * advertising materials, and other materials related to such
  9.  * distribution and use acknowledge that the software was developed
  10.  * by the University of California, Berkeley.  The name of the
  11.  * University may not be used to endorse or promote products derived
  12.  * from this software without specific prior written permission.
  13.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  14.  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  15.  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  16.  */
  17.  
  18. #ifndef lint
  19. char copyright[] =
  20. "@(#) Copyright (c) 1985, 1989 Regents of the University of California.\n\
  21.  All rights reserved.\n";
  22. #endif /* not lint */
  23.  
  24. /*
  25.  * BFTP User Program -- Command Interface.
  26.  * based on 5.13 (Berkeley) 3/14/89 "main.c"
  27.  * 
  28.  * Modified at ISI 3/9/90 -- ucb_cp.c
  29.  */
  30.  
  31. #include <stdio.h>
  32. #include <ctype.h>
  33. #include <sys/signal.h>
  34. #include <sys/types.h>
  35. #include <sys/time.h>
  36. #include <netinet/in.h>
  37. #include <arpa/inet.h>
  38. #include <netdb.h>
  39. #include <sys/socket.h>
  40.  
  41. #include <sys/ioctl.h>
  42. #include <arpa/ftp.h>
  43.  
  44. #include <errno.h>
  45. #include <pwd.h>
  46.  
  47. #include "ucb_cp.h"
  48.  
  49. /* This section is from main.c 5.13 (Berkeley) 3/14/89 */
  50.  
  51. extern struct cmd cmdtab[];
  52. extern char *help_preamble;
  53. extern int NCMDS;
  54.  
  55. intr()
  56. {
  57.     longjmp(toplevel, 1);
  58. }
  59.  
  60. do_main()
  61. {
  62.     int top;
  63.  
  64.     fromatty = isatty(fileno(stdin));
  65.  
  66.     top = setjmp(toplevel) == 0;
  67.     if (top) {
  68.         (void) signal(SIGINT, intr);
  69.     }
  70.     for (;;) {
  71.         cmdscanner(top);
  72.         top = 1;
  73.     }
  74. }
  75.  
  76. /*
  77.  * Command parser.
  78.  */
  79. cmdscanner(top)
  80.     int top;
  81. {
  82.     char *cp;
  83.     register struct cmd *c;
  84.     struct cmd *getcmd();
  85.  
  86.     if (!top)
  87.         (void) putchar('\n');
  88.     for (;;) {
  89.         if (fromatty) {
  90.             printf("BFTP> ");
  91.             (void) fflush(stdout);
  92.         }
  93.         if (gets(line) == 0) {
  94.             if (feof(stdin) || ferror(stdin))
  95.                 quit();
  96.             break;
  97.         }
  98.         if (line[0] == 0)
  99.             break;
  100.         makeargv();
  101.         if (margc == 0) {
  102.             continue;
  103.         }
  104.         c = getcmd(margv[0]);
  105.         if (c == (struct cmd *)-1) {
  106.             printf("?Ambiguous command\n");
  107.             continue;
  108.         }
  109.         if (c == 0) {
  110. /* ISI addition */
  111.            for (cp = margv[0]; *cp; cp++)
  112.               if (*cp == '?') {
  113.              strcpy(line, "help");
  114.                  makeargv();
  115.              help(margc, margv);
  116.              break;
  117.                  }
  118.            if (!*cp)
  119. /* ************ */
  120.               printf("?Invalid command\n");
  121.            continue;
  122.         }
  123.         (*c->c_handler)(margc, margv);
  124.         if (c->c_handler != help)
  125.             break;
  126.     }
  127.     (void) signal(SIGINT, intr);
  128. }
  129.  
  130. struct cmd *
  131. getcmd(name)
  132.     register char *name;
  133. {
  134.     register char *p, *q;
  135.     register struct cmd *c, *found;
  136.     register int nmatches, longest;
  137.  
  138.     longest = 0;
  139.     nmatches = 0;
  140.     found = 0;
  141.     for (c = cmdtab; p = c->c_name; c++) {
  142.         for (q = name; *q == *p++; q++)
  143.             if (*q == 0)        /* exact match? */
  144.                 return (c);
  145.         if (!*q) {            /* the name was a prefix */
  146.             if (q - name > longest) {
  147.                 longest = q - name;
  148.                 nmatches = 1;
  149.                 found = c;
  150.             } else if (q - name == longest)
  151.                 nmatches++;
  152.         }
  153.     }
  154.     if (nmatches > 1)
  155.         return ((struct cmd *)-1);
  156.     return (found);
  157. }
  158.  
  159. /*
  160.  * Slice a string up into argc/argv.
  161.  */
  162.  
  163. int slrflag;
  164.  
  165. makeargv()
  166. {
  167.     char **argp;
  168.     char *slurpstring();
  169.  
  170.     margc = 0;
  171.     argp = margv;
  172.     stringbase = line;        /* scan from first of buffer */
  173.     argbase = argbuf;        /* store from first of buffer */
  174.     slrflag = 0;
  175.     while (*argp++ = slurpstring())
  176.         margc++;
  177. }
  178.  
  179. /*
  180.  * Parse string into argbuf;
  181.  * implemented with FSM to
  182.  * handle quoting and strings
  183.  */
  184. char *
  185. slurpstring()
  186. {
  187.     int got_one = 0;
  188.     register char *sb = stringbase;
  189.     register char *ap = argbase;
  190.     char *tmp = argbase;        /* will return this if token found */
  191.  
  192.     if (*sb == '!' || *sb == '$') {    /* recognize ! as a token for shell */
  193.         switch (slrflag) {    /* and $ as token for macro invoke */
  194.             case 0:
  195.                 slrflag++;
  196.                 stringbase++;
  197.                 return ((*sb == '!') ? "!" : "$");
  198.                 /* NOTREACHED */
  199.             case 1:
  200.                 slrflag++;
  201.                 altarg = stringbase;
  202.                 break;
  203.             default:
  204.                 break;
  205.         }
  206.     }
  207.  
  208. S0:
  209.     switch (*sb) {
  210.  
  211.     case '\0':
  212.         goto OUT;
  213.  
  214.     case ' ':
  215.     case '\t':
  216.         sb++; goto S0;
  217.  
  218.     default:
  219.         switch (slrflag) {
  220.             case 0:
  221.                 slrflag++;
  222.                 break;
  223.             case 1:
  224.                 slrflag++;
  225.                 altarg = sb;
  226.                 break;
  227.             default:
  228.                 break;
  229.         }
  230.         goto S1;
  231.     }
  232.  
  233. S1:
  234.     switch (*sb) {
  235.  
  236.     case ' ':
  237.     case '\t':
  238.     case '\0':
  239.         goto OUT;    /* end of token */
  240.  
  241.     case '\\':
  242.         sb++; goto S2;    /* slurp next character */
  243.  
  244.     case '"':
  245.         sb++; goto S3;    /* slurp quoted string */
  246.  
  247.     default:
  248.         *ap++ = *sb++;    /* add character to token */
  249.         got_one = 1;
  250.         goto S1;
  251.     }
  252.  
  253. S2:
  254.     switch (*sb) {
  255.  
  256.     case '\0':
  257.         goto OUT;
  258.  
  259.     default:
  260.         *ap++ = *sb++;
  261.         got_one = 1;
  262.         goto S1;
  263.     }
  264.  
  265. S3:
  266.     switch (*sb) {
  267.  
  268.     case '\0':
  269.         goto OUT;
  270.  
  271.     case '"':
  272.         sb++; goto S1;
  273.  
  274.     default:
  275.         *ap++ = *sb++;
  276.         got_one = 1;
  277.         goto S3;
  278.     }
  279.  
  280. OUT:
  281.     if (got_one)
  282.         *ap++ = '\0';
  283.     argbase = ap;            /* update storage pointer */
  284.     stringbase = sb;        /* update scan pointer */
  285.     if (got_one) {
  286.         return(tmp);
  287.     }
  288.     switch (slrflag) {
  289.         case 0:
  290.             slrflag++;
  291.             break;
  292.         case 1:
  293.             slrflag++;
  294.             altarg = (char *) 0;
  295.             break;
  296.         default:
  297.             break;
  298.     }
  299.     return((char *)0);
  300. }
  301.  
  302. /*
  303.  * Help command.
  304.  * Call each command handler with argc == 0 and argv[0] == name.
  305.  */
  306. help(argc, argv)
  307.     int argc;
  308.     char *argv[];
  309. {
  310.     register struct cmd *c;
  311.  
  312.     if (argc == 1) {
  313.         register int i, j, w, k;
  314.         int columns, width = 0, lines;
  315.         extern int NCMDS;
  316.  
  317.         printf(help_preamble);
  318.         for (c = cmdtab; c < &cmdtab[NCMDS]; c++) {
  319.             int len = strlen(c->c_name);
  320.  
  321.             if (len > width)
  322.                 width = len;
  323.         }
  324.         width = (width + 8) &~ 7;
  325.         columns = 80 / width;
  326.         if (columns == 0)
  327.             columns = 1;
  328.         lines = (NCMDS + columns - 1) / columns;
  329.         for (i = 0; i < lines; i++) {
  330.             for (j = 0; j < columns; j++) {
  331.                 c = cmdtab + j * lines + i;
  332.                 if (c->c_name) {
  333.                     printf("%s", c->c_name);
  334.                 }
  335.                 if (c + lines >= &cmdtab[NCMDS]) {
  336.                     printf("\n");
  337.                     break;
  338.                 }
  339.                 w = strlen(c->c_name);
  340.                 while (w < width) {
  341.                     w = (w + 8) &~ 7;
  342.                     (void) putchar('\t');
  343.                 }
  344.             }
  345.         }
  346.         return;
  347.     }
  348.     while (--argc > 0) {
  349.         register char *arg;
  350.         arg = *++argv;
  351.         c = getcmd(arg);
  352.         if (c == (struct cmd *)-1)
  353.             printf("?Ambiguous help command %s\n", arg);
  354.         else if (c == (struct cmd *)0)
  355.             printf("?Invalid help command %s\n", arg);
  356.         else
  357.             printf("%-*s %s\n", HELPINDENT,
  358.                 c->c_name, c->c_help);
  359.     }
  360. }
  361.