Annotation of 43BSD/contrib/xns/examples/filing/main.c, revision 1.1.1.1

1.1       root        1: #ifndef lint
                      2: static char RCSid[] = "$Header: main.c,v 2.0 85/11/21 07:22:49 jqj Exp $";
                      3: #endif
                      4: 
                      5: /*
                      6:  * FTP User Program -- Command Interface.
                      7:  */
                      8: /* $Log:       main.c,v $
                      9:  * Revision 2.0  85/11/21  07:22:49  jqj
                     10:  * 4.3BSD standard release
                     11:  * 
                     12:  * Revision 1.1  85/05/27  06:31:05  jqj
                     13:  * Initial revision
                     14:  * 
                     15:  * Revision 1.1  85/05/27  06:31:05  jqj
                     16:  * Initial revision
                     17:  * 
                     18:  * Based on Berkeley tcp/ftp
                     19:  */
                     20: #include <sys/param.h>
                     21: #include <sys/socket.h>
                     22: #include <sys/ioctl.h>
                     23: 
                     24: #include <xnscourier/except.h>
                     25: #include <stdio.h>
                     26: #include <errno.h>
                     27: #include <ctype.h>
                     28: #include <pwd.h>
                     29: 
                     30: #include "ftp_var.h"
                     31: 
                     32: int    intr();
                     33: int    lostpeer();
                     34: extern char *home;
                     35: 
                     36: main(argc, argv)
                     37:        char *argv[];
                     38: {
                     39:        register char *cp;
                     40:        int top;
                     41:        struct passwd *pw;
                     42:        char homedir[MAXPATHLEN];
                     43: 
                     44:        doglob = 1;
                     45:        interactive = 1;
                     46:        autologin = 1;
                     47:        argc--, argv++;
                     48:        while (argc > 0 && **argv == '-') {
                     49:                for (cp = *argv + 1; *cp; cp++)
                     50:                        switch (*cp) {
                     51: 
                     52:                        case 'd':
                     53:                                debug++;
                     54:                                break;
                     55:                        
                     56:                        case 'v':
                     57:                                verbose++;
                     58:                                break;
                     59: 
                     60:                        case 't':
                     61:                                trace++;
                     62:                                break;
                     63: 
                     64:                        case 'i':
                     65:                                interactive = 0;
                     66:                                break;
                     67: 
                     68:                        case 'n':
                     69:                                autologin = 0;
                     70:                                break;
                     71: 
                     72:                        case 'g':
                     73:                                doglob = 0;
                     74:                                break;
                     75: 
                     76:                        default:
                     77:                                fprintf(stderr,
                     78:                                  "ftp: %c: unknown option\n", *cp);
                     79:                                exit(1);
                     80:                        }
                     81:                argc--, argv++;
                     82:        }
                     83:        fromatty = isatty(fileno(stdin));
                     84:        /*
                     85:         * Set up defaults for FTP.
                     86:         */
                     87:        strcpy(typename, "ascii"), typevalue = TYPE_A;
                     88:        strcpy(formname, "non-print"), form = FORM_N;
                     89:        strcpy(modename, "stream"), mode = MODE_S;
                     90:        strcpy(structname, "file"), stru = STRU_F;
                     91:        strcpy(bytename, "8"), bytesize = 8;
                     92:        if (fromatty)
                     93:                verbose++;
                     94:        /*
                     95:         * Set up the home directory in case we're globbing.
                     96:         */
                     97:        pw = getpwnam(getlogin());
                     98:        if (pw == NULL)
                     99:                pw = getpwuid(getuid());
                    100:        if (pw != NULL) {
                    101:                home = homedir;
                    102:                strcpy(home, pw->pw_dir);
                    103:        }
                    104:        signal(SIGINT, intr);
                    105:        signal(SIGPIPE, lostpeer);
                    106:        DURING {
                    107:                if (argc > 0)
                    108:                  setpeer(argc + 1, argv - 1);
                    109:        } HANDLER {
                    110:                FilingErrMsg(Exception.Code, Exception.Message);
                    111:                exit(0);
                    112:        } END_HANDLER;
                    113:        for (;;) {
                    114:                DURING {
                    115:                        for (;;)
                    116:                          cmdscanner();
                    117:                } HANDLER {
                    118:                        FilingErrMsg(Exception.Code, Exception.Message);
                    119:                        if (connected != (CourierConnection*)0) {
                    120:                                DURING
                    121:                                  probe();      /* reset alarm */
                    122:                                HANDLER {       /* can't?  Lost peer */
                    123:                                  connected = (CourierConnection*) 0;
                    124:                                } END_HANDLER;
                    125:                        }
                    126:                } END_HANDLER;
                    127:        }
                    128: }
                    129: 
                    130: intr()
                    131: {
                    132:        extern probe();
                    133: 
                    134:        printf("\n");
                    135:        raise(0, (char *)0);
                    136: }
                    137: 
                    138: lostpeer()
                    139: {
                    140:        if (connected != (CourierConnection*)0) {
                    141:                /* CourierClose(connected); */  /* probably won't work */
                    142:                connected = (CourierConnection*) 0;
                    143:        }
                    144:        raise(EPIPE, "lost peer");
                    145: }
                    146: 
                    147: char *
                    148: tail(filename)
                    149:        char *filename;
                    150: {
                    151:        register char *s;
                    152:        
                    153:        while (*filename) {
                    154:                s = rindex(filename, '/');
                    155:                if (s == NULL)
                    156:                        break;
                    157:                if (s[1])
                    158:                        return (s + 1);
                    159:                *s = '\0';
                    160:        }
                    161:        return (filename);
                    162: }
                    163: 
                    164: /*
                    165:  * Command parser.
                    166:  */
                    167: cmdscanner()
                    168: {
                    169:        register struct cmd *c;
                    170:        struct cmd *getcmd();
                    171:        extern struct cmd cmdtab[];
                    172:        extern int help();
                    173: 
                    174:        for (;;) {
                    175:                if (fromatty) {
                    176:                        printf("xnsftp> ");
                    177:                        fflush(stdout);
                    178:                }
                    179:                if (gets(line) == 0) {
                    180:                        if (feof(stdin)) {
                    181:                                clearerr(stdin);
                    182:                                putchar('\n');
                    183:                        }
                    184:                        break;
                    185:                }
                    186:                if (line[0] == 0)
                    187:                        break;
                    188:                makeargv();
                    189:                c = getcmd(margv[0]);
                    190:                if (c == (struct cmd *)-1) {
                    191:                        printf("?Ambiguous command\n");
                    192:                        continue;
                    193:                }
                    194:                if (c == 0) {
                    195:                        printf("?Invalid command\n");
                    196:                        continue;
                    197:                }
                    198:                if (c->c_conn && !connected) {
                    199:                        printf ("Not connected.\n");
                    200:                        continue;
                    201:                }
                    202:                (*c->c_handler)(margc, margv);
                    203:                if (bell && c->c_bell)
                    204:                        putchar(CTRL(g));
                    205:                if (c->c_handler != help)
                    206:                        break;
                    207:        }
                    208: }
                    209: 
                    210: struct cmd *
                    211: getcmd(name)
                    212:        register char *name;
                    213: {
                    214:        register char *p, *q;
                    215:        register struct cmd *c, *found;
                    216:        register int nmatches, longest;
                    217: 
                    218:        longest = 0;
                    219:        nmatches = 0;
                    220:        found = 0;
                    221:        for (c = cmdtab; p = c->c_name; c++) {
                    222:                for (q = name; *q == *p++; q++)
                    223:                        if (*q == 0)            /* exact match? */
                    224:                                return (c);
                    225:                if (!*q) {                      /* the name was a prefix */
                    226:                        if (q - name > longest) {
                    227:                                longest = q - name;
                    228:                                nmatches = 1;
                    229:                                found = c;
                    230:                        } else if (q - name == longest)
                    231:                                nmatches++;
                    232:                }
                    233:        }
                    234:        if (nmatches > 1)
                    235:                return ((struct cmd *)-1);
                    236:        return (found);
                    237: }
                    238: 
                    239: /*
                    240:  * Slice a string up into argc/argv.
                    241:  */
                    242: makeargv()
                    243: {
                    244:        char **argp;
                    245:        char *slurpstring();
                    246: 
                    247:        margc = 0;
                    248:        argp = margv;
                    249:        stringbase = line;              /* scan from first of buffer */
                    250:        argbase = argbuf;               /* store from first of buffer */
                    251:        while (*argp++ = slurpstring())
                    252:                margc++;
                    253: }
                    254: 
                    255: /*
                    256:  * Parse string into argbuf;
                    257:  * implemented with FSM to
                    258:  * handle quoting and strings
                    259:  */
                    260: char *
                    261: slurpstring()
                    262: {
                    263:        int got_one = 0;
                    264:        register char *sb = stringbase;
                    265:        register char *ap = argbase;
                    266:        char *tmp = argbase;            /* will return this if token found */
                    267: 
                    268:        if (*sb == '!') {               /* recognize ! as a token for shell */
                    269:                stringbase++;
                    270:                return ("!");
                    271:        }
                    272: S0:
                    273:        switch (*sb) {
                    274: 
                    275:        case '\0':
                    276:                goto OUT;
                    277: 
                    278:        case ' ':
                    279:        case '\t':
                    280:                sb++; goto S0;
                    281: 
                    282:        default:
                    283:                goto S1;
                    284:        }
                    285: 
                    286: S1:
                    287:        switch (*sb) {
                    288: 
                    289:        case ' ':
                    290:        case '\t':
                    291:        case '\0':
                    292:                goto OUT;       /* end of token */
                    293: 
                    294:        case '\\':
                    295:                sb++; goto S2;  /* slurp next character */
                    296: 
                    297:        case '"':
                    298:                sb++; goto S3;  /* slurp quoted string */
                    299: 
                    300:        default:
                    301:                *ap++ = *sb++;  /* add character to token */
                    302:                got_one = 1;
                    303:                goto S1;
                    304:        }
                    305: 
                    306: S2:
                    307:        switch (*sb) {
                    308: 
                    309:        case '\0':
                    310:                goto OUT;
                    311: 
                    312:        default:
                    313:                *ap++ = *sb++;
                    314:                got_one = 1;
                    315:                goto S1;
                    316:        }
                    317: 
                    318: S3:
                    319:        switch (*sb) {
                    320: 
                    321:        case '\0':
                    322:                goto OUT;
                    323: 
                    324:        case '"':
                    325:                sb++; goto S1;
                    326: 
                    327:        default:
                    328:                *ap++ = *sb++;
                    329:                got_one = 1;
                    330:                goto S3;
                    331:        }
                    332: 
                    333: OUT:
                    334:        if (got_one)
                    335:                *ap++ = '\0';
                    336:        argbase = ap;                   /* update storage pointer */
                    337:        stringbase = sb;                /* update scan pointer */
                    338:        if (got_one)
                    339:                return(tmp);
                    340:        return((char *)0);
                    341: }
                    342: 
                    343: #define HELPINDENT (sizeof ("directory"))
                    344: 
                    345: /*
                    346:  * Help command.
                    347:  * Call each command handler with argc == 0 and argv[0] == name.
                    348:  */
                    349: help(argc, argv)
                    350:        int argc;
                    351:        char *argv[];
                    352: {
                    353:        register struct cmd *c;
                    354: 
                    355:        if (argc == 1) {
                    356:                register int i, j, w;
                    357:                int columns, width = 0, lines;
                    358:                extern int NCMDS;
                    359: 
                    360:                printf("Commands may be abbreviated.  Commands are:\n\n");
                    361:                for (c = cmdtab; c < &cmdtab[NCMDS]; c++) {
                    362:                        int len = strlen(c->c_name);
                    363: 
                    364:                        if (len > width)
                    365:                                width = len;
                    366:                }
                    367:                width = (width + 8) &~ 7;
                    368:                columns = 80 / width;
                    369:                if (columns == 0)
                    370:                        columns = 1;
                    371:                lines = (NCMDS + columns - 1) / columns;
                    372:                for (i = 0; i < lines; i++) {
                    373:                        for (j = 0; j < columns; j++) {
                    374:                                c = cmdtab + j * lines + i;
                    375:                                printf("%s", c->c_name);
                    376:                                if (c + lines >= &cmdtab[NCMDS]) {
                    377:                                        printf("\n");
                    378:                                        break;
                    379:                                }
                    380:                                w = strlen(c->c_name);
                    381:                                while (w < width) {
                    382:                                        w = (w + 8) &~ 7;
                    383:                                        putchar('\t');
                    384:                                }
                    385:                        }
                    386:                }
                    387:                return;
                    388:        }
                    389:        while (--argc > 0) {
                    390:                register char *arg;
                    391:                arg = *++argv;
                    392:                c = getcmd(arg);
                    393:                if (c == (struct cmd *)-1)
                    394:                        printf("?Ambiguous help command %s\n", arg);
                    395:                else if (c == (struct cmd *)0)
                    396:                        printf("?Invalid help command %s\n", arg);
                    397:                else
                    398:                        printf("%-*s\t%s\n", HELPINDENT,
                    399:                                c->c_name, c->c_help);
                    400:        }
                    401: }
                    402: 
                    403: /*
                    404:  * Call routine with argc, argv set from args (terminated by 0).
                    405:  */
                    406: /* VARARGS2 */
                    407: call(routine, args)
                    408:        int (*routine)();
                    409:        int args;
                    410: {
                    411:        register int *argp;
                    412:        register int argc;
                    413: 
                    414:        for (argc = 0, argp = &args; *argp++ != 0; argc++)
                    415:                ;
                    416:        (*routine)(argc, &args);
                    417: }
                    418: 

unix.superglobalmegacorp.com

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