Annotation of 43BSDTahoe/new/xns/examples/filing_client/main.c, revision 1.1.1.1

1.1       root        1: #ifndef lint
                      2: static char RCSid[] = "$Header: main.c,v 2.3 87/03/23 12:29:53 ed Exp $";
                      3: #endif
                      4: 
                      5: /*
                      6:  * FTP User Program -- Command Interface.
                      7:  */
                      8: /* $Log:       main.c,v $
                      9:  * Revision 2.3  87/03/23  12:29:53  ed
                     10:  * Added -c switch to allow xnsftp commands to be specified directly
                     11:  * on commandline.
                     12:  * 
                     13:  * Revision 2.2  87/01/09  16:51:37  ed
                     14:  * Use FilingSubset, if rejected attempt Filing
                     15:  * Allows user override with -F switch
                     16:  * Maintain FilingSubset mandatory attributes
                     17:  * User niceties:  echo file name/type on transfer commands
                     18:  *             prompt on delete
                     19:  * guess type which will determine file type implied by content
                     20:  * New commands: (type related) Guess, Whatis
                     21:  *           (file transfer) Copy, Move, Rename
                     22:  * 
                     23:  * Revision 2.1  86/12/11  06:12:14  jqj
                     24:  * Eliminated form, mode, and struct commands.  Started adding support for
                     25:  * more file types.
                     26:  * 
                     27:  * Revision 2.0  85/11/21  07:22:49  jqj
                     28:  * 4.3BSD standard release
                     29:  * 
                     30:  * Revision 1.1  85/05/27  06:31:05  jqj
                     31:  * Initial revision
                     32:  * 
                     33:  * Revision 1.1  85/05/27  06:31:05  jqj
                     34:  * Initial revision
                     35:  * 
                     36:  * Based on Berkeley tcp/ftp
                     37:  */
                     38: #include <sys/param.h>
                     39: #include <sys/socket.h>
                     40: #include <sys/ioctl.h>
                     41: 
                     42: #include <xnscourier/except.h>
                     43: #include <stdio.h>
                     44: #include <errno.h>
                     45: #include <ctype.h>
                     46: #include <pwd.h>
                     47: 
                     48: #include "ftp_var.h"
                     49: 
                     50: int    intr();
                     51: int    lostpeer();
                     52: extern char *home;
                     53: 
                     54: main(argc, argv)
                     55:        char *argv[];
                     56: {
                     57:        register char *cp;
                     58:        int top;
                     59:        int continue_flag= 1;
                     60:        struct passwd *pw;
                     61:        char homedir[MAXPATHLEN];
                     62:        char *cmd;
                     63: 
                     64:        doglob = 1;
                     65:        interactive = 1;
                     66:        autologin = 1;
                     67:        argc--, argv++;
                     68:        fromatty = isatty(fileno(stdin));
                     69:        if (fromatty)
                     70:                verbose++;
                     71:        while (argc > 0 && **argv == '-') {
                     72:                for (cp = *argv + 1; *cp; cp++)
                     73:                        switch (*cp) {
                     74: 
                     75:                        case 'd':
                     76:                                debug++;
                     77:                                break;
                     78:                        
                     79:                        case 'v':
                     80:                                verbose++;
                     81:                                break;
                     82: 
                     83:                        case 't':
                     84:                                trace++;
                     85:                                break;
                     86: 
                     87:                        case 'i':
                     88:                                interactive = 0;
                     89:                                break;
                     90: 
                     91:                        case 'n':
                     92:                                autologin = 0;
                     93:                                break;
                     94: 
                     95:                        case 'g':
                     96:                                doglob = 0;
                     97:                                break;
                     98: 
                     99:                        case 'F':
                    100:                                usefiling++;
                    101:                                break;
                    102: 
                    103:                        case 'c':
                    104:                                argc--, argv++;
                    105:                                cmd= *argv;
                    106:                                interactive= verbose= continue_flag= 0;
                    107:                                break;
                    108: 
                    109:                        default:
                    110:                                fprintf(stderr,
                    111:                                  "xnsftp: %c: unknown option\n", *cp);
                    112:                                exit(1);
                    113:                        }
                    114:                argc--, argv++;
                    115:        }
                    116:        /*
                    117:         * Set up defaults for FTP.
                    118:         */
                    119:        strcpy(typename, "guess"), typevalue = TYPE_Guess;
                    120:        /*
                    121:         * Set up the home directory in case we're globbing.
                    122:         */
                    123:        pw = getpwnam(getlogin());
                    124:        if (pw == NULL)
                    125:                pw = getpwuid(getuid());
                    126:        if (pw != NULL) {
                    127:                home = homedir;
                    128:                strcpy(home, pw->pw_dir);
                    129:        }
                    130:        signal(SIGINT, intr);
                    131:        signal(SIGPIPE, lostpeer);
                    132: 
                    133:        DURING {
                    134:                if (argc > 0)
                    135:                  setpeer(argc + 1, argv - 1);
                    136:        } HANDLER {
                    137:                FilingErrMsg(Exception.Code, Exception.Message);
                    138:                exit(0);
                    139:        } END_HANDLER;
                    140: 
                    141:        if ( cmd ) {
                    142:                continue_flag= cmdfromargv(cmd);
                    143:        }
                    144: 
                    145:        if (continue_flag) {
                    146:                for (;;) {
                    147:                        DURING {
                    148:                                for (;;)
                    149:                                  cmdscanner();
                    150:                        } HANDLER {
                    151:                                FilingErrMsg(Exception.Code, Exception.Message);
                    152:                                if (connected != (CourierConnection*)0) {
                    153:                                        DURING
                    154:                                          probe();      /* reset alarm */
                    155:                                        HANDLER {       /* can't?  Lost peer */
                    156:                                          connected = (CourierConnection*) 0;
                    157:                                        } END_HANDLER;
                    158:                                }
                    159:                        } END_HANDLER;
                    160:                }
                    161:        }
                    162: }
                    163: 
                    164: intr()
                    165: {
                    166:        extern probe();
                    167: 
                    168:        printf("\n");
                    169:        raise(0, (char *)0);
                    170: }
                    171: 
                    172: lostpeer()
                    173: {
                    174:        if (connected != (CourierConnection*)0) {
                    175:                /* CourierClose(connected); */  /* probably won't work */
                    176:                connected = (CourierConnection*) 0;
                    177:        }
                    178:        raise(EPIPE, "lost peer");
                    179: }
                    180: 
                    181: char *
                    182: tail(filename)
                    183:        char *filename;
                    184: {
                    185:        register char *s;
                    186:        
                    187:        while (*filename) {
                    188:                s = rindex(filename, '/');
                    189:                if (s == NULL)
                    190:                        break;
                    191:                if (s[1])
                    192:                        return (s + 1);
                    193:                *s = '\0';
                    194:        }
                    195:        return (filename);
                    196: }
                    197: 
                    198: /*
                    199:  * Command parser.
                    200:  */
                    201: cmdscanner()
                    202: {
                    203:        register struct cmd *c;
                    204:        struct cmd *getcmd();
                    205:        extern struct cmd cmdtab[];
                    206:        extern int help();
                    207: 
                    208:        for (;;) {
                    209:                if (fromatty) {
                    210:                        printf("xnsftp> ");
                    211:                        fflush(stdout);
                    212:                }
                    213:                if (gets(line) == 0) {
                    214:                        if (feof(stdin)) {
                    215:                                clearerr(stdin);
                    216:                                putchar('\n');
                    217:                        }
                    218:                        break;
                    219:                }
                    220:                if (line[0] == 0)
                    221:                        break;
                    222:                makeargv();
                    223:                c = getcmd(margv[0]);
                    224:                if (c == (struct cmd *)-1) {
                    225:                        printf("?Ambiguous command\n");
                    226:                        continue;
                    227:                }
                    228:                if (c == 0) {
                    229:                        printf("?Invalid command\n");
                    230:                        continue;
                    231:                }
                    232:                if (c->c_conn && !connected) {
                    233:                        printf ("Not connected.\n");
                    234:                        continue;
                    235:                }
                    236:                (*c->c_handler)(margc, margv);
                    237:                if (bell && c->c_bell)
                    238:                        putchar(CTRL(g));
                    239:                if (c->c_handler != help)
                    240:                        break;
                    241:        }
                    242: }
                    243: /*
                    244:  * Execute commands from command line.
                    245:  *     command is of form  "command1 ; command2 ; command3 ; ..."
                    246:  */
                    247: cmdfromargv(command)
                    248: char *command;
                    249: {
                    250:        register struct cmd *c;
                    251:        struct cmd *getcmd();
                    252:        extern struct cmd cmdtab[];
                    253:        extern int help();
                    254:        int done= 0;
                    255:        char *ptr, *endptr;
                    256: 
                    257:        endptr= command + strlen(command) - 1;
                    258: 
                    259:        for (;;) {
                    260:                if ( done ) break;
                    261: 
                    262:                if ( (ptr= index(command, ';')) == 0 )  {
                    263:                        done= 1;
                    264:                } else {
                    265:                        if  (ptr == endptr)
                    266:                                done= 1;
                    267:                        *ptr= '\0';
                    268:                }
                    269: 
                    270:                strcpy(line,command);
                    271:                command= ptr + 1;
                    272: 
                    273:                makeargv();
                    274:                c = getcmd(margv[0]);
                    275:                if (c == (struct cmd *)-1) {
                    276:                        printf("?Ambiguous command\n");
                    277:                        continue;
                    278:                }
                    279:                if (c == 0) {
                    280:                        printf("?Invalid command\n");
                    281:                        continue;
                    282:                }
                    283:                if (c->c_conn && !connected) {
                    284:                        printf ("Not connected.\n");
                    285:                        continue;
                    286:                }
                    287: 
                    288:                DURING {
                    289:                        (*c->c_handler)(margc, margv);
                    290:                } HANDLER {
                    291:                        FilingErrMsg(Exception.Code, Exception.Message);
                    292:                        ptr= 0;                 /* force exit */
                    293:                        break;
                    294:                } END_HANDLER;
                    295: 
                    296:                if (bell && c->c_bell)
                    297:                        putchar(CTRL(g));
                    298:                if (c->c_handler != help)
                    299:                        continue;
                    300:        }
                    301: 
                    302:        if ( ptr == endptr )            /* semi as last character */
                    303:                return(1);
                    304:        else
                    305:                return(0);
                    306: 
                    307: }
                    308: 
                    309: struct cmd *
                    310: getcmd(name)
                    311:        register char *name;
                    312: {
                    313:        register char *p, *q;
                    314:        register struct cmd *c, *found;
                    315:        register int nmatches, longest;
                    316: 
                    317:        longest = 0;
                    318:        nmatches = 0;
                    319:        found = 0;
                    320:        for (c = cmdtab; p = c->c_name; c++) {
                    321:                for (q = name; *q == *p++; q++)
                    322:                        if (*q == 0)            /* exact match? */
                    323:                                return (c);
                    324:                if (!*q) {                      /* the name was a prefix */
                    325:                        if (q - name > longest) {
                    326:                                longest = q - name;
                    327:                                nmatches = 1;
                    328:                                found = c;
                    329:                        } else if (q - name == longest)
                    330:                                nmatches++;
                    331:                }
                    332:        }
                    333:        if (nmatches > 1)
                    334:                return ((struct cmd *)-1);
                    335:        return (found);
                    336: }
                    337: 
                    338: /*
                    339:  * Slice a string up into argc/argv.
                    340:  */
                    341: makeargv()
                    342: {
                    343:        char **argp;
                    344:        char *slurpstring();
                    345: 
                    346:        margc = 0;
                    347:        argp = margv;
                    348:        stringbase = line;              /* scan from first of buffer */
                    349:        argbase = argbuf;               /* store from first of buffer */
                    350:        while (*argp++ = slurpstring())
                    351:                margc++;
                    352: }
                    353: 
                    354: /*
                    355:  * Parse string into argbuf;
                    356:  * implemented with FSM to
                    357:  * handle quoting and strings
                    358:  */
                    359: char *
                    360: slurpstring()
                    361: {
                    362:        int got_one = 0;
                    363:        register char *sb = stringbase;
                    364:        register char *ap = argbase;
                    365:        char *tmp = argbase;            /* will return this if token found */
                    366: 
                    367:        if (*sb == '!') {               /* recognize ! as a token for shell */
                    368:                stringbase++;
                    369:                return ("!");
                    370:        }
                    371: S0:
                    372:        switch (*sb) {
                    373: 
                    374:        case '\0':
                    375:                goto OUT;
                    376: 
                    377:        case ' ':
                    378:        case '\t':
                    379:                sb++; goto S0;
                    380: 
                    381:        default:
                    382:                goto S1;
                    383:        }
                    384: 
                    385: S1:
                    386:        switch (*sb) {
                    387: 
                    388:        case ' ':
                    389:        case '\t':
                    390:        case '\0':
                    391:                goto OUT;       /* end of token */
                    392: 
                    393:        case '\\':
                    394:                sb++; goto S2;  /* slurp next character */
                    395: 
                    396:        case '"':
                    397:                sb++; goto S3;  /* slurp quoted string */
                    398: 
                    399:        default:
                    400:                *ap++ = *sb++;  /* add character to token */
                    401:                got_one = 1;
                    402:                goto S1;
                    403:        }
                    404: 
                    405: S2:
                    406:        switch (*sb) {
                    407: 
                    408:        case '\0':
                    409:                goto OUT;
                    410: 
                    411:        default:
                    412:                *ap++ = *sb++;
                    413:                got_one = 1;
                    414:                goto S1;
                    415:        }
                    416: 
                    417: S3:
                    418:        switch (*sb) {
                    419: 
                    420:        case '\0':
                    421:                goto OUT;
                    422: 
                    423:        case '"':
                    424:                sb++; goto S1;
                    425: 
                    426:        default:
                    427:                *ap++ = *sb++;
                    428:                got_one = 1;
                    429:                goto S3;
                    430:        }
                    431: 
                    432: OUT:
                    433:        if (got_one)
                    434:                *ap++ = '\0';
                    435:        argbase = ap;                   /* update storage pointer */
                    436:        stringbase = sb;                /* update scan pointer */
                    437:        if (got_one)
                    438:                return(tmp);
                    439:        return((char *)0);
                    440: }
                    441: 
                    442: #define HELPINDENT (sizeof ("directory"))
                    443: 
                    444: /*
                    445:  * Help command.
                    446:  * Call each command handler with argc == 0 and argv[0] == name.
                    447:  */
                    448: help(argc, argv)
                    449:        int argc;
                    450:        char *argv[];
                    451: {
                    452:        register struct cmd *c;
                    453: 
                    454:        if (argc == 1) {
                    455:                register int i, j, w;
                    456:                int columns, width = 0, lines;
                    457:                extern int NCMDS;
                    458: 
                    459:                printf("Commands may be abbreviated.  Commands are:\n\n");
                    460:                for (c = cmdtab; c < &cmdtab[NCMDS]; c++) {
                    461:                        int len = strlen(c->c_name);
                    462: 
                    463:                        if (len > width)
                    464:                                width = len;
                    465:                }
                    466:                width = (width + 8) &~ 7;
                    467:                columns = 80 / width;
                    468:                if (columns == 0)
                    469:                        columns = 1;
                    470:                lines = (NCMDS + columns - 1) / columns;
                    471:                for (i = 0; i < lines; i++) {
                    472:                        for (j = 0; j < columns; j++) {
                    473:                                c = cmdtab + j * lines + i;
                    474:                                printf("%s", c->c_name);
                    475:                                if (c + lines >= &cmdtab[NCMDS]) {
                    476:                                        printf("\n");
                    477:                                        break;
                    478:                                }
                    479:                                w = strlen(c->c_name);
                    480:                                while (w < width) {
                    481:                                        w = (w + 8) &~ 7;
                    482:                                        putchar('\t');
                    483:                                }
                    484:                        }
                    485:                }
                    486:                return;
                    487:        }
                    488:        while (--argc > 0) {
                    489:                register char *arg;
                    490:                arg = *++argv;
                    491:                c = getcmd(arg);
                    492:                if (c == (struct cmd *)-1)
                    493:                        printf("?Ambiguous help command %s\n", arg);
                    494:                else if (c == (struct cmd *)0)
                    495:                        printf("?Invalid help command %s\n", arg);
                    496:                else
                    497:                        printf("%-*s\t%s\n", HELPINDENT,
                    498:                                c->c_name, c->c_help);
                    499:        }
                    500: }
                    501: 
                    502: /*
                    503:  * Call routine with argc, argv set from args (terminated by 0).
                    504:  */
                    505: /* VARARGS2 */
                    506: call(routine, args)
                    507:        int (*routine)();
                    508:        int args;
                    509: {
                    510:        register int *argp;
                    511:        register int argc;
                    512: 
                    513:        for (argc = 0, argp = &args; *argp++ != 0; argc++)
                    514:                ;
                    515:        (*routine)(argc, &args);
                    516: }
                    517: 

unix.superglobalmegacorp.com

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