122403Sdist /* 226095Sminshall * Copyright (c) 1985 Regents of the University of California. 322403Sdist * All rights reserved. The Berkeley software License Agreement 422403Sdist * specifies the terms and conditions for redistribution. 522403Sdist */ 622403Sdist 714553Ssam #ifndef lint 822403Sdist char copyright[] = 922403Sdist "@(#) Copyright (c) 1983 Regents of the University of California.\n\ 1022403Sdist All rights reserved.\n"; 1122403Sdist #endif not lint 127769Ssam 1322403Sdist #ifndef lint 14*26110Sminshall static char sccsid[] = "@(#)main.c 5.5 (Berkeley) 02/07/86"; 1522403Sdist #endif not lint 1622403Sdist 1726095Sminshall /* Many bug fixes are from Jim Guyton <guyton@rand-unix> */ 1826095Sminshall 197769Ssam /* 207769Ssam * TFTP User Program -- Command Interface. 217769Ssam */ 227769Ssam #include <sys/types.h> 237769Ssam #include <sys/socket.h> 2413017Ssam #include <sys/file.h> 259219Ssam 269219Ssam #include <netinet/in.h> 279219Ssam 287769Ssam #include <signal.h> 297769Ssam #include <stdio.h> 307769Ssam #include <errno.h> 317769Ssam #include <setjmp.h> 327769Ssam #include <ctype.h> 338384Ssam #include <netdb.h> 347769Ssam 3513017Ssam #define TIMEOUT 5 /* secs between rexmt's */ 3613017Ssam 3726095Sminshall struct sockaddr_in sin; 387769Ssam int f; 3926095Sminshall short port; 407769Ssam int trace; 4126095Sminshall int verbose; 427769Ssam int connected; 437769Ssam char mode[32]; 447769Ssam char line[200]; 457769Ssam int margc; 467769Ssam char *margv[20]; 477769Ssam char *prompt = "tftp"; 487769Ssam jmp_buf toplevel; 497769Ssam int intr(); 508384Ssam struct servent *sp; 517769Ssam 5226095Sminshall int quit(), help(), setverbose(), settrace(), status(); 5326095Sminshall int get(), put(), setpeer(), modecmd(), setrexmt(), settimeout(); 5426095Sminshall int setbinary(), setascii(); 557769Ssam 567769Ssam #define HELPINDENT (sizeof("connect")) 577769Ssam 587769Ssam struct cmd { 597769Ssam char *name; 607769Ssam char *help; 617769Ssam int (*handler)(); 627769Ssam }; 637769Ssam 6426095Sminshall char vhelp[] = "toggle verbose mode"; 657769Ssam char thelp[] = "toggle packet tracing"; 667769Ssam char chelp[] = "connect to remote tftp"; 677769Ssam char qhelp[] = "exit tftp"; 687769Ssam char hhelp[] = "print help information"; 697769Ssam char shelp[] = "send file"; 707769Ssam char rhelp[] = "receive file"; 717769Ssam char mhelp[] = "set file transfer mode"; 727769Ssam char sthelp[] = "show current status"; 7313017Ssam char xhelp[] = "set per-packet retransmission timeout"; 7413017Ssam char ihelp[] = "set total retransmission timeout"; 7526095Sminshall char ashelp[] = "set mode to netascii"; 7626095Sminshall char bnhelp[] = "set mode to octet"; 777769Ssam 787769Ssam struct cmd cmdtab[] = { 797769Ssam { "connect", chelp, setpeer }, 8026095Sminshall { "mode", mhelp, modecmd }, 817769Ssam { "put", shelp, put }, 827769Ssam { "get", rhelp, get }, 837769Ssam { "quit", qhelp, quit }, 8426095Sminshall { "verbose", vhelp, setverbose }, 857769Ssam { "trace", thelp, settrace }, 867769Ssam { "status", sthelp, status }, 8726095Sminshall { "binary", bnhelp, setbinary }, 8826095Sminshall { "ascii", ashelp, setascii }, 8913017Ssam { "rexmt", xhelp, setrexmt }, 9013017Ssam { "timeout", ihelp, settimeout }, 917769Ssam { "?", hhelp, help }, 927769Ssam 0 937769Ssam }; 947769Ssam 957769Ssam struct cmd *getcmd(); 967769Ssam char *tail(); 977769Ssam char *index(); 987769Ssam char *rindex(); 997769Ssam 1007769Ssam main(argc, argv) 1017769Ssam char *argv[]; 1027769Ssam { 10326095Sminshall struct sockaddr_in sin; 10413017Ssam int top; 10513017Ssam 1068384Ssam sp = getservbyname("tftp", "udp"); 1078384Ssam if (sp == 0) { 1088384Ssam fprintf(stderr, "tftp: udp/tftp: unknown service\n"); 1098384Ssam exit(1); 1108384Ssam } 111*26110Sminshall f = socket(AF_INET, SOCK_DGRAM, 0); 1127769Ssam if (f < 0) { 11313017Ssam perror("tftp: socket"); 1147769Ssam exit(3); 1157769Ssam } 11626095Sminshall bzero((char *)&sin, sizeof (sin)); 11726095Sminshall sin.sin_family = AF_INET; 11813017Ssam if (bind(f, &sin, sizeof (sin)) < 0) { 11913017Ssam perror("tftp: bind"); 12013017Ssam exit(1); 12113017Ssam } 12226095Sminshall strcpy(mode, "netascii"); 12313017Ssam signal(SIGINT, intr); 1247769Ssam if (argc > 1) { 1257769Ssam if (setjmp(toplevel) != 0) 1267769Ssam exit(0); 1277769Ssam setpeer(argc, argv); 1287769Ssam } 12913017Ssam top = setjmp(toplevel) == 0; 1307769Ssam for (;;) 13113017Ssam command(top); 1327769Ssam } 1337769Ssam 13426095Sminshall char hostname[100]; 1357769Ssam 1367769Ssam setpeer(argc, argv) 1377769Ssam int argc; 1387769Ssam char *argv[]; 1397769Ssam { 1408384Ssam struct hostent *host; 1417769Ssam 1427769Ssam if (argc < 2) { 1437769Ssam strcpy(line, "Connect "); 1447769Ssam printf("(to) "); 1457769Ssam gets(&line[strlen(line)]); 1467769Ssam makeargv(); 1477769Ssam argc = margc; 1487769Ssam argv = margv; 1497769Ssam } 1507769Ssam if (argc > 3) { 1517769Ssam printf("usage: %s host-name [port]\n", argv[0]); 1527769Ssam return; 1537769Ssam } 1548384Ssam host = gethostbyname(argv[1]); 1558384Ssam if (host) { 1569219Ssam sin.sin_family = host->h_addrtype; 1578384Ssam bcopy(host->h_addr, &sin.sin_addr, host->h_length); 15826095Sminshall strcpy(hostname, host->h_name); 1598384Ssam } else { 1609219Ssam sin.sin_family = AF_INET; 1618384Ssam sin.sin_addr.s_addr = inet_addr(argv[1]); 1628384Ssam if (sin.sin_addr.s_addr == -1) { 1638384Ssam connected = 0; 1648384Ssam printf("%s: unknown host\n", argv[1]); 1658384Ssam return; 1668384Ssam } 16726095Sminshall strcpy(hostname, argv[1]); 1687769Ssam } 16926095Sminshall port = sp->s_port; 1707769Ssam if (argc == 3) { 17126095Sminshall port = atoi(argv[2]); 17226095Sminshall if (port < 0) { 1737769Ssam printf("%s: bad port number\n", argv[2]); 1747769Ssam connected = 0; 1757769Ssam return; 1767769Ssam } 17726095Sminshall port = htons(port); 1788384Ssam } 1797769Ssam connected = 1; 1807769Ssam } 1817769Ssam 1827769Ssam struct modes { 1837769Ssam char *m_name; 1847769Ssam char *m_mode; 1857769Ssam } modes[] = { 18626095Sminshall { "ascii", "netascii" }, 18726095Sminshall { "netascii", "netascii" }, 18826095Sminshall { "binary", "octet" }, 18926095Sminshall { "image", "octet" }, 19026103Sminshall { "octet", "octet" }, 19126095Sminshall /* { "mail", "mail" }, */ 1927769Ssam { 0, 0 } 1937769Ssam }; 1947769Ssam 19526095Sminshall modecmd(argc, argv) 1967769Ssam char *argv[]; 1977769Ssam { 1987769Ssam register struct modes *p; 19926095Sminshall char *sep; 2007769Ssam 2017769Ssam if (argc < 2) { 2027769Ssam printf("Using %s mode to transfer files.\n", mode); 2037769Ssam return; 2047769Ssam } 20526095Sminshall if (argc == 2) { 20626095Sminshall for (p = modes; p->m_name; p++) 20726095Sminshall if (strcmp(argv[1], p->m_name) == 0) 20826095Sminshall break; 20926095Sminshall if (p->m_name) { 21026095Sminshall setmode(p->m_mode); 21126095Sminshall return; 21226095Sminshall } 2137769Ssam printf("%s: unknown mode\n", argv[1]); 21426095Sminshall /* drop through and print usage message */ 21526095Sminshall } 21626095Sminshall 21726095Sminshall printf("usage: %s [", argv[0]); 21826095Sminshall sep = " "; 21926095Sminshall for (p = modes; p->m_name; p++) { 22026095Sminshall printf("%s%s", sep, p->m_name); 22126095Sminshall if (*sep == ' ') 22226095Sminshall sep = " | "; 22326095Sminshall } 22426095Sminshall printf(" ]\n"); 22526095Sminshall return; 2267769Ssam } 2277769Ssam 22826095Sminshall setbinary(argc, argv) 22926095Sminshall char *argv[]; 23026095Sminshall { setmode("octet"); 23126095Sminshall } 23226095Sminshall 23326095Sminshall setascii(argc, argv) 23426095Sminshall char *argv[]; 23526095Sminshall { setmode("netascii"); 23626095Sminshall } 23726095Sminshall 23826095Sminshall setmode(newmode) 23926095Sminshall char *newmode; 24026095Sminshall { 24126095Sminshall strcpy(mode, newmode); 24226095Sminshall if (verbose) 24326095Sminshall printf("mode set to %s\n", mode); 24426095Sminshall } 24526095Sminshall 24626095Sminshall 2477769Ssam /* 2487769Ssam * Send file(s). 2497769Ssam */ 2507769Ssam put(argc, argv) 2517769Ssam char *argv[]; 2527769Ssam { 2537769Ssam int fd; 25426095Sminshall register int n; 2557769Ssam register char *cp, *targ; 2567769Ssam 2577769Ssam if (argc < 2) { 2587769Ssam strcpy(line, "send "); 2597769Ssam printf("(file) "); 2607769Ssam gets(&line[strlen(line)]); 2617769Ssam makeargv(); 2627769Ssam argc = margc; 2637769Ssam argv = margv; 2647769Ssam } 2657769Ssam if (argc < 2) { 2667769Ssam putusage(argv[0]); 2677769Ssam return; 2687769Ssam } 2697769Ssam targ = argv[argc - 1]; 2707769Ssam if (index(argv[argc - 1], ':')) { 2718384Ssam char *cp; 2728384Ssam struct hostent *hp; 2737769Ssam 2747769Ssam for (n = 1; n < argc - 1; n++) 2757769Ssam if (index(argv[n], ':')) { 2767769Ssam putusage(argv[0]); 2777769Ssam return; 2787769Ssam } 2798384Ssam cp = argv[argc - 1]; 2808384Ssam targ = index(cp, ':'); 2817769Ssam *targ++ = 0; 2828384Ssam hp = gethostbyname(cp); 2838384Ssam if (hp == 0) { 2848384Ssam printf("%s: Unknown host.\n", cp); 2857769Ssam return; 2867769Ssam } 2879219Ssam bcopy(hp->h_addr, (caddr_t)&sin.sin_addr, hp->h_length); 2888384Ssam sin.sin_family = hp->h_addrtype; 2897769Ssam connected = 1; 29026095Sminshall strcpy(hostname, hp->h_name); 2917769Ssam } 2927769Ssam if (!connected) { 2937769Ssam printf("No target machine specified.\n"); 2947769Ssam return; 2957769Ssam } 2967769Ssam if (argc < 4) { 2977769Ssam cp = argc == 2 ? tail(targ) : argv[1]; 29813017Ssam fd = open(cp, O_RDONLY); 2997769Ssam if (fd < 0) { 30013017Ssam fprintf(stderr, "tftp: "); perror(cp); 3017769Ssam return; 3027769Ssam } 30326095Sminshall if (verbose) 30426095Sminshall printf("putting %s to %s:%s [%s]\n", 30526095Sminshall cp, hostname, targ, mode); 30626095Sminshall sin.sin_port = port; 30726095Sminshall sendfile(fd, targ, mode); 3087769Ssam return; 3097769Ssam } 31026095Sminshall /* this assumes the target is a directory */ 31126095Sminshall /* on a remote unix system. hmmmm. */ 3127769Ssam cp = index(targ, '\0'); 3137769Ssam *cp++ = '/'; 3147769Ssam for (n = 1; n < argc - 1; n++) { 3157769Ssam strcpy(cp, tail(argv[n])); 31613017Ssam fd = open(argv[n], O_RDONLY); 3177769Ssam if (fd < 0) { 31813017Ssam fprintf(stderr, "tftp: "); perror(argv[n]); 3197769Ssam continue; 3207769Ssam } 32126095Sminshall if (verbose) 32226095Sminshall printf("putting %s to %s:%s [%s]\n", 32326095Sminshall argv[n], hostname, targ, mode); 32426095Sminshall sin.sin_port = port; 32526095Sminshall sendfile(fd, targ, mode); 3267769Ssam } 3277769Ssam } 3287769Ssam 3297769Ssam putusage(s) 3307769Ssam char *s; 3317769Ssam { 3327769Ssam printf("usage: %s file ... host:target, or\n", s); 3337769Ssam printf(" %s file ... target (when already connected)\n", s); 3347769Ssam } 3357769Ssam 3367769Ssam /* 3377769Ssam * Receive file(s). 3387769Ssam */ 3397769Ssam get(argc, argv) 3407769Ssam char *argv[]; 3417769Ssam { 3427769Ssam int fd; 34326095Sminshall register int n; 3447769Ssam register char *cp; 3457769Ssam char *src; 3467769Ssam 3477769Ssam if (argc < 2) { 3487769Ssam strcpy(line, "get "); 3497769Ssam printf("(files) "); 3507769Ssam gets(&line[strlen(line)]); 3517769Ssam makeargv(); 3527769Ssam argc = margc; 3537769Ssam argv = margv; 3547769Ssam } 3557769Ssam if (argc < 2) { 3567769Ssam getusage(argv[0]); 3577769Ssam return; 3587769Ssam } 35926095Sminshall if (!connected) { 36026095Sminshall for (n = 1; n < argc ; n++) 3617769Ssam if (index(argv[n], ':') == 0) { 3627769Ssam getusage(argv[0]); 3637769Ssam return; 3647769Ssam } 36526095Sminshall } 36626095Sminshall for (n = 1; n < argc ; n++) { 3677769Ssam src = index(argv[n], ':'); 3687769Ssam if (src == NULL) 3697769Ssam src = argv[n]; 3707769Ssam else { 3718384Ssam struct hostent *hp; 3728384Ssam 3737769Ssam *src++ = 0; 3748384Ssam hp = gethostbyname(argv[n]); 3758384Ssam if (hp == 0) { 3767769Ssam printf("%s: Unknown host.\n", argv[n]); 3777769Ssam continue; 3787769Ssam } 3799219Ssam bcopy(hp->h_addr, (caddr_t)&sin.sin_addr, hp->h_length); 3808384Ssam sin.sin_family = hp->h_addrtype; 3817769Ssam connected = 1; 38226095Sminshall strcpy(hostname, hp->h_name); 3837769Ssam } 3847769Ssam if (argc < 4) { 3857769Ssam cp = argc == 3 ? argv[2] : tail(src); 3867769Ssam fd = creat(cp, 0644); 3877769Ssam if (fd < 0) { 38813017Ssam fprintf(stderr, "tftp: "); perror(cp); 3897769Ssam return; 3907769Ssam } 39126095Sminshall if (verbose) 39226095Sminshall printf("getting from %s:%s to %s [%s]\n", 39326095Sminshall hostname, src, cp, mode); 39426095Sminshall sin.sin_port = port; 39526095Sminshall recvfile(fd, src, mode); 3967769Ssam break; 3977769Ssam } 39826095Sminshall cp = tail(src); /* new .. jdg */ 39926095Sminshall fd = creat(cp, 0644); 4007769Ssam if (fd < 0) { 40126095Sminshall fprintf(stderr, "tftp: "); perror(cp); 4027769Ssam continue; 4037769Ssam } 40426095Sminshall if (verbose) 40526095Sminshall printf("getting from %s:%s to %s [%s]\n", 40626095Sminshall hostname, src, cp, mode); 40726095Sminshall sin.sin_port = port; 40826095Sminshall recvfile(fd, src, mode); 4097769Ssam } 4107769Ssam } 4117769Ssam 4127769Ssam getusage(s) 413*26110Sminshall char * s; 4147769Ssam { 4157769Ssam printf("usage: %s host:file host:file ... file, or\n", s); 4167769Ssam printf(" %s file file ... file if connected\n", s); 4177769Ssam } 4187769Ssam 41913017Ssam int rexmtval = TIMEOUT; 42013017Ssam 42113017Ssam setrexmt(argc, argv) 42213017Ssam char *argv[]; 42313017Ssam { 42413017Ssam int t; 42513017Ssam 42613017Ssam if (argc < 2) { 42713017Ssam strcpy(line, "Rexmt-timeout "); 42813017Ssam printf("(value) "); 42913017Ssam gets(&line[strlen(line)]); 43013017Ssam makeargv(); 43113017Ssam argc = margc; 43213017Ssam argv = margv; 43313017Ssam } 43413017Ssam if (argc != 2) { 43513017Ssam printf("usage: %s value\n", argv[0]); 43613017Ssam return; 43713017Ssam } 43813017Ssam t = atoi(argv[1]); 43913017Ssam if (t < 0) 44013017Ssam printf("%s: bad value\n", t); 44113017Ssam else 44213017Ssam rexmtval = t; 44313017Ssam } 44413017Ssam 44513017Ssam int maxtimeout = 5 * TIMEOUT; 44613017Ssam 44713017Ssam settimeout(argc, argv) 44813017Ssam char *argv[]; 44913017Ssam { 45013017Ssam int t; 45113017Ssam 45213017Ssam if (argc < 2) { 45313017Ssam strcpy(line, "Maximum-timeout "); 45413017Ssam printf("(value) "); 45513017Ssam gets(&line[strlen(line)]); 45613017Ssam makeargv(); 45713017Ssam argc = margc; 45813017Ssam argv = margv; 45913017Ssam } 46013017Ssam if (argc != 2) { 46113017Ssam printf("usage: %s value\n", argv[0]); 46213017Ssam return; 46313017Ssam } 46413017Ssam t = atoi(argv[1]); 46513017Ssam if (t < 0) 46613017Ssam printf("%s: bad value\n", t); 46713017Ssam else 46813017Ssam maxtimeout = t; 46913017Ssam } 47013017Ssam 4717769Ssam status(argc, argv) 4727769Ssam char *argv[]; 4737769Ssam { 4747769Ssam if (connected) 4758384Ssam printf("Connected to %s.\n", hostname); 4767769Ssam else 4777769Ssam printf("Not connected.\n"); 47826095Sminshall printf("Mode: %s Verbose: %s Tracing: %s\n", mode, 47926095Sminshall verbose ? "on" : "off", trace ? "on" : "off"); 48013017Ssam printf("Rexmt-interval: %d seconds, Max-timeout: %d seconds\n", 48113017Ssam rexmtval, maxtimeout); 4827769Ssam } 4837769Ssam 4847769Ssam intr() 4857769Ssam { 48626095Sminshall signal(SIGALRM, SIG_IGN); 48716382Ssam alarm(0); 4887769Ssam longjmp(toplevel, -1); 4897769Ssam } 4907769Ssam 4917769Ssam char * 4927769Ssam tail(filename) 4937769Ssam char *filename; 4947769Ssam { 4957769Ssam register char *s; 4967769Ssam 4977769Ssam while (*filename) { 4987769Ssam s = rindex(filename, '/'); 4997769Ssam if (s == NULL) 5007769Ssam break; 5017769Ssam if (s[1]) 5027769Ssam return (s + 1); 5037769Ssam *s = '\0'; 5047769Ssam } 5057769Ssam return (filename); 5067769Ssam } 5077769Ssam 5087769Ssam /* 5097769Ssam * Command parser. 5107769Ssam */ 5117769Ssam command(top) 5127769Ssam int top; 5137769Ssam { 5147769Ssam register struct cmd *c; 5157769Ssam 5167769Ssam if (!top) 5177769Ssam putchar('\n'); 5187769Ssam for (;;) { 5197769Ssam printf("%s> ", prompt); 52026103Sminshall if (gets(line) == 0) { 52126103Sminshall if (feof(stdin)) { 52226103Sminshall quit(); 52326103Sminshall } else { 52426103Sminshall continue; 52526103Sminshall } 52626103Sminshall } 5277769Ssam if (line[0] == 0) 52813017Ssam continue; 5297769Ssam makeargv(); 5307769Ssam c = getcmd(margv[0]); 5317769Ssam if (c == (struct cmd *)-1) { 5327769Ssam printf("?Ambiguous command\n"); 5337769Ssam continue; 5347769Ssam } 5357769Ssam if (c == 0) { 5367769Ssam printf("?Invalid command\n"); 5377769Ssam continue; 5387769Ssam } 5397769Ssam (*c->handler)(margc, margv); 5407769Ssam } 5417769Ssam } 5427769Ssam 5437769Ssam struct cmd * 5447769Ssam getcmd(name) 5457769Ssam register char *name; 5467769Ssam { 5477769Ssam register char *p, *q; 5487769Ssam register struct cmd *c, *found; 5497769Ssam register int nmatches, longest; 5507769Ssam 5517769Ssam longest = 0; 5527769Ssam nmatches = 0; 5537769Ssam found = 0; 5547769Ssam for (c = cmdtab; p = c->name; c++) { 5557769Ssam for (q = name; *q == *p++; q++) 5567769Ssam if (*q == 0) /* exact match? */ 5577769Ssam return (c); 5587769Ssam if (!*q) { /* the name was a prefix */ 5597769Ssam if (q - name > longest) { 5607769Ssam longest = q - name; 5617769Ssam nmatches = 1; 5627769Ssam found = c; 5637769Ssam } else if (q - name == longest) 5647769Ssam nmatches++; 5657769Ssam } 5667769Ssam } 5677769Ssam if (nmatches > 1) 5687769Ssam return ((struct cmd *)-1); 5697769Ssam return (found); 5707769Ssam } 5717769Ssam 5727769Ssam /* 5737769Ssam * Slice a string up into argc/argv. 5747769Ssam */ 5757769Ssam makeargv() 5767769Ssam { 5777769Ssam register char *cp; 5787769Ssam register char **argp = margv; 5797769Ssam 5807769Ssam margc = 0; 5817769Ssam for (cp = line; *cp;) { 5827769Ssam while (isspace(*cp)) 5837769Ssam cp++; 5847769Ssam if (*cp == '\0') 5857769Ssam break; 5867769Ssam *argp++ = cp; 5877769Ssam margc += 1; 5887769Ssam while (*cp != '\0' && !isspace(*cp)) 5897769Ssam cp++; 5907769Ssam if (*cp == '\0') 5917769Ssam break; 5927769Ssam *cp++ = '\0'; 5937769Ssam } 5947769Ssam *argp++ = 0; 5957769Ssam } 5967769Ssam 5977769Ssam /*VARARGS*/ 5987769Ssam quit() 5997769Ssam { 6007769Ssam exit(0); 6017769Ssam } 6027769Ssam 6037769Ssam /* 6047769Ssam * Help command. 6057769Ssam */ 6067769Ssam help(argc, argv) 6077769Ssam int argc; 6087769Ssam char *argv[]; 6097769Ssam { 6107769Ssam register struct cmd *c; 6117769Ssam 6127769Ssam if (argc == 1) { 6137769Ssam printf("Commands may be abbreviated. Commands are:\n\n"); 6147769Ssam for (c = cmdtab; c->name; c++) 6157769Ssam printf("%-*s\t%s\n", HELPINDENT, c->name, c->help); 6167769Ssam return; 6177769Ssam } 6187769Ssam while (--argc > 0) { 6197769Ssam register char *arg; 6207769Ssam arg = *++argv; 6217769Ssam c = getcmd(arg); 6227769Ssam if (c == (struct cmd *)-1) 6237769Ssam printf("?Ambiguous help command %s\n", arg); 6247769Ssam else if (c == (struct cmd *)0) 6257769Ssam printf("?Invalid help command %s\n", arg); 6267769Ssam else 6277769Ssam printf("%s\n", c->help); 6287769Ssam } 6297769Ssam } 6307769Ssam 6317769Ssam /*VARARGS*/ 6327769Ssam settrace() 6337769Ssam { 6347769Ssam trace = !trace; 6357769Ssam printf("Packet tracing %s.\n", trace ? "on" : "off"); 6367769Ssam } 63726095Sminshall 63826095Sminshall /*VARARGS*/ 63926095Sminshall setverbose() 64026095Sminshall { 64126095Sminshall verbose = !verbose; 64226095Sminshall printf("Verbose mode %s.\n", verbose ? "on" : "off"); 64326095Sminshall } 644