[BACK]Return to main.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / ftp

Annotation of src/usr.bin/ftp/main.c, Revision 1.17

1.17    ! millert     1: /*     $NetBSD: main.c,v 1.17 1997/02/01 10:45:07 lukem Exp $  */
1.5       deraadt     2:
1.1       deraadt     3: /*
                      4:  * Copyright (c) 1985, 1989, 1993, 1994
                      5:  *     The Regents of the University of California.  All rights reserved.
                      6:  *
                      7:  * Redistribution and use in source and binary forms, with or without
                      8:  * modification, are permitted provided that the following conditions
                      9:  * are met:
                     10:  * 1. Redistributions of source code must retain the above copyright
                     11:  *    notice, this list of conditions and the following disclaimer.
                     12:  * 2. Redistributions in binary form must reproduce the above copyright
                     13:  *    notice, this list of conditions and the following disclaimer in the
                     14:  *    documentation and/or other materials provided with the distribution.
                     15:  * 3. All advertising materials mentioning features or use of this software
                     16:  *    must display the following acknowledgement:
                     17:  *     This product includes software developed by the University of
                     18:  *     California, Berkeley and its contributors.
                     19:  * 4. Neither the name of the University nor the names of its contributors
                     20:  *    may be used to endorse or promote products derived from this software
                     21:  *    without specific prior written permission.
                     22:  *
                     23:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
                     24:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     25:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     26:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     27:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     28:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     29:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     30:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     31:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     32:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     33:  * SUCH DAMAGE.
                     34:  */
                     35:
                     36: #ifndef lint
                     37: static char copyright[] =
                     38: "@(#) Copyright (c) 1985, 1989, 1993, 1994\n\
                     39:        The Regents of the University of California.  All rights reserved.\n";
                     40: #endif /* not lint */
                     41:
                     42: #ifndef lint
                     43: #if 0
                     44: static char sccsid[] = "@(#)main.c     8.6 (Berkeley) 10/9/94";
                     45: #else
1.17    ! millert    46: static char rcsid[] = "$NetBSD: main.c,v 1.17 1997/02/01 10:45:07 lukem Exp $";
1.1       deraadt    47: #endif
                     48: #endif /* not lint */
                     49:
                     50: /*
                     51:  * FTP User Program -- Command Interface.
                     52:  */
                     53: #include <sys/types.h>
                     54: #include <sys/socket.h>
                     55:
                     56: #include <err.h>
                     57: #include <netdb.h>
                     58: #include <pwd.h>
                     59: #include <stdio.h>
                     60: #include <string.h>
                     61: #include <unistd.h>
                     62:
                     63: #include "ftp_var.h"
                     64:
                     65: int
                     66: main(argc, argv)
                     67:        int argc;
                     68:        char *argv[];
                     69: {
1.17    ! millert    70:        struct servent *sp;
        !            71:        int ch, top, port, rval;
1.1       deraadt    72:        struct passwd *pw = NULL;
                     73:        char *cp, homedir[MAXPATHLEN];
                     74:
                     75:        sp = getservbyname("ftp", "tcp");
                     76:        if (sp == 0)
1.17    ! millert    77:                ftpport = htons(FTP_PORT);      /* good fallback */
        !            78:        else
        !            79:                ftpport = sp->s_port;
        !            80:        sp = getservbyname("http", "tcp");
        !            81:        if (sp == 0)
        !            82:                httpport = htons(HTTP_PORT);    /* good fallback */
        !            83:        else
        !            84:                httpport = sp->s_port;
1.1       deraadt    85:        doglob = 1;
                     86:        interactive = 1;
                     87:        autologin = 1;
1.17    ! millert    88:        passivemode = 0;
        !            89:        preserve = 1;
        !            90:        verbose = 0;
        !            91:        progress = 0;
1.8       kstailey   92:        mark = HASHBYTES;
1.17    ! millert    93:        marg_sl = sl_init();
1.1       deraadt    94:
1.17    ! millert    95:        cp = strrchr(argv[0], '/');
        !            96:        cp = (cp == NULL) ? argv[0] : cp + 1;
        !            97:        if (strcmp(cp, "pftp") == 0)
        !            98:                passivemode = 1;
        !            99:
        !           100:        fromatty = isatty(fileno(stdin));
        !           101:        if (fromatty)
        !           102:                verbose = 1;            /* verbose if from a tty */
        !           103:        if (isatty(fileno(stdout)))
        !           104:                progress = 1;           /* progress bar on if going to a tty */
        !           105:
        !           106:        while ((ch = getopt(argc, argv, "adginpP:tvV")) != EOF) {
1.1       deraadt   107:                switch (ch) {
1.17    ! millert   108:                case 'a':
        !           109:                        anonftp = 1;
        !           110:                        break;
        !           111:
1.1       deraadt   112:                case 'd':
                    113:                        options |= SO_DEBUG;
                    114:                        debug++;
                    115:                        break;
1.17    ! millert   116:
1.1       deraadt   117:                case 'g':
                    118:                        doglob = 0;
                    119:                        break;
                    120:
                    121:                case 'i':
                    122:                        interactive = 0;
                    123:                        break;
                    124:
                    125:                case 'n':
                    126:                        autologin = 0;
                    127:                        break;
                    128:
1.3       deraadt   129:                case 'p':
1.17    ! millert   130:                        passivemode = 1;
1.3       deraadt   131:                        break;
                    132:
1.17    ! millert   133:                case 'P':
        !           134:                        port = atoi(optarg);
        !           135:                        if (port <= 0)
        !           136:                                warnx("bad port number: %s", optarg);
        !           137:                        else
        !           138:                                ftpport = htons(port);
1.7       mickey    139:                        break;
                    140:
1.1       deraadt   141:                case 't':
1.17    ! millert   142:                        trace = 1;
1.1       deraadt   143:                        break;
                    144:
                    145:                case 'v':
1.17    ! millert   146:                        verbose = 1;
        !           147:                        break;
        !           148:
        !           149:                case 'V':
        !           150:                        verbose = 0;
1.1       deraadt   151:                        break;
                    152:
                    153:                default:
1.17    ! millert   154:                        usage();
1.1       deraadt   155:                }
                    156:        }
                    157:        argc -= optind;
                    158:        argv += optind;
                    159:
                    160:        cpend = 0;      /* no pending replies */
                    161:        proxy = 0;      /* proxy not active */
                    162:        crflag = 1;     /* strip c.r. on ascii gets */
                    163:        sendport = -1;  /* not using ports */
                    164:        /*
                    165:         * Set up the home directory in case we're globbing.
                    166:         */
                    167:        cp = getlogin();
                    168:        if (cp != NULL) {
                    169:                pw = getpwnam(cp);
                    170:        }
                    171:        if (pw == NULL)
                    172:                pw = getpwuid(getuid());
                    173:        if (pw != NULL) {
                    174:                home = homedir;
                    175:                (void) strcpy(home, pw->pw_dir);
1.3       deraadt   176:        }
1.9       michaels  177:
1.17    ! millert   178: #ifndef SMALLFTP
        !           179:        editing = 0;                    /* command line editing off */
        !           180:        if (fromatty) {
        !           181:                editing = 1;            /* editing mode on if a tty */
        !           182:                el = el_init(__progname, stdin, stdout); /* init editline */
        !           183:
        !           184:                hist = history_init();          /* init the builtin history */
        !           185:                history(hist, H_EVENT, 100);    /* remember 100 events */
        !           186:                el_set(el, EL_HIST, history, hist);     /* use history */
        !           187:
        !           188:                el_set(el, EL_EDITOR, "emacs"); /* default editor is emacs */
        !           189:                el_set(el, EL_PROMPT, prompt);  /* set the prompt function */
        !           190:
        !           191:                /* add local file completion, bind to TAB */
        !           192:                el_set(el, EL_ADDFN, "ftp-complete",
        !           193:                    "Context sensitive argument completion",
        !           194:                    complete);
        !           195:                el_set(el, EL_BIND, "^I", "ftp-complete", NULL);
        !           196:
        !           197:                el_source(el, NULL);    /* read ~/.editrc */
        !           198:        }
        !           199: #endif /* !SMALLFTP */
1.3       deraadt   200:
1.17    ! millert   201:        setttywidth(0);
        !           202:        (void) signal(SIGWINCH, setttywidth);
        !           203:
        !           204:        if (argc > 0) {
        !           205:                if (strchr(argv[0], ':') != NULL) {
        !           206:                        anonftp = 1;    /* Handle "automatic" transfers. */
        !           207:                        rval = auto_fetch(argc, argv);
        !           208:                        if (rval >= 0)          /* -1 == connected and cd-ed */
        !           209:                                exit(rval);
        !           210:                } else {
1.3       deraadt   211:                        char *xargv[5];
                    212:
                    213:                        if (setjmp(toplevel))
                    214:                                exit(0);
                    215:                        (void) signal(SIGINT, intr);
                    216:                        (void) signal(SIGPIPE, lostpeer);
                    217:                        xargv[0] = __progname;
1.17    ! millert   218:                        xargv[1] = argv[0];
        !           219:                        xargv[2] = argv[1];
        !           220:                        xargv[3] = argv[2];
        !           221:                        xargv[4] = NULL;
        !           222:                        setpeer(argc+1, xargv);
1.3       deraadt   223:                }
1.1       deraadt   224:        }
                    225:        top = setjmp(toplevel) == 0;
                    226:        if (top) {
                    227:                (void) signal(SIGINT, intr);
                    228:                (void) signal(SIGPIPE, lostpeer);
                    229:        }
                    230:        for (;;) {
                    231:                cmdscanner(top);
                    232:                top = 1;
                    233:        }
                    234: }
                    235:
                    236: void
                    237: intr()
                    238: {
                    239:
1.17    ! millert   240:        alarmtimer(0);
1.1       deraadt   241:        longjmp(toplevel, 1);
                    242: }
                    243:
                    244: void
                    245: lostpeer()
                    246: {
                    247:
1.17    ! millert   248:        alarmtimer(0);
1.1       deraadt   249:        if (connected) {
                    250:                if (cout != NULL) {
                    251:                        (void) shutdown(fileno(cout), 1+1);
                    252:                        (void) fclose(cout);
                    253:                        cout = NULL;
                    254:                }
                    255:                if (data >= 0) {
                    256:                        (void) shutdown(data, 1+1);
                    257:                        (void) close(data);
                    258:                        data = -1;
                    259:                }
                    260:                connected = 0;
                    261:        }
                    262:        pswitch(1);
                    263:        if (connected) {
                    264:                if (cout != NULL) {
                    265:                        (void) shutdown(fileno(cout), 1+1);
                    266:                        (void) fclose(cout);
                    267:                        cout = NULL;
                    268:                }
                    269:                connected = 0;
                    270:        }
                    271:        proxflag = 0;
                    272:        pswitch(0);
                    273: }
                    274:
                    275: /*
1.17    ! millert   276:  * Generate a prompt
        !           277:  */
1.1       deraadt   278: char *
1.17    ! millert   279: prompt()
1.1       deraadt   280: {
1.17    ! millert   281:        return ("ftp> ");
1.1       deraadt   282: }
                    283:
                    284: /*
                    285:  * Command parser.
                    286:  */
                    287: void
                    288: cmdscanner(top)
                    289:        int top;
                    290: {
                    291:        struct cmd *c;
1.17    ! millert   292:        int num;
1.1       deraadt   293:
1.17    ! millert   294:        if (!top
        !           295: #ifndef SMALLFTP
        !           296:            && !editing
        !           297: #endif /* !SMALLFTP */
        !           298:            )
1.1       deraadt   299:                (void) putchar('\n');
                    300:        for (;;) {
1.17    ! millert   301: #ifndef SMALLFTP
        !           302:                if (!editing) {
        !           303: #endif /* !SMALLFTP */
        !           304:                        if (fromatty) {
        !           305:                                printf("%s", prompt());
        !           306:                                (void) fflush(stdout);
        !           307:                        }
        !           308:                        if (fgets(line, sizeof(line), stdin) == NULL)
        !           309:                                quit(0, 0);
        !           310:                        num = strlen(line);
        !           311:                        if (num == 0)
        !           312:                                break;
        !           313:                        if (line[--num] == '\n') {
        !           314:                                if (num == 0)
        !           315:                                        break;
        !           316:                                line[num] = '\0';
        !           317:                        } else if (num == sizeof(line) - 2) {
        !           318:                                printf("sorry, input line too long\n");
        !           319:                                while ((num = getchar()) != '\n' && num != EOF)
        !           320:                                        /* void */;
        !           321:                                break;
        !           322:                        } /* else it was a line without a newline */
        !           323: #ifndef SMALLFTP
        !           324:                } else {
        !           325:                        const char *buf;
        !           326:                        cursor_pos = NULL;
        !           327:
        !           328:                        if ((buf = el_gets(el, &num)) == NULL || num == 0)
        !           329:                                quit(0, 0);
        !           330:                        if (line[--num] == '\n') {
        !           331:                                if (num == 0)
        !           332:                                        break;
        !           333:                        } else if (num >= sizeof(line)) {
        !           334:                                printf("sorry, input line too long\n");
1.1       deraadt   335:                                break;
1.17    ! millert   336:                        }
        !           337:                        memcpy(line, buf, num);
        !           338:                        line[num] = '\0';
        !           339:                        history(hist, H_ENTER, buf);
        !           340:                }
        !           341: #endif /* !SMALLFTP */
        !           342:
1.1       deraadt   343:                makeargv();
1.17    ! millert   344:                if (margc == 0)
1.1       deraadt   345:                        continue;
1.17    ! millert   346: #if 0 && !defined(SMALLFTP)    /* XXX: don't want el_parse */
        !           347:                /*
        !           348:                 * el_parse returns -1 to signal that it's not been handled
        !           349:                 * internally.
        !           350:                 */
        !           351:                if (el_parse(el, margc, margv) != -1)
        !           352:                        continue;
        !           353: #endif /* !SMALLFTP */
1.1       deraadt   354:                c = getcmd(margv[0]);
                    355:                if (c == (struct cmd *)-1) {
                    356:                        printf("?Ambiguous command\n");
                    357:                        continue;
                    358:                }
                    359:                if (c == 0) {
                    360:                        printf("?Invalid command\n");
                    361:                        continue;
                    362:                }
                    363:                if (c->c_conn && !connected) {
                    364:                        printf("Not connected.\n");
                    365:                        continue;
                    366:                }
1.17    ! millert   367:                confirmrest = 0;
1.1       deraadt   368:                (*c->c_handler)(margc, margv);
                    369:                if (bell && c->c_bell)
                    370:                        (void) putchar('\007');
                    371:                if (c->c_handler != help)
                    372:                        break;
                    373:        }
                    374:        (void) signal(SIGINT, intr);
                    375:        (void) signal(SIGPIPE, lostpeer);
                    376: }
                    377:
                    378: struct cmd *
                    379: getcmd(name)
1.17    ! millert   380:        const char *name;
1.1       deraadt   381: {
1.17    ! millert   382:        const char *p, *q;
1.1       deraadt   383:        struct cmd *c, *found;
                    384:        int nmatches, longest;
1.2       deraadt   385:
                    386:        if (name == NULL)
                    387:                return (0);
1.1       deraadt   388:
                    389:        longest = 0;
                    390:        nmatches = 0;
                    391:        found = 0;
1.17    ! millert   392:        for (c = cmdtab; (p = c->c_name) != NULL; c++) {
1.1       deraadt   393:                for (q = name; *q == *p++; q++)
                    394:                        if (*q == 0)            /* exact match? */
                    395:                                return (c);
                    396:                if (!*q) {                      /* the name was a prefix */
                    397:                        if (q - name > longest) {
                    398:                                longest = q - name;
                    399:                                nmatches = 1;
                    400:                                found = c;
                    401:                        } else if (q - name == longest)
                    402:                                nmatches++;
                    403:                }
                    404:        }
                    405:        if (nmatches > 1)
                    406:                return ((struct cmd *)-1);
                    407:        return (found);
                    408: }
                    409:
                    410: /*
                    411:  * Slice a string up into argc/argv.
                    412:  */
                    413:
                    414: int slrflag;
                    415:
                    416: void
                    417: makeargv()
                    418: {
1.17    ! millert   419:        char *argp;
1.1       deraadt   420:
                    421:        stringbase = line;              /* scan from first of buffer */
                    422:        argbase = argbuf;               /* store from first of buffer */
                    423:        slrflag = 0;
1.17    ! millert   424:        marg_sl->sl_cur = 0;            /* reset to start of marg_sl */
1.1       deraadt   425:        for (margc = 0; ; margc++) {
1.17    ! millert   426:                argp = slurpstring();
        !           427:                sl_add(marg_sl, argp);
        !           428:                if (argp == NULL)
1.1       deraadt   429:                        break;
                    430:        }
1.17    ! millert   431: #ifndef SMALLFTP
        !           432:        if (cursor_pos == line) {
        !           433:                cursor_argc = 0;
        !           434:                cursor_argo = 0;
        !           435:        } else if (cursor_pos != NULL) {
        !           436:                cursor_argc = margc;
        !           437:                cursor_argo = strlen(margv[margc-1]);
        !           438:        }
        !           439: #endif /* !SMALLFTP */
        !           440: }
1.1       deraadt   441:
1.17    ! millert   442: #ifdef SMALLFTP
        !           443: #define INC_CHKCURSOR(x)       (x)++
        !           444: #else  /* !SMALLFTP */
        !           445: #define INC_CHKCURSOR(x)       { (x)++ ; \
        !           446:                                if (x == cursor_pos) { \
        !           447:                                        cursor_argc = margc; \
        !           448:                                        cursor_argo = ap-argbase; \
        !           449:                                        cursor_pos = NULL; \
        !           450:                                } }
        !           451:
        !           452: #endif /* !SMALLFTP */
1.1       deraadt   453:
                    454: /*
                    455:  * Parse string into argbuf;
                    456:  * implemented with FSM to
                    457:  * handle quoting and strings
                    458:  */
                    459: char *
                    460: slurpstring()
                    461: {
                    462:        int got_one = 0;
                    463:        char *sb = stringbase;
                    464:        char *ap = argbase;
                    465:        char *tmp = argbase;            /* will return this if token found */
                    466:
                    467:        if (*sb == '!' || *sb == '$') { /* recognize ! as a token for shell */
                    468:                switch (slrflag) {      /* and $ as token for macro invoke */
                    469:                        case 0:
                    470:                                slrflag++;
1.17    ! millert   471:                                INC_CHKCURSOR(stringbase);
1.1       deraadt   472:                                return ((*sb == '!') ? "!" : "$");
                    473:                                /* NOTREACHED */
                    474:                        case 1:
                    475:                                slrflag++;
                    476:                                altarg = stringbase;
                    477:                                break;
                    478:                        default:
                    479:                                break;
                    480:                }
                    481:        }
                    482:
                    483: S0:
                    484:        switch (*sb) {
                    485:
                    486:        case '\0':
                    487:                goto OUT;
                    488:
                    489:        case ' ':
                    490:        case '\t':
1.17    ! millert   491:                INC_CHKCURSOR(sb);
        !           492:                goto S0;
1.1       deraadt   493:
                    494:        default:
                    495:                switch (slrflag) {
                    496:                        case 0:
                    497:                                slrflag++;
                    498:                                break;
                    499:                        case 1:
                    500:                                slrflag++;
                    501:                                altarg = sb;
                    502:                                break;
                    503:                        default:
                    504:                                break;
                    505:                }
                    506:                goto S1;
                    507:        }
                    508:
                    509: S1:
                    510:        switch (*sb) {
                    511:
                    512:        case ' ':
                    513:        case '\t':
                    514:        case '\0':
                    515:                goto OUT;       /* end of token */
                    516:
                    517:        case '\\':
1.17    ! millert   518:                INC_CHKCURSOR(sb);
        !           519:                goto S2;        /* slurp next character */
1.1       deraadt   520:
                    521:        case '"':
1.17    ! millert   522:                INC_CHKCURSOR(sb);
        !           523:                goto S3;        /* slurp quoted string */
1.1       deraadt   524:
                    525:        default:
1.17    ! millert   526:                *ap = *sb;      /* add character to token */
        !           527:                ap++;
        !           528:                INC_CHKCURSOR(sb);
1.1       deraadt   529:                got_one = 1;
                    530:                goto S1;
                    531:        }
                    532:
                    533: S2:
                    534:        switch (*sb) {
                    535:
                    536:        case '\0':
                    537:                goto OUT;
                    538:
                    539:        default:
1.17    ! millert   540:                *ap = *sb;
        !           541:                ap++;
        !           542:                INC_CHKCURSOR(sb);
1.1       deraadt   543:                got_one = 1;
                    544:                goto S1;
                    545:        }
                    546:
                    547: S3:
                    548:        switch (*sb) {
                    549:
                    550:        case '\0':
                    551:                goto OUT;
                    552:
                    553:        case '"':
1.17    ! millert   554:                INC_CHKCURSOR(sb);
        !           555:                goto S1;
1.1       deraadt   556:
                    557:        default:
1.17    ! millert   558:                *ap = *sb;
        !           559:                ap++;
        !           560:                INC_CHKCURSOR(sb);
1.1       deraadt   561:                got_one = 1;
                    562:                goto S3;
                    563:        }
                    564:
                    565: OUT:
                    566:        if (got_one)
                    567:                *ap++ = '\0';
                    568:        argbase = ap;                   /* update storage pointer */
                    569:        stringbase = sb;                /* update scan pointer */
                    570:        if (got_one) {
                    571:                return (tmp);
                    572:        }
                    573:        switch (slrflag) {
                    574:                case 0:
                    575:                        slrflag++;
                    576:                        break;
                    577:                case 1:
                    578:                        slrflag++;
                    579:                        altarg = (char *) 0;
                    580:                        break;
                    581:                default:
                    582:                        break;
                    583:        }
                    584:        return ((char *)0);
                    585: }
                    586:
                    587: /*
                    588:  * Help command.
                    589:  * Call each command handler with argc == 0 and argv[0] == name.
                    590:  */
                    591: void
                    592: help(argc, argv)
                    593:        int argc;
                    594:        char *argv[];
                    595: {
                    596:        struct cmd *c;
                    597:
                    598:        if (argc == 1) {
1.17    ! millert   599:                StringList *buf;
1.1       deraadt   600:
1.17    ! millert   601:                buf = sl_init();
        !           602:                printf("%sommands may be abbreviated.  Commands are:\n\n",
        !           603:                    proxy ? "Proxy c" : "C");
        !           604:                for (c = cmdtab; c < &cmdtab[NCMDS]; c++)
        !           605:                        if (c->c_name && (!proxy || c->c_proxy))
        !           606:                                sl_add(buf, c->c_name);
        !           607:                list_vertical(buf);
        !           608:                sl_free(buf, 0);
1.1       deraadt   609:                return;
                    610:        }
1.17    ! millert   611:
        !           612: #define HELPINDENT ((int) sizeof ("disconnect"))
        !           613:
1.1       deraadt   614:        while (--argc > 0) {
                    615:                char *arg;
1.17    ! millert   616:
1.1       deraadt   617:                arg = *++argv;
                    618:                c = getcmd(arg);
                    619:                if (c == (struct cmd *)-1)
                    620:                        printf("?Ambiguous help command %s\n", arg);
                    621:                else if (c == (struct cmd *)0)
                    622:                        printf("?Invalid help command %s\n", arg);
                    623:                else
                    624:                        printf("%-*s\t%s\n", HELPINDENT,
                    625:                                c->c_name, c->c_help);
                    626:        }
1.17    ! millert   627: }
        !           628:
        !           629: void
        !           630: usage()
        !           631: {
        !           632:        (void)fprintf(stderr,
        !           633:            "usage: %s [-adginptvV] [host [port]]\n"
        !           634:            "       %s host:path[/]\n"
        !           635:            "       %s ftp://host[:port]/path[/]\n"
        !           636:            "       %s http://host[:port]/file\n",
        !           637:            __progname, __progname, __progname, __progname);
        !           638:        exit(1);
1.1       deraadt   639: }