* Copyright (c) 1983 Regents of the University of California.
* All rights reserved. The Berkeley software License Agreement
* specifies the terms and conditions for redistribution.
"@(#) Copyright (c) 1983 Regents of the University of California.\n\
static char sccsid
[] = "@(#)main.c 5.1 (Berkeley) %G%";
* TFTP User Program -- Command Interface.
#define TIMEOUT 5 /* secs between rexmt's */
struct sockaddr_in sin
= { AF_INET
};
int quit(), help(), settrace(), status();
int get(), put(), setpeer(), setmode(), setrexmt(), settimeout();
#define HELPINDENT (sizeof("connect"))
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";
{ "connect", chelp
, setpeer
},
{ "mode", mhelp
, setmode
},
{ "trace", thelp
, settrace
},
{ "status", sthelp
, status
},
{ "rexmt", xhelp
, setrexmt
},
{ "timeout", ihelp
, settimeout
},
sp
= getservbyname("tftp", "udp");
fprintf(stderr
, "tftp: udp/tftp: unknown service\n");
f
= socket(AF_INET
, SOCK_DGRAM
, 0, 0);
if (bind(f
, &sin
, sizeof (sin
)) < 0) {
if (setjmp(toplevel
) != 0)
top
= setjmp(toplevel
) == 0;
strcpy(line
, "Connect ");
gets(&line
[strlen(line
)]);
printf("usage: %s host-name [port]\n", argv
[0]);
host
= gethostbyname(argv
[1]);
sin
.sin_family
= host
->h_addrtype
;
bcopy(host
->h_addr
, &sin
.sin_addr
, host
->h_length
);
sin
.sin_family
= AF_INET
;
sin
.sin_addr
.s_addr
= inet_addr(argv
[1]);
if (sin
.sin_addr
.s_addr
== -1) {
printf("%s: unknown host\n", argv
[1]);
strcpy(hnamebuf
, argv
[1]);
sin
.sin_port
= sp
->s_port
;
sin
.sin_port
= atoi(argv
[2]);
printf("%s: bad port number\n", argv
[2]);
sin
.sin_port
= htons((u_short
)sin
.sin_port
);
register struct modes
*p
;
printf("usage: %s [", argv
[0]);
for (p
= modes
; p
->m_name
; p
++) {
printf("%s%s", sep
, p
->m_name
);
printf("Using %s mode to transfer files.\n", mode
);
for (p
= modes
; p
->m_name
; p
++)
if (strcmp(argv
[1], p
->m_name
) == 0)
printf("%s: unknown mode\n", argv
[1]);
register char *cp
, *targ
;
gets(&line
[strlen(line
)]);
if (index(argv
[argc
- 1], ':')) {
for (n
= 1; n
< argc
- 1; n
++)
if (index(argv
[n
], ':')) {
printf("%s: Unknown host.\n", cp
);
bcopy(hp
->h_addr
, (caddr_t
)&sin
.sin_addr
, hp
->h_length
);
sin
.sin_family
= hp
->h_addrtype
;
printf("No target machine specified.\n");
cp
= argc
== 2 ? tail(targ
) : argv
[1];
fprintf(stderr
, "tftp: "); perror(cp
);
(void) sendfile(fd
, targ
);
for (n
= 1; n
< argc
- 1; n
++) {
strcpy(cp
, tail(argv
[n
]));
fd
= open(argv
[n
], O_RDONLY
);
fprintf(stderr
, "tftp: "); perror(argv
[n
]);
(void) sendfile(fd
, targ
);
printf("usage: %s file ... host:target, or\n", s
);
printf(" %s file ... target (when already connected)\n", s
);
gets(&line
[strlen(line
)]);
for (n
= 1; n
< argc
- 1; n
++)
if (index(argv
[n
], ':') == 0) {
for (n
= 1; argc
== 2 || n
< argc
- 1; n
++) {
src
= index(argv
[n
], ':');
hp
= gethostbyname(argv
[n
]);
printf("%s: Unknown host.\n", argv
[n
]);
bcopy(hp
->h_addr
, (caddr_t
)&sin
.sin_addr
, hp
->h_length
);
sin
.sin_family
= hp
->h_addrtype
;
cp
= argc
== 3 ? argv
[2] : tail(src
);
fprintf(stderr
, "tftp: "); perror(cp
);
(void) recvfile(fd
, src
);
cp
= index(argv
[argc
- 1], '\0');
fprintf(stderr
, "tftp: "); perror(src
);
(void) recvfile(fd
, src
);
printf("usage: %s host:file host:file ... file, or\n", s
);
printf(" %s file file ... file if connected\n", s
);
strcpy(line
, "Rexmt-timeout ");
gets(&line
[strlen(line
)]);
printf("usage: %s value\n", argv
[0]);
printf("%s: bad value\n", t
);
int maxtimeout
= 5 * TIMEOUT
;
strcpy(line
, "Maximum-timeout ");
gets(&line
[strlen(line
)]);
printf("usage: %s value\n", argv
[0]);
printf("%s: bad value\n", t
);
printf("Connected to %s.\n", hostname
);
printf("Not connected.\n");
printf("Mode: %s Tracing: %s\n", mode
, trace
? "on" : "off");
printf("Rexmt-interval: %d seconds, Max-timeout: %d seconds\n",
s
= rindex(filename
, '/');
if (c
== (struct cmd
*)-1) {
printf("?Ambiguous command\n");
printf("?Invalid command\n");
(*c
->handler
)(margc
, margv
);
register struct cmd
*c
, *found
;
register int nmatches
, longest
;
for (c
= cmdtab
; p
= c
->name
; c
++) {
for (q
= name
; *q
== *p
++; q
++)
if (*q
== 0) /* exact match? */
if (!*q
) { /* the name was a prefix */
if (q
- name
> longest
) {
} else if (q
- name
== longest
)
return ((struct cmd
*)-1);
* Slice a string up into argc/argv.
register char **argp
= margv
;
while (*cp
!= '\0' && !isspace(*cp
))
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
);
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
);
printf("Packet tracing %s.\n", trace
? "on" : "off");