Annotation of 42BSD/ucb/tftp/main.c, revision 1.1

1.1     ! root        1: #ifndef lint
        !             2: static char sccsid[] = "@(#)main.c     4.7 (Berkeley) 8/11/83";
        !             3: #endif
        !             4: 
        !             5: /*
        !             6:  * TFTP User Program -- Command Interface.
        !             7:  */
        !             8: #include <sys/types.h>
        !             9: #include <sys/socket.h>
        !            10: #include <sys/file.h>
        !            11: 
        !            12: #include <netinet/in.h>
        !            13: 
        !            14: #include <signal.h>
        !            15: #include <stdio.h>
        !            16: #include <errno.h>
        !            17: #include <setjmp.h>
        !            18: #include <ctype.h>
        !            19: #include <netdb.h>
        !            20: 
        !            21: #define        TIMEOUT         5               /* secs between rexmt's */
        !            22: 
        !            23: struct sockaddr_in sin;
        !            24: int    f;
        !            25: int    trace;
        !            26: int    verbose;
        !            27: int    connected;
        !            28: char   mode[32];
        !            29: char   line[200];
        !            30: int    margc;
        !            31: char   *margv[20];
        !            32: char   *prompt = "tftp";
        !            33: jmp_buf        toplevel;
        !            34: int    intr();
        !            35: struct servent *sp;
        !            36: 
        !            37: int    quit(), help(), setverbose(), settrace(), status();
        !            38: int    get(), put(), setpeer(), setmode(), setrexmt(), settimeout();
        !            39: 
        !            40: #define HELPINDENT (sizeof("connect"))
        !            41: 
        !            42: struct cmd {
        !            43:        char    *name;
        !            44:        char    *help;
        !            45:        int     (*handler)();
        !            46: };
        !            47: 
        !            48: char   vhelp[] = "toggle verbose mode";
        !            49: char   thelp[] = "toggle packet tracing";
        !            50: char   chelp[] = "connect to remote tftp";
        !            51: char   qhelp[] = "exit tftp";
        !            52: char   hhelp[] = "print help information";
        !            53: char   shelp[] = "send file";
        !            54: char   rhelp[] = "receive file";
        !            55: char   mhelp[] = "set file transfer mode";
        !            56: char   sthelp[] = "show current status";
        !            57: char   xhelp[] = "set per-packet retransmission timeout";
        !            58: char   ihelp[] = "set total retransmission timeout";
        !            59: 
        !            60: struct cmd cmdtab[] = {
        !            61:        { "connect",    chelp,          setpeer },
        !            62:        { "mode",       mhelp,          setmode },
        !            63:        { "put",        shelp,          put },
        !            64:        { "get",        rhelp,          get },
        !            65:        { "quit",       qhelp,          quit },
        !            66:        { "verbose",    vhelp,          setverbose },
        !            67:        { "trace",      thelp,          settrace },
        !            68:        { "status",     sthelp,         status },
        !            69:        { "rexmt",      xhelp,          setrexmt },
        !            70:        { "timeout",    ihelp,          settimeout },
        !            71:        { "?",          hhelp,          help },
        !            72:        0
        !            73: };
        !            74: 
        !            75: struct cmd *getcmd();
        !            76: char   *tail();
        !            77: char   *index();
        !            78: char   *rindex();
        !            79: 
        !            80: main(argc, argv)
        !            81:        char *argv[];
        !            82: {
        !            83:        struct sockaddr_in sin;
        !            84:        int top;
        !            85: 
        !            86:        sp = getservbyname("tftp", "udp");
        !            87:        if (sp == 0) {
        !            88:                fprintf(stderr, "tftp: udp/tftp: unknown service\n");
        !            89:                exit(1);
        !            90:        }
        !            91:        f = socket(AF_INET, SOCK_DGRAM, 0, 0);
        !            92:        if (f < 0) {
        !            93:                perror("tftp: socket");
        !            94:                exit(3);
        !            95:        }
        !            96:        bzero((char *)&sin, sizeof (sin));
        !            97:        sin.sin_family = AF_INET;
        !            98:        if (bind(f, &sin, sizeof (sin)) < 0) {
        !            99:                perror("tftp: bind");
        !           100:                exit(1);
        !           101:        }
        !           102:        strcpy(mode, "netascii");
        !           103:        signal(SIGINT, intr);
        !           104:        if (argc > 1) {
        !           105:                if (setjmp(toplevel) != 0)
        !           106:                        exit(0);
        !           107:                setpeer(argc, argv);
        !           108:        }
        !           109:        top = setjmp(toplevel) == 0;
        !           110:        for (;;)
        !           111:                command(top);
        !           112: }
        !           113: 
        !           114: char   *hostname;
        !           115: char   hnamebuf[32];
        !           116: 
        !           117: setpeer(argc, argv)
        !           118:        int argc;
        !           119:        char *argv[];
        !           120: {
        !           121:        register int c;
        !           122:        struct hostent *host;
        !           123: 
        !           124:        if (argc < 2) {
        !           125:                strcpy(line, "Connect ");
        !           126:                printf("(to) ");
        !           127:                gets(&line[strlen(line)]);
        !           128:                makeargv();
        !           129:                argc = margc;
        !           130:                argv = margv;
        !           131:        }
        !           132:        if (argc > 3) {
        !           133:                printf("usage: %s host-name [port]\n", argv[0]);
        !           134:                return;
        !           135:        }
        !           136:        host = gethostbyname(argv[1]);
        !           137:        if (host) {
        !           138:                sin.sin_family = host->h_addrtype;
        !           139:                bcopy(host->h_addr, &sin.sin_addr, host->h_length);
        !           140:                hostname = host->h_name;
        !           141:        } else {
        !           142:                sin.sin_family = AF_INET;
        !           143:                sin.sin_addr.s_addr = inet_addr(argv[1]);
        !           144:                if (sin.sin_addr.s_addr == -1) {
        !           145:                        connected = 0;
        !           146:                        printf("%s: unknown host\n", argv[1]);
        !           147:                        return;
        !           148:                }
        !           149:                strcpy(hnamebuf, argv[1]);
        !           150:                hostname = hnamebuf;
        !           151:        }
        !           152:        sin.sin_port = sp->s_port;
        !           153:        if (argc == 3) {
        !           154:                sin.sin_port = atoi(argv[2]);
        !           155:                if (sin.sin_port < 0) {
        !           156:                        printf("%s: bad port number\n", argv[2]);
        !           157:                        connected = 0;
        !           158:                        return;
        !           159:                }
        !           160:                sin.sin_port = htons((u_short)sin.sin_port);
        !           161:        }
        !           162:        connected = 1;
        !           163: }
        !           164: 
        !           165: struct modes {
        !           166:        char *m_name;
        !           167:        char *m_mode;
        !           168: } modes[] = {
        !           169:        { "ascii",      "netascii" },
        !           170:        { "binary",     "octect" },
        !           171:        { "mail",       "mail" },
        !           172:        { 0,            0 }
        !           173: };
        !           174: 
        !           175: setmode(argc, argv)
        !           176:        char *argv[];
        !           177: {
        !           178:        register struct modes *p;
        !           179: 
        !           180:        if (argc > 2) {
        !           181:                char *sep;
        !           182: 
        !           183:                printf("usage: %s [", argv[0]);
        !           184:                sep = " ";
        !           185:                for (p = modes; p->m_name; p++) {
        !           186:                        printf("%s%s", sep, p->m_name);
        !           187:                        if (*sep == ' ')
        !           188:                                sep = " | ";
        !           189:                }
        !           190:                printf(" ]\n");
        !           191:                return;
        !           192:        }
        !           193:        if (argc < 2) {
        !           194:                printf("Using %s mode to transfer files.\n", mode);
        !           195:                return;
        !           196:        }
        !           197:        for (p = modes; p->m_name; p++)
        !           198:                if (strcmp(argv[1], p->m_name) == 0)
        !           199:                        break;
        !           200:        if (p->m_name)
        !           201:                strcpy(mode, p->m_mode);
        !           202:        else
        !           203:                printf("%s: unknown mode\n", argv[1]);
        !           204: }
        !           205: 
        !           206: /*
        !           207:  * Send file(s).
        !           208:  */
        !           209: put(argc, argv)
        !           210:        char *argv[];
        !           211: {
        !           212:        int fd;
        !           213:        register int n, addr;
        !           214:        register char *cp, *targ;
        !           215: 
        !           216:        if (argc < 2) {
        !           217:                strcpy(line, "send ");
        !           218:                printf("(file) ");
        !           219:                gets(&line[strlen(line)]);
        !           220:                makeargv();
        !           221:                argc = margc;
        !           222:                argv = margv;
        !           223:        }
        !           224:        if (argc < 2) {
        !           225:                putusage(argv[0]);
        !           226:                return;
        !           227:        }
        !           228:        targ = argv[argc - 1];
        !           229:        if (index(argv[argc - 1], ':')) {
        !           230:                char *cp;
        !           231:                struct hostent *hp;
        !           232: 
        !           233:                for (n = 1; n < argc - 1; n++)
        !           234:                        if (index(argv[n], ':')) {
        !           235:                                putusage(argv[0]);
        !           236:                                return;
        !           237:                        }
        !           238:                cp = argv[argc - 1];
        !           239:                targ = index(cp, ':');
        !           240:                *targ++ = 0;
        !           241:                hp = gethostbyname(cp);
        !           242:                if (hp == 0) {
        !           243:                        printf("%s: Unknown host.\n", cp);
        !           244:                        return;
        !           245:                }
        !           246:                bcopy(hp->h_addr, (caddr_t)&sin.sin_addr, hp->h_length);
        !           247:                sin.sin_family = hp->h_addrtype;
        !           248:                connected = 1;
        !           249:                hostname = hp->h_name;
        !           250:        }
        !           251:        if (!connected) {
        !           252:                printf("No target machine specified.\n");
        !           253:                return;
        !           254:        }
        !           255:        if (argc < 4) {
        !           256:                cp = argc == 2 ? tail(targ) : argv[1];
        !           257:                fd = open(cp, O_RDONLY);
        !           258:                if (fd < 0) {
        !           259:                        fprintf(stderr, "tftp: "); perror(cp);
        !           260:                        return;
        !           261:                }
        !           262:                sendfile(fd, targ);
        !           263:                return;
        !           264:        }
        !           265:        cp = index(targ, '\0'); 
        !           266:        *cp++ = '/';
        !           267:        for (n = 1; n < argc - 1; n++) {
        !           268:                strcpy(cp, tail(argv[n]));
        !           269:                fd = open(argv[n], O_RDONLY);
        !           270:                if (fd < 0) {
        !           271:                        fprintf(stderr, "tftp: "); perror(argv[n]);
        !           272:                        continue;
        !           273:                }
        !           274:                sendfile(fd, targ);
        !           275:        }
        !           276: }
        !           277: 
        !           278: putusage(s)
        !           279:        char *s;
        !           280: {
        !           281:        printf("usage: %s file ... host:target, or\n", s);
        !           282:        printf("       %s file ... target (when already connected)\n", s);
        !           283: }
        !           284: 
        !           285: /*
        !           286:  * Receive file(s).
        !           287:  */
        !           288: get(argc, argv)
        !           289:        char *argv[];
        !           290: {
        !           291:        int fd;
        !           292:        register int n, addr;
        !           293:        register char *cp;
        !           294:        char *src;
        !           295: 
        !           296:        if (argc < 2) {
        !           297:                strcpy(line, "get ");
        !           298:                printf("(files) ");
        !           299:                gets(&line[strlen(line)]);
        !           300:                makeargv();
        !           301:                argc = margc;
        !           302:                argv = margv;
        !           303:        }
        !           304:        if (argc < 2) {
        !           305:                getusage(argv[0]);
        !           306:                return;
        !           307:        }
        !           308:        if (!connected)
        !           309:                for (n = 1; n < argc - 1; n++)
        !           310:                        if (index(argv[n], ':') == 0) {
        !           311:                                getusage(argv[0]);
        !           312:                                return;
        !           313:                        }
        !           314:        for (n = 1; argc == 2 || n < argc - 1; n++) {
        !           315:                src = index(argv[n], ':');
        !           316:                if (src == NULL)
        !           317:                        src = argv[n];
        !           318:                else {
        !           319:                        struct hostent *hp;
        !           320: 
        !           321:                        *src++ = 0;
        !           322:                        hp = gethostbyname(argv[n]);
        !           323:                        if (hp == 0) {
        !           324:                                printf("%s: Unknown host.\n", argv[n]);
        !           325:                                continue;
        !           326:                        }
        !           327:                        bcopy(hp->h_addr, (caddr_t)&sin.sin_addr, hp->h_length);
        !           328:                        sin.sin_family = hp->h_addrtype;
        !           329:                        connected = 1;
        !           330:                        hostname = hp->h_name;
        !           331:                }
        !           332:                if (argc < 4) {
        !           333:                        cp = argc == 3 ? argv[2] : tail(src);
        !           334:                        fd = creat(cp, 0644);
        !           335:                        if (fd < 0) {
        !           336:                                fprintf(stderr, "tftp: "); perror(cp);
        !           337:                                return;
        !           338:                        }
        !           339:                        recvfile(fd, src);
        !           340:                        break;
        !           341:                }
        !           342:                cp = index(argv[argc - 1], '\0');
        !           343:                *cp++ = '/';
        !           344:                strcpy(cp, tail(src));
        !           345:                fd = creat(src, 0644);
        !           346:                if (fd < 0) {
        !           347:                        fprintf(stderr, "tftp: "); perror(src);
        !           348:                        continue;
        !           349:                }
        !           350:                recvfile(fd, src);
        !           351:        }
        !           352: }
        !           353: 
        !           354: getusage(s)
        !           355: {
        !           356:        printf("usage: %s host:file host:file ... file, or\n", s);
        !           357:        printf("       %s file file ... file if connected\n", s);
        !           358: }
        !           359: 
        !           360: int    rexmtval = TIMEOUT;
        !           361: 
        !           362: setrexmt(argc, argv)
        !           363:        char *argv[];
        !           364: {
        !           365:        int t;
        !           366: 
        !           367:        if (argc < 2) {
        !           368:                strcpy(line, "Rexmt-timeout ");
        !           369:                printf("(value) ");
        !           370:                gets(&line[strlen(line)]);
        !           371:                makeargv();
        !           372:                argc = margc;
        !           373:                argv = margv;
        !           374:        }
        !           375:        if (argc != 2) {
        !           376:                printf("usage: %s value\n", argv[0]);
        !           377:                return;
        !           378:        }
        !           379:        t = atoi(argv[1]);
        !           380:        if (t < 0)
        !           381:                printf("%s: bad value\n", t);
        !           382:        else
        !           383:                rexmtval = t;
        !           384: }
        !           385: 
        !           386: int    maxtimeout = 5 * TIMEOUT;
        !           387: 
        !           388: settimeout(argc, argv)
        !           389:        char *argv[];
        !           390: {
        !           391:        int t;
        !           392: 
        !           393:        if (argc < 2) {
        !           394:                strcpy(line, "Maximum-timeout ");
        !           395:                printf("(value) ");
        !           396:                gets(&line[strlen(line)]);
        !           397:                makeargv();
        !           398:                argc = margc;
        !           399:                argv = margv;
        !           400:        }
        !           401:        if (argc != 2) {
        !           402:                printf("usage: %s value\n", argv[0]);
        !           403:                return;
        !           404:        }
        !           405:        t = atoi(argv[1]);
        !           406:        if (t < 0)
        !           407:                printf("%s: bad value\n", t);
        !           408:        else
        !           409:                maxtimeout = t;
        !           410: }
        !           411: 
        !           412: status(argc, argv)
        !           413:        char *argv[];
        !           414: {
        !           415:        if (connected)
        !           416:                printf("Connected to %s.\n", hostname);
        !           417:        else
        !           418:                printf("Not connected.\n");
        !           419:        printf("Mode: %s Verbose: %s Tracing: %s\n", mode,
        !           420:                verbose ? "on" : "off", trace ? "on" : "off");
        !           421:        printf("Rexmt-interval: %d seconds, Max-timeout: %d seconds\n",
        !           422:                rexmtval, maxtimeout);
        !           423: }
        !           424: 
        !           425: intr()
        !           426: {
        !           427: 
        !           428:        longjmp(toplevel, -1);
        !           429: }
        !           430: 
        !           431: char *
        !           432: tail(filename)
        !           433:        char *filename;
        !           434: {
        !           435:        register char *s;
        !           436:        
        !           437:        while (*filename) {
        !           438:                s = rindex(filename, '/');
        !           439:                if (s == NULL)
        !           440:                        break;
        !           441:                if (s[1])
        !           442:                        return (s + 1);
        !           443:                *s = '\0';
        !           444:        }
        !           445:        return (filename);
        !           446: }
        !           447: 
        !           448: /*
        !           449:  * Command parser.
        !           450:  */
        !           451: command(top)
        !           452:        int top;
        !           453: {
        !           454:        register struct cmd *c;
        !           455: 
        !           456:        if (!top)
        !           457:                putchar('\n');
        !           458:        for (;;) {
        !           459:                printf("%s> ", prompt);
        !           460:                if (gets(line) == 0)
        !           461:                        continue;
        !           462:                if (line[0] == 0)
        !           463:                        continue;
        !           464:                makeargv();
        !           465:                c = getcmd(margv[0]);
        !           466:                if (c == (struct cmd *)-1) {
        !           467:                        printf("?Ambiguous command\n");
        !           468:                        continue;
        !           469:                }
        !           470:                if (c == 0) {
        !           471:                        printf("?Invalid command\n");
        !           472:                        continue;
        !           473:                }
        !           474:                (*c->handler)(margc, margv);
        !           475:        }
        !           476: }
        !           477: 
        !           478: struct cmd *
        !           479: getcmd(name)
        !           480:        register char *name;
        !           481: {
        !           482:        register char *p, *q;
        !           483:        register struct cmd *c, *found;
        !           484:        register int nmatches, longest;
        !           485: 
        !           486:        longest = 0;
        !           487:        nmatches = 0;
        !           488:        found = 0;
        !           489:        for (c = cmdtab; p = c->name; c++) {
        !           490:                for (q = name; *q == *p++; q++)
        !           491:                        if (*q == 0)            /* exact match? */
        !           492:                                return (c);
        !           493:                if (!*q) {                      /* the name was a prefix */
        !           494:                        if (q - name > longest) {
        !           495:                                longest = q - name;
        !           496:                                nmatches = 1;
        !           497:                                found = c;
        !           498:                        } else if (q - name == longest)
        !           499:                                nmatches++;
        !           500:                }
        !           501:        }
        !           502:        if (nmatches > 1)
        !           503:                return ((struct cmd *)-1);
        !           504:        return (found);
        !           505: }
        !           506: 
        !           507: /*
        !           508:  * Slice a string up into argc/argv.
        !           509:  */
        !           510: makeargv()
        !           511: {
        !           512:        register char *cp;
        !           513:        register char **argp = margv;
        !           514: 
        !           515:        margc = 0;
        !           516:        for (cp = line; *cp;) {
        !           517:                while (isspace(*cp))
        !           518:                        cp++;
        !           519:                if (*cp == '\0')
        !           520:                        break;
        !           521:                *argp++ = cp;
        !           522:                margc += 1;
        !           523:                while (*cp != '\0' && !isspace(*cp))
        !           524:                        cp++;
        !           525:                if (*cp == '\0')
        !           526:                        break;
        !           527:                *cp++ = '\0';
        !           528:        }
        !           529:        *argp++ = 0;
        !           530: }
        !           531: 
        !           532: /*VARARGS*/
        !           533: quit()
        !           534: {
        !           535:        exit(0);
        !           536: }
        !           537: 
        !           538: /*
        !           539:  * Help command.
        !           540:  */
        !           541: help(argc, argv)
        !           542:        int argc;
        !           543:        char *argv[];
        !           544: {
        !           545:        register struct cmd *c;
        !           546: 
        !           547:        if (argc == 1) {
        !           548:                printf("Commands may be abbreviated.  Commands are:\n\n");
        !           549:                for (c = cmdtab; c->name; c++)
        !           550:                        printf("%-*s\t%s\n", HELPINDENT, c->name, c->help);
        !           551:                return;
        !           552:        }
        !           553:        while (--argc > 0) {
        !           554:                register char *arg;
        !           555:                arg = *++argv;
        !           556:                c = getcmd(arg);
        !           557:                if (c == (struct cmd *)-1)
        !           558:                        printf("?Ambiguous help command %s\n", arg);
        !           559:                else if (c == (struct cmd *)0)
        !           560:                        printf("?Invalid help command %s\n", arg);
        !           561:                else
        !           562:                        printf("%s\n", c->help);
        !           563:        }
        !           564: }
        !           565: 
        !           566: /*
        !           567:  * Call routine with argc, argv set from args (terminated by 0).
        !           568:  */
        !           569: /* VARARGS2 */
        !           570: call(routine, args)
        !           571:        int (*routine)();
        !           572:        int args;
        !           573: {
        !           574:        register int *argp;
        !           575:        register int argc;
        !           576: 
        !           577:        for (argc = 0, argp = &args; *argp++ != 0; argc++)
        !           578:                ;
        !           579:        (*routine)(argc, &args);
        !           580: }
        !           581: 
        !           582: /*VARARGS*/
        !           583: settrace()
        !           584: {
        !           585:        trace = !trace;
        !           586:        printf("Packet tracing %s.\n", trace ? "on" : "off");
        !           587: }
        !           588: 
        !           589: /*VARARGS*/
        !           590: setverbose()
        !           591: {
        !           592:        verbose = !verbose;
        !           593:        printf("Verbose mode %s.\n", verbose ? "on" : "off");
        !           594: }

unix.superglobalmegacorp.com

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