Unix Technical Forum

Re: tftp diff

This is a discussion on Re: tftp diff within the lucky.openbsd.tech forums, part of the OpenBSD category; --> After reading your explanation I agree with you. Attached the reworked diff which kills also the last setjmp() and ...


Go Back   Unix Technical Forum > Unix Operating Systems > OpenBSD > lucky.openbsd.tech

Register FAQ Members List Calendar Search Today's Posts Mark Forums Read
  #1 (permalink)  
Old 02-22-2008, 12:23 PM
Marcus Glocker
 
Posts: n/a
Default Re: tftp diff

After reading your explanation I agree with you.

Attached the reworked diff which kills also the last setjmp() and
handles ctrl-c by catching it with a poll() loop wrapped in front
of the fgets() call.

Tested it and works OK for me.

On Thu, Apr 27, 2006 at 12:25:08PM -0600, Theo de Raadt wrote:

> > The setjmp(3) in main.c which is used when ctrl-c is catched (SIGINT)
> > is kept which is legitim IMO for that use and done this way by a lot
> > of command line programs (ftp, ed, restore etc.) to return to the
> > command prompt no matter which routine was active (e.g. blocking
> > fgets(3)).

>
> Well, just because lots of programs use that method does not make it
> legitimate, because in the end I must say this: IT IS STILL NOT SAFE.
>
> Think about it.
>
> When that ^C comes in, is it not possible that our code is currently running
> inside malloc()? Just picking an example here, but what about stdio? Or
> who knows what else?
>
> So then the signal comes in, and we longjmp back into main, and now what?
>
> Now your malloc heap is unsafe. Or stdio is in an inconsistant state.
> Or who knows what else.
>
> And now the code WILL crash later on. And there is no solution to
> this besides adding signal blocking stubs all through the code, for
> everytime you wish to do something which might conceiveably not be
> re-entrant.
>
> So while it might be what a lot of programs do, my point is that it
> is 100% unsafe -- in all cases -- to ever use setjmp. Well, I have
> actually used it safely in one program before, but the costs are very
> high because you really must do signal blocks around just about any
> sequence of code which calls a function which is NOT LISTED in signal.h
>
> This is what I call a reverse signal race.


--
Marcus Glocker, marcus@nazgul.ch, http://www.nazgul.ch -----------------
diff -urN -x CVS src/usr.bin/tftp.orig/main.c src/usr.bin/tftp/main.c
--- src/usr.bin/tftp.orig/main.c Wed Apr 26 12:36:12 2006
+++ src/usr.bin/tftp/main.c Fri Apr 28 20:17:26 2006
@@ -48,34 +48,35 @@
/*
* TFTP User Program -- Command Interface.
*/
+
#include <sys/param.h>
#include <sys/socket.h>
#include <sys/file.h>

#include <netinet/in.h>
-
#include <arpa/inet.h>

#include <ctype.h>
#include <errno.h>
#include <netdb.h>
-#include <setjmp.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <err.h>
+#include <poll.h>

#include "extern.h"

#define TIMEOUT 5 /* secs between rexmt's */
#define LBUFLEN 200 /* size of input buffer */
#define MAXARGV 20
+#define HELPINDENT (sizeof("connect"))

struct sockaddr_in peeraddr;
int f;
-short port;
+short port;
int trace;
int verbose;
int connected;
@@ -84,10 +85,15 @@
int margc;
char *margv[MAXARGV+1];
char *prompt = "tftp";
-jmp_buf toplevel;
void intr(int);
struct servent *sp;
+int rexmtval = TIMEOUT;
+int maxtimeout = 5 * TIMEOUT;
+char hostname[MAXHOSTNAMELEN];
+FILE *file = NULL;

+volatile sig_atomic_t intrflag = 0;
+
void get(int, char **);
void help(int, char **);
void modecmd(int, char **);
@@ -101,6 +107,7 @@
void settrace(int, char **);
void setverbose(int, char **);
void status(int, char **);
+int readcmd(char *, int, FILE *);

static __dead void command(void);

@@ -109,8 +116,6 @@
static void putusage(char *);
static void settftpmode(char *);

-#define HELPINDENT (sizeof("connect"))
-
struct cmd {
char *name;
char *help;
@@ -128,8 +133,8 @@
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 ashelp[] = "set mode to netascii";
+char bnhelp[] = "set mode to octet";

struct cmd cmdtab[] = {
{ "connect", chelp, setpeer },
@@ -144,10 +149,24 @@
{ "ascii", ashelp, setascii },
{ "rexmt", xhelp, setrexmt },
{ "timeout", ihelp, settimeout },
+ { "help", hhelp, help },
{ "?", hhelp, help },
{ NULL, NULL, NULL }
};

+struct modes {
+ char *m_name;
+ char *m_mode;
+} modes[] = {
+ { "ascii", "netascii" },
+ { "netascii", "netascii" },
+ { "binary", "octet" },
+ { "image", "octet" },
+ { "octet", "octet" },
+/* { "mail", "mail" }, */
+ { NULL, NULL }
+};
+
struct cmd *getcmd(char *);
char *tail(char *);

@@ -156,31 +175,34 @@
{
struct sockaddr_in s_in;

+ /* socket, bind */
sp = getservbyname("tftp", "udp");
if (sp == 0)
errx(1, "udp/tftp: unknown service");
f = socket(AF_INET, SOCK_DGRAM, 0);
if (f < 0)
err(3, "socket");
- bzero((char *)&s_in, sizeof (s_in));
+ bzero((char *)&s_in, sizeof(s_in));
s_in.sin_family = AF_INET;
- if (bind(f, (struct sockaddr *)&s_in, sizeof (s_in)) < 0)
+ if (bind(f, (struct sockaddr *)&s_in, sizeof(s_in)) < 0)
err(1, "bind");
- strlcpy(mode, "netascii", sizeof mode);
- signal(SIGINT, intr);
- if (argc > 1) {
- if (setjmp(toplevel) != 0)
- exit(0);
+
+ /* set default transfer mode */
+ strlcpy(mode, "netascii", sizeof(mode));
+
+ /* set peer if given */
+ if (argc > 1)
setpeer(argc, argv);
- }
- if (setjmp(toplevel) != 0)
- (void)putchar('\n');
+
+ /* catch SIGINT */
+ signal(SIGINT, intr);
+
+ /* command prompt */
command();
+
return (0);
}

-char hostname[MAXHOSTNAMELEN];
-
void
setpeer(int argc, char *argv[])
{
@@ -189,7 +211,7 @@
if (argc < 2) {
strlcpy(line, "Connect ", sizeof line);
printf("(to) ");
- fgets(&line[strlen(line)], LBUFLEN-strlen(line), stdin);
+ readcmd(&line[strlen(line)], LBUFLEN-strlen(line), stdin);
if (makeargv())
return;
argc = margc;
@@ -227,19 +249,6 @@
connected = 1;
}

-struct modes {
- char *m_name;
- char *m_mode;
-} modes[] = {
- { "ascii", "netascii" },
- { "netascii", "netascii" },
- { "binary", "octet" },
- { "image", "octet" },
- { "octet", "octet" },
-/* { "mail", "mail" }, */
- { NULL, NULL }
-};
-
void
modecmd(int argc, char *argv[])
{
@@ -276,14 +285,12 @@
void
setbinary(int argc, char *argv[])
{
-
settftpmode("octet");
}

void
setascii(int argc, char *argv[])
{
-
settftpmode("netascii");
}

@@ -295,7 +302,6 @@
printf("mode set to %s\n", mode);
}

-
/*
* Send file(s).
*/
@@ -309,7 +315,7 @@
if (argc < 2) {
strlcpy(line, "send ", sizeof line);
printf("(file) ");
- fgets(&line[strlen(line)], LBUFLEN-strlen(line), stdin);
+ readcmd(&line[strlen(line)], LBUFLEN - strlen(line), stdin);
if (makeargv())
return;
argc = margc;
@@ -362,8 +368,10 @@
return;
}

- /* this assumes the target is a directory */
- /* on a remote unix system. hmmmm. */
+ /*
+ * this assumes the target is a directory on
+ * on a remote unix system. hmmmm.
+ */
for (n = 1; n < argc - 1; n++) {
if (asprintf(&cp, "%s/%s", targ, tail(argv[n])) == -1)
err(1, "asprintf");
@@ -386,7 +394,8 @@
putusage(char *s)
{
printf("usage: %s file [[host:]remotename]\n", s);
- printf(" %s file1 file2 ... fileN [[host:]remote-directory]\n", s);
+ printf(" %s file1 file2 ... fileN [[host:]remote-directory]\n",
+ s);
}

/*
@@ -403,7 +412,7 @@
if (argc < 2) {
strlcpy(line, "get ", sizeof line);
printf("(files) ");
- fgets(&line[strlen(line)], LBUFLEN-strlen(line), stdin);
+ readcmd(&line[strlen(line)], LBUFLEN-strlen(line), stdin);
if (makeargv())
return;
argc = margc;
@@ -474,8 +483,6 @@
printf(" %s [host1:]file1 [host2:]file2 ... [hostN:]fileN\n", s);
}

-int rexmtval = TIMEOUT;
-
void
setrexmt(int argc, char *argv[])
{
@@ -484,7 +491,7 @@
if (argc < 2) {
strlcpy(line, "Rexmt-timeout ", sizeof line);
printf("(value) ");
- fgets(&line[strlen(line)], LBUFLEN-strlen(line), stdin);
+ readcmd(&line[strlen(line)], LBUFLEN-strlen(line), stdin);
if (makeargv())
return;
argc = margc;
@@ -501,8 +508,6 @@
rexmtval = t;
}

-int maxtimeout = 5 * TIMEOUT;
-
void
settimeout(int argc, char *argv[])
{
@@ -511,7 +516,7 @@
if (argc < 2) {
strlcpy(line, "Maximum-timeout ", sizeof line);
printf("(value) ");
- fgets(&line[strlen(line)], LBUFLEN-strlen(line), stdin);
+ readcmd(&line[strlen(line)], LBUFLEN-strlen(line), stdin);
if (makeargv())
return;
argc = margc;
@@ -544,10 +549,7 @@
void
intr(int signo)
{
-
- signal(SIGALRM, SIG_IGN);
- alarm(0);
- longjmp(toplevel, -1);
+ intrflag = 1;
}

char *
@@ -576,13 +578,8 @@

for (; {
printf("%s> ", prompt);
- if (fgets(line, LBUFLEN, stdin) == 0) {
- if (feof(stdin)) {
- exit(0);
- } else {
- continue;
- }
- }
+ if (readcmd(line, LBUFLEN, stdin) < 1)
+ continue;
if ((line[0] == 0) || (line[0] == '\n'))
continue;
if (makeargv())
@@ -612,6 +609,7 @@
longest = 0;
nmatches = 0;
found = 0;
+ intrflag = 0;
for (c = cmdtab; (p = c->name) != NULL; c++) {
for (q = name; *q == *p++; q++)
if (*q == 0) /* exact match? */
@@ -666,7 +664,6 @@
void
quit(int argc, char *argv[])
{
-
exit(0);
}

@@ -709,4 +706,34 @@
{
verbose = !verbose;
printf("Verbose mode %s.\n", verbose ? "on" : "off");
+}
+
+int
+readcmd(char *input, int len, FILE *stream)
+{
+ int nfds;
+ struct pollfd pfd[1];
+
+ fflush(stdout);
+
+ pfd[0].fd = 0;
+ pfd[0].events = POLLIN;
+ nfds = poll(pfd, 1, -1);
+ if (nfds == -1) {
+ if (intrflag) {
+ intrflag = 0;
+ putchar('\n');
+ return (0);
+ }
+ exit(1);
+ }
+
+ if (fgets(input, len, stream) == NULL) {
+ if (feof(stdin))
+ exit(0);
+ else
+ return (-1);
+ }
+
+ return (1);
}
diff -urN -x CVS src/usr.bin/tftp.orig/tftp.c src/usr.bin/tftp/tftp.c
--- src/usr.bin/tftp.orig/tftp.c Tue Apr 25 22:08:37 2006
+++ src/usr.bin/tftp/tftp.c Fri Apr 28 20:17:46 2006
@@ -42,16 +42,16 @@
/*
* TFTP User Program -- Protocol Machines
*/
+
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/time.h>

#include <netinet/in.h>
-
#include <arpa/tftp.h>

#include <errno.h>
-#include <setjmp.h>
+#include <poll.h>
#include <signal.h>
#include <stdio.h>
#include <stddef.h>
@@ -62,40 +62,57 @@
#include "extern.h"
#include "tftpsubs.h"

+#define PKTSIZE SEGSIZE + 4

-extern struct sockaddr_in peeraddr; /* filled in by main */
-extern int f; /* the opened socket */
-extern int trace;
-extern int verbose;
-extern int rexmtval;
-extern int maxtimeout;
+extern struct sockaddr_in peeraddr; /* filled in by main */
+extern int f; /* the opened socket */
+extern int trace;
+extern int verbose;
+extern int rexmtval;
+extern int maxtimeout;
+extern FILE *file;
+extern volatile sig_atomic_t intrflag;

-#define PKTSIZE SEGSIZE+4
-char ackbuf[PKTSIZE];
-int timeout;
-jmp_buf toplevel;
-jmp_buf timeoutbuf;
+char ackbuf[PKTSIZE];

-static void nak(int);
-static int makerequest(int, const char *, struct tftphdr *, const char *);
-static void printstats(const char *, unsigned long);
-static void startclock(void);
-static void stopclock(void);
-static void timer(int);
-static void tpacket(const char *, struct tftphdr *, int);
+struct timeval tstart;
+struct timeval tstop;

+struct errmsg {
+ int e_code;
+ char *e_msg;
+} errmsgs[] = {
+ { EUNDEF, "Undefined error code" },
+ { ENOTFOUND, "File not found" },
+ { EACCESS, "Access violation" },
+ { ENOSPACE, "Disk full or allocation exceeded" },
+ { EBADOP, "Illegal TFTP operation" },
+ { EBADID, "Unknown transfer ID" },
+ { EEXISTS, "File already exists" },
+ { ENOUSER, "No such user" },
+ { -1, NULL }
+};
+
+static int makerequest(int, const char *, struct tftphdr *, const char *);
+static void nak(int);
+static void tpacket(const char *, struct tftphdr *, int);
+static void startclock(void);
+static void stopclock(void);
+static void printstats(const char *, unsigned long);
+static void printtimeout(void);
+
/*
* Send the requested file.
*/
void
sendfile(int fd, char *name, char *mode)
{
- struct tftphdr *dp, *ap; /* data and ack packets */
- volatile int block, size, convert;
- volatile unsigned long amount;
+ struct tftphdr *dp, *ap; /* data and ack packets */
struct sockaddr_in from;
- int n, fromlen;
- FILE *file;
+ struct pollfd pfd[1];
+ unsigned long amount;
+ int convert; /* true if converting crlf -> lf */
+ int n, nfds, error, fromlen, timeouts, block, size;

startclock(); /* start stat's clock */
dp = r_init(); /* reset fillbuf/read-ahead code */
@@ -105,12 +122,11 @@
block = 0;
amount = 0;

- signal(SIGALRM, timer);
do {
- if (block == 0)
+ /* read data from file */
+ if (!block)
size = makerequest(WRQ, name, dp, mode) - 4;
else {
- /* size = read(fd, dp->th_data, SEGSIZE); */
size = readit(file, &dp, convert);
if (size < 0) {
nak(errno + 100);
@@ -119,66 +135,93 @@
dp->th_opcode = htons((u_short)DATA);
dp->th_block = htons((u_short)block);
}
- timeout = 0;
- (void) setjmp(timeoutbuf);
-send_data:
- if (trace)
- tpacket("sent", dp, size + 4);
- n = sendto(f, dp, size + 4, 0,
- (struct sockaddr *)&peeraddr, sizeof(peeraddr));
- if (n != size + 4) {
- warn("sendto");
- goto abort;
- }
- read_ahead(file, convert);
- for ( ; ; ) {
- alarm(rexmtval);
- do {
- fromlen = sizeof(from);
- n = recvfrom(f, ackbuf, sizeof(ackbuf), 0,
- (struct sockaddr *)&from, &fromlen);
- } while (n <= 0);
- alarm(0);
- if (n < 0) {
+
+ /* send data to server and wait for server ACK */
+ for (timeouts = 0, error = 0; !intrflag {
+ if (timeouts == maxtimeout) {
+ printtimeout();
+ goto abort;
+ }
+
+ if (!error) {
+ if (trace)
+ tpacket("sent", dp, size + 4);
+ if (sendto(f, dp, size + 4, 0,
+ (struct sockaddr *)&peeraddr,
+ sizeof(peeraddr)) != size + 4) {
+ warn("sendto");
+ goto abort;
+ }
+ read_ahead(file, convert);
+ }
+ error = 0;
+
+ pfd[0].fd = f;
+ pfd[0].events = POLLIN;
+ nfds = poll(pfd, 1, rexmtval * 1000);
+ if (nfds == 0) {
+ timeouts++;
+ continue;
+ }
+ if (nfds == -1) {
+ error = 1;
+ if (errno == EINTR)
+ continue;
+ warn("poll");
+ goto abort;
+ }
+ fromlen = sizeof(from);
+ n = recvfrom(f, ackbuf, sizeof(ackbuf), 0,
+ (struct sockaddr *)&from, &fromlen);
+ if (n == 0) {
warn("recvfrom");
goto abort;
}
+ if (n == -1) {
+ error = 1;
+ if (errno == EINTR)
+ continue;
+ warn("recvfrom");
+ goto abort;
+ }
peeraddr.sin_port = from.sin_port; /* added */
if (trace)
tpacket("received", ap, n);
- /* should verify packet came from server */
ap->th_opcode = ntohs(ap->th_opcode);
ap->th_block = ntohs(ap->th_block);
+
if (ap->th_opcode == ERROR) {
- printf("Error code %d: %s\n", ap->th_code,
- ap->th_msg);
+ printf("Error code %d: %s\n",
+ ap->th_code, ap->th_msg);
goto abort;
}
if (ap->th_opcode == ACK) {
int j;
-
- if (ap->th_block == block) {
+ if (ap->th_block == block)
break;
- }
- /* On an error, try to synchronize
- * both sides.
- */
+ /* re-synchronize with other side */
j = synchnet(f);
if (j && trace)
printf("discarded %d packets\n", j);
- if (ap->th_block == (block-1))
- goto send_data;
+ if (ap->th_block == (block - 1))
+ continue;
}
+ error = 1; /* received packet does not match */
}
+
if (block > 0)
amount += size;
block++;
- } while (size == SEGSIZE || block == 1);
+ } while ((size == SEGSIZE || block == 1) && !intrflag);
+
abort:
fclose(file);
stopclock();
- if (amount > 0)
+ if (amount > 0) {
+ if (intrflag)
+ putchar('\n');
printstats("Sent", amount);
+ }
}

/*
@@ -187,25 +230,25 @@
void
recvfile(int fd, char *name, char *mode)
{
- struct tftphdr *dp, *ap;
- volatile int block, size, firsttrip;
- volatile unsigned long amount;
+ struct tftphdr *dp, *ap; /* data and ack packets */
struct sockaddr_in from;
- int n, fromlen;
- FILE *file;
- volatile int convert; /* true if converting crlf -> lf */
+ struct pollfd pfd[1];
+ unsigned long amount;
+ int convert; /* true if converting crlf -> lf */
+ int n, nfds, error, fromlen, timeouts, block, size, firsttrip;

- startclock();
- dp = w_init();
+ startclock(); /* start stat's clock */
+ dp = w_init(); /* reset fillbuf/read-ahead code */
ap = (struct tftphdr *)ackbuf;
file = fdopen(fd, "w");
convert = !strcmp(mode, "netascii");
+ n = 0;
block = 1;
- firsttrip = 1;
amount = 0;
+ firsttrip = 1;

- signal(SIGALRM, timer);
do {
+ /* create new ACK packet */
if (firsttrip) {
size = makerequest(RRQ, name, ap, mode);
firsttrip = 0;
@@ -215,75 +258,104 @@
size = 4;
block++;
}
- timeout = 0;
- (void) setjmp(timeoutbuf);
-send_ack:
- if (trace)
- tpacket("sent", ap, size);
- if (sendto(f, ackbuf, size, 0, (struct sockaddr *)&peeraddr,
- sizeof(peeraddr)) != size) {
- alarm(0);
- warn("sendto");
- goto abort;
- }
- write_behind(file, convert);
- for ( ; ; ) {
- alarm(rexmtval);
- do {
- fromlen = sizeof(from);
- n = recvfrom(f, dp, PKTSIZE, 0,
- (struct sockaddr *)&from, &fromlen);
- } while (n <= 0);
- alarm(0);
- if (n < 0) {
+
+ /* send ACK to server and wait for server data */
+ for (timeouts = 0, error = 0; !intrflag {
+ if (timeouts == maxtimeout) {
+ printtimeout();
+ goto abort;
+ }
+
+ if (!error) {
+ if (trace)
+ tpacket("sent", ap, size);
+ if (sendto(f, ackbuf, size, 0,
+ (struct sockaddr *)&peeraddr,
+ sizeof(peeraddr)) != size) {
+ warn("sendto");
+ goto abort;
+ }
+ write_behind(file, convert);
+ }
+ error = 0;
+
+ pfd[0].fd = f;
+ pfd[0].events = POLLIN;
+ nfds = poll(pfd, 1, rexmtval * 1000);
+ if (nfds == 0) {
+ timeouts++;
+ continue;
+ }
+ if (nfds == -1) {
+ error = 1;
+ if (errno == EINTR)
+ continue;
+ warn("poll");
+ goto abort;
+ }
+ fromlen = sizeof(from);
+ n = recvfrom(f, dp, PKTSIZE, 0,
+ (struct sockaddr *)&from, &fromlen);
+ if (n == 0) {
warn("recvfrom");
goto abort;
}
+ if (n == -1) {
+ error = 1;
+ if (errno == EINTR)
+ continue;
+ warn("recvfrom");
+ goto abort;
+ }
peeraddr.sin_port = from.sin_port; /* added */
if (trace)
tpacket("received", dp, n);
- /* should verify client address */
dp->th_opcode = ntohs(dp->th_opcode);
dp->th_block = ntohs(dp->th_block);
+
if (dp->th_opcode == ERROR) {
- printf("Error code %d: %s\n", dp->th_code,
- dp->th_msg);
+ printf("Error code %d: %s\n",
+ dp->th_code, dp->th_msg);
goto abort;
}
if (dp->th_opcode == DATA) {
int j;
-
- if (dp->th_block == block) {
- break; /* have next packet */
- }
- /* On an error, try to synchronize
- * both sides.
- */
+ if (dp->th_block == block)
+ break;
+ /* re-synchronize with other side */
j = synchnet(f);
if (j && trace)
printf("discarded %d packets\n", j);
- if (dp->th_block == (block-1))
- goto send_ack; /* resend ack */
+ if (dp->th_block == (block - 1))
+ continue;
}
+ error = 1; /* received packet does not match */
}
- /* size = write(fd, dp->th_data, n - 4); */
+
+ /* write data to file */
size = writeit(file, &dp, n - 4, convert);
if (size < 0) {
nak(errno + 100);
break;
}
amount += size;
- } while (size == SEGSIZE);
-abort: /* ok to ack, since user */
- ap->th_opcode = htons((u_short)ACK); /* has seen err msg */
+ } while (size == SEGSIZE && !intrflag);
+
+abort:
+ /* ok to ack, since user has seen err msg */
+ ap->th_opcode = htons((u_short)ACK);
ap->th_block = htons((u_short)block);
(void) sendto(f, ackbuf, 4, 0, (struct sockaddr *)&peeraddr,
sizeof(peeraddr));
- write_behind(file, convert); /* flush last buffer */
+ write_behind(file, convert); /* flush last buffer */
+
fclose(file);
stopclock();
- if (amount > 0)
+ if (amount > 0) {
+ if (intrflag)
+ putchar('\n');
printstats("Received", amount);
+ }
}

static int
@@ -303,21 +375,6 @@
return (cp + len - (char *)tp);
}

-struct errmsg {
- int e_code;
- char *e_msg;
-} errmsgs[] = {
- { EUNDEF, "Undefined error code" },
- { ENOTFOUND, "File not found" },
- { EACCESS, "Access violation" },
- { ENOSPACE, "Disk full or allocation exceeded" },
- { EBADOP, "Illegal TFTP operation" },
- { EBADID, "Unknown transfer ID" },
- { EEXISTS, "File already exists" },
- { ENOUSER, "No such user" },
- { -1, NULL }
-};
-
/*
* Send a nak packet (error message).
* Error code passed in is one of the
@@ -355,7 +412,7 @@
tpacket(const char *s, struct tftphdr *tp, int n)
{
static char *opcodes[] =
- { "#0", "RRQ", "WRQ", "DATA", "ACK", "ERROR" };
+ { "#0", "RRQ", "WRQ", "DATA", "ACK", "ERROR" };
char *cp, *file;
u_short op = ntohs(tp->th_opcode);

@@ -363,8 +420,8 @@
printf("%s opcode=%x ", s, op);
else
printf("%s %s ", s, opcodes[op]);
- switch (op) {

+ switch (op) {
case RRQ:
case WRQ:
n -= 2;
@@ -372,36 +429,28 @@
cp = strchr(cp, '\0');
printf("<file=%s, mode=%s>\n", file, cp + 1);
break;
-
case DATA:
printf("<block=%d, %d bytes>\n", ntohs(tp->th_block), n - 4);
break;
-
case ACK:
printf("<block=%d>\n", ntohs(tp->th_block));
break;
-
case ERROR:
printf("<code=%d, msg=%s>\n", ntohs(tp->th_code), tp->th_msg);
break;
}
}

-struct timeval tstart;
-struct timeval tstop;
-
static void
startclock(void)
{
-
- (void)gettimeofday(&tstart, NULL);
+ (void) gettimeofday(&tstart, NULL);
}

static void
stopclock(void)
{
-
- (void)gettimeofday(&tstop, NULL);
+ (void) gettimeofday(&tstop, NULL);
}

static void
@@ -410,26 +459,17 @@
double delta;

/* compute delta in 1/10's second units */
- delta = ((tstop.tv_sec*10.)+(tstop.tv_usec/100000)) -
- ((tstart.tv_sec*10.)+(tstart.tv_usec/100000));
- delta = delta/10.; /* back to seconds */
+ delta = ((tstop.tv_sec * 10.) + (tstop.tv_usec / 100000)) -
+ ((tstart.tv_sec * 10.) + (tstart.tv_usec / 100000));
+ delta = delta / 10.; /* back to seconds */
printf("%s %lu bytes in %.1f seconds", direction, amount, delta);
if (verbose)
- printf(" [%.0f bits/sec]", (amount*8.)/delta);
+ printf(" [%.0f bits/sec]", (amount * 8.) / delta);
putchar('\n');
}

static void
-timer(int sig)
+printtimeout(void)
{
- int save_errno = errno;
-
- timeout += rexmtval;
- if (timeout >= maxtimeout) {
- printf("Transfer timed out.\n");
- errno = save_errno;
- longjmp(toplevel, -1);
- }
- errno = save_errno;
- longjmp(timeoutbuf, 1);
+ printf("Transfer timed out.\n");
}

Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
Reply


Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On
Forum Jump


All times are GMT. The time now is 01:09 AM.


Powered by vBulletin® Version 3.6.5
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
SEO by vBSEO 3.2.0
www.UnixAdminTalk.com