Annotation of researchv9/ipc/src/bin/ftpmain.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * FTP User Program -- Command Interface.
                      3:  */
                      4: #include <sys/types.h>
                      5: #include <sys/ioctl.h>
                      6: 
                      7: #include <signal.h>
                      8: #include <stdio.h>
                      9: #include <errno.h>
                     10: #include <ctype.h>
                     11: #include <libc.h>
                     12: #include "ftp.h"
                     13: #include "ftp_var.h"
                     14: 
                     15: int    intr();
                     16: int    lostpeer();
                     17: 
                     18: main(argc, argv)
                     19:        char *argv[];
                     20: {
                     21:        register char *cp;
                     22:        int top;
                     23: 
                     24:        sp = in_service("ftp", "tcp", 0);
                     25:        if (sp == 0) {
                     26:                fprintf(stderr, "ftp: ftp/tcp: unknown service\n");
                     27:                exit(1);
                     28:        }
                     29:        argc--, argv++;
                     30:        while (argc > 0 && **argv == '-') {
                     31:                for (cp = *argv + 1; *cp; cp++)
                     32:                        switch (*cp) {
                     33: 
                     34:                        case 'd':
                     35:                                debug++;
                     36:                                break;
                     37:                        
                     38:                        case 'v':
                     39:                                verbose++;
                     40:                                break;
                     41: 
                     42:                        case 't':
                     43:                                trace++;
                     44:                                break;
                     45: 
                     46:                        case 'i':
                     47:                                interactive++;
                     48:                                break;
                     49: 
                     50:                        case 'n':
                     51:                                autologin = 0;
                     52:                                break;
                     53: 
                     54:                        default:
                     55:                                fprintf(stderr,
                     56:                                  "ftp: %c: unknown option\n", *cp);
                     57:                                exit(1);
                     58:                        }
                     59:                argc--, argv++;
                     60:        }
                     61:        fromatty = isatty(fileno(stdin));
                     62:        /*
                     63:         * Set up defaults for FTP.
                     64:         */
                     65:        strcpy(typename, "ascii"), type = TYPE_A;
                     66:        strcpy(formname, "non-print"), form = FORM_N;
                     67:        strcpy(modename, "stream"), mode = MODE_S;
                     68:        strcpy(structname, "file"), stru = STRU_F;
                     69:        strcpy(bytename, "8"), bytesize = 8;
                     70:        if (fromatty)
                     71:                verbose++;
                     72:        if (argc > 0) {
                     73:                if (setjmp(toplevel))
                     74:                        exit(0);
                     75:                signal(SIGINT, intr);
                     76:                signal(SIGPIPE, lostpeer);
                     77:                setpeer(argc + 1, argv - 1);
                     78:        }
                     79:        top = setjmp(toplevel) == 0;
                     80:        if (top) {
                     81:                signal(SIGINT, intr);
                     82:                signal(SIGPIPE, lostpeer);
                     83:        }
                     84:        for (;;) {
                     85:                cmdscanner(top);
                     86:                top = 1;
                     87:        }
                     88: }
                     89: 
                     90: intr()
                     91: {
                     92: 
                     93:        longjmp(toplevel, 1);
                     94: }
                     95: 
                     96: lostpeer()
                     97: {
                     98:        extern FILE *cout;
                     99:        extern int data;
                    100: 
                    101:        if (connected) {
                    102:                if (cout != NULL) {
                    103:                        fclose(cout);
                    104:                        cout = NULL;
                    105:                }
                    106:                if (data >= 0) {
                    107:                        (void) close(data);
                    108:                        data = -1;
                    109:                }
                    110:                connected = 0;
                    111:        }
                    112:        longjmp(toplevel, 1);
                    113: }
                    114: 
                    115: char *
                    116: tail(filename)
                    117:        char *filename;
                    118: {
                    119:        register char *s;
                    120:        
                    121:        while (*filename) {
                    122:                s = strrchr(filename, '/');
                    123:                if (s == NULL)
                    124:                        break;
                    125:                if (s[1])
                    126:                        return (s + 1);
                    127:                *s = '\0';
                    128:        }
                    129:        return (filename);
                    130: }
                    131: 
                    132: /*
                    133:  * Command parser.
                    134:  */
                    135: cmdscanner(top)
                    136:        int top;
                    137: {
                    138:        register struct cmd *c;
                    139:        struct cmd *getcmd();
                    140:        extern struct cmd cmdtab[];
                    141:        extern int help();
                    142: 
                    143:        if (!top)
                    144:                putchar('\n');
                    145:        for (;;) {
                    146:                if (fromatty) {
                    147:                        printf("ftp> ");
                    148:                        fflush(stdout);
                    149:                }
                    150:                if (gets(line) == 0)
                    151:                        break;
                    152:                if (line[0] == 0)
                    153:                        break;
                    154:                makeargv();
                    155:                c = getcmd(margv[0]);
                    156:                if (c == (struct cmd *)-1) {
                    157:                        printf("?Ambiguous command\n");
                    158:                        continue;
                    159:                }
                    160:                if (c == 0) {
                    161:                        printf("?Invalid command\n");
                    162:                        continue;
                    163:                }
                    164:                (*c->c_handler)(margc, margv);
                    165:                if (bell && c->c_bell)
                    166:                        putchar(007);
                    167:                if (c->c_handler != help)
                    168:                        break;
                    169:        }
                    170:        longjmp(toplevel, 0);
                    171: }
                    172: 
                    173: struct cmd *
                    174: getcmd(name)
                    175:        register char *name;
                    176: {
                    177:        register char *p, *q;
                    178:        register struct cmd *c, *found;
                    179:        register int nmatches, longest;
                    180: 
                    181:        longest = 0;
                    182:        nmatches = 0;
                    183:        found = 0;
                    184:        for (c = cmdtab; p = c->c_name; c++) {
                    185:                for (q = name; *q == *p++; q++)
                    186:                        if (*q == 0)            /* exact match? */
                    187:                                return (c);
                    188:                if (!*q) {                      /* the name was a prefix */
                    189:                        if (q - name > longest) {
                    190:                                longest = q - name;
                    191:                                nmatches = 1;
                    192:                                found = c;
                    193:                        } else if (q - name == longest)
                    194:                                nmatches++;
                    195:                }
                    196:        }
                    197:        if (nmatches > 1)
                    198:                return ((struct cmd *)-1);
                    199:        return (found);
                    200: }
                    201: 
                    202: /*
                    203:  * Slice a string up into argc/argv.
                    204:  */
                    205: makeargv()
                    206: {
                    207:        char **argp;
                    208:        char *slurpstring();
                    209: 
                    210:        margc = 0;
                    211:        argp = margv;
                    212:        stringbase = line;              /* scan from first of buffer */
                    213:        argbase = argbuf;               /* store from first of buffer */
                    214:        while (*argp++ = slurpstring())
                    215:                margc++;
                    216: }
                    217: 
                    218: /*
                    219:  * Parse string into argbuf;
                    220:  * implemented with FSM to
                    221:  * handle quoting and strings
                    222:  */
                    223: char *
                    224: slurpstring()
                    225: {
                    226:        int got_one = 0;
                    227:        register char *sb = stringbase;
                    228:        register char *ap = argbase;
                    229:        char *tmp = argbase;            /* will return this if token found */
                    230: 
                    231: S0:
                    232:        switch (*sb) {
                    233: 
                    234:        case '\0':
                    235:                goto OUT;
                    236: 
                    237:        case ' ':
                    238:        case '\t':
                    239:                sb++; goto S0;
                    240: 
                    241:        default:
                    242:                goto S1;
                    243:        }
                    244: 
                    245: S1:
                    246:        switch (*sb) {
                    247: 
                    248:        case ' ':
                    249:        case '\t':
                    250:        case '\0':
                    251:                goto OUT;       /* end of token */
                    252: 
                    253:        case '\\':
                    254:                sb++; goto S2;  /* slurp next character */
                    255: 
                    256:        case '"':
                    257:                sb++; goto S3;  /* slurp quoted string */
                    258: 
                    259:        default:
                    260:                *ap++ = *sb++;  /* add character to token */
                    261:                got_one = 1;
                    262:                goto S1;
                    263:        }
                    264: 
                    265: S2:
                    266:        switch (*sb) {
                    267: 
                    268:        case '\0':
                    269:                goto OUT;
                    270: 
                    271:        default:
                    272:                *ap++ = *sb++;
                    273:                got_one = 1;
                    274:                goto S1;
                    275:        }
                    276: 
                    277: S3:
                    278:        switch (*sb) {
                    279: 
                    280:        case '\0':
                    281:                goto OUT;
                    282: 
                    283:        case '"':
                    284:                sb++; goto S1;
                    285: 
                    286:        default:
                    287:                *ap++ = *sb++;
                    288:                got_one = 1;
                    289:                goto S3;
                    290:        }
                    291: 
                    292: OUT:
                    293:        if (got_one)
                    294:                *ap++ = '\0';
                    295:        argbase = ap;                   /* update storage pointer */
                    296:        stringbase = sb;                /* update scan pointer */
                    297:        if (got_one)
                    298:                return(tmp);
                    299:        return((char *)0);
                    300: }
                    301: 
                    302: #define HELPINDENT (sizeof ("directory"))
                    303: 
                    304: /*
                    305:  * Help command.
                    306:  * Call each command handler with argc == 0 and argv[0] == name.
                    307:  */
                    308: help(argc, argv)
                    309:        int argc;
                    310:        char *argv[];
                    311: {
                    312:        register struct cmd *c;
                    313: 
                    314:        if (argc == 1) {
                    315:                register int i, j, w;
                    316:                int columns, width = 0, lines;
                    317:                extern int NCMDS;
                    318: 
                    319:                printf("Commands may be abbreviated.  Commands are:\n\n");
                    320:                for (c = cmdtab; c < &cmdtab[NCMDS]; c++) {
                    321:                        int len = strlen(c->c_name);
                    322: 
                    323:                        if (len > width)
                    324:                                width = len;
                    325:                }
                    326:                width = (width + 8) &~ 7;
                    327:                columns = 80 / width;
                    328:                if (columns == 0)
                    329:                        columns = 1;
                    330:                lines = (NCMDS + columns - 1) / columns;
                    331:                for (i = 0; i < lines; i++) {
                    332:                        for (j = 0; j < columns; j++) {
                    333:                                c = cmdtab + j * lines + i;
                    334:                                printf("%s", c->c_name);
                    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:                                        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\t%s\n", HELPINDENT,
                    358:                                c->c_name, c->c_help);
                    359:        }
                    360: }
                    361: 
                    362: /*
                    363:  * Call routine with argc, argv set from args (terminated by 0).
                    364:  */
                    365: /* VARARGS2 */
                    366: call(routine, args)
                    367:        int (*routine)();
                    368:        int args;
                    369: {
                    370:        register int *argp;
                    371:        register int argc;
                    372: 
                    373:        for (argc = 0, argp = &args; *argp++ != 0; argc++)
                    374:                ;
                    375:        (*routine)(argc, &args);
                    376: }

unix.superglobalmegacorp.com

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