summaryrefslogtreecommitdiffstats
path: root/contrib/tftp/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/tftp/main.c')
-rw-r--r--contrib/tftp/main.c684
1 files changed, 0 insertions, 684 deletions
diff --git a/contrib/tftp/main.c b/contrib/tftp/main.c
deleted file mode 100644
index ca4427a1..00000000
--- 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;
-}