Annotation of 43BSDReno/usr.bin/ftp/cmds.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1985, 1989 Regents of the University of California.
                      3:  * All rights reserved.
                      4:  *
                      5:  * Redistribution and use in source and binary forms are permitted
                      6:  * provided that: (1) source distributions retain this entire copyright
                      7:  * notice and comment, and (2) distributions including binaries display
                      8:  * the following acknowledgement:  ``This product includes software
                      9:  * developed by the University of California, Berkeley and its contributors''
                     10:  * in the documentation or other materials provided with the distribution
                     11:  * and in all advertising materials mentioning features or use of this
                     12:  * software. Neither the name of the University nor the names of its
                     13:  * contributors may be used to endorse or promote products derived
                     14:  * from this software without specific prior written permission.
                     15:  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
                     16:  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
                     17:  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
                     18:  */
                     19: 
                     20: #ifndef lint
                     21: static char sccsid[] = "@(#)cmds.c     5.23 (Berkeley) 6/1/90";
                     22: #endif /* not lint */
                     23: 
                     24: /*
                     25:  * FTP User Program -- Command Routines.
                     26:  */
                     27: #include <sys/param.h>
                     28: #include <sys/wait.h>
                     29: #include <sys/stat.h>
                     30: #include <sys/socket.h>
                     31: 
                     32: #include <arpa/ftp.h>
                     33: 
                     34: #include <signal.h>
                     35: #include <stdio.h>
                     36: #include <errno.h>
                     37: #include <netdb.h>
                     38: #include <ctype.h>
                     39: #include <time.h>
                     40: #include <netinet/in.h>
                     41: 
                     42: #include "ftp_var.h"
                     43: #include "pathnames.h"
                     44: 
                     45: extern char *globerr;
                     46: extern char **glob();
                     47: extern char *home;
                     48: extern char *remglob();
                     49: extern char *getenv();
                     50: extern char *index();
                     51: extern char *rindex();
                     52: extern char *strerror();
                     53: extern int  errno;
                     54: extern off_t restart_point;
                     55: extern char reply_string[];
                     56: 
                     57: char *mname;
                     58: jmp_buf jabort;
                     59: char *dotrans(), *domap();
                     60: 
                     61: /*
                     62:  * Connect to peer server and
                     63:  * auto-login, if possible.
                     64:  */
                     65: setpeer(argc, argv)
                     66:        int argc;
                     67:        char *argv[];
                     68: {
                     69:        char *host, *hookup();
                     70:        short port;
                     71: 
                     72:        if (connected) {
                     73:                printf("Already connected to %s, use close first.\n",
                     74:                        hostname);
                     75:                code = -1;
                     76:                return;
                     77:        }
                     78:        if (argc < 2) {
                     79:                (void) strcat(line, " ");
                     80:                printf("(to) ");
                     81:                (void) gets(&line[strlen(line)]);
                     82:                makeargv();
                     83:                argc = margc;
                     84:                argv = margv;
                     85:        }
                     86:        if (argc > 3) {
                     87:                printf("usage: %s host-name [port]\n", argv[0]);
                     88:                code = -1;
                     89:                return;
                     90:        }
                     91:        port = sp->s_port;
                     92:        if (argc > 2) {
                     93:                port = atoi(argv[2]);
                     94:                if (port <= 0) {
                     95:                        printf("%s: bad port number-- %s\n", argv[1], argv[2]);
                     96:                        printf ("usage: %s host-name [port]\n", argv[0]);
                     97:                        code = -1;
                     98:                        return;
                     99:                }
                    100:                port = htons(port);
                    101:        }
                    102:        host = hookup(argv[1], port);
                    103:        if (host) {
                    104:                int overbose;
                    105: 
                    106:                connected = 1;
                    107:                /*
                    108:                 * Set up defaults for FTP.
                    109:                 */
                    110:                (void) strcpy(typename, "ascii"), type = TYPE_A;
                    111:                curtype = TYPE_A;
                    112:                (void) strcpy(formname, "non-print"), form = FORM_N;
                    113:                (void) strcpy(modename, "stream"), mode = MODE_S;
                    114:                (void) strcpy(structname, "file"), stru = STRU_F;
                    115:                (void) strcpy(bytename, "8"), bytesize = 8;
                    116:                if (autologin)
                    117:                        (void) login(argv[1]);
                    118: 
                    119: #if defined(unix) && NBBY == 8
                    120: /*
                    121:  * this ifdef is to keep someone form "porting" this to an incompatible
                    122:  * system and not checking this out. This way they have to think about it.
                    123:  */
                    124:                overbose = verbose;
                    125:                if (debug == 0)
                    126:                        verbose = -1;
                    127:                if (command("SYST") == COMPLETE && overbose) {
                    128:                        register char *cp, c;
                    129:                        cp = index(reply_string+4, ' ');
                    130:                        if (cp == NULL)
                    131:                                cp = index(reply_string+4, '\r');
                    132:                        if (cp) {
                    133:                                if (cp[-1] == '.')
                    134:                                        cp--;
                    135:                                c = *cp;
                    136:                                *cp = '\0';
                    137:                        }
                    138: 
                    139:                        printf("Remote system type is %s.\n",
                    140:                                reply_string+4);
                    141:                        if (cp)
                    142:                                *cp = c;
                    143:                }
                    144:                if (!strncmp(reply_string, "215 UNIX Type: L8", 17)) {
                    145:                        if (proxy)
                    146:                                unix_proxy = 1;
                    147:                        else
                    148:                                unix_server = 1;
                    149:                        /*
                    150:                         * Set type to 0 (not specified by user),
                    151:                         * meaning binary by default, but don't bother
                    152:                         * telling server.  We can use binary
                    153:                         * for text files unless changed by the user.
                    154:                         */
                    155:                        type = 0;
                    156:                        (void) strcpy(typename, "binary");
                    157:                        if (overbose)
                    158:                            printf("Using %s mode to transfer files.\n",
                    159:                                typename);
                    160:                } else {
                    161:                        if (proxy)
                    162:                                unix_proxy = 0;
                    163:                        else
                    164:                                unix_server = 0;
                    165:                        if (overbose && 
                    166:                            !strncmp(reply_string, "215 TOPS20", 10))
                    167:                                printf(
                    168: "Remember to set tenex mode when transfering binary files from this machine.\n");
                    169:                }
                    170:                verbose = overbose;
                    171: #endif /* unix */
                    172:        }
                    173: }
                    174: 
                    175: struct types {
                    176:        char    *t_name;
                    177:        char    *t_mode;
                    178:        int     t_type;
                    179:        char    *t_arg;
                    180: } types[] = {
                    181:        { "ascii",      "A",    TYPE_A, 0 },
                    182:        { "binary",     "I",    TYPE_I, 0 },
                    183:        { "image",      "I",    TYPE_I, 0 },
                    184:        { "ebcdic",     "E",    TYPE_E, 0 },
                    185:        { "tenex",      "L",    TYPE_L, bytename },
                    186:        0
                    187: };
                    188: 
                    189: /*
                    190:  * Set transfer type.
                    191:  */
                    192: settype(argc, argv)
                    193:        char *argv[];
                    194: {
                    195:        register struct types *p;
                    196:        int comret;
                    197: 
                    198:        if (argc > 2) {
                    199:                char *sep;
                    200: 
                    201:                printf("usage: %s [", argv[0]);
                    202:                sep = " ";
                    203:                for (p = types; p->t_name; p++) {
                    204:                        printf("%s%s", sep, p->t_name);
                    205:                        sep = " | ";
                    206:                }
                    207:                printf(" ]\n");
                    208:                code = -1;
                    209:                return;
                    210:        }
                    211:        if (argc < 2) {
                    212:                printf("Using %s mode to transfer files.\n", typename);
                    213:                code = 0;
                    214:                return;
                    215:        }
                    216:        for (p = types; p->t_name; p++)
                    217:                if (strcmp(argv[1], p->t_name) == 0)
                    218:                        break;
                    219:        if (p->t_name == 0) {
                    220:                printf("%s: unknown mode\n", argv[1]);
                    221:                code = -1;
                    222:                return;
                    223:        }
                    224:        if ((p->t_arg != NULL) && (*(p->t_arg) != '\0'))
                    225:                comret = command ("TYPE %s %s", p->t_mode, p->t_arg);
                    226:        else
                    227:                comret = command("TYPE %s", p->t_mode);
                    228:        if (comret == COMPLETE) {
                    229:                (void) strcpy(typename, p->t_name);
                    230:                curtype = type = p->t_type;
                    231:        }
                    232: }
                    233: 
                    234: /*
                    235:  * Internal form of settype; changes current type in use with server
                    236:  * without changing our notion of the type for data transfers.
                    237:  * Used to change to and from ascii for listings.
                    238:  */
                    239: changetype(newtype, show)
                    240:        int newtype, show;
                    241: {
                    242:        register struct types *p;
                    243:        int comret, oldverbose = verbose;
                    244: 
                    245:        if (newtype == 0)
                    246:                newtype = TYPE_I;
                    247:        if (newtype == curtype)
                    248:                return;
                    249:        if (debug == 0 && show == 0)
                    250:                verbose = 0;
                    251:        for (p = types; p->t_name; p++)
                    252:                if (newtype == p->t_type)
                    253:                        break;
                    254:        if (p->t_name == 0) {
                    255:                printf("ftp: internal error: unknown type %d\n", newtype);
                    256:                return;
                    257:        }
                    258:        if (newtype == TYPE_L && bytename[0] != '\0')
                    259:                comret = command("TYPE %s %s", p->t_mode, bytename);
                    260:        else
                    261:                comret = command("TYPE %s", p->t_mode);
                    262:        if (comret == COMPLETE)
                    263:                curtype = newtype;
                    264:        verbose = oldverbose;
                    265: }
                    266: 
                    267: char *stype[] = {
                    268:        "type",
                    269:        "",
                    270:        0
                    271: };
                    272: 
                    273: /*
                    274:  * Set binary transfer type.
                    275:  */
                    276: /*VARARGS*/
                    277: setbinary()
                    278: {
                    279:        stype[1] = "binary";
                    280:        settype(2, stype);
                    281: }
                    282: 
                    283: /*
                    284:  * Set ascii transfer type.
                    285:  */
                    286: /*VARARGS*/
                    287: setascii()
                    288: {
                    289:        stype[1] = "ascii";
                    290:        settype(2, stype);
                    291: }
                    292: 
                    293: /*
                    294:  * Set tenex transfer type.
                    295:  */
                    296: /*VARARGS*/
                    297: settenex()
                    298: {
                    299:        stype[1] = "tenex";
                    300:        settype(2, stype);
                    301: }
                    302: 
                    303: /*
                    304:  * Set file transfer mode.
                    305:  */
                    306: /*ARGSUSED*/
                    307: setmode(argc, argv)
                    308:        char *argv[];
                    309: {
                    310: 
                    311:        printf("We only support %s mode, sorry.\n", modename);
                    312:        code = -1;
                    313: }
                    314: 
                    315: /*
                    316:  * Set file transfer format.
                    317:  */
                    318: /*ARGSUSED*/
                    319: setform(argc, argv)
                    320:        char *argv[];
                    321: {
                    322: 
                    323:        printf("We only support %s format, sorry.\n", formname);
                    324:        code = -1;
                    325: }
                    326: 
                    327: /*
                    328:  * Set file transfer structure.
                    329:  */
                    330: /*ARGSUSED*/
                    331: setstruct(argc, argv)
                    332:        char *argv[];
                    333: {
                    334: 
                    335:        printf("We only support %s structure, sorry.\n", structname);
                    336:        code = -1;
                    337: }
                    338: 
                    339: /*
                    340:  * Send a single file.
                    341:  */
                    342: put(argc, argv)
                    343:        int argc;
                    344:        char *argv[];
                    345: {
                    346:        char *cmd;
                    347:        int loc = 0;
                    348:        char *oldargv1, *oldargv2;
                    349: 
                    350:        if (argc == 2) {
                    351:                argc++;
                    352:                argv[2] = argv[1];
                    353:                loc++;
                    354:        }
                    355:        if (argc < 2) {
                    356:                (void) strcat(line, " ");
                    357:                printf("(local-file) ");
                    358:                (void) gets(&line[strlen(line)]);
                    359:                makeargv();
                    360:                argc = margc;
                    361:                argv = margv;
                    362:        }
                    363:        if (argc < 2) {
                    364: usage:
                    365:                printf("usage:%s local-file remote-file\n", argv[0]);
                    366:                code = -1;
                    367:                return;
                    368:        }
                    369:        if (argc < 3) {
                    370:                (void) strcat(line, " ");
                    371:                printf("(remote-file) ");
                    372:                (void) gets(&line[strlen(line)]);
                    373:                makeargv();
                    374:                argc = margc;
                    375:                argv = margv;
                    376:        }
                    377:        if (argc < 3) 
                    378:                goto usage;
                    379:        oldargv1 = argv[1];
                    380:        oldargv2 = argv[2];
                    381:        if (!globulize(&argv[1])) {
                    382:                code = -1;
                    383:                return;
                    384:        }
                    385:        /*
                    386:         * If "globulize" modifies argv[1], and argv[2] is a copy of
                    387:         * the old argv[1], make it a copy of the new argv[1].
                    388:         */
                    389:        if (argv[1] != oldargv1 && argv[2] == oldargv1) {
                    390:                argv[2] = argv[1];
                    391:        }
                    392:        cmd = (argv[0][0] == 'a') ? "APPE" : ((sunique) ? "STOU" : "STOR");
                    393:        if (loc && ntflag) {
                    394:                argv[2] = dotrans(argv[2]);
                    395:        }
                    396:        if (loc && mapflag) {
                    397:                argv[2] = domap(argv[2]);
                    398:        }
                    399:        sendrequest(cmd, argv[1], argv[2],
                    400:            argv[1] != oldargv1 || argv[2] != oldargv2);
                    401: }
                    402: 
                    403: /*
                    404:  * Send multiple files.
                    405:  */
                    406: mput(argc, argv)
                    407:        int argc;
                    408:        char **argv;
                    409: {
                    410:        extern jmp_buf jabort;
                    411:        register int i;
                    412:        sig_t oldintr;
                    413:        int ointer;
                    414:        char *tp;
                    415:        void mabort();
                    416: 
                    417:        if (argc < 2) {
                    418:                (void) strcat(line, " ");
                    419:                printf("(local-files) ");
                    420:                (void) gets(&line[strlen(line)]);
                    421:                makeargv();
                    422:                argc = margc;
                    423:                argv = margv;
                    424:        }
                    425:        if (argc < 2) {
                    426:                printf("usage:%s local-files\n", argv[0]);
                    427:                code = -1;
                    428:                return;
                    429:        }
                    430:        mname = argv[0];
                    431:        mflag = 1;
                    432:        oldintr = signal(SIGINT, mabort);
                    433:        (void) setjmp(jabort);
                    434:        if (proxy) {
                    435:                char *cp, *tp2, tmpbuf[MAXPATHLEN];
                    436: 
                    437:                while ((cp = remglob(argv,0)) != NULL) {
                    438:                        if (*cp == 0) {
                    439:                                mflag = 0;
                    440:                                continue;
                    441:                        }
                    442:                        if (mflag && confirm(argv[0], cp)) {
                    443:                                tp = cp;
                    444:                                if (mcase) {
                    445:                                        while (*tp && !islower(*tp)) {
                    446:                                                tp++;
                    447:                                        }
                    448:                                        if (!*tp) {
                    449:                                                tp = cp;
                    450:                                                tp2 = tmpbuf;
                    451:                                                while ((*tp2 = *tp) != NULL) {
                    452:                                                     if (isupper(*tp2)) {
                    453:                                                        *tp2 = 'a' + *tp2 - 'A';
                    454:                                                     }
                    455:                                                     tp++;
                    456:                                                     tp2++;
                    457:                                                }
                    458:                                        }
                    459:                                        tp = tmpbuf;
                    460:                                }
                    461:                                if (ntflag) {
                    462:                                        tp = dotrans(tp);
                    463:                                }
                    464:                                if (mapflag) {
                    465:                                        tp = domap(tp);
                    466:                                }
                    467:                                sendrequest((sunique) ? "STOU" : "STOR",
                    468:                                    cp, tp, cp != tp || !interactive);
                    469:                                if (!mflag && fromatty) {
                    470:                                        ointer = interactive;
                    471:                                        interactive = 1;
                    472:                                        if (confirm("Continue with","mput")) {
                    473:                                                mflag++;
                    474:                                        }
                    475:                                        interactive = ointer;
                    476:                                }
                    477:                        }
                    478:                }
                    479:                (void) signal(SIGINT, oldintr);
                    480:                mflag = 0;
                    481:                return;
                    482:        }
                    483:        for (i = 1; i < argc; i++) {
                    484:                register char **cpp, **gargs;
                    485: 
                    486:                if (!doglob) {
                    487:                        if (mflag && confirm(argv[0], argv[i])) {
                    488:                                tp = (ntflag) ? dotrans(argv[i]) : argv[i];
                    489:                                tp = (mapflag) ? domap(tp) : tp;
                    490:                                sendrequest((sunique) ? "STOU" : "STOR",
                    491:                                    argv[i], tp, tp != argv[i] || !interactive);
                    492:                                if (!mflag && fromatty) {
                    493:                                        ointer = interactive;
                    494:                                        interactive = 1;
                    495:                                        if (confirm("Continue with","mput")) {
                    496:                                                mflag++;
                    497:                                        }
                    498:                                        interactive = ointer;
                    499:                                }
                    500:                        }
                    501:                        continue;
                    502:                }
                    503:                gargs = glob(argv[i]);
                    504:                if (globerr != NULL) {
                    505:                        printf("%s\n", globerr);
                    506:                        if (gargs) {
                    507:                                blkfree(gargs);
                    508:                                free((char *)gargs);
                    509:                        }
                    510:                        continue;
                    511:                }
                    512:                for (cpp = gargs; cpp && *cpp != NULL; cpp++) {
                    513:                        if (mflag && confirm(argv[0], *cpp)) {
                    514:                                tp = (ntflag) ? dotrans(*cpp) : *cpp;
                    515:                                tp = (mapflag) ? domap(tp) : tp;
                    516:                                sendrequest((sunique) ? "STOU" : "STOR",
                    517:                                    *cpp, tp, *cpp != tp || !interactive);
                    518:                                if (!mflag && fromatty) {
                    519:                                        ointer = interactive;
                    520:                                        interactive = 1;
                    521:                                        if (confirm("Continue with","mput")) {
                    522:                                                mflag++;
                    523:                                        }
                    524:                                        interactive = ointer;
                    525:                                }
                    526:                        }
                    527:                }
                    528:                if (gargs != NULL) {
                    529:                        blkfree(gargs);
                    530:                        free((char *)gargs);
                    531:                }
                    532:        }
                    533:        (void) signal(SIGINT, oldintr);
                    534:        mflag = 0;
                    535: }
                    536: 
                    537: reget(argc, argv)
                    538:        char *argv[];
                    539: {
                    540:        (void) getit(argc, argv, 1, "r+w");
                    541: }
                    542: 
                    543: get(argc, argv)
                    544:        char *argv[];
                    545: {
                    546:        (void) getit(argc, argv, 0, restart_point ? "r+w" : "w" );
                    547: }
                    548: 
                    549: /*
                    550:  * Receive one file.
                    551:  */
                    552: getit(argc, argv, restartit, mode)
                    553:        char *argv[];
                    554:        char *mode;
                    555: {
                    556:        int loc = 0;
                    557:        char *oldargv1, *oldargv2;
                    558: 
                    559:        if (argc == 2) {
                    560:                argc++;
                    561:                argv[2] = argv[1];
                    562:                loc++;
                    563:        }
                    564:        if (argc < 2) {
                    565:                (void) strcat(line, " ");
                    566:                printf("(remote-file) ");
                    567:                (void) gets(&line[strlen(line)]);
                    568:                makeargv();
                    569:                argc = margc;
                    570:                argv = margv;
                    571:        }
                    572:        if (argc < 2) {
                    573: usage:
                    574:                printf("usage: %s remote-file [ local-file ]\n", argv[0]);
                    575:                code = -1;
                    576:                return (0);
                    577:        }
                    578:        if (argc < 3) {
                    579:                (void) strcat(line, " ");
                    580:                printf("(local-file) ");
                    581:                (void) gets(&line[strlen(line)]);
                    582:                makeargv();
                    583:                argc = margc;
                    584:                argv = margv;
                    585:        }
                    586:        if (argc < 3) 
                    587:                goto usage;
                    588:        oldargv1 = argv[1];
                    589:        oldargv2 = argv[2];
                    590:        if (!globulize(&argv[2])) {
                    591:                code = -1;
                    592:                return (0);
                    593:        }
                    594:        if (loc && mcase) {
                    595:                char *tp = argv[1], *tp2, tmpbuf[MAXPATHLEN];
                    596: 
                    597:                while (*tp && !islower(*tp)) {
                    598:                        tp++;
                    599:                }
                    600:                if (!*tp) {
                    601:                        tp = argv[2];
                    602:                        tp2 = tmpbuf;
                    603:                        while ((*tp2 = *tp) != NULL) {
                    604:                                if (isupper(*tp2)) {
                    605:                                        *tp2 = 'a' + *tp2 - 'A';
                    606:                                }
                    607:                                tp++;
                    608:                                tp2++;
                    609:                        }
                    610:                        argv[2] = tmpbuf;
                    611:                }
                    612:        }
                    613:        if (loc && ntflag)
                    614:                argv[2] = dotrans(argv[2]);
                    615:        if (loc && mapflag)
                    616:                argv[2] = domap(argv[2]);
                    617:        if (restartit) {
                    618:                struct stat stbuf;
                    619:                int ret;
                    620: 
                    621:                ret = stat(argv[2], &stbuf);
                    622:                if (restartit == 1) {
                    623:                        if (ret < 0) {
                    624:                                fprintf(stderr, "local: %s: %s\n", argv[2],
                    625:                                        strerror(errno));
                    626:                                return (0);
                    627:                        }
                    628:                        restart_point = stbuf.st_size;
                    629:                } else {
                    630:                        if (ret == 0) {
                    631:                                int overbose;
                    632: 
                    633:                                overbose = verbose;
                    634:                                if (debug == 0)
                    635:                                        verbose = -1;
                    636:                                if (command("MDTM %s", argv[1]) == COMPLETE) {
                    637:                                        int yy, mo, day, hour, min, sec;
                    638:                                        struct tm *tm;
                    639:                                        verbose = overbose;
                    640:                                        sscanf(reply_string,
                    641:                                            "%*s %04d%02d%02d%02d%02d%02d",
                    642:                                            &yy, &mo, &day, &hour, &min, &sec);
                    643:                                        tm = gmtime(&stbuf.st_mtime);
                    644:                                        tm->tm_mon++;
                    645:                                        if (tm->tm_year > yy%100)
                    646:                                                return (1);
                    647:                                        else if (tm->tm_year == yy%100) {
                    648:                                                if (tm->tm_mon > mo)
                    649:                                                        return (1);
                    650:                                        } else if (tm->tm_mon == mo) {
                    651:                                                if (tm->tm_mday > day)
                    652:                                                        return (1);
                    653:                                        } else if (tm->tm_mday == day) {
                    654:                                                if (tm->tm_hour > hour)
                    655:                                                        return (1);
                    656:                                        } else if (tm->tm_hour == hour) {
                    657:                                                if (tm->tm_min > min)
                    658:                                                        return (1);
                    659:                                        } else if (tm->tm_min == min) {
                    660:                                                if (tm->tm_sec > sec)
                    661:                                                        return (1);
                    662:                                        }
                    663:                                } else {
                    664:                                        printf("%s\n", reply_string);
                    665:                                        verbose = overbose;
                    666:                                        return (0);
                    667:                                }
                    668:                        }
                    669:                }
                    670:        }
                    671: 
                    672:        recvrequest("RETR", argv[2], argv[1], mode,
                    673:            argv[1] != oldargv1 || argv[2] != oldargv2);
                    674:        restart_point = 0;
                    675:        return (0);
                    676: }
                    677: 
                    678: void
                    679: mabort()
                    680: {
                    681:        int ointer;
                    682:        extern jmp_buf jabort;
                    683: 
                    684:        printf("\n");
                    685:        (void) fflush(stdout);
                    686:        if (mflag && fromatty) {
                    687:                ointer = interactive;
                    688:                interactive = 1;
                    689:                if (confirm("Continue with", mname)) {
                    690:                        interactive = ointer;
                    691:                        longjmp(jabort,0);
                    692:                }
                    693:                interactive = ointer;
                    694:        }
                    695:        mflag = 0;
                    696:        longjmp(jabort,0);
                    697: }
                    698: 
                    699: /*
                    700:  * Get multiple files.
                    701:  */
                    702: mget(argc, argv)
                    703:        int argc;
                    704:        char **argv;
                    705: {
                    706:        extern jmp_buf jabort;
                    707:        sig_t oldintr;
                    708:        int ointer;
                    709:        char *cp, *tp, *tp2, tmpbuf[MAXPATHLEN];
                    710:        void mabort();
                    711: 
                    712:        if (argc < 2) {
                    713:                (void) strcat(line, " ");
                    714:                printf("(remote-files) ");
                    715:                (void) gets(&line[strlen(line)]);
                    716:                makeargv();
                    717:                argc = margc;
                    718:                argv = margv;
                    719:        }
                    720:        if (argc < 2) {
                    721:                printf("usage:%s remote-files\n", argv[0]);
                    722:                code = -1;
                    723:                return;
                    724:        }
                    725:        mname = argv[0];
                    726:        mflag = 1;
                    727:        oldintr = signal(SIGINT,mabort);
                    728:        (void) setjmp(jabort);
                    729:        while ((cp = remglob(argv,proxy)) != NULL) {
                    730:                if (*cp == '\0') {
                    731:                        mflag = 0;
                    732:                        continue;
                    733:                }
                    734:                if (mflag && confirm(argv[0], cp)) {
                    735:                        tp = cp;
                    736:                        if (mcase) {
                    737:                                while (*tp && !islower(*tp)) {
                    738:                                        tp++;
                    739:                                }
                    740:                                if (!*tp) {
                    741:                                        tp = cp;
                    742:                                        tp2 = tmpbuf;
                    743:                                        while ((*tp2 = *tp) != NULL) {
                    744:                                                if (isupper(*tp2)) {
                    745:                                                        *tp2 = 'a' + *tp2 - 'A';
                    746:                                                }
                    747:                                                tp++;
                    748:                                                tp2++;
                    749:                                        }
                    750:                                }
                    751:                                tp = tmpbuf;
                    752:                        }
                    753:                        if (ntflag) {
                    754:                                tp = dotrans(tp);
                    755:                        }
                    756:                        if (mapflag) {
                    757:                                tp = domap(tp);
                    758:                        }
                    759:                        recvrequest("RETR", tp, cp, "w",
                    760:                            tp != cp || !interactive);
                    761:                        if (!mflag && fromatty) {
                    762:                                ointer = interactive;
                    763:                                interactive = 1;
                    764:                                if (confirm("Continue with","mget")) {
                    765:                                        mflag++;
                    766:                                }
                    767:                                interactive = ointer;
                    768:                        }
                    769:                }
                    770:        }
                    771:        (void) signal(SIGINT,oldintr);
                    772:        mflag = 0;
                    773: }
                    774: 
                    775: char *
                    776: remglob(argv,doswitch)
                    777:        char *argv[];
                    778:        int doswitch;
                    779: {
                    780:        char temp[16];
                    781:        static char buf[MAXPATHLEN];
                    782:        static FILE *ftemp = NULL;
                    783:        static char **args;
                    784:        int oldverbose, oldhash;
                    785:        char *cp, *mode;
                    786: 
                    787:        if (!mflag) {
                    788:                if (!doglob) {
                    789:                        args = NULL;
                    790:                }
                    791:                else {
                    792:                        if (ftemp) {
                    793:                                (void) fclose(ftemp);
                    794:                                ftemp = NULL;
                    795:                        }
                    796:                }
                    797:                return(NULL);
                    798:        }
                    799:        if (!doglob) {
                    800:                if (args == NULL)
                    801:                        args = argv;
                    802:                if ((cp = *++args) == NULL)
                    803:                        args = NULL;
                    804:                return (cp);
                    805:        }
                    806:        if (ftemp == NULL) {
                    807:                (void) strcpy(temp, _PATH_TMP);
                    808:                (void) mktemp(temp);
                    809:                oldverbose = verbose, verbose = 0;
                    810:                oldhash = hash, hash = 0;
                    811:                if (doswitch) {
                    812:                        pswitch(!proxy);
                    813:                }
                    814:                for (mode = "w"; *++argv != NULL; mode = "a")
                    815:                        recvrequest ("NLST", temp, *argv, mode, 0);
                    816:                if (doswitch) {
                    817:                        pswitch(!proxy);
                    818:                }
                    819:                verbose = oldverbose; hash = oldhash;
                    820:                ftemp = fopen(temp, "r");
                    821:                (void) unlink(temp);
                    822:                if (ftemp == NULL) {
                    823:                        printf("can't find list of remote files, oops\n");
                    824:                        return (NULL);
                    825:                }
                    826:        }
                    827:        if (fgets(buf, sizeof (buf), ftemp) == NULL) {
                    828:                (void) fclose(ftemp), ftemp = NULL;
                    829:                return (NULL);
                    830:        }
                    831:        if ((cp = index(buf, '\n')) != NULL)
                    832:                *cp = '\0';
                    833:        return (buf);
                    834: }
                    835: 
                    836: char *
                    837: onoff(bool)
                    838:        int bool;
                    839: {
                    840: 
                    841:        return (bool ? "on" : "off");
                    842: }
                    843: 
                    844: /*
                    845:  * Show status.
                    846:  */
                    847: /*ARGSUSED*/
                    848: status(argc, argv)
                    849:        char *argv[];
                    850: {
                    851:        int i;
                    852: 
                    853:        if (connected)
                    854:                printf("Connected to %s.\n", hostname);
                    855:        else
                    856:                printf("Not connected.\n");
                    857:        if (!proxy) {
                    858:                pswitch(1);
                    859:                if (connected) {
                    860:                        printf("Connected for proxy commands to %s.\n", hostname);
                    861:                }
                    862:                else {
                    863:                        printf("No proxy connection.\n");
                    864:                }
                    865:                pswitch(0);
                    866:        }
                    867:        printf("Mode: %s; Type: %s; Form: %s; Structure: %s\n",
                    868:                modename, typename, formname, structname);
                    869:        printf("Verbose: %s; Bell: %s; Prompting: %s; Globbing: %s\n", 
                    870:                onoff(verbose), onoff(bell), onoff(interactive),
                    871:                onoff(doglob));
                    872:        printf("Store unique: %s; Receive unique: %s\n", onoff(sunique),
                    873:                onoff(runique));
                    874:        printf("Case: %s; CR stripping: %s\n",onoff(mcase),onoff(crflag));
                    875:        if (ntflag) {
                    876:                printf("Ntrans: (in) %s (out) %s\n", ntin,ntout);
                    877:        }
                    878:        else {
                    879:                printf("Ntrans: off\n");
                    880:        }
                    881:        if (mapflag) {
                    882:                printf("Nmap: (in) %s (out) %s\n", mapin, mapout);
                    883:        }
                    884:        else {
                    885:                printf("Nmap: off\n");
                    886:        }
                    887:        printf("Hash mark printing: %s; Use of PORT cmds: %s\n",
                    888:                onoff(hash), onoff(sendport));
                    889:        if (macnum > 0) {
                    890:                printf("Macros:\n");
                    891:                for (i=0; i<macnum; i++) {
                    892:                        printf("\t%s\n",macros[i].mac_name);
                    893:                }
                    894:        }
                    895:        code = 0;
                    896: }
                    897: 
                    898: /*
                    899:  * Set beep on cmd completed mode.
                    900:  */
                    901: /*VARARGS*/
                    902: setbell()
                    903: {
                    904: 
                    905:        bell = !bell;
                    906:        printf("Bell mode %s.\n", onoff(bell));
                    907:        code = bell;
                    908: }
                    909: 
                    910: /*
                    911:  * Turn on packet tracing.
                    912:  */
                    913: /*VARARGS*/
                    914: settrace()
                    915: {
                    916: 
                    917:        trace = !trace;
                    918:        printf("Packet tracing %s.\n", onoff(trace));
                    919:        code = trace;
                    920: }
                    921: 
                    922: /*
                    923:  * Toggle hash mark printing during transfers.
                    924:  */
                    925: /*VARARGS*/
                    926: sethash()
                    927: {
                    928: 
                    929:        hash = !hash;
                    930:        printf("Hash mark printing %s", onoff(hash));
                    931:        code = hash;
                    932:        if (hash)
                    933:                printf(" (%d bytes/hash mark)", 1024);
                    934:        printf(".\n");
                    935: }
                    936: 
                    937: /*
                    938:  * Turn on printing of server echo's.
                    939:  */
                    940: /*VARARGS*/
                    941: setverbose()
                    942: {
                    943: 
                    944:        verbose = !verbose;
                    945:        printf("Verbose mode %s.\n", onoff(verbose));
                    946:        code = verbose;
                    947: }
                    948: 
                    949: /*
                    950:  * Toggle PORT cmd use before each data connection.
                    951:  */
                    952: /*VARARGS*/
                    953: setport()
                    954: {
                    955: 
                    956:        sendport = !sendport;
                    957:        printf("Use of PORT cmds %s.\n", onoff(sendport));
                    958:        code = sendport;
                    959: }
                    960: 
                    961: /*
                    962:  * Turn on interactive prompting
                    963:  * during mget, mput, and mdelete.
                    964:  */
                    965: /*VARARGS*/
                    966: setprompt()
                    967: {
                    968: 
                    969:        interactive = !interactive;
                    970:        printf("Interactive mode %s.\n", onoff(interactive));
                    971:        code = interactive;
                    972: }
                    973: 
                    974: /*
                    975:  * Toggle metacharacter interpretation
                    976:  * on local file names.
                    977:  */
                    978: /*VARARGS*/
                    979: setglob()
                    980: {
                    981:        
                    982:        doglob = !doglob;
                    983:        printf("Globbing %s.\n", onoff(doglob));
                    984:        code = doglob;
                    985: }
                    986: 
                    987: /*
                    988:  * Set debugging mode on/off and/or
                    989:  * set level of debugging.
                    990:  */
                    991: /*VARARGS*/
                    992: setdebug(argc, argv)
                    993:        char *argv[];
                    994: {
                    995:        int val;
                    996: 
                    997:        if (argc > 1) {
                    998:                val = atoi(argv[1]);
                    999:                if (val < 0) {
                   1000:                        printf("%s: bad debugging value.\n", argv[1]);
                   1001:                        code = -1;
                   1002:                        return;
                   1003:                }
                   1004:        } else
                   1005:                val = !debug;
                   1006:        debug = val;
                   1007:        if (debug)
                   1008:                options |= SO_DEBUG;
                   1009:        else
                   1010:                options &= ~SO_DEBUG;
                   1011:        printf("Debugging %s (debug=%d).\n", onoff(debug), debug);
                   1012:        code = debug > 0;
                   1013: }
                   1014: 
                   1015: /*
                   1016:  * Set current working directory
                   1017:  * on remote machine.
                   1018:  */
                   1019: cd(argc, argv)
                   1020:        char *argv[];
                   1021: {
                   1022: 
                   1023:        if (argc < 2) {
                   1024:                (void) strcat(line, " ");
                   1025:                printf("(remote-directory) ");
                   1026:                (void) gets(&line[strlen(line)]);
                   1027:                makeargv();
                   1028:                argc = margc;
                   1029:                argv = margv;
                   1030:        }
                   1031:        if (argc < 2) {
                   1032:                printf("usage:%s remote-directory\n", argv[0]);
                   1033:                code = -1;
                   1034:                return;
                   1035:        }
                   1036:        if (command("CWD %s", argv[1]) == ERROR && code == 500) {
                   1037:                if (verbose)
                   1038:                        printf("CWD command not recognized, trying XCWD\n");
                   1039:                (void) command("XCWD %s", argv[1]);
                   1040:        }
                   1041: }
                   1042: 
                   1043: /*
                   1044:  * Set current working directory
                   1045:  * on local machine.
                   1046:  */
                   1047: lcd(argc, argv)
                   1048:        char *argv[];
                   1049: {
                   1050:        char buf[MAXPATHLEN];
                   1051:        extern char *getwd();
                   1052: 
                   1053:        if (argc < 2)
                   1054:                argc++, argv[1] = home;
                   1055:        if (argc != 2) {
                   1056:                printf("usage:%s local-directory\n", argv[0]);
                   1057:                code = -1;
                   1058:                return;
                   1059:        }
                   1060:        if (!globulize(&argv[1])) {
                   1061:                code = -1;
                   1062:                return;
                   1063:        }
                   1064:        if (chdir(argv[1]) < 0) {
                   1065:                fprintf(stderr, "local: %s: %s\n", argv[1], strerror(errno));
                   1066:                code = -1;
                   1067:                return;
                   1068:        }
                   1069:        printf("Local directory now %s\n", getwd(buf));
                   1070:        code = 0;
                   1071: }
                   1072: 
                   1073: /*
                   1074:  * Delete a single file.
                   1075:  */
                   1076: delete(argc, argv)
                   1077:        char *argv[];
                   1078: {
                   1079: 
                   1080:        if (argc < 2) {
                   1081:                (void) strcat(line, " ");
                   1082:                printf("(remote-file) ");
                   1083:                (void) gets(&line[strlen(line)]);
                   1084:                makeargv();
                   1085:                argc = margc;
                   1086:                argv = margv;
                   1087:        }
                   1088:        if (argc < 2) {
                   1089:                printf("usage:%s remote-file\n", argv[0]);
                   1090:                code = -1;
                   1091:                return;
                   1092:        }
                   1093:        (void) command("DELE %s", argv[1]);
                   1094: }
                   1095: 
                   1096: /*
                   1097:  * Delete multiple files.
                   1098:  */
                   1099: mdelete(argc, argv)
                   1100:        int argc;
                   1101:        char **argv;
                   1102: {
                   1103:        extern jmp_buf jabort;
                   1104:        sig_t oldintr;
                   1105:        int ointer;
                   1106:        char *cp;
                   1107:        void mabort();
                   1108: 
                   1109:        if (argc < 2) {
                   1110:                (void) strcat(line, " ");
                   1111:                printf("(remote-files) ");
                   1112:                (void) gets(&line[strlen(line)]);
                   1113:                makeargv();
                   1114:                argc = margc;
                   1115:                argv = margv;
                   1116:        }
                   1117:        if (argc < 2) {
                   1118:                printf("usage:%s remote-files\n", argv[0]);
                   1119:                code = -1;
                   1120:                return;
                   1121:        }
                   1122:        mname = argv[0];
                   1123:        mflag = 1;
                   1124:        oldintr = signal(SIGINT, mabort);
                   1125:        (void) setjmp(jabort);
                   1126:        while ((cp = remglob(argv,0)) != NULL) {
                   1127:                if (*cp == '\0') {
                   1128:                        mflag = 0;
                   1129:                        continue;
                   1130:                }
                   1131:                if (mflag && confirm(argv[0], cp)) {
                   1132:                        (void) command("DELE %s", cp);
                   1133:                        if (!mflag && fromatty) {
                   1134:                                ointer = interactive;
                   1135:                                interactive = 1;
                   1136:                                if (confirm("Continue with", "mdelete")) {
                   1137:                                        mflag++;
                   1138:                                }
                   1139:                                interactive = ointer;
                   1140:                        }
                   1141:                }
                   1142:        }
                   1143:        (void) signal(SIGINT, oldintr);
                   1144:        mflag = 0;
                   1145: }
                   1146: 
                   1147: /*
                   1148:  * Rename a remote file.
                   1149:  */
                   1150: renamefile(argc, argv)
                   1151:        char *argv[];
                   1152: {
                   1153: 
                   1154:        if (argc < 2) {
                   1155:                (void) strcat(line, " ");
                   1156:                printf("(from-name) ");
                   1157:                (void) gets(&line[strlen(line)]);
                   1158:                makeargv();
                   1159:                argc = margc;
                   1160:                argv = margv;
                   1161:        }
                   1162:        if (argc < 2) {
                   1163: usage:
                   1164:                printf("%s from-name to-name\n", argv[0]);
                   1165:                code = -1;
                   1166:                return;
                   1167:        }
                   1168:        if (argc < 3) {
                   1169:                (void) strcat(line, " ");
                   1170:                printf("(to-name) ");
                   1171:                (void) gets(&line[strlen(line)]);
                   1172:                makeargv();
                   1173:                argc = margc;
                   1174:                argv = margv;
                   1175:        }
                   1176:        if (argc < 3) 
                   1177:                goto usage;
                   1178:        if (command("RNFR %s", argv[1]) == CONTINUE)
                   1179:                (void) command("RNTO %s", argv[2]);
                   1180: }
                   1181: 
                   1182: /*
                   1183:  * Get a directory listing
                   1184:  * of remote files.
                   1185:  */
                   1186: ls(argc, argv)
                   1187:        char *argv[];
                   1188: {
                   1189:        char *cmd;
                   1190: 
                   1191:        if (argc < 2)
                   1192:                argc++, argv[1] = NULL;
                   1193:        if (argc < 3)
                   1194:                argc++, argv[2] = "-";
                   1195:        if (argc > 3) {
                   1196:                printf("usage: %s remote-directory local-file\n", argv[0]);
                   1197:                code = -1;
                   1198:                return;
                   1199:        }
                   1200:        cmd = argv[0][0] == 'n' ? "NLST" : "LIST";
                   1201:        if (strcmp(argv[2], "-") && !globulize(&argv[2])) {
                   1202:                code = -1;
                   1203:                return;
                   1204:        }
                   1205:        if (strcmp(argv[2], "-") && *argv[2] != '|')
                   1206:                if (!globulize(&argv[2]) || !confirm("output to local-file:", argv[2])) {
                   1207:                        code = -1;
                   1208:                        return;
                   1209:        }
                   1210:        recvrequest(cmd, argv[2], argv[1], "w", 0);
                   1211: }
                   1212: 
                   1213: /*
                   1214:  * Get a directory listing
                   1215:  * of multiple remote files.
                   1216:  */
                   1217: mls(argc, argv)
                   1218:        int argc;
                   1219:        char **argv;
                   1220: {
                   1221:        extern jmp_buf jabort;
                   1222:        sig_t oldintr;
                   1223:        int ointer, i;
                   1224:        char *cmd, mode[1], *dest;
                   1225:        void mabort();
                   1226: 
                   1227:        if (argc < 2) {
                   1228:                (void) strcat(line, " ");
                   1229:                printf("(remote-files) ");
                   1230:                (void) gets(&line[strlen(line)]);
                   1231:                makeargv();
                   1232:                argc = margc;
                   1233:                argv = margv;
                   1234:        }
                   1235:        if (argc < 3) {
                   1236:                (void) strcat(line, " ");
                   1237:                printf("(local-file) ");
                   1238:                (void) gets(&line[strlen(line)]);
                   1239:                makeargv();
                   1240:                argc = margc;
                   1241:                argv = margv;
                   1242:        }
                   1243:        if (argc < 3) {
                   1244:                printf("usage:%s remote-files local-file\n", argv[0]);
                   1245:                code = -1;
                   1246:                return;
                   1247:        }
                   1248:        dest = argv[argc - 1];
                   1249:        argv[argc - 1] = NULL;
                   1250:        if (strcmp(dest, "-") && *dest != '|')
                   1251:                if (!globulize(&dest) || !confirm("output to local-file:", dest)) {
                   1252:                        code = -1;
                   1253:                        return;
                   1254:        }
                   1255:        cmd = argv[0][1] == 'l' ? "NLST" : "LIST";
                   1256:        mname = argv[0];
                   1257:        mflag = 1;
                   1258:        oldintr = signal(SIGINT, mabort);
                   1259:        (void) setjmp(jabort);
                   1260:        for (i = 1; mflag && i < argc-1; ++i) {
                   1261:                *mode = (i == 1) ? 'w' : 'a';
                   1262:                recvrequest(cmd, dest, argv[i], mode, 0);
                   1263:                if (!mflag && fromatty) {
                   1264:                        ointer = interactive;
                   1265:                        interactive = 1;
                   1266:                        if (confirm("Continue with", argv[0])) {
                   1267:                                mflag ++;
                   1268:                        }
                   1269:                        interactive = ointer;
                   1270:                }
                   1271:        }
                   1272:        (void) signal(SIGINT, oldintr);
                   1273:        mflag = 0;
                   1274: }
                   1275: 
                   1276: /*
                   1277:  * Do a shell escape
                   1278:  */
                   1279: /*ARGSUSED*/
                   1280: shell(argc, argv)
                   1281:        int argc;
                   1282:        char **argv;
                   1283: {
                   1284:        int pid;
                   1285:        sig_t old1, old2;
                   1286:        char shellnam[40], *shell, *namep; 
                   1287:        union wait status;
                   1288: 
                   1289:        old1 = signal (SIGINT, SIG_IGN);
                   1290:        old2 = signal (SIGQUIT, SIG_IGN);
                   1291:        if ((pid = fork()) == 0) {
                   1292:                for (pid = 3; pid < 20; pid++)
                   1293:                        (void) close(pid);
                   1294:                (void) signal(SIGINT, SIG_DFL);
                   1295:                (void) signal(SIGQUIT, SIG_DFL);
                   1296:                shell = getenv("SHELL");
                   1297:                if (shell == NULL)
                   1298:                        shell = _PATH_BSHELL;
                   1299:                namep = rindex(shell,'/');
                   1300:                if (namep == NULL)
                   1301:                        namep = shell;
                   1302:                (void) strcpy(shellnam,"-");
                   1303:                (void) strcat(shellnam, ++namep);
                   1304:                if (strcmp(namep, "sh") != 0)
                   1305:                        shellnam[0] = '+';
                   1306:                if (debug) {
                   1307:                        printf ("%s\n", shell);
                   1308:                        (void) fflush (stdout);
                   1309:                }
                   1310:                if (argc > 1) {
                   1311:                        execl(shell,shellnam,"-c",altarg,(char *)0);
                   1312:                }
                   1313:                else {
                   1314:                        execl(shell,shellnam,(char *)0);
                   1315:                }
                   1316:                perror(shell);
                   1317:                code = -1;
                   1318:                exit(1);
                   1319:                }
                   1320:        if (pid > 0)
                   1321:                while (wait(&status) != pid)
                   1322:                        ;
                   1323:        (void) signal(SIGINT, old1);
                   1324:        (void) signal(SIGQUIT, old2);
                   1325:        if (pid == -1) {
                   1326:                perror("Try again later");
                   1327:                code = -1;
                   1328:        }
                   1329:        else {
                   1330:                code = 0;
                   1331:        }
                   1332:        return (0);
                   1333: }
                   1334: 
                   1335: /*
                   1336:  * Send new user information (re-login)
                   1337:  */
                   1338: user(argc, argv)
                   1339:        int argc;
                   1340:        char **argv;
                   1341: {
                   1342:        char acct[80], *getpass();
                   1343:        int n, aflag = 0;
                   1344: 
                   1345:        if (argc < 2) {
                   1346:                (void) strcat(line, " ");
                   1347:                printf("(username) ");
                   1348:                (void) gets(&line[strlen(line)]);
                   1349:                makeargv();
                   1350:                argc = margc;
                   1351:                argv = margv;
                   1352:        }
                   1353:        if (argc > 4) {
                   1354:                printf("usage: %s username [password] [account]\n", argv[0]);
                   1355:                code = -1;
                   1356:                return (0);
                   1357:        }
                   1358:        n = command("USER %s", argv[1]);
                   1359:        if (n == CONTINUE) {
                   1360:                if (argc < 3 )
                   1361:                        argv[2] = getpass("Password: "), argc++;
                   1362:                n = command("PASS %s", argv[2]);
                   1363:        }
                   1364:        if (n == CONTINUE) {
                   1365:                if (argc < 4) {
                   1366:                        printf("Account: "); (void) fflush(stdout);
                   1367:                        (void) fgets(acct, sizeof(acct) - 1, stdin);
                   1368:                        acct[strlen(acct) - 1] = '\0';
                   1369:                        argv[3] = acct; argc++;
                   1370:                }
                   1371:                n = command("ACCT %s", argv[3]);
                   1372:                aflag++;
                   1373:        }
                   1374:        if (n != COMPLETE) {
                   1375:                fprintf(stdout, "Login failed.\n");
                   1376:                return (0);
                   1377:        }
                   1378:        if (!aflag && argc == 4) {
                   1379:                (void) command("ACCT %s", argv[3]);
                   1380:        }
                   1381:        return (1);
                   1382: }
                   1383: 
                   1384: /*
                   1385:  * Print working directory.
                   1386:  */
                   1387: /*VARARGS*/
                   1388: pwd()
                   1389: {
                   1390:        int oldverbose = verbose;
                   1391: 
                   1392:        /*
                   1393:         * If we aren't verbose, this doesn't do anything!
                   1394:         */
                   1395:        verbose = 1;
                   1396:        if (command("PWD") == ERROR && code == 500) {
                   1397:                printf("PWD command not recognized, trying XPWD\n");
                   1398:                (void) command("XPWD");
                   1399:        }
                   1400:        verbose = oldverbose;
                   1401: }
                   1402: 
                   1403: /*
                   1404:  * Make a directory.
                   1405:  */
                   1406: makedir(argc, argv)
                   1407:        char *argv[];
                   1408: {
                   1409: 
                   1410:        if (argc < 2) {
                   1411:                (void) strcat(line, " ");
                   1412:                printf("(directory-name) ");
                   1413:                (void) gets(&line[strlen(line)]);
                   1414:                makeargv();
                   1415:                argc = margc;
                   1416:                argv = margv;
                   1417:        }
                   1418:        if (argc < 2) {
                   1419:                printf("usage: %s directory-name\n", argv[0]);
                   1420:                code = -1;
                   1421:                return;
                   1422:        }
                   1423:        if (command("MKD %s", argv[1]) == ERROR && code == 500) {
                   1424:                if (verbose)
                   1425:                        printf("MKD command not recognized, trying XMKD\n");
                   1426:                (void) command("XMKD %s", argv[1]);
                   1427:        }
                   1428: }
                   1429: 
                   1430: /*
                   1431:  * Remove a directory.
                   1432:  */
                   1433: removedir(argc, argv)
                   1434:        char *argv[];
                   1435: {
                   1436: 
                   1437:        if (argc < 2) {
                   1438:                (void) strcat(line, " ");
                   1439:                printf("(directory-name) ");
                   1440:                (void) gets(&line[strlen(line)]);
                   1441:                makeargv();
                   1442:                argc = margc;
                   1443:                argv = margv;
                   1444:        }
                   1445:        if (argc < 2) {
                   1446:                printf("usage: %s directory-name\n", argv[0]);
                   1447:                code = -1;
                   1448:                return;
                   1449:        }
                   1450:        if (command("RMD %s", argv[1]) == ERROR && code == 500) {
                   1451:                if (verbose)
                   1452:                        printf("RMD command not recognized, trying XRMD\n");
                   1453:                (void) command("XRMD %s", argv[1]);
                   1454:        }
                   1455: }
                   1456: 
                   1457: /*
                   1458:  * Send a line, verbatim, to the remote machine.
                   1459:  */
                   1460: quote(argc, argv)
                   1461:        char *argv[];
                   1462: {
                   1463:        int i;
                   1464:        char buf[BUFSIZ];
                   1465: 
                   1466:        if (argc < 2) {
                   1467:                (void) strcat(line, " ");
                   1468:                printf("(command line to send) ");
                   1469:                (void) gets(&line[strlen(line)]);
                   1470:                makeargv();
                   1471:                argc = margc;
                   1472:                argv = margv;
                   1473:        }
                   1474:        if (argc < 2) {
                   1475:                printf("usage: %s line-to-send\n", argv[0]);
                   1476:                code = -1;
                   1477:                return;
                   1478:        }
                   1479:        (void) strcpy(buf, argv[1]);
                   1480:        for (i = 2; i < argc; i++) {
                   1481:                (void) strcat(buf, " ");
                   1482:                (void) strcat(buf, argv[i]);
                   1483:        }
                   1484:        if (command(buf) == PRELIM) {
                   1485:                while (getreply(0) == PRELIM);
                   1486:        }
                   1487: }
                   1488: 
                   1489: /*
                   1490:  * Send a SITE command to the remote machine.  The line
                   1491:  * is sent almost verbatim to the remote machine, the
                   1492:  * first argument is changed to SITE.
                   1493:  */
                   1494: 
                   1495: site(argc, argv)
                   1496:        char *argv[];
                   1497: {
                   1498:        int i;
                   1499:        char buf[BUFSIZ];
                   1500: 
                   1501:        if (argc < 2) {
                   1502:                (void) strcat(line, " ");
                   1503:                printf("(arguments to SITE command) ");
                   1504:                (void) gets(&line[strlen(line)]);
                   1505:                makeargv();
                   1506:                argc = margc;
                   1507:                argv = margv;
                   1508:        }
                   1509:        if (argc < 2) {
                   1510:                printf("usage: %s line-to-send\n", argv[0]);
                   1511:                code = -1;
                   1512:                return;
                   1513:        }
                   1514:        (void) strcpy(buf, "SITE ");
                   1515:        (void) strcat(buf, argv[1]);
                   1516:        for (i = 2; i < argc; i++) {
                   1517:                (void) strcat(buf, " ");
                   1518:                (void) strcat(buf, argv[i]);
                   1519:        }
                   1520:        if (command(buf) == PRELIM) {
                   1521:                while (getreply(0) == PRELIM);
                   1522:        }
                   1523: }
                   1524: 
                   1525: do_chmod(argc, argv)
                   1526:        char *argv[];
                   1527: {
                   1528:        if (argc == 2) {
                   1529:                printf("usage: %s mode file-name\n", argv[0]);
                   1530:                code = -1;
                   1531:                return;
                   1532:        }
                   1533:        if (argc < 3) {
                   1534:                (void) strcat(line, " ");
                   1535:                printf("(mode and file-name) ");
                   1536:                (void) gets(&line[strlen(line)]);
                   1537:                makeargv();
                   1538:                argc = margc;
                   1539:                argv = margv;
                   1540:        }
                   1541:        if (argc != 3) {
                   1542:                printf("usage: %s mode file-name\n", argv[0]);
                   1543:                code = -1;
                   1544:                return;
                   1545:        }
                   1546:        (void)command("SITE CHMOD %s %s", argv[1], argv[2]);
                   1547: }
                   1548: 
                   1549: do_umask(argc, argv)
                   1550:        char *argv[];
                   1551: {
                   1552:        int oldverbose = verbose;
                   1553: 
                   1554:        verbose = 1;
                   1555:        (void) command(argc == 1 ? "SITE UMASK" : "SITE UMASK %s", argv[1]);
                   1556:        verbose = oldverbose;
                   1557: }
                   1558: 
                   1559: idle(argc, argv)
                   1560:        char *argv[];
                   1561: {
                   1562:        int oldverbose = verbose;
                   1563: 
                   1564:        verbose = 1;
                   1565:        (void) command(argc == 1 ? "SITE IDLE" : "SITE IDLE %s", argv[1]);
                   1566:        verbose = oldverbose;
                   1567: }
                   1568: 
                   1569: /*
                   1570:  * Ask the other side for help.
                   1571:  */
                   1572: rmthelp(argc, argv)
                   1573:        char *argv[];
                   1574: {
                   1575:        int oldverbose = verbose;
                   1576: 
                   1577:        verbose = 1;
                   1578:        (void) command(argc == 1 ? "HELP" : "HELP %s", argv[1]);
                   1579:        verbose = oldverbose;
                   1580: }
                   1581: 
                   1582: /*
                   1583:  * Terminate session and exit.
                   1584:  */
                   1585: /*VARARGS*/
                   1586: quit()
                   1587: {
                   1588: 
                   1589:        if (connected)
                   1590:                disconnect();
                   1591:        pswitch(1);
                   1592:        if (connected) {
                   1593:                disconnect();
                   1594:        }
                   1595:        exit(0);
                   1596: }
                   1597: 
                   1598: /*
                   1599:  * Terminate session, but don't exit.
                   1600:  */
                   1601: disconnect()
                   1602: {
                   1603:        extern FILE *cout;
                   1604:        extern int data;
                   1605: 
                   1606:        if (!connected)
                   1607:                return;
                   1608:        (void) command("QUIT");
                   1609:        if (cout) {
                   1610:                (void) fclose(cout);
                   1611:        }
                   1612:        cout = NULL;
                   1613:        connected = 0;
                   1614:        data = -1;
                   1615:        if (!proxy) {
                   1616:                macnum = 0;
                   1617:        }
                   1618: }
                   1619: 
                   1620: confirm(cmd, file)
                   1621:        char *cmd, *file;
                   1622: {
                   1623:        char line[BUFSIZ];
                   1624: 
                   1625:        if (!interactive)
                   1626:                return (1);
                   1627:        printf("%s %s? ", cmd, file);
                   1628:        (void) fflush(stdout);
                   1629:        (void) gets(line);
                   1630:        return (*line != 'n' && *line != 'N');
                   1631: }
                   1632: 
                   1633: fatal(msg)
                   1634:        char *msg;
                   1635: {
                   1636: 
                   1637:        fprintf(stderr, "ftp: %s\n", msg);
                   1638:        exit(1);
                   1639: }
                   1640: 
                   1641: /*
                   1642:  * Glob a local file name specification with
                   1643:  * the expectation of a single return value.
                   1644:  * Can't control multiple values being expanded
                   1645:  * from the expression, we return only the first.
                   1646:  */
                   1647: globulize(cpp)
                   1648:        char **cpp;
                   1649: {
                   1650:        char **globbed;
                   1651: 
                   1652:        if (!doglob)
                   1653:                return (1);
                   1654:        globbed = glob(*cpp);
                   1655:        if (globerr != NULL) {
                   1656:                printf("%s: %s\n", *cpp, globerr);
                   1657:                if (globbed) {
                   1658:                        blkfree(globbed);
                   1659:                        free((char *)globbed);
                   1660:                }
                   1661:                return (0);
                   1662:        }
                   1663:        if (globbed) {
                   1664:                *cpp = *globbed++;
                   1665:                /* don't waste too much memory */
                   1666:                if (*globbed) {
                   1667:                        blkfree(globbed);
                   1668:                        free((char *)globbed);
                   1669:                }
                   1670:        }
                   1671:        return (1);
                   1672: }
                   1673: 
                   1674: account(argc,argv)
                   1675:        int argc;
                   1676:        char **argv;
                   1677: {
                   1678:        char acct[50], *getpass(), *ap;
                   1679: 
                   1680:        if (argc > 1) {
                   1681:                ++argv;
                   1682:                --argc;
                   1683:                (void) strncpy(acct,*argv,49);
                   1684:                acct[49] = '\0';
                   1685:                while (argc > 1) {
                   1686:                        --argc;
                   1687:                        ++argv;
                   1688:                        (void) strncat(acct,*argv, 49-strlen(acct));
                   1689:                }
                   1690:                ap = acct;
                   1691:        }
                   1692:        else {
                   1693:                ap = getpass("Account:");
                   1694:        }
                   1695:        (void) command("ACCT %s", ap);
                   1696: }
                   1697: 
                   1698: jmp_buf abortprox;
                   1699: 
                   1700: void
                   1701: proxabort()
                   1702: {
                   1703:        extern int proxy;
                   1704: 
                   1705:        if (!proxy) {
                   1706:                pswitch(1);
                   1707:        }
                   1708:        if (connected) {
                   1709:                proxflag = 1;
                   1710:        }
                   1711:        else {
                   1712:                proxflag = 0;
                   1713:        }
                   1714:        pswitch(0);
                   1715:        longjmp(abortprox,1);
                   1716: }
                   1717: 
                   1718: doproxy(argc,argv)
                   1719:        int argc;
                   1720:        char *argv[];
                   1721: {
                   1722:        extern struct cmd cmdtab[];
                   1723:        extern jmp_buf abortprox;
                   1724:        register struct cmd *c;
                   1725:        struct cmd *getcmd();
                   1726:        sig_t oldintr;
                   1727:        void proxabort();
                   1728: 
                   1729:        if (argc < 2) {
                   1730:                (void) strcat(line, " ");
                   1731:                printf("(command) ");
                   1732:                (void) gets(&line[strlen(line)]);
                   1733:                makeargv();
                   1734:                argc = margc;
                   1735:                argv = margv;
                   1736:        }
                   1737:        if (argc < 2) {
                   1738:                printf("usage:%s command\n", argv[0]);
                   1739:                code = -1;
                   1740:                return;
                   1741:        }
                   1742:        c = getcmd(argv[1]);
                   1743:        if (c == (struct cmd *) -1) {
                   1744:                printf("?Ambiguous command\n");
                   1745:                (void) fflush(stdout);
                   1746:                code = -1;
                   1747:                return;
                   1748:        }
                   1749:        if (c == 0) {
                   1750:                printf("?Invalid command\n");
                   1751:                (void) fflush(stdout);
                   1752:                code = -1;
                   1753:                return;
                   1754:        }
                   1755:        if (!c->c_proxy) {
                   1756:                printf("?Invalid proxy command\n");
                   1757:                (void) fflush(stdout);
                   1758:                code = -1;
                   1759:                return;
                   1760:        }
                   1761:        if (setjmp(abortprox)) {
                   1762:                code = -1;
                   1763:                return;
                   1764:        }
                   1765:        oldintr = signal(SIGINT, proxabort);
                   1766:        pswitch(1);
                   1767:        if (c->c_conn && !connected) {
                   1768:                printf("Not connected\n");
                   1769:                (void) fflush(stdout);
                   1770:                pswitch(0);
                   1771:                (void) signal(SIGINT, oldintr);
                   1772:                code = -1;
                   1773:                return;
                   1774:        }
                   1775:        (*c->c_handler)(argc-1, argv+1);
                   1776:        if (connected) {
                   1777:                proxflag = 1;
                   1778:        }
                   1779:        else {
                   1780:                proxflag = 0;
                   1781:        }
                   1782:        pswitch(0);
                   1783:        (void) signal(SIGINT, oldintr);
                   1784: }
                   1785: 
                   1786: setcase()
                   1787: {
                   1788:        mcase = !mcase;
                   1789:        printf("Case mapping %s.\n", onoff(mcase));
                   1790:        code = mcase;
                   1791: }
                   1792: 
                   1793: setcr()
                   1794: {
                   1795:        crflag = !crflag;
                   1796:        printf("Carriage Return stripping %s.\n", onoff(crflag));
                   1797:        code = crflag;
                   1798: }
                   1799: 
                   1800: setntrans(argc,argv)
                   1801:        int argc;
                   1802:        char *argv[];
                   1803: {
                   1804:        if (argc == 1) {
                   1805:                ntflag = 0;
                   1806:                printf("Ntrans off.\n");
                   1807:                code = ntflag;
                   1808:                return;
                   1809:        }
                   1810:        ntflag++;
                   1811:        code = ntflag;
                   1812:        (void) strncpy(ntin, argv[1], 16);
                   1813:        ntin[16] = '\0';
                   1814:        if (argc == 2) {
                   1815:                ntout[0] = '\0';
                   1816:                return;
                   1817:        }
                   1818:        (void) strncpy(ntout, argv[2], 16);
                   1819:        ntout[16] = '\0';
                   1820: }
                   1821: 
                   1822: char *
                   1823: dotrans(name)
                   1824:        char *name;
                   1825: {
                   1826:        static char new[MAXPATHLEN];
                   1827:        char *cp1, *cp2 = new;
                   1828:        register int i, ostop, found;
                   1829: 
                   1830:        for (ostop = 0; *(ntout + ostop) && ostop < 16; ostop++);
                   1831:        for (cp1 = name; *cp1; cp1++) {
                   1832:                found = 0;
                   1833:                for (i = 0; *(ntin + i) && i < 16; i++) {
                   1834:                        if (*cp1 == *(ntin + i)) {
                   1835:                                found++;
                   1836:                                if (i < ostop) {
                   1837:                                        *cp2++ = *(ntout + i);
                   1838:                                }
                   1839:                                break;
                   1840:                        }
                   1841:                }
                   1842:                if (!found) {
                   1843:                        *cp2++ = *cp1;
                   1844:                }
                   1845:        }
                   1846:        *cp2 = '\0';
                   1847:        return(new);
                   1848: }
                   1849: 
                   1850: setnmap(argc, argv)
                   1851:        int argc;
                   1852:        char *argv[];
                   1853: {
                   1854:        char *cp;
                   1855: 
                   1856:        if (argc == 1) {
                   1857:                mapflag = 0;
                   1858:                printf("Nmap off.\n");
                   1859:                code = mapflag;
                   1860:                return;
                   1861:        }
                   1862:        if (argc < 3) {
                   1863:                (void) strcat(line, " ");
                   1864:                printf("(mapout) ");
                   1865:                (void) gets(&line[strlen(line)]);
                   1866:                makeargv();
                   1867:                argc = margc;
                   1868:                argv = margv;
                   1869:        }
                   1870:        if (argc < 3) {
                   1871:                printf("Usage: %s [mapin mapout]\n",argv[0]);
                   1872:                code = -1;
                   1873:                return;
                   1874:        }
                   1875:        mapflag = 1;
                   1876:        code = 1;
                   1877:        cp = index(altarg, ' ');
                   1878:        if (proxy) {
                   1879:                while(*++cp == ' ');
                   1880:                altarg = cp;
                   1881:                cp = index(altarg, ' ');
                   1882:        }
                   1883:        *cp = '\0';
                   1884:        (void) strncpy(mapin, altarg, MAXPATHLEN - 1);
                   1885:        while (*++cp == ' ');
                   1886:        (void) strncpy(mapout, cp, MAXPATHLEN - 1);
                   1887: }
                   1888: 
                   1889: char *
                   1890: domap(name)
                   1891:        char *name;
                   1892: {
                   1893:        static char new[MAXPATHLEN];
                   1894:        register char *cp1 = name, *cp2 = mapin;
                   1895:        char *tp[9], *te[9];
                   1896:        int i, toks[9], toknum = 0, match = 1;
                   1897: 
                   1898:        for (i=0; i < 9; ++i) {
                   1899:                toks[i] = 0;
                   1900:        }
                   1901:        while (match && *cp1 && *cp2) {
                   1902:                switch (*cp2) {
                   1903:                        case '\\':
                   1904:                                if (*++cp2 != *cp1) {
                   1905:                                        match = 0;
                   1906:                                }
                   1907:                                break;
                   1908:                        case '$':
                   1909:                                if (*(cp2+1) >= '1' && (*cp2+1) <= '9') {
                   1910:                                        if (*cp1 != *(++cp2+1)) {
                   1911:                                                toks[toknum = *cp2 - '1']++;
                   1912:                                                tp[toknum] = cp1;
                   1913:                                                while (*++cp1 && *(cp2+1)
                   1914:                                                        != *cp1);
                   1915:                                                te[toknum] = cp1;
                   1916:                                        }
                   1917:                                        cp2++;
                   1918:                                        break;
                   1919:                                }
                   1920:                                /* FALLTHROUGH */
                   1921:                        default:
                   1922:                                if (*cp2 != *cp1) {
                   1923:                                        match = 0;
                   1924:                                }
                   1925:                                break;
                   1926:                }
                   1927:                if (match && *cp1) {
                   1928:                        cp1++;
                   1929:                }
                   1930:                if (match && *cp2) {
                   1931:                        cp2++;
                   1932:                }
                   1933:        }
                   1934:        if (!match && *cp1) /* last token mismatch */
                   1935:        {
                   1936:                toks[toknum] = 0;
                   1937:        }
                   1938:        cp1 = new;
                   1939:        *cp1 = '\0';
                   1940:        cp2 = mapout;
                   1941:        while (*cp2) {
                   1942:                match = 0;
                   1943:                switch (*cp2) {
                   1944:                        case '\\':
                   1945:                                if (*(cp2 + 1)) {
                   1946:                                        *cp1++ = *++cp2;
                   1947:                                }
                   1948:                                break;
                   1949:                        case '[':
                   1950: LOOP:
                   1951:                                if (*++cp2 == '$' && isdigit(*(cp2+1))) { 
                   1952:                                        if (*++cp2 == '0') {
                   1953:                                                char *cp3 = name;
                   1954: 
                   1955:                                                while (*cp3) {
                   1956:                                                        *cp1++ = *cp3++;
                   1957:                                                }
                   1958:                                                match = 1;
                   1959:                                        }
                   1960:                                        else if (toks[toknum = *cp2 - '1']) {
                   1961:                                                char *cp3 = tp[toknum];
                   1962: 
                   1963:                                                while (cp3 != te[toknum]) {
                   1964:                                                        *cp1++ = *cp3++;
                   1965:                                                }
                   1966:                                                match = 1;
                   1967:                                        }
                   1968:                                }
                   1969:                                else {
                   1970:                                        while (*cp2 && *cp2 != ',' && 
                   1971:                                            *cp2 != ']') {
                   1972:                                                if (*cp2 == '\\') {
                   1973:                                                        cp2++;
                   1974:                                                }
                   1975:                                                else if (*cp2 == '$' &&
                   1976:                                                        isdigit(*(cp2+1))) {
                   1977:                                                        if (*++cp2 == '0') {
                   1978:                                                           char *cp3 = name;
                   1979: 
                   1980:                                                           while (*cp3) {
                   1981:                                                                *cp1++ = *cp3++;
                   1982:                                                           }
                   1983:                                                        }
                   1984:                                                        else if (toks[toknum =
                   1985:                                                            *cp2 - '1']) {
                   1986:                                                           char *cp3=tp[toknum];
                   1987: 
                   1988:                                                           while (cp3 !=
                   1989:                                                                  te[toknum]) {
                   1990:                                                                *cp1++ = *cp3++;
                   1991:                                                           }
                   1992:                                                        }
                   1993:                                                }
                   1994:                                                else if (*cp2) {
                   1995:                                                        *cp1++ = *cp2++;
                   1996:                                                }
                   1997:                                        }
                   1998:                                        if (!*cp2) {
                   1999:                                                printf("nmap: unbalanced brackets\n");
                   2000:                                                return(name);
                   2001:                                        }
                   2002:                                        match = 1;
                   2003:                                        cp2--;
                   2004:                                }
                   2005:                                if (match) {
                   2006:                                        while (*++cp2 && *cp2 != ']') {
                   2007:                                              if (*cp2 == '\\' && *(cp2 + 1)) {
                   2008:                                                        cp2++;
                   2009:                                              }
                   2010:                                        }
                   2011:                                        if (!*cp2) {
                   2012:                                                printf("nmap: unbalanced brackets\n");
                   2013:                                                return(name);
                   2014:                                        }
                   2015:                                        break;
                   2016:                                }
                   2017:                                switch (*++cp2) {
                   2018:                                        case ',':
                   2019:                                                goto LOOP;
                   2020:                                        case ']':
                   2021:                                                break;
                   2022:                                        default:
                   2023:                                                cp2--;
                   2024:                                                goto LOOP;
                   2025:                                }
                   2026:                                break;
                   2027:                        case '$':
                   2028:                                if (isdigit(*(cp2 + 1))) {
                   2029:                                        if (*++cp2 == '0') {
                   2030:                                                char *cp3 = name;
                   2031: 
                   2032:                                                while (*cp3) {
                   2033:                                                        *cp1++ = *cp3++;
                   2034:                                                }
                   2035:                                        }
                   2036:                                        else if (toks[toknum = *cp2 - '1']) {
                   2037:                                                char *cp3 = tp[toknum];
                   2038: 
                   2039:                                                while (cp3 != te[toknum]) {
                   2040:                                                        *cp1++ = *cp3++;
                   2041:                                                }
                   2042:                                        }
                   2043:                                        break;
                   2044:                                }
                   2045:                                /* intentional drop through */
                   2046:                        default:
                   2047:                                *cp1++ = *cp2;
                   2048:                                break;
                   2049:                }
                   2050:                cp2++;
                   2051:        }
                   2052:        *cp1 = '\0';
                   2053:        if (!*new) {
                   2054:                return(name);
                   2055:        }
                   2056:        return(new);
                   2057: }
                   2058: 
                   2059: setsunique()
                   2060: {
                   2061:        sunique = !sunique;
                   2062:        printf("Store unique %s.\n", onoff(sunique));
                   2063:        code = sunique;
                   2064: }
                   2065: 
                   2066: setrunique()
                   2067: {
                   2068:        runique = !runique;
                   2069:        printf("Receive unique %s.\n", onoff(runique));
                   2070:        code = runique;
                   2071: }
                   2072: 
                   2073: /* change directory to perent directory */
                   2074: cdup()
                   2075: {
                   2076:        if (command("CDUP") == ERROR && code == 500) {
                   2077:                if (verbose)
                   2078:                        printf("CDUP command not recognized, trying XCUP\n");
                   2079:                (void) command("XCUP");
                   2080:        }
                   2081: }
                   2082: 
                   2083: /* restart transfer at specific point */
                   2084: restart(argc, argv)
                   2085:        int argc;
                   2086:        char *argv[];
                   2087: {
                   2088:        extern long atol();
                   2089:        if (argc != 2)
                   2090:                printf("restart: offset not specified\n");
                   2091:        else {
                   2092:                restart_point = atol(argv[1]);
                   2093:                printf("restarting at %ld. %s\n", restart_point,
                   2094:                    "execute get, put or append to initiate transfer");
                   2095:        }
                   2096: }
                   2097: 
                   2098: /* show remote system type */
                   2099: syst()
                   2100: {
                   2101:        (void) command("SYST");
                   2102: }
                   2103: 
                   2104: macdef(argc, argv)
                   2105:        int argc;
                   2106:        char *argv[];
                   2107: {
                   2108:        char *tmp;
                   2109:        int c;
                   2110: 
                   2111:        if (macnum == 16) {
                   2112:                printf("Limit of 16 macros have already been defined\n");
                   2113:                code = -1;
                   2114:                return;
                   2115:        }
                   2116:        if (argc < 2) {
                   2117:                (void) strcat(line, " ");
                   2118:                printf("(macro name) ");
                   2119:                (void) gets(&line[strlen(line)]);
                   2120:                makeargv();
                   2121:                argc = margc;
                   2122:                argv = margv;
                   2123:        }
                   2124:        if (argc != 2) {
                   2125:                printf("Usage: %s macro_name\n",argv[0]);
                   2126:                code = -1;
                   2127:                return;
                   2128:        }
                   2129:        if (interactive) {
                   2130:                printf("Enter macro line by line, terminating it with a null line\n");
                   2131:        }
                   2132:        (void) strncpy(macros[macnum].mac_name, argv[1], 8);
                   2133:        if (macnum == 0) {
                   2134:                macros[macnum].mac_start = macbuf;
                   2135:        }
                   2136:        else {
                   2137:                macros[macnum].mac_start = macros[macnum - 1].mac_end + 1;
                   2138:        }
                   2139:        tmp = macros[macnum].mac_start;
                   2140:        while (tmp != macbuf+4096) {
                   2141:                if ((c = getchar()) == EOF) {
                   2142:                        printf("macdef:end of file encountered\n");
                   2143:                        code = -1;
                   2144:                        return;
                   2145:                }
                   2146:                if ((*tmp = c) == '\n') {
                   2147:                        if (tmp == macros[macnum].mac_start) {
                   2148:                                macros[macnum++].mac_end = tmp;
                   2149:                                code = 0;
                   2150:                                return;
                   2151:                        }
                   2152:                        if (*(tmp-1) == '\0') {
                   2153:                                macros[macnum++].mac_end = tmp - 1;
                   2154:                                code = 0;
                   2155:                                return;
                   2156:                        }
                   2157:                        *tmp = '\0';
                   2158:                }
                   2159:                tmp++;
                   2160:        }
                   2161:        while (1) {
                   2162:                while ((c = getchar()) != '\n' && c != EOF)
                   2163:                        /* LOOP */;
                   2164:                if (c == EOF || getchar() == '\n') {
                   2165:                        printf("Macro not defined - 4k buffer exceeded\n");
                   2166:                        code = -1;
                   2167:                        return;
                   2168:                }
                   2169:        }
                   2170: }
                   2171: 
                   2172: /*
                   2173:  * get size of file on remote machine
                   2174:  */
                   2175: sizecmd(argc, argv)
                   2176:        char *argv[];
                   2177: {
                   2178: 
                   2179:        if (argc < 2) {
                   2180:                (void) strcat(line, " ");
                   2181:                printf("(filename) ");
                   2182:                (void) gets(&line[strlen(line)]);
                   2183:                makeargv();
                   2184:                argc = margc;
                   2185:                argv = margv;
                   2186:        }
                   2187:        if (argc < 2) {
                   2188:                printf("usage:%s filename\n", argv[0]);
                   2189:                code = -1;
                   2190:                return;
                   2191:        }
                   2192:        (void) command("SIZE %s", argv[1]);
                   2193: }
                   2194: 
                   2195: /*
                   2196:  * get last modification time of file on remote machine
                   2197:  */
                   2198: modtime(argc, argv)
                   2199:        char *argv[];
                   2200: {
                   2201:        int overbose;
                   2202: 
                   2203:        if (argc < 2) {
                   2204:                (void) strcat(line, " ");
                   2205:                printf("(filename) ");
                   2206:                (void) gets(&line[strlen(line)]);
                   2207:                makeargv();
                   2208:                argc = margc;
                   2209:                argv = margv;
                   2210:        }
                   2211:        if (argc < 2) {
                   2212:                printf("usage:%s filename\n", argv[0]);
                   2213:                code = -1;
                   2214:                return;
                   2215:        }
                   2216:        overbose = verbose;
                   2217:        if (debug == 0)
                   2218:                verbose = -1;
                   2219:        if (command("MDTM %s", argv[1]) == COMPLETE) {
                   2220:                int yy, mo, day, hour, min, sec;
                   2221:                sscanf(reply_string, "%*s %04d%02d%02d%02d%02d%02d", &yy, &mo,
                   2222:                        &day, &hour, &min, &sec);
                   2223:                /* might want to print this in local time */
                   2224:                printf("%s\t%02d/%02d/%04d %02d:%02d:%02d GMT\n", argv[1],
                   2225:                        mo, day, yy, hour, min, sec);
                   2226:        } else
                   2227:                printf("%s\n", reply_string);
                   2228:        verbose = overbose;
                   2229: }
                   2230: 
                   2231: /*
                   2232:  * show status on reomte machine
                   2233:  */
                   2234: rmtstatus(argc, argv)
                   2235:        char *argv[];
                   2236: {
                   2237:        (void) command(argc > 1 ? "STAT %s" : "STAT" , argv[1]);
                   2238: }
                   2239: 
                   2240: /*
                   2241:  * get file if modtime is more recent than current file
                   2242:  */
                   2243: newer(argc, argv)
                   2244:        char *argv[];
                   2245: {
                   2246:        if (getit(argc, argv, -1, "w"))
                   2247:                printf("Local file \"%s\" is newer than remote file \"%s\"\n",
                   2248:                        argv[1], argv[2]);
                   2249: }

unix.superglobalmegacorp.com

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