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

Annotation of src/usr.bin/ftp/small.c, Revision 1.11

1.10      kmos        1: /*     $OpenBSD: small.c,v 1.9 2017/01/21 08:33:07 krw Exp $   */
1.1       martynas    2: /*     $NetBSD: cmds.c,v 1.27 1997/08/18 10:20:15 lukem Exp $  */
                      3:
                      4: /*
                      5:  * Copyright (C) 1997 and 1998 WIDE Project.
                      6:  * All rights reserved.
1.9       krw         7:  *
1.1       martynas    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.
1.9       krw        19:  *
1.1       martynas   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: /*
                     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.
                     45:  * 3. Neither the name of the University nor the names of its contributors
                     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:  */
                     65: #include <sys/types.h>
                     66: #include <sys/socket.h>
                     67: #include <sys/stat.h>
                     68: #include <sys/wait.h>
                     69: #include <arpa/ftp.h>
                     70:
                     71: #include <ctype.h>
                     72: #include <err.h>
                     73: #include <fnmatch.h>
                     74: #include <glob.h>
                     75: #include <netdb.h>
                     76: #include <stdio.h>
                     77: #include <stdlib.h>
                     78: #include <string.h>
                     79: #include <unistd.h>
1.2       deraadt    80: #include <errno.h>
1.1       martynas   81:
                     82: #include "ftp_var.h"
                     83: #include "pathnames.h"
                     84: #include "small.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: } types[] = {
1.4       tedu       95:        { "ascii",      "A",    TYPE_A },
                     96:        { "binary",     "I",    TYPE_I },
                     97:        { "image",      "I",    TYPE_I },
1.1       martynas   98:        { NULL }
                     99: };
                    100:
                    101: /*
                    102:  * Set transfer type.
                    103:  */
                    104: void
                    105: settype(int argc, char *argv[])
                    106: {
                    107:        struct types *p;
                    108:        int comret;
                    109:
                    110:        if (argc > 2) {
                    111:                char *sep;
                    112:
                    113:                fprintf(ttyout, "usage: %s [", argv[0]);
                    114:                sep = "";
                    115:                for (p = types; p->t_name; p++) {
                    116:                        fprintf(ttyout, "%s%s", sep, p->t_name);
                    117:                        sep = " | ";
                    118:                }
                    119:                fputs("]\n", ttyout);
                    120:                code = -1;
                    121:                return;
                    122:        }
                    123:        if (argc < 2) {
                    124:                fprintf(ttyout, "Using %s mode to transfer files.\n", typename);
                    125:                code = 0;
                    126:                return;
                    127:        }
                    128:        for (p = types; p->t_name; p++)
                    129:                if (strcmp(argv[1], p->t_name) == 0)
                    130:                        break;
                    131:        if (p->t_name == 0) {
                    132:                fprintf(ttyout, "%s: unknown mode.\n", argv[1]);
                    133:                code = -1;
                    134:                return;
                    135:        }
1.4       tedu      136:        comret = command("TYPE %s", p->t_mode);
1.1       martynas  137:        if (comret == COMPLETE) {
                    138:                (void)strlcpy(typename, p->t_name, sizeof typename);
                    139:                curtype = type = p->t_type;
                    140:        }
                    141: }
                    142:
                    143: /*
                    144:  * Internal form of settype; changes current type in use with server
                    145:  * without changing our notion of the type for data transfers.
                    146:  * Used to change to and from ascii for listings.
                    147:  */
                    148: void
                    149: changetype(int newtype, int show)
                    150: {
                    151:        struct types *p;
                    152:        int comret, oldverbose = verbose;
                    153:
                    154:        if (newtype == 0)
                    155:                newtype = TYPE_I;
                    156:        if (newtype == curtype)
                    157:                return;
                    158:        if (
                    159: #ifndef SMALL
                    160:            !debug &&
                    161: #endif /* !SMALL */
                    162:            show == 0)
                    163:                verbose = 0;
                    164:        for (p = types; p->t_name; p++)
                    165:                if (newtype == p->t_type)
                    166:                        break;
                    167:        if (p->t_name == 0) {
                    168:                warnx("internal error: unknown type %d.", newtype);
                    169:                return;
                    170:        }
                    171:        if (newtype == TYPE_L && bytename[0] != '\0')
                    172:                comret = command("TYPE %s %s", p->t_mode, bytename);
                    173:        else
                    174:                comret = command("TYPE %s", p->t_mode);
                    175:        if (comret == COMPLETE)
                    176:                curtype = newtype;
                    177:        verbose = oldverbose;
                    178: }
                    179:
                    180: char *stype[] = {
                    181:        "type",
                    182:        "",
                    183:        0
                    184: };
                    185:
                    186: /*
                    187:  * Set binary transfer type.
                    188:  */
                    189: /*ARGSUSED*/
                    190: void
                    191: setbinary(int argc, char *argv[])
                    192: {
                    193:
                    194:        stype[1] = "binary";
                    195:        settype(2, stype);
                    196: }
                    197:
                    198: void
                    199: get(int argc, char *argv[])
                    200: {
                    201:
                    202:        (void)getit(argc, argv, 0, restart_point ? "a+w" : "w" );
                    203: }
                    204:
                    205: /*
                    206:  * Receive one file.
                    207:  */
                    208: int
                    209: getit(int argc, char *argv[], int restartit, const char *mode)
                    210: {
                    211:        int loc = 0;
                    212:        int rval = 0;
                    213:        char *oldargv1, *oldargv2, *globargv2;
                    214:
                    215:        if (argc == 2) {
                    216:                argc++;
                    217:                argv[2] = argv[1];
                    218:                loc++;
                    219:        }
                    220: #ifndef SMALL
                    221:        if (argc < 2 && !another(&argc, &argv, "remote-file"))
                    222:                goto usage;
                    223:        if ((argc < 3 && !another(&argc, &argv, "local-file")) || argc > 3) {
                    224: usage:
                    225:                fprintf(ttyout, "usage: %s remote-file [local-file]\n",
                    226:                    argv[0]);
                    227:                code = -1;
                    228:                return (0);
                    229:        }
                    230: #endif /* !SMALL */
                    231:        oldargv1 = argv[1];
                    232:        oldargv2 = argv[2];
                    233:        if (!globulize(&argv[2])) {
                    234:                code = -1;
                    235:                return (0);
                    236:        }
                    237:        globargv2 = argv[2];
                    238:        if (loc && mcase) {
1.3       deraadt   239:                char *tp = argv[1], *tp2, tmpbuf[PATH_MAX];
1.1       martynas  240:
1.5       mmcc      241:                while (*tp && !islower((unsigned char)*tp)) {
1.1       martynas  242:                        tp++;
                    243:                }
                    244:                if (!*tp) {
                    245:                        tp = argv[2];
                    246:                        tp2 = tmpbuf;
                    247:                        while ((*tp2 = *tp) != '\0') {
1.5       mmcc      248:                                if (isupper((unsigned char)*tp2)) {
                    249:                                        *tp2 = tolower((unsigned char)*tp2);
1.1       martynas  250:                                }
                    251:                                tp++;
                    252:                                tp2++;
                    253:                        }
                    254:                        argv[2] = tmpbuf;
                    255:                }
                    256:        }
                    257:        if (loc && ntflag)
                    258:                argv[2] = dotrans(argv[2]);
                    259:        if (loc && mapflag)
                    260:                argv[2] = domap(argv[2]);
                    261: #ifndef SMALL
                    262:        if (restartit) {
                    263:                struct stat stbuf;
                    264:                int ret;
                    265:
                    266:                ret = stat(argv[2], &stbuf);
                    267:                if (restartit == 1) {
                    268:                        restart_point = (ret < 0) ? 0 : stbuf.st_size;
                    269:                } else {
                    270:                        if (ret == 0) {
                    271:                                time_t mtime;
                    272:
                    273:                                mtime = remotemodtime(argv[1], 0);
                    274:                                if (mtime == -1)
                    275:                                        goto freegetit;
                    276:                                if (stbuf.st_mtime >= mtime) {
                    277:                                        rval = 1;
1.6       krw       278:                                        fprintf(ttyout,
                    279:                                                "Local file \"%s\" is newer "\
                    280:                                                "than remote file \"%s\".\n",
                    281:                                                argv[2], argv[1]);
1.1       martynas  282:                                        goto freegetit;
                    283:                                }
                    284:                        }
                    285:                }
                    286:        }
                    287: #endif /* !SMALL */
                    288:
                    289:        recvrequest("RETR", argv[2], argv[1], mode,
                    290:            argv[1] != oldargv1 || argv[2] != oldargv2 || !interactive, loc);
                    291:        restart_point = 0;
1.8       krw       292: #ifndef SMALL
1.1       martynas  293: freegetit:
1.8       krw       294: #endif
1.1       martynas  295:        if (oldargv2 != globargv2)      /* free up after globulize() */
                    296:                free(globargv2);
                    297:        return (rval);
                    298: }
                    299:
                    300: /* XXX - Signal race. */
                    301: /* ARGSUSED */
                    302: void
                    303: mabort(int signo)
                    304: {
1.2       deraadt   305:        int save_errno = errno;
                    306:
1.1       martynas  307:        alarmtimer(0);
1.2       deraadt   308:        (void) write(fileno(ttyout), "\n\r", 2);
1.1       martynas  309: #ifndef SMALL
1.2       deraadt   310:        if (mflag && fromatty) {
                    311:                /* XXX signal race, crazy unbelievable stdio misuse */
                    312:                if (confirm(mname, NULL)) {
                    313:                        errno = save_errno;
1.1       martynas  314:                        longjmp(jabort, 1);
1.2       deraadt   315:                }
                    316:        }
1.1       martynas  317: #endif /* !SMALL */
                    318:        mflag = 0;
1.2       deraadt   319:        errno = save_errno;
1.1       martynas  320:        longjmp(jabort, 1);
                    321: }
                    322:
                    323: /*
                    324:  * Get multiple files.
                    325:  */
                    326: void
                    327: mget(int argc, char *argv[])
                    328: {
                    329:        extern int optind, optreset;
                    330:        sig_t oldintr;
1.7       krw       331:        int xargc = 2;
1.3       deraadt   332:        char *cp, localcwd[PATH_MAX], *xargv[] = { argv[0], NULL, NULL };
1.1       martynas  333:        static int restartit = 0;
                    334: #ifndef SMALL
                    335:        extern char *optarg;
                    336:        const char *errstr;
1.7       krw       337:        int ch, i = 1;
1.1       martynas  338:        char type = 0, *dummyargv[] = { argv[0], ".", NULL };
                    339:        FILE *ftemp = NULL;
                    340:        static int depth = 0, max_depth = 0;
                    341:
                    342:        optind = optreset = 1;
                    343:
                    344:        if (depth)
                    345:                depth++;
                    346:
                    347:        while ((ch = getopt(argc, argv, "cd:nr")) != -1) {
                    348:                switch(ch) {
                    349:                case 'c':
                    350:                        restartit = 1;
                    351:                        break;
                    352:                case 'd':
                    353:                        max_depth = strtonum(optarg, 0, INT_MAX, &errstr);
                    354:                        if (errstr != NULL) {
                    355:                                fprintf(ttyout, "bad depth value, %s: %s\n",
                    356:                                    errstr, optarg);
                    357:                                code = -1;
                    358:                                return;
                    359:                        }
                    360:                        break;
                    361:                case 'n':
                    362:                        restartit = -1;
                    363:                        break;
                    364:                case 'r':
                    365:                        depth = 1;
                    366:                        break;
                    367:                default:
                    368:                        goto usage;
                    369:                }
                    370:        }
                    371:
                    372:        if (argc - optind < 1 && !another(&argc, &argv, "remote-files")) {
                    373: usage:
                    374:                fprintf(ttyout, "usage: %s [-cnr] [-d depth] remote-files\n",
                    375:                    argv[0]);
                    376:                code = -1;
                    377:                return;
                    378:        }
                    379:
                    380:        argv[optind - 1] = argv[0];
                    381:        argc -= optind - 1;
                    382:        argv += optind - 1;
                    383: #endif /* !SMALL */
                    384:
                    385:        mname = argv[0];
                    386:        mflag = 1;
                    387:        if (getcwd(localcwd, sizeof(localcwd)) == NULL)
                    388:                err(1, "can't get cwd");
                    389:
                    390:        oldintr = signal(SIGINT, mabort);
                    391:        (void)setjmp(jabort);
                    392:        while ((cp =
                    393: #ifdef SMALL
                    394:            remglob(argv, proxy, NULL)) != NULL
                    395:            ) {
                    396: #else /* SMALL */
                    397:            depth ? remglob2(dummyargv, proxy, NULL, &ftemp, &type) :
                    398:            remglob(argv, proxy, NULL)) != NULL
                    399:            || (mflag && depth && ++i < argc)
                    400:            ) {
                    401:                if (cp == NULL)
                    402:                        continue;
                    403: #endif /* SMALL */
                    404:                if (*cp == '\0') {
                    405:                        mflag = 0;
                    406:                        continue;
                    407:                }
                    408:                if (!mflag)
                    409:                        continue;
                    410: #ifndef SMALL
                    411:                if (depth && fnmatch(argv[i], cp, FNM_PATHNAME) != 0)
                    412:                        continue;
                    413: #endif /* !SMALL */
                    414:                if (!fileindir(cp, localcwd)) {
                    415:                        fprintf(ttyout, "Skipping non-relative filename `%s'\n",
                    416:                            cp);
                    417:                        continue;
                    418:                }
                    419: #ifndef SMALL
                    420:                if (type == 'd' && depth == max_depth)
                    421:                        continue;
                    422:                if (!confirm(argv[0], cp))
                    423:                        continue;
                    424:                if (type == 'd') {
                    425:                        mkdir(cp, 0755);
                    426:                        if (chdir(cp) != 0) {
                    427:                                warn("local: %s", cp);
                    428:                                continue;
                    429:                        }
                    430:
                    431:                        xargv[1] = cp;
                    432:                        cd(xargc, xargv);
                    433:                        if (dirchange != 1)
                    434:                                goto out;
                    435:
                    436:                        xargv[1] = "*";
                    437:                        mget(xargc, xargv);
                    438:
                    439:                        xargv[1] = "..";
                    440:                        cd(xargc, xargv);
                    441:                        if (dirchange != 1) {
                    442:                                mflag = 0;
                    443:                                goto out;
                    444:                        }
                    445:
                    446: out:
                    447:                        if (chdir("..") != 0) {
                    448:                                warn("local: %s", cp);
                    449:                                mflag = 0;
                    450:                        }
                    451:                        continue;
                    452:                }
                    453:                if (type == 's')
                    454:                        /* Currently ignored. */
                    455:                        continue;
                    456: #endif /* !SMALL */
                    457:                xargv[1] = cp;
                    458:                (void)getit(xargc, xargv, restartit,
                    459:                    (restartit == 1 || restart_point) ? "a+w" : "w");
                    460: #ifndef SMALL
                    461:                if (!mflag && fromatty) {
                    462:                        if (confirm(argv[0], NULL))
                    463:                                mflag = 1;
                    464:                }
                    465: #endif /* !SMALL */
                    466:        }
                    467:        (void)signal(SIGINT, oldintr);
                    468: #ifndef SMALL
                    469:        if (depth)
                    470:                depth--;
                    471:        if (depth == 0 || mflag == 0)
                    472:                depth = max_depth = mflag = restartit = 0;
                    473: #else /* !SMALL */
                    474:        mflag = 0;
                    475: #endif /* !SMALL */
                    476: }
                    477:
                    478: /*
                    479:  * Set current working directory on remote machine.
                    480:  */
                    481: void
                    482: cd(int argc, char *argv[])
                    483: {
                    484:        int r;
                    485:
                    486: #ifndef SMALL
                    487:        if ((argc < 2 && !another(&argc, &argv, "remote-directory")) ||
                    488:            argc > 2) {
                    489:                fprintf(ttyout, "usage: %s remote-directory\n", argv[0]);
                    490:                code = -1;
                    491:                return;
                    492:        }
                    493: #endif /* !SMALL */
                    494:        r = command("CWD %s", argv[1]);
                    495:        if (r == ERROR && code == 500) {
                    496:                if (verbose)
                    497:                        fputs("CWD command not recognized, trying XCWD.\n", ttyout);
                    498:                r = command("XCWD %s", argv[1]);
                    499:        }
                    500:        if (r == ERROR && code == 550) {
                    501:                dirchange = 0;
                    502:                return;
                    503:        }
                    504:        if (r == COMPLETE)
                    505:                dirchange = 1;
                    506: }
                    507:
                    508: /*
                    509:  * Terminate session, but don't exit.
                    510:  */
                    511: /* ARGSUSED */
                    512: void
                    513: disconnect(int argc, char *argv[])
                    514: {
                    515:
                    516:        if (!connected)
                    517:                return;
                    518:        (void)command("QUIT");
                    519:        if (cout) {
                    520:                (void)fclose(cout);
                    521:        }
                    522:        cout = NULL;
                    523:        connected = 0;
                    524:        data = -1;
                    525: #ifndef SMALL
                    526:        if (!proxy) {
                    527:                macnum = 0;
                    528:        }
                    529: #endif /* !SMALL */
                    530: }
                    531:
                    532: char *
                    533: dotrans(char *name)
                    534: {
1.3       deraadt   535:        static char new[PATH_MAX];
1.1       martynas  536:        char *cp1, *cp2 = new;
                    537:        int i, ostop, found;
                    538:
                    539:        for (ostop = 0; *(ntout + ostop) && ostop < 16; ostop++)
                    540:                continue;
                    541:        for (cp1 = name; *cp1; cp1++) {
                    542:                found = 0;
                    543:                for (i = 0; *(ntin + i) && i < 16; i++) {
                    544:                        if (*cp1 == *(ntin + i)) {
                    545:                                found++;
                    546:                                if (i < ostop) {
                    547:                                        *cp2++ = *(ntout + i);
                    548:                                }
                    549:                                break;
                    550:                        }
                    551:                }
                    552:                if (!found) {
                    553:                        *cp2++ = *cp1;
                    554:                }
                    555:        }
                    556:        *cp2 = '\0';
                    557:        return (new);
                    558: }
                    559:
                    560: char *
                    561: domap(char *name)
                    562: {
1.3       deraadt   563:        static char new[PATH_MAX];
1.1       martynas  564:        char *cp1 = name, *cp2 = mapin;
                    565:        char *tp[9], *te[9];
                    566:        int i, toks[9], toknum = 0, match = 1;
                    567:
                    568:        for (i=0; i < 9; ++i) {
                    569:                toks[i] = 0;
                    570:        }
                    571:        while (match && *cp1 && *cp2) {
                    572:                switch (*cp2) {
                    573:                        case '\\':
                    574:                                if (*++cp2 != *cp1) {
                    575:                                        match = 0;
                    576:                                }
                    577:                                break;
                    578:                        case '$':
                    579:                                if (*(cp2+1) >= '1' && (*cp2+1) <= '9') {
                    580:                                        if (*cp1 != *(++cp2+1)) {
                    581:                                                toks[toknum = *cp2 - '1']++;
                    582:                                                tp[toknum] = cp1;
                    583:                                                while (*++cp1 && *(cp2+1)
                    584:                                                        != *cp1);
                    585:                                                te[toknum] = cp1;
                    586:                                        }
                    587:                                        cp2++;
                    588:                                        break;
                    589:                                }
                    590:                                /* FALLTHROUGH */
                    591:                        default:
                    592:                                if (*cp2 != *cp1) {
                    593:                                        match = 0;
                    594:                                }
                    595:                                break;
                    596:                }
                    597:                if (match && *cp1) {
                    598:                        cp1++;
                    599:                }
                    600:                if (match && *cp2) {
                    601:                        cp2++;
                    602:                }
                    603:        }
                    604:        if (!match && *cp1) /* last token mismatch */
                    605:        {
                    606:                toks[toknum] = 0;
                    607:        }
                    608:        cp1 = new;
                    609:        *cp1 = '\0';
                    610:        cp2 = mapout;
                    611:        while (*cp2) {
                    612:                match = 0;
                    613:                switch (*cp2) {
                    614:                        case '\\':
                    615:                                if (*(cp2 + 1)) {
                    616:                                        *cp1++ = *++cp2;
                    617:                                }
                    618:                                break;
                    619:                        case '[':
                    620: LOOP:
1.5       mmcc      621:                                if (*++cp2 == '$' && isdigit((unsigned char)*(cp2 + 1))) {
1.1       martynas  622:                                        if (*++cp2 == '0') {
                    623:                                                char *cp3 = name;
                    624:
                    625:                                                while (*cp3) {
                    626:                                                        *cp1++ = *cp3++;
                    627:                                                }
                    628:                                                match = 1;
                    629:                                        }
                    630:                                        else if (toks[toknum = *cp2 - '1']) {
                    631:                                                char *cp3 = tp[toknum];
                    632:
                    633:                                                while (cp3 != te[toknum]) {
                    634:                                                        *cp1++ = *cp3++;
                    635:                                                }
                    636:                                                match = 1;
                    637:                                        }
                    638:                                }
                    639:                                else {
                    640:                                        while (*cp2 && *cp2 != ',' &&
                    641:                                            *cp2 != ']') {
                    642:                                                if (*cp2 == '\\') {
                    643:                                                        cp2++;
                    644:                                                }
                    645:                                                else if (*cp2 == '$' &&
1.9       krw       646:                                                        isdigit((unsigned char)*(cp2 + 1))) {
1.1       martynas  647:                                                        if (*++cp2 == '0') {
                    648:                                                           char *cp3 = name;
                    649:
                    650:                                                           while (*cp3) {
                    651:                                                                *cp1++ = *cp3++;
                    652:                                                           }
                    653:                                                        }
                    654:                                                        else if (toks[toknum =
                    655:                                                            *cp2 - '1']) {
                    656:                                                           char *cp3=tp[toknum];
                    657:
                    658:                                                           while (cp3 !=
                    659:                                                                  te[toknum]) {
                    660:                                                                *cp1++ = *cp3++;
                    661:                                                           }
                    662:                                                        }
                    663:                                                }
                    664:                                                else if (*cp2) {
                    665:                                                        *cp1++ = *cp2++;
                    666:                                                }
                    667:                                        }
                    668:                                        if (!*cp2) {
                    669:                                                fputs(
                    670: "nmap: unbalanced brackets.\n", ttyout);
                    671:                                                return (name);
                    672:                                        }
                    673:                                        match = 1;
                    674:                                        cp2--;
                    675:                                }
                    676:                                if (match) {
                    677:                                        while (*++cp2 && *cp2 != ']') {
                    678:                                              if (*cp2 == '\\' && *(cp2 + 1)) {
                    679:                                                        cp2++;
                    680:                                              }
                    681:                                        }
                    682:                                        if (!*cp2) {
                    683:                                                fputs(
                    684: "nmap: unbalanced brackets.\n", ttyout);
                    685:                                                return (name);
                    686:                                        }
                    687:                                        break;
                    688:                                }
                    689:                                switch (*++cp2) {
                    690:                                        case ',':
                    691:                                                goto LOOP;
                    692:                                        case ']':
                    693:                                                break;
                    694:                                        default:
                    695:                                                cp2--;
                    696:                                                goto LOOP;
                    697:                                }
                    698:                                break;
                    699:                        case '$':
1.5       mmcc      700:                                if (isdigit((unsigned char)*(cp2 + 1))) {
1.1       martynas  701:                                        if (*++cp2 == '0') {
                    702:                                                char *cp3 = name;
                    703:
                    704:                                                while (*cp3) {
                    705:                                                        *cp1++ = *cp3++;
                    706:                                                }
                    707:                                        }
                    708:                                        else if (toks[toknum = *cp2 - '1']) {
                    709:                                                char *cp3 = tp[toknum];
                    710:
                    711:                                                while (cp3 != te[toknum]) {
                    712:                                                        *cp1++ = *cp3++;
                    713:                                                }
                    714:                                        }
                    715:                                        break;
                    716:                                }
                    717:                                /* FALLTHROUGH */
                    718:                        default:
                    719:                                *cp1++ = *cp2;
                    720:                                break;
                    721:                }
                    722:                cp2++;
                    723:        }
                    724:        *cp1 = '\0';
                    725:        if (!*new) {
                    726:                return (name);
                    727:        }
                    728:        return (new);
                    729: }
                    730: