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

Annotation of src/usr.bin/ftp/cmds.c, Revision 1.68

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