diff options
Diffstat (limited to 'contrib/tftp/main.c')
-rw-r--r-- | contrib/tftp/main.c | 684 |
1 files changed, 0 insertions, 684 deletions
diff --git a/contrib/tftp/main.c b/contrib/tftp/main.c deleted file mode 100644 index ca4427a17..000000000 --- a/contrib/tftp/main.c +++ /dev/null @@ -1,684 +0,0 @@ -/* - * Copyright (c) 1983 Regents of the University of California. - * All rights reserved. - * - * Redistribution and use in source and binary forms are permitted - * provided that the above copyright notice and this paragraph are - * duplicated in all such forms and that any documentation, - * advertising materials, and other materials related to such - * distribution and use acknowledge that the software was developed - * by the University of California, Berkeley. The name of the - * University may not be used to endorse or promote products derived - * from this software without specific prior written permission. - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ - -#ifndef lint -char copyright[] = -"@(#) Copyright (c) 1983 Regents of the University of California.\n\ - All rights reserved.\n"; -#endif /* not lint */ - -#ifndef lint -static char sccsid[] = "@(#)main.c 5.8 (Berkeley) 10/11/88"; -#endif /* not lint */ - -/* Many bug fixes are from Jim Guyton <guyton@rand-unix> */ - -/* - * TFTP User Program -- Command Interface. - */ -#include <sys/types.h> -#include <sys/socket.h> -#include <sys/file.h> - -#include <netinet/in.h> - -#include <signal.h> -#include <stdio.h> -#include <errno.h> -#include <setjmp.h> -#include <ctype.h> -#include <netdb.h> - -#define TIMEOUT 5 /* secs between rexmt's */ - -struct sockaddr_in sin; -int f; -short port; -int trace; -int verbose; -int connected; -char mode[32]; -char line[200]; -int margc; -char *margv[20]; -char *prompt = "tftp"; -jmp_buf toplevel; -void intr(int); -struct servent *sp; - -int segsize = 512; - -int quit(), help(), setverbose(), settrace(), status(); -int get(), put(), setpeer(), modecmd(), setrexmt(), settimeout(); -int setbinary(), setascii(), setblocksize(); - -#define HELPINDENT (sizeof("connect")) - -struct cmd { - char *name; - char *help; - int (*handler)(); -}; - -char vhelp[] = "toggle verbose mode"; -char thelp[] = "toggle packet tracing"; -char chelp[] = "connect to remote tftp"; -char qhelp[] = "exit tftp"; -char hhelp[] = "print help information"; -char shelp[] = "send file"; -char rhelp[] = "receive file"; -char mhelp[] = "set file transfer mode"; -char sthelp[] = "show current status"; -char xhelp[] = "set per-packet retransmission timeout"; -char ihelp[] = "set total retransmission timeout"; -char ashelp[] = "set mode to netascii"; -char bnhelp[] = "set mode to octet"; -char bshelp[] = "set blocksize for next transfer"; - -struct cmd cmdtab[] = { - { "connect", chelp, setpeer }, - { "mode", mhelp, modecmd }, - { "put", shelp, put }, - { "get", rhelp, get }, - { "quit", qhelp, quit }, - { "verbose", vhelp, setverbose }, - { "trace", thelp, settrace }, - { "status", sthelp, status }, - { "binary", bnhelp, setbinary }, - { "ascii", ashelp, setascii }, - { "rexmt", xhelp, setrexmt }, - { "timeout", ihelp, settimeout }, - { "blocksize", bshelp, setblocksize }, - { "?", hhelp, help }, - 0 -}; - -struct cmd *getcmd(); -char *tail(); -char *index(); -char *rindex(); - -main(argc, argv) - char *argv[]; -{ - struct sockaddr_in sin; - int top; - - sp = getservbyname("tftp", "udp"); - if (sp == 0) { - fprintf(stderr, "tftp: udp/tftp: unknown service\n"); - exit(1); - } - f = socket(AF_INET, SOCK_DGRAM, 0); - if (f < 0) { - perror("tftp: socket"); - exit(3); - } - bzero((char *)&sin, sizeof (sin)); - sin.sin_family = AF_INET; - if (bind(f, (struct sockaddr *)&sin, sizeof (sin)) < 0) { - perror("tftp: bind"); - exit(1); - } - strcpy(mode, "netascii"); - signal(SIGINT, intr); - if (argc > 1) { - if (setjmp(toplevel) != 0) - exit(0); - setpeer(argc, argv); - } - top = setjmp(toplevel) == 0; - for (;;) - command(top); -} - -char hostname[100]; - -setpeer(argc, argv) - int argc; - char *argv[]; -{ - struct hostent *host; - - if (argc < 2) { - strcpy(line, "Connect "); - printf("(to) "); - fgets(&line[strlen(line)], sizeof(line) - strlen(line) - 1, stdin); - makeargv(); - argc = margc; - argv = margv; - } - if (argc > 3) { - printf("usage: %s host-name [port]\n", argv[0]); - return; - } - host = gethostbyname(argv[1]); - if (host) { - sin.sin_family = host->h_addrtype; - bcopy(host->h_addr, &sin.sin_addr, host->h_length); - strcpy(hostname, host->h_name); - } else { - sin.sin_family = AF_INET; - sin.sin_addr.s_addr = inet_addr(argv[1]); - if (sin.sin_addr.s_addr == -1) { - connected = 0; - printf("%s: unknown host\n", argv[1]); - return; - } - strcpy(hostname, argv[1]); - } - port = sp->s_port; - if (argc == 3) { - port = atoi(argv[2]); - if (port < 0) { - printf("%s: bad port number\n", argv[2]); - connected = 0; - return; - } - port = htons(port); - } - connected = 1; -} - -struct modes { - char *m_name; - char *m_mode; -} modes[] = { - { "ascii", "netascii" }, - { "netascii", "netascii" }, - { "binary", "octet" }, - { "image", "octet" }, - { "octet", "octet" }, -/* { "mail", "mail" }, */ - { 0, 0 } -}; - -modecmd(argc, argv) - char *argv[]; -{ - register struct modes *p; - char *sep; - - if (argc < 2) { - printf("Using %s mode to transfer files.\n", mode); - return; - } - if (argc == 2) { - for (p = modes; p->m_name; p++) - if (strcmp(argv[1], p->m_name) == 0) - break; - if (p->m_name) { - setmode(p->m_mode); - return; - } - printf("%s: unknown mode\n", argv[1]); - /* drop through and print usage message */ - } - - printf("usage: %s [", argv[0]); - sep = " "; - for (p = modes; p->m_name; p++) { - printf("%s%s", sep, p->m_name); - if (*sep == ' ') - sep = " | "; - } - printf(" ]\n"); - return; -} - -setbinary(argc, argv) -char *argv[]; -{ setmode("octet"); -} - -setascii(argc, argv) -char *argv[]; -{ setmode("netascii"); -} - -setmode(newmode) -char *newmode; -{ - strcpy(mode, newmode); - if (verbose) - printf("mode set to %s\n", mode); -} - - -/* - * Send file(s). - */ -put(argc, argv) - char *argv[]; -{ - int fd; - register int n; - register char *cp, *targ; - - if (argc < 2) { - strcpy(line, "send "); - printf("(file) "); - fgets(&line[strlen(line)], sizeof(line) - strlen(line) - 1, stdin); - makeargv(); - argc = margc; - argv = margv; - } - if (argc < 2) { - putusage(argv[0]); - return; - } - targ = argv[argc - 1]; - if (index(argv[argc - 1], ':')) { - char *cp; - struct hostent *hp; - - for (n = 1; n < argc - 1; n++) - if (index(argv[n], ':')) { - putusage(argv[0]); - return; - } - cp = argv[argc - 1]; - targ = index(cp, ':'); - *targ++ = 0; - hp = gethostbyname(cp); - if (hp == NULL) { - fprintf(stderr, "tftp: %s: ", cp); - herror((char *)NULL); - return; - } - bcopy(hp->h_addr, (caddr_t)&sin.sin_addr, hp->h_length); - sin.sin_family = hp->h_addrtype; - connected = 1; - strcpy(hostname, hp->h_name); - } - if (!connected) { - printf("No target machine specified.\n"); - return; - } - if (argc < 4) { - cp = argc == 2 ? tail(targ) : argv[1]; - fd = open(cp, O_RDONLY); - if (fd < 0) { - fprintf(stderr, "tftp: "); perror(cp); - return; - } - if (verbose) - printf("putting %s to %s:%s [%s]\n", - cp, hostname, targ, mode); - sin.sin_port = port; - sendfile(fd, targ, mode); - return; - } - /* this assumes the target is a directory */ - /* on a remote unix system. hmmmm. */ - cp = index(targ, '\0'); - *cp++ = '/'; - for (n = 1; n < argc - 1; n++) { - strcpy(cp, tail(argv[n])); - fd = open(argv[n], O_RDONLY); - if (fd < 0) { - fprintf(stderr, "tftp: "); perror(argv[n]); - continue; - } - if (verbose) - printf("putting %s to %s:%s [%s]\n", - argv[n], hostname, targ, mode); - sin.sin_port = port; - sendfile(fd, targ, mode); - } -} - -putusage(s) - char *s; -{ - printf("usage: %s file ... host:target, or\n", s); - printf(" %s file ... target (when already connected)\n", s); -} - -/* - * Receive file(s). - */ -get(argc, argv) - char *argv[]; -{ - int fd; - register int n; - register char *cp; - char *src; - - if (argc < 2) { - strcpy(line, "get "); - printf("(files) "); - fgets(&line[strlen(line)], sizeof(line) - strlen(line) - 1, stdin); - makeargv(); - argc = margc; - argv = margv; - } - if (argc < 2) { - getusage(argv[0]); - return; - } - if (!connected) { - for (n = 1; n < argc ; n++) - if (index(argv[n], ':') == 0) { - getusage(argv[0]); - return; - } - } - for (n = 1; n < argc ; n++) { - src = index(argv[n], ':'); - if (src == NULL) - src = argv[n]; - else { - struct hostent *hp; - - *src++ = 0; - hp = gethostbyname(argv[n]); - if (hp == NULL) { - fprintf(stderr, "tftp: %s: ", argv[n]); - herror((char *)NULL); - continue; - } - bcopy(hp->h_addr, (caddr_t)&sin.sin_addr, hp->h_length); - sin.sin_family = hp->h_addrtype; - connected = 1; - strcpy(hostname, hp->h_name); - } - if (argc < 4) { - cp = argc == 3 ? argv[2] : tail(src); - fd = creat(cp, 0644); - if (fd < 0) { - fprintf(stderr, "tftp: "); perror(cp); - return; - } - if (verbose) - printf("getting from %s:%s to %s [%s]\n", - hostname, src, cp, mode); - sin.sin_port = port; - recvfile(fd, src, mode); - break; - } - cp = tail(src); /* new .. jdg */ - fd = creat(cp, 0644); - if (fd < 0) { - fprintf(stderr, "tftp: "); perror(cp); - continue; - } - if (verbose) - printf("getting from %s:%s to %s [%s]\n", - hostname, src, cp, mode); - sin.sin_port = port; - recvfile(fd, src, mode); - } -} - -getusage(s) -char * s; -{ - printf("usage: %s host:file host:file ... file, or\n", s); - printf(" %s file file ... file if connected\n", s); -} - -int rexmtval = TIMEOUT; - -setrexmt(argc, argv) - char *argv[]; -{ - int t; - - if (argc < 2) { - strcpy(line, "Rexmt-timeout "); - printf("(value) "); - fgets(&line[strlen(line)], sizeof(line) - strlen(line) - 1, stdin); - makeargv(); - argc = margc; - argv = margv; - } - if (argc != 2) { - printf("usage: %s value\n", argv[0]); - return; - } - t = atoi(argv[1]); - if (t < 0) - printf("%d: bad value\n", t); - else - rexmtval = t; -} - -int maxtimeout = 5 * TIMEOUT; - -settimeout(argc, argv) - char *argv[]; -{ - int t; - - if (argc < 2) { - strcpy(line, "Maximum-timeout "); - printf("(value) "); - fgets(&line[strlen(line)], sizeof(line) - strlen(line) - 1, stdin); - makeargv(); - argc = margc; - argv = margv; - } - if (argc != 2) { - printf("usage: %s value\n", argv[0]); - return; - } - t = atoi(argv[1]); - if (t < 0) - printf("%d: bad value\n", t); - else - maxtimeout = t; -} - -status(argc, argv) - char *argv[]; -{ - if (connected) - printf("Connected to %s.\n", hostname); - else - printf("Not connected.\n"); - printf("Mode: %s Verbose: %s Tracing: %s\n", mode, - verbose ? "on" : "off", trace ? "on" : "off"); - printf("Rexmt-interval: %d seconds, Max-timeout: %d seconds\n", - rexmtval, maxtimeout); -} - -void intr(int sig) -{ - signal(SIGALRM, SIG_IGN); - alarm(0); - longjmp(toplevel, -1); -} - -char * -tail(filename) - char *filename; -{ - register char *s; - - while (*filename) { - s = rindex(filename, '/'); - if (s == NULL) - break; - if (s[1]) - return (s + 1); - *s = '\0'; - } - return (filename); -} - -/* - * Command parser. - */ -command(top) - int top; -{ - register struct cmd *c; - - if (!top) - putchar('\n'); - for (;;) { - printf("%s> ", prompt); - if (fgets(line, sizeof(line), stdin) == 0) { - if (feof(stdin)) { - quit(); - } else { - continue; - } - } - if (line[0] == 0) - continue; - makeargv(); - c = getcmd(margv[0]); - if (c == (struct cmd *)-1) { - printf("?Ambiguous command\n"); - continue; - } - if (c == 0) { - printf("?Invalid command\n"); - continue; - } - (*c->handler)(margc, margv); - } -} - -struct cmd * -getcmd(name) - register char *name; -{ - register char *p, *q; - register struct cmd *c, *found; - register int nmatches, longest; - - longest = 0; - nmatches = 0; - found = 0; - for (c = cmdtab; p = c->name; c++) { - for (q = name; *q == *p++; q++) - if (*q == 0) /* exact match? */ - return (c); - if (!*q) { /* the name was a prefix */ - if (q - name > longest) { - longest = q - name; - nmatches = 1; - found = c; - } else if (q - name == longest) - nmatches++; - } - } - if (nmatches > 1) - return ((struct cmd *)-1); - return (found); -} - -/* - * Slice a string up into argc/argv. - */ -makeargv() -{ - register char *cp; - register char **argp = margv; - - margc = 0; - for (cp = line; *cp;) { - while (isspace(*cp)) - cp++; - if (*cp == '\0') - break; - *argp++ = cp; - margc += 1; - while (*cp != '\0' && !isspace(*cp)) - cp++; - if (*cp == '\0') - break; - *cp++ = '\0'; - } - *argp++ = 0; -} - -/*VARARGS*/ -quit() -{ - exit(0); -} - -/* - * Help command. - */ -help(argc, argv) - int argc; - char *argv[]; -{ - register struct cmd *c; - - if (argc == 1) { - printf("Commands may be abbreviated. Commands are:\n\n"); - for (c = cmdtab; c->name; c++) - printf("%-*s\t%s\n", HELPINDENT, c->name, c->help); - return; - } - while (--argc > 0) { - register char *arg; - arg = *++argv; - c = getcmd(arg); - if (c == (struct cmd *)-1) - printf("?Ambiguous help command %s\n", arg); - else if (c == (struct cmd *)0) - printf("?Invalid help command %s\n", arg); - else - printf("%s\n", c->help); - } -} - -/*VARARGS*/ -settrace() -{ - trace = !trace; - printf("Packet tracing %s.\n", trace ? "on" : "off"); -} - -/*VARARGS*/ -setverbose() -{ - verbose = !verbose; - printf("Verbose mode %s.\n", verbose ? "on" : "off"); -} - -setblocksize(argc, argv) - char *argv[]; -{ - int t; - - if (argc < 2) { - strcpy(line, "blocksize "); - printf("(value) "); - fgets(&line[strlen(line)], sizeof(line) - strlen(line) - 1, stdin); - makeargv(); - argc = margc; - argv = margv; - } - if (argc != 2) { - printf("usage: %s value\n", argv[0]); - return; - } - t = atoi(argv[1]); - if (t < 8 || t > 1432) - printf("%d: bad value\n", t); - else - segsize = t; -} |