Reformat the source code

The source code was a mix of different styles; normalize on NASM
style; basically K&R style with 4 space indentation.
This commit is contained in:
H. Peter Anvin 2008-07-08 17:14:44 -04:00
parent 62533e7441
commit 22accddda0
18 changed files with 2794 additions and 2820 deletions

View file

@ -41,9 +41,8 @@
#ifndef lint #ifndef lint
/* static char sccsid[] = "@(#)tftpsubs.c 8.1 (Berkeley) 6/6/93"; */ /* static char sccsid[] = "@(#)tftpsubs.c 8.1 (Berkeley) 6/6/93"; */
/* static char rcsid[] = "$OpenBSD: tftpsubs.c,v 1.2 1996/06/26 05:40:36 deraadt Exp $"; */ /* static char rcsid[] = "$OpenBSD: tftpsubs.c,v 1.2 1996/06/26 05:40:36 deraadt Exp $"; */
static const char *rcsid UNUSED = static const char *rcsid UNUSED = "tftp-hpa: $Id$";
"tftp-hpa: $Id$"; #endif /* not lint */
#endif /* not lint */
/* Simple minded read-ahead/write-behind subroutines for tftp user and /* Simple minded read-ahead/write-behind subroutines for tftp user and
server. Written originally with multiple buffers in mind, but current server. Written originally with multiple buffers in mind, but current
@ -58,127 +57,130 @@ static const char *rcsid UNUSED =
#include <sys/ioctl.h> #include <sys/ioctl.h>
#define PKTSIZE MAX_SEGSIZE+4 /* should be moved to tftp.h */ #define PKTSIZE MAX_SEGSIZE+4 /* should be moved to tftp.h */
int segsize = SEGSIZE; /* Default segsize */ int segsize = SEGSIZE; /* Default segsize */
struct bf { struct bf {
int counter; /* size of data in buffer, or flag */ int counter; /* size of data in buffer, or flag */
char buf[PKTSIZE]; /* room for data packet */ char buf[PKTSIZE]; /* room for data packet */
} bfs[2]; } bfs[2];
/* Values for bf.counter */ /* Values for bf.counter */
#define BF_ALLOC -3 /* alloc'd but not yet filled */ #define BF_ALLOC -3 /* alloc'd but not yet filled */
#define BF_FREE -2 /* free */ #define BF_FREE -2 /* free */
/* [-1 .. segsize] = size of data in the data buffer */ /* [-1 .. segsize] = size of data in the data buffer */
static int nextone; /* index of next buffer to use */ static int nextone; /* index of next buffer to use */
static int current; /* index of buffer in use */ static int current; /* index of buffer in use */
/* control flags for crlf conversions */ /* control flags for crlf conversions */
int newline = 0; /* fillbuf: in middle of newline expansion */ int newline = 0; /* fillbuf: in middle of newline expansion */
int prevchar = -1; /* putbuf: previous char (cr check) */ int prevchar = -1; /* putbuf: previous char (cr check) */
static struct tftphdr *rw_init(int); static struct tftphdr *rw_init(int);
struct tftphdr *w_init() { return rw_init(0); } /* write-behind */ struct tftphdr *w_init()
struct tftphdr *r_init() { return rw_init(1); } /* read-ahead */ {
return rw_init(0);
} /* write-behind */
struct tftphdr *r_init()
{
return rw_init(1);
} /* read-ahead */
/* init for either read-ahead or write-behind */ /* init for either read-ahead or write-behind */
/* x == zero for write-behind, one for read-head */ /* x == zero for write-behind, one for read-head */
static struct tftphdr * static struct tftphdr *rw_init(int x)
rw_init(int x)
{ {
newline = 0; /* init crlf flag */ newline = 0; /* init crlf flag */
prevchar = -1; prevchar = -1;
bfs[0].counter = BF_ALLOC; /* pass out the first buffer */ bfs[0].counter = BF_ALLOC; /* pass out the first buffer */
current = 0; current = 0;
bfs[1].counter = BF_FREE; bfs[1].counter = BF_FREE;
nextone = x; /* ahead or behind? */ nextone = x; /* ahead or behind? */
return (struct tftphdr *)bfs[0].buf; return (struct tftphdr *)bfs[0].buf;
} }
/* Have emptied current buffer by sending to net and getting ack. /* Have emptied current buffer by sending to net and getting ack.
Free it and return next buffer filled with data. Free it and return next buffer filled with data.
*/ */
int int readit(FILE * file, struct tftphdr **dpp, int convert)
readit(FILE *file, struct tftphdr **dpp, int convert)
{ {
struct bf *b; struct bf *b;
bfs[current].counter = BF_FREE; /* free old one */ bfs[current].counter = BF_FREE; /* free old one */
current = !current; /* "incr" current */ current = !current; /* "incr" current */
b = &bfs[current]; /* look at new buffer */ b = &bfs[current]; /* look at new buffer */
if (b->counter == BF_FREE) /* if it's empty */ if (b->counter == BF_FREE) /* if it's empty */
read_ahead(file, convert); /* fill it */ read_ahead(file, convert); /* fill it */
/* assert(b->counter != BF_FREE);*//* check */ /* assert(b->counter != BF_FREE);*//* check */
*dpp = (struct tftphdr *)b->buf; /* set caller's ptr */ *dpp = (struct tftphdr *)b->buf; /* set caller's ptr */
return b->counter; return b->counter;
} }
/* /*
* fill the input buffer, doing ascii conversions if requested * fill the input buffer, doing ascii conversions if requested
* conversions are lf -> cr,lf and cr -> cr, nul * conversions are lf -> cr,lf and cr -> cr, nul
*/ */
void void read_ahead(FILE * file, int convert)
read_ahead(FILE *file, int convert)
{ {
int i; int i;
char *p; char *p;
int c; int c;
struct bf *b; struct bf *b;
struct tftphdr *dp; struct tftphdr *dp;
b = &bfs[nextone]; /* look at "next" buffer */ b = &bfs[nextone]; /* look at "next" buffer */
if (b->counter != BF_FREE) /* nop if not free */ if (b->counter != BF_FREE) /* nop if not free */
return; return;
nextone = !nextone; /* "incr" next buffer ptr */ nextone = !nextone; /* "incr" next buffer ptr */
dp = (struct tftphdr *)b->buf; dp = (struct tftphdr *)b->buf;
if (convert == 0) { if (convert == 0) {
b->counter = read(fileno(file), dp->th_data, segsize); b->counter = read(fileno(file), dp->th_data, segsize);
return; return;
} }
p = dp->th_data; p = dp->th_data;
for (i = 0 ; i < segsize; i++) { for (i = 0; i < segsize; i++) {
if (newline) { if (newline) {
if (prevchar == '\n') if (prevchar == '\n')
c = '\n'; /* lf to cr,lf */ c = '\n'; /* lf to cr,lf */
else c = '\0'; /* cr to cr,nul */ else
newline = 0; c = '\0'; /* cr to cr,nul */
} newline = 0;
else { } else {
c = getc(file); c = getc(file);
if (c == EOF) break; if (c == EOF)
if (c == '\n' || c == '\r') { break;
prevchar = c; if (c == '\n' || c == '\r') {
c = '\r'; prevchar = c;
newline = 1; c = '\r';
} newline = 1;
} }
*p++ = c; }
} *p++ = c;
b->counter = (int)(p - dp->th_data); }
b->counter = (int)(p - dp->th_data);
} }
/* Update count associated with the buffer, get new buffer /* Update count associated with the buffer, get new buffer
from the queue. Calls write_behind only if next buffer not from the queue. Calls write_behind only if next buffer not
available. available.
*/ */
int int writeit(FILE * file, struct tftphdr **dpp, int ct, int convert)
writeit(FILE *file, struct tftphdr **dpp, int ct, int convert)
{ {
bfs[current].counter = ct; /* set size of data to write */ bfs[current].counter = ct; /* set size of data to write */
current = !current; /* switch to other buffer */ current = !current; /* switch to other buffer */
if (bfs[current].counter != BF_FREE) /* if not free */ if (bfs[current].counter != BF_FREE) /* if not free */
(void)write_behind(file, convert); /* flush it */ (void)write_behind(file, convert); /* flush it */
bfs[current].counter = BF_ALLOC; /* mark as alloc'd */ bfs[current].counter = BF_ALLOC; /* mark as alloc'd */
*dpp = (struct tftphdr *)bfs[current].buf; *dpp = (struct tftphdr *)bfs[current].buf;
return ct; /* this is a lie of course */ return ct; /* this is a lie of course */
} }
/* /*
@ -187,52 +189,50 @@ writeit(FILE *file, struct tftphdr **dpp, int ct, int convert)
* Note spec is undefined if we get CR as last byte of file or a * Note spec is undefined if we get CR as last byte of file or a
* CR followed by anything else. In this case we leave it alone. * CR followed by anything else. In this case we leave it alone.
*/ */
int int write_behind(FILE * file, int convert)
write_behind(FILE *file, int convert)
{ {
char *buf; char *buf;
int count; int count;
int ct; int ct;
char *p; char *p;
int c; /* current character */ int c; /* current character */
struct bf *b; struct bf *b;
struct tftphdr *dp; struct tftphdr *dp;
b = &bfs[nextone]; b = &bfs[nextone];
if (b->counter < -1) /* anything to flush? */ if (b->counter < -1) /* anything to flush? */
return 0; /* just nop if nothing to do */ return 0; /* just nop if nothing to do */
count = b->counter; /* remember byte count */ count = b->counter; /* remember byte count */
b->counter = BF_FREE; /* reset flag */ b->counter = BF_FREE; /* reset flag */
dp = (struct tftphdr *)b->buf; dp = (struct tftphdr *)b->buf;
nextone = !nextone; /* incr for next time */ nextone = !nextone; /* incr for next time */
buf = dp->th_data; buf = dp->th_data;
if (count <= 0) return -1; /* nak logic? */ if (count <= 0)
return -1; /* nak logic? */
if (convert == 0) if (convert == 0)
return write(fileno(file), buf, count); return write(fileno(file), buf, count);
p = buf; p = buf;
ct = count; ct = count;
while (ct--) { /* loop over the buffer */ while (ct--) { /* loop over the buffer */
c = *p++; /* pick up a character */ c = *p++; /* pick up a character */
if (prevchar == '\r') { /* if prev char was cr */ if (prevchar == '\r') { /* if prev char was cr */
if (c == '\n') /* if have cr,lf then just */ if (c == '\n') /* if have cr,lf then just */
fseek(file, -1, 1); /* smash lf on top of the cr */ fseek(file, -1, 1); /* smash lf on top of the cr */
else else if (c == '\0') /* if have cr,nul then */
if (c == '\0') /* if have cr,nul then */ goto skipit; /* just skip over the putc */
goto skipit; /* just skip over the putc */ /* else just fall through and allow it */
/* else just fall through and allow it */ }
} putc(c, file);
putc(c, file); skipit:
skipit: prevchar = c;
prevchar = c; }
} return count;
return count;
} }
/* When an error has occurred, it is possible that the two sides /* When an error has occurred, it is possible that the two sides
* are out of synch. Ie: that what I think is the other side's * are out of synch. Ie: that what I think is the other side's
* response to packet N is really their response to packet N-1. * response to packet N is really their response to packet N-1.
@ -244,69 +244,69 @@ skipit:
* when trace is active). * when trace is active).
*/ */
int int synchnet(int f)
synchnet(int f) /* socket to flush */ { /* socket to flush */
{ int pktcount = 0;
int pktcount = 0; char rbuf[PKTSIZE];
char rbuf[PKTSIZE]; struct sockaddr_in from;
struct sockaddr_in from; socklen_t fromlen;
socklen_t fromlen; fd_set socketset;
fd_set socketset; struct timeval notime;
struct timeval notime;
while ( 1 ) { while (1) {
notime.tv_sec = notime.tv_usec = 0; notime.tv_sec = notime.tv_usec = 0;
FD_ZERO(&socketset); FD_ZERO(&socketset);
FD_SET(f, &socketset); FD_SET(f, &socketset);
if ( select(f, &socketset, NULL, NULL, &notime) <= 0 ) if (select(f, &socketset, NULL, NULL, &notime) <= 0)
break; /* Nothing to read */ break; /* Nothing to read */
/* Otherwise drain the packet */ /* Otherwise drain the packet */
pktcount++; pktcount++;
fromlen = sizeof from; fromlen = sizeof from;
(void) recvfrom(f, rbuf, sizeof (rbuf), 0, (void)recvfrom(f, rbuf, sizeof(rbuf), 0,
(struct sockaddr *)&from, &fromlen); (struct sockaddr *)&from, &fromlen);
}
return pktcount; /* Return packets drained */
}
int pick_port_bind(int sockfd, struct sockaddr_in *myaddr, unsigned int port_range_from, unsigned int port_range_to)
{
unsigned int port, firstport;
int port_range = 0;
if (port_range_from != 0 && port_range_to != 0) {
port_range = 1;
}
firstport = port_range
? port_range_from + rand() % (port_range_to-port_range_from+1)
: 0;
port = firstport;
do {
myaddr->sin_port = htons(port);
if (bind(sockfd, (struct sockaddr *)myaddr, sizeof *myaddr) < 0) {
/* Some versions of Linux return EINVAL instead of EADDRINUSE */
if ( !(port_range && (errno == EINVAL || errno == EADDRINUSE)) )
return -1;
/* Normally, we shouldn't have to loop, but some situations involving
aborted transfers make it possible. */
} else {
return 0;
} }
port++; return pktcount; /* Return packets drained */
if ( port > port_range_to ) }
port = port_range_from;
} while ( port != firstport ); int pick_port_bind(int sockfd, struct sockaddr_in *myaddr,
unsigned int port_range_from,
return -1; unsigned int port_range_to)
{
unsigned int port, firstport;
int port_range = 0;
if (port_range_from != 0 && port_range_to != 0) {
port_range = 1;
}
firstport = port_range
? port_range_from + rand() % (port_range_to - port_range_from + 1)
: 0;
port = firstport;
do {
myaddr->sin_port = htons(port);
if (bind(sockfd, (struct sockaddr *)myaddr, sizeof *myaddr) < 0) {
/* Some versions of Linux return EINVAL instead of EADDRINUSE */
if (!(port_range && (errno == EINVAL || errno == EADDRINUSE)))
return -1;
/* Normally, we shouldn't have to loop, but some situations involving
aborted transfers make it possible. */
} else {
return 0;
}
port++;
if (port > port_range_to)
port = port_range_from;
} while (port != firstport);
return -1;
} }

View file

@ -50,18 +50,19 @@
struct tftphdr; struct tftphdr;
struct tftphdr *r_init(void); struct tftphdr *r_init(void);
void read_ahead(FILE *, int); void read_ahead(FILE *, int);
int readit(FILE *, struct tftphdr **, int); int readit(FILE *, struct tftphdr **, int);
int synchnet(int); int synchnet(int);
struct tftphdr *w_init(void); struct tftphdr *w_init(void);
int write_behind(FILE *, int); int write_behind(FILE *, int);
int writeit(FILE *, struct tftphdr **, int, int); int writeit(FILE *, struct tftphdr **, int, int);
extern int segsize; extern int segsize;
#define MAX_SEGSIZE 65464 #define MAX_SEGSIZE 65464
int pick_port_bind(int sockfd, struct sockaddr_in *myaddr, unsigned int from, unsigned int to); int pick_port_bind(int sockfd, struct sockaddr_in *myaddr,
unsigned int from, unsigned int to);
#endif #endif

View file

@ -19,7 +19,7 @@
#define CONFIG_H 1 #define CONFIG_H 1
/* Must be included before we include any system headers! */ /* Must be included before we include any system headers! */
#include "aconfig.h" /* autogenerated configuration header */ #include "aconfig.h" /* autogenerated configuration header */
/* Standard includes */ /* Standard includes */
@ -293,7 +293,7 @@ void *xmalloc(size_t);
char *xstrdup(const char *); char *xstrdup(const char *);
#ifndef HAVE_BSD_SIGNAL #ifndef HAVE_BSD_SIGNAL
void (*bsd_signal(int, void (*)(int)))(int); void (*bsd_signal(int, void (*)(int))) (int);
#endif #endif
#ifndef HAVE_DUP2 #ifndef HAVE_DUP2
int dup2(int, int); int dup2(int, int);

View file

@ -6,23 +6,22 @@
#include "config.h" #include "config.h"
void (*bsd_signal(int signum, void (*handler)(int)))(int) void (*bsd_signal(int signum, void (*handler) (int))) (int) {
{ struct sigaction action, oldaction;
struct sigaction action, oldaction;
memset(&action, 0, sizeof action); memset(&action, 0, sizeof action);
action.sa_handler = handler; action.sa_handler = handler;
sigemptyset(&action.sa_mask); sigemptyset(&action.sa_mask);
sigaddset(&action.sa_mask, signum); sigaddset(&action.sa_mask, signum);
action.sa_flags = SA_RESTART; action.sa_flags = SA_RESTART;
if (sigaction(signum, &action, &oldaction) == -1) { if (sigaction(signum, &action, &oldaction) == -1) {
#ifdef SIG_ERR #ifdef SIG_ERR
return SIG_ERR; return SIG_ERR;
#else #else
return NULL; return NULL;
#endif #endif
} }
return oldaction.sa_handler; return oldaction.sa_handler;
} }

View file

@ -6,32 +6,31 @@
int daemon(int nochdir, int noclose) int daemon(int nochdir, int noclose)
{ {
int nullfd; int nullfd;
pid_t f; pid_t f;
if (!nochdir) { if (!nochdir) {
if (chdir("/")) if (chdir("/"))
return -1; return -1;
} }
if (!noclose) { if (!noclose) {
if ((nullfd = open("/dev/null", O_RDWR)) < 0 || if ((nullfd = open("/dev/null", O_RDWR)) < 0 ||
dup2(nullfd, 0) < 0 || dup2(nullfd, 0) < 0 ||
dup2(nullfd, 1) < 0 || dup2(nullfd, 1) < 0 || dup2(nullfd, 2) < 0)
dup2(nullfd, 2) < 0) return -1;
return -1; close(nullfd);
close(nullfd); }
}
f = fork(); f = fork();
if (f < 0) if (f < 0)
return -1; return -1;
else if (f > 0) else if (f > 0)
_exit(0); _exit(0);
#ifdef HAVE_SETSID #ifdef HAVE_SETSID
return setsid(); return setsid();
#else #else
return 0; return 0;
#endif #endif
} }

View file

@ -8,18 +8,16 @@
int dup2(int oldfd, int newfd) int dup2(int oldfd, int newfd)
{ {
int rv, nfd; int rv, nfd;
close(newfd); close(newfd);
nfd = rv = dup(oldfd); nfd = rv = dup(oldfd);
if (rv >= 0 && rv != newfd) { if (rv >= 0 && rv != newfd) {
rv = dup2(oldfd, newfd); rv = dup2(oldfd, newfd);
close(nfd); close(nfd);
} }
return rv; return rv;
} }

View file

@ -9,12 +9,12 @@
void *xmalloc(size_t size) void *xmalloc(size_t size)
{ {
void *p = malloc(size); void *p = malloc(size);
if ( !p ) { if (!p) {
fprintf(stderr, "Out of memory!\n"); fprintf(stderr, "Out of memory!\n");
exit(128); exit(128);
} }
return p; return p;
} }

View file

@ -9,12 +9,12 @@
char *xstrdup(const char *s) char *xstrdup(const char *s)
{ {
char *p = strdup(s); char *p = strdup(s);
if ( !p ) { if (!p) {
fprintf(stderr, "Out of memory!\n"); fprintf(stderr, "Out of memory!\n");
exit(128); exit(128);
} }
return p; return p;
} }

View file

@ -41,7 +41,7 @@
#ifndef RECVFILE_H #ifndef RECVFILE_H
#define RECVFILE_H #define RECVFILE_H
void tftp_recvfile (int, const char *, const char *); void tftp_recvfile(int, const char *, const char *);
void tftp_sendfile (int, const char *, const char *); void tftp_sendfile(int, const char *, const char *);
#endif #endif

File diff suppressed because it is too large Load diff

View file

@ -39,9 +39,8 @@
#ifndef lint #ifndef lint
/* static char sccsid[] = "@(#)tftp.c 8.1 (Berkeley) 6/6/93"; */ /* static char sccsid[] = "@(#)tftp.c 8.1 (Berkeley) 6/6/93"; */
/* static char rcsid[] = "$OpenBSD: tftp.c,v 1.4 1997/08/06 06:43:45 deraadt Exp $"; */ /* static char rcsid[] = "$OpenBSD: tftp.c,v 1.4 1997/08/06 06:43:45 deraadt Exp $"; */
static const char *rcsid UNUSED = static const char *rcsid UNUSED = "tftp-hpa $Id$";
"tftp-hpa $Id$"; #endif /* not lint */
#endif /* not lint */
/* Many bug fixes are from Jim Guyton <guyton@rand-unix> */ /* Many bug fixes are from Jim Guyton <guyton@rand-unix> */
@ -50,18 +49,18 @@ static const char *rcsid UNUSED =
*/ */
#include "extern.h" #include "extern.h"
extern struct sockaddr_in peeraddr; /* filled in by main */ extern struct sockaddr_in peeraddr; /* filled in by main */
extern int f; /* the opened socket */ extern int f; /* the opened socket */
extern int trace; extern int trace;
extern int verbose; extern int verbose;
extern int rexmtval; extern int rexmtval;
extern int maxtimeout; extern int maxtimeout;
#define PKTSIZE SEGSIZE+4 #define PKTSIZE SEGSIZE+4
char ackbuf[PKTSIZE]; char ackbuf[PKTSIZE];
int timeout; int timeout;
sigjmp_buf toplevel; sigjmp_buf toplevel;
sigjmp_buf timeoutbuf; sigjmp_buf timeoutbuf;
static void nak(int, const char *); static void nak(int, const char *);
static int makerequest(int, const char *, struct tftphdr *, const char *); static int makerequest(int, const char *, struct tftphdr *, const char *);
@ -74,251 +73,247 @@ static void tpacket(const char *, struct tftphdr *, int);
/* /*
* Send the requested file. * Send the requested file.
*/ */
void void tftp_sendfile(int fd, const char *name, const char *mode)
tftp_sendfile(int fd, const char *name, const char *mode)
{ {
struct tftphdr *ap; /* data and ack packets */ struct tftphdr *ap; /* data and ack packets */
struct tftphdr *dp; struct tftphdr *dp;
int n; int n;
volatile int is_request; volatile int is_request;
volatile u_short block; volatile u_short block;
volatile int size, convert; volatile int size, convert;
volatile off_t amount; volatile off_t amount;
struct sockaddr_in from; struct sockaddr_in from;
socklen_t fromlen; socklen_t fromlen;
FILE *file; FILE *file;
u_short ap_opcode, ap_block; u_short ap_opcode, ap_block;
startclock(); /* start stat's clock */ startclock(); /* start stat's clock */
dp = r_init(); /* reset fillbuf/read-ahead code */ dp = r_init(); /* reset fillbuf/read-ahead code */
ap = (struct tftphdr *)ackbuf; ap = (struct tftphdr *)ackbuf;
convert = !strcmp(mode, "netascii"); convert = !strcmp(mode, "netascii");
file = fdopen(fd, convert ? "rt" : "rb"); file = fdopen(fd, convert ? "rt" : "rb");
block = 0; block = 0;
is_request = 1; /* First packet is the actual WRQ */ is_request = 1; /* First packet is the actual WRQ */
amount = 0; amount = 0;
bsd_signal(SIGALRM, timer); bsd_signal(SIGALRM, timer);
do { do {
if (is_request) { if (is_request) {
size = makerequest(WRQ, name, dp, mode) - 4; size = makerequest(WRQ, name, dp, mode) - 4;
} else { } else {
/* size = read(fd, dp->th_data, SEGSIZE); */ /* size = read(fd, dp->th_data, SEGSIZE); */
size = readit(file, &dp, convert); size = readit(file, &dp, convert);
if (size < 0) { if (size < 0) {
nak(errno + 100, NULL); nak(errno + 100, NULL);
break; break;
} }
dp->th_opcode = htons((u_short)DATA); dp->th_opcode = htons((u_short) DATA);
dp->th_block = htons((u_short)block); dp->th_block = htons((u_short) block);
} }
timeout = 0; timeout = 0;
(void) sigsetjmp(timeoutbuf,1); (void)sigsetjmp(timeoutbuf, 1);
if (trace) if (trace)
tpacket("sent", dp, size + 4); tpacket("sent", dp, size + 4);
n = sendto(f, dp, size + 4, 0, n = sendto(f, dp, size + 4, 0,
(struct sockaddr *)&peeraddr, sizeof(peeraddr)); (struct sockaddr *)&peeraddr, sizeof(peeraddr));
if (n != size + 4) { if (n != size + 4) {
perror("tftp: sendto"); perror("tftp: sendto");
goto abort; goto abort;
} }
read_ahead(file, convert); read_ahead(file, convert);
for ( ; ; ) { for (;;) {
alarm(rexmtval); alarm(rexmtval);
do { do {
fromlen = sizeof(from); fromlen = sizeof(from);
n = recvfrom(f, ackbuf, sizeof(ackbuf), 0, n = recvfrom(f, ackbuf, sizeof(ackbuf), 0,
(struct sockaddr *)&from, &fromlen); (struct sockaddr *)&from, &fromlen);
} while (n <= 0); } while (n <= 0);
alarm(0); alarm(0);
if (n < 0) { if (n < 0) {
perror("tftp: recvfrom"); perror("tftp: recvfrom");
goto abort; goto abort;
} }
peeraddr.sin_port = from.sin_port; /* added */ peeraddr.sin_port = from.sin_port; /* added */
if (trace) if (trace)
tpacket("received", ap, n); tpacket("received", ap, n);
/* should verify packet came from server */ /* should verify packet came from server */
ap_opcode = ntohs((u_short)ap->th_opcode); ap_opcode = ntohs((u_short) ap->th_opcode);
ap_block = ntohs((u_short)ap->th_block); ap_block = ntohs((u_short) ap->th_block);
if (ap_opcode == ERROR) { if (ap_opcode == ERROR) {
printf("Error code %d: %s\n", ap_block, printf("Error code %d: %s\n", ap_block, ap->th_msg);
ap->th_msg); goto abort;
goto abort; }
} if (ap_opcode == ACK) {
if (ap_opcode == ACK) { int j;
int j;
if (ap_block == block) { if (ap_block == block) {
break; break;
} }
/* On an error, try to synchronize /* On an error, try to synchronize
* both sides. * both sides.
*/ */
j = synchnet(f); j = synchnet(f);
if (j && trace) { if (j && trace) {
printf("discarded %d packets\n", printf("discarded %d packets\n", j);
j); }
} /*
/* * RFC1129/RFC1350: We MUST NOT re-send the DATA
* RFC1129/RFC1350: We MUST NOT re-send the DATA * packet in response to an invalid ACK. Doing so
* packet in response to an invalid ACK. Doing so * would cause the Sorcerer's Apprentice bug.
* would cause the Sorcerer's Apprentice bug. */
*/ }
} }
} if (!is_request)
if ( !is_request ) amount += size;
amount += size; is_request = 0;
is_request = 0; block++;
block++; } while (size == SEGSIZE || block == 1);
} while (size == SEGSIZE || block == 1); abort:
abort: fclose(file);
fclose(file); stopclock();
stopclock(); if (amount > 0)
if (amount > 0) printstats("Sent", amount);
printstats("Sent", amount);
} }
/* /*
* Receive a file. * Receive a file.
*/ */
void void tftp_recvfile(int fd, const char *name, const char *mode)
tftp_recvfile(int fd, const char *name, const char *mode)
{ {
struct tftphdr *ap; struct tftphdr *ap;
struct tftphdr *dp; struct tftphdr *dp;
int n; int n;
volatile u_short block; volatile u_short block;
volatile int size, firsttrip; volatile int size, firsttrip;
volatile unsigned long amount; volatile unsigned long amount;
struct sockaddr_in from; struct sockaddr_in from;
socklen_t fromlen; socklen_t fromlen;
FILE *file; FILE *file;
volatile int convert; /* true if converting crlf -> lf */ volatile int convert; /* true if converting crlf -> lf */
u_short dp_opcode, dp_block; u_short dp_opcode, dp_block;
startclock(); startclock();
dp = w_init(); dp = w_init();
ap = (struct tftphdr *)ackbuf; ap = (struct tftphdr *)ackbuf;
convert = !strcmp(mode, "netascii"); convert = !strcmp(mode, "netascii");
file = fdopen(fd, convert ?"wt":"wb"); file = fdopen(fd, convert ? "wt" : "wb");
block = 1; block = 1;
firsttrip = 1; firsttrip = 1;
amount = 0; amount = 0;
bsd_signal(SIGALRM, timer); bsd_signal(SIGALRM, timer);
do { do {
if (firsttrip) { if (firsttrip) {
size = makerequest(RRQ, name, ap, mode); size = makerequest(RRQ, name, ap, mode);
firsttrip = 0; firsttrip = 0;
} else { } else {
ap->th_opcode = htons((u_short)ACK); ap->th_opcode = htons((u_short) ACK);
ap->th_block = htons((u_short)block); ap->th_block = htons((u_short) block);
size = 4; size = 4;
block++; block++;
} }
timeout = 0; timeout = 0;
(void) sigsetjmp(timeoutbuf,1); (void)sigsetjmp(timeoutbuf, 1);
send_ack: send_ack:
if (trace) if (trace)
tpacket("sent", ap, size); tpacket("sent", ap, size);
if (sendto(f, ackbuf, size, 0, (struct sockaddr *)&peeraddr, if (sendto(f, ackbuf, size, 0, (struct sockaddr *)&peeraddr,
sizeof(peeraddr)) != size) { sizeof(peeraddr)) != size) {
alarm(0); alarm(0);
perror("tftp: sendto"); perror("tftp: sendto");
goto abort; goto abort;
} }
write_behind(file, convert); write_behind(file, convert);
for ( ; ; ) { for (;;) {
alarm(rexmtval); alarm(rexmtval);
do { do {
fromlen = sizeof(from); fromlen = sizeof(from);
n = recvfrom(f, dp, PKTSIZE, 0, n = recvfrom(f, dp, PKTSIZE, 0,
(struct sockaddr *)&from, &fromlen); (struct sockaddr *)&from, &fromlen);
} while (n <= 0); } while (n <= 0);
alarm(0); alarm(0);
if (n < 0) { if (n < 0) {
perror("tftp: recvfrom"); perror("tftp: recvfrom");
goto abort; goto abort;
} }
peeraddr.sin_port = from.sin_port; /* added */ peeraddr.sin_port = from.sin_port; /* added */
if (trace) if (trace)
tpacket("received", dp, n); tpacket("received", dp, n);
/* should verify client address */ /* should verify client address */
dp_opcode = ntohs((u_short)dp->th_opcode); dp_opcode = ntohs((u_short) dp->th_opcode);
dp_block = ntohs((u_short)dp->th_block); dp_block = ntohs((u_short) dp->th_block);
if (dp_opcode == ERROR) { if (dp_opcode == ERROR) {
printf("Error code %d: %s\n", dp_block, dp->th_msg); printf("Error code %d: %s\n", dp_block, dp->th_msg);
goto abort; goto abort;
} }
if (dp_opcode == DATA) { if (dp_opcode == DATA) {
int j; int j;
if (dp_block == block) { if (dp_block == block) {
break; /* have next packet */ break; /* have next packet */
} }
/* On an error, try to synchronize /* On an error, try to synchronize
* both sides. * both sides.
*/ */
j = synchnet(f); j = synchnet(f);
if (j && trace) { if (j && trace) {
printf("discarded %d packets\n", j); printf("discarded %d packets\n", j);
} }
if (dp_block == (block-1)) { if (dp_block == (block - 1)) {
goto send_ack; /* resend ack */ goto send_ack; /* resend ack */
} }
} }
} }
/* size = write(fd, dp->th_data, n - 4); */ /* size = write(fd, dp->th_data, n - 4); */
size = writeit(file, &dp, n - 4, convert); size = writeit(file, &dp, n - 4, convert);
if (size < 0) { if (size < 0) {
nak(errno + 100, NULL); nak(errno + 100, NULL);
break; break;
} }
amount += size; amount += size;
} while (size == SEGSIZE); } while (size == SEGSIZE);
abort: /* ok to ack, since user */ abort: /* ok to ack, since user */
ap->th_opcode = htons((u_short)ACK); /* has seen err msg */ ap->th_opcode = htons((u_short) ACK); /* has seen err msg */
ap->th_block = htons((u_short)block); ap->th_block = htons((u_short) block);
(void) sendto(f, ackbuf, 4, 0, (struct sockaddr *)&peeraddr, (void)sendto(f, ackbuf, 4, 0, (struct sockaddr *)&peeraddr,
sizeof(peeraddr)); sizeof(peeraddr));
write_behind(file, convert); /* flush last buffer */ write_behind(file, convert); /* flush last buffer */
fclose(file); fclose(file);
stopclock(); stopclock();
if (amount > 0) if (amount > 0)
printstats("Received", amount); printstats("Received", amount);
} }
static int static int
makerequest(int request, const char *name, makerequest(int request, const char *name,
struct tftphdr *tp, const char *mode) struct tftphdr *tp, const char *mode)
{ {
char *cp; char *cp;
tp->th_opcode = htons((u_short)request); tp->th_opcode = htons((u_short) request);
cp = (char *) &(tp->th_stuff); cp = (char *)&(tp->th_stuff);
strcpy(cp, name); strcpy(cp, name);
cp += strlen(name); cp += strlen(name);
*cp++ = '\0'; *cp++ = '\0';
strcpy(cp, mode); strcpy(cp, mode);
cp += strlen(mode); cp += strlen(mode);
*cp++ = '\0'; *cp++ = '\0';
return (cp - (char *)tp); return (cp - (char *)tp);
} }
static const char * const errmsgs[] = static const char *const errmsgs[] = {
{ "Undefined error code", /* 0 - EUNDEF */
"Undefined error code", /* 0 - EUNDEF */ "File not found", /* 1 - ENOTFOUND */
"File not found", /* 1 - ENOTFOUND */ "Access denied", /* 2 - EACCESS */
"Access denied", /* 2 - EACCESS */ "Disk full or allocation exceeded", /* 3 - ENOSPACE */
"Disk full or allocation exceeded", /* 3 - ENOSPACE */ "Illegal TFTP operation", /* 4 - EBADOP */
"Illegal TFTP operation", /* 4 - EBADOP */ "Unknown transfer ID", /* 5 - EBADID */
"Unknown transfer ID", /* 5 - EBADID */ "File already exists", /* 6 - EEXISTS */
"File already exists", /* 6 - EEXISTS */ "No such user", /* 7 - ENOUSER */
"No such user", /* 7 - ENOUSER */ "Failure to negotiate RFC2347 options" /* 8 - EOPTNEG */
"Failure to negotiate RFC2347 options" /* 8 - EOPTNEG */
}; };
#define ERR_CNT (sizeof(errmsgs)/sizeof(const char *)) #define ERR_CNT (sizeof(errmsgs)/sizeof(const char *))
/* /*
@ -327,121 +322,115 @@ static const char * const errmsgs[] =
* standard TFTP codes, or a UNIX errno * standard TFTP codes, or a UNIX errno
* offset by 100. * offset by 100.
*/ */
static void static void nak(int error, const char *msg)
nak(int error, const char *msg)
{ {
struct tftphdr *tp; struct tftphdr *tp;
int length; int length;
tp = (struct tftphdr *)ackbuf; tp = (struct tftphdr *)ackbuf;
tp->th_opcode = htons((u_short)ERROR); tp->th_opcode = htons((u_short) ERROR);
tp->th_code = htons((u_short)error); tp->th_code = htons((u_short) error);
if ( error >= 100 ) { if (error >= 100) {
/* This is a Unix errno+100 */ /* This is a Unix errno+100 */
if ( !msg ) if (!msg)
msg = strerror(error - 100); msg = strerror(error - 100);
error = EUNDEF; error = EUNDEF;
} else { } else {
if ( (unsigned)error >= ERR_CNT ) if ((unsigned)error >= ERR_CNT)
error = EUNDEF; error = EUNDEF;
if ( !msg ) if (!msg)
msg = errmsgs[error]; msg = errmsgs[error];
} }
tp->th_code = htons((u_short)error); tp->th_code = htons((u_short) error);
length = strlen(msg)+1; length = strlen(msg) + 1;
memcpy(tp->th_msg, msg, length); memcpy(tp->th_msg, msg, length);
length += 4; /* Add space for header */ length += 4; /* Add space for header */
if (trace) if (trace)
tpacket("sent", tp, length); tpacket("sent", tp, length);
if (sendto(f, ackbuf, length, 0, (struct sockaddr *)&peeraddr, if (sendto(f, ackbuf, length, 0, (struct sockaddr *)&peeraddr,
sizeof(peeraddr)) != length) sizeof(peeraddr)) != length)
perror("nak"); perror("nak");
} }
static void static void tpacket(const char *s, struct tftphdr *tp, int n)
tpacket(const char *s, struct tftphdr *tp, int n)
{ {
static const char *opcodes[] = static const char *opcodes[] =
{ "#0", "RRQ", "WRQ", "DATA", "ACK", "ERROR", "OACK" }; { "#0", "RRQ", "WRQ", "DATA", "ACK", "ERROR", "OACK" };
char *cp, *file; char *cp, *file;
u_short op = ntohs((u_short)tp->th_opcode); u_short op = ntohs((u_short) tp->th_opcode);
if (op < RRQ || op > ERROR) if (op < RRQ || op > ERROR)
printf("%s opcode=%x ", s, op); printf("%s opcode=%x ", s, op);
else else
printf("%s %s ", s, opcodes[op]); printf("%s %s ", s, opcodes[op]);
switch (op) { switch (op) {
case RRQ: case RRQ:
case WRQ: case WRQ:
n -= 2; n -= 2;
file = cp = (char *) &(tp->th_stuff); file = cp = (char *)&(tp->th_stuff);
cp = strchr(cp, '\0'); cp = strchr(cp, '\0');
printf("<file=%s, mode=%s>\n", file, cp + 1); printf("<file=%s, mode=%s>\n", file, cp + 1);
break; break;
case DATA: case DATA:
printf("<block=%d, %d bytes>\n", ntohs(tp->th_block), n - 4); printf("<block=%d, %d bytes>\n", ntohs(tp->th_block), n - 4);
break; break;
case ACK: case ACK:
printf("<block=%d>\n", ntohs(tp->th_block)); printf("<block=%d>\n", ntohs(tp->th_block));
break; break;
case ERROR: case ERROR:
printf("<code=%d, msg=%s>\n", ntohs(tp->th_code), tp->th_msg); printf("<code=%d, msg=%s>\n", ntohs(tp->th_code), tp->th_msg);
break; break;
} }
} }
struct timeval tstart; struct timeval tstart;
struct timeval tstop; struct timeval tstop;
static void static void startclock(void)
startclock(void)
{ {
(void)gettimeofday(&tstart, NULL); (void)gettimeofday(&tstart, NULL);
} }
static void static void stopclock(void)
stopclock(void)
{ {
(void)gettimeofday(&tstop, NULL); (void)gettimeofday(&tstop, NULL);
} }
static void static void printstats(const char *direction, unsigned long amount)
printstats(const char *direction, unsigned long amount)
{ {
double delta; double delta;
delta = (tstop.tv_sec+(tstop.tv_usec/100000.0)) - delta = (tstop.tv_sec + (tstop.tv_usec / 100000.0)) -
(tstart.tv_sec+(tstart.tv_usec/100000.0)); (tstart.tv_sec + (tstart.tv_usec / 100000.0));
if (verbose) { if (verbose) {
printf("%s %lu bytes in %.1f seconds", direction, amount, delta); printf("%s %lu bytes in %.1f seconds", direction, amount, delta);
printf(" [%.0f bit/s]", (amount*8.)/delta); printf(" [%.0f bit/s]", (amount * 8.) / delta);
putchar('\n'); putchar('\n');
} }
} }
static void static void timer(int sig)
timer(int sig)
{ {
int save_errno = errno; int save_errno = errno;
(void)sig; /* Shut up unused warning */ (void)sig; /* Shut up unused warning */
timeout += rexmtval; timeout += rexmtval;
if (timeout >= maxtimeout) { if (timeout >= maxtimeout) {
printf("Transfer timed out.\n"); printf("Transfer timed out.\n");
errno = save_errno; errno = save_errno;
siglongjmp(toplevel, -1); siglongjmp(toplevel, -1);
} }
errno = save_errno; errno = save_errno;
siglongjmp(timeoutbuf, 1); siglongjmp(timeoutbuf, 1);
} }

View file

@ -14,7 +14,7 @@
* Minor help routines. * Minor help routines.
*/ */
#include "config.h" /* Must be included first! */ #include "config.h" /* Must be included first! */
#include <syslog.h> #include <syslog.h>
#include "tftpd.h" #include "tftpd.h"
@ -22,19 +22,19 @@
* Set the signal handler and flags. Basically a user-friendly * Set the signal handler and flags. Basically a user-friendly
* wrapper around sigaction(). * wrapper around sigaction().
*/ */
void set_signal(int signum, void (*handler)(int), int flags) void set_signal(int signum, void (*handler) (int), int flags)
{ {
struct sigaction sa; struct sigaction sa;
memset(&sa, 0, sizeof sa); memset(&sa, 0, sizeof sa);
sa.sa_handler = handler; sa.sa_handler = handler;
sigemptyset(&sa.sa_mask); sigemptyset(&sa.sa_mask);
sa.sa_flags = flags; sa.sa_flags = flags;
if ( sigaction(signum, &sa, NULL) ) { if (sigaction(signum, &sa, NULL)) {
syslog(LOG_ERR, "sigaction: %m"); syslog(LOG_ERR, "sigaction: %m");
exit(EX_OSERR); exit(EX_OSERR);
} }
} }
/* /*
@ -42,14 +42,14 @@ void set_signal(int signum, void (*handler)(int), int flags)
*/ */
void *tfmalloc(size_t size) void *tfmalloc(size_t size)
{ {
void *p = malloc(size); void *p = malloc(size);
if ( !p ) { if (!p) {
syslog(LOG_ERR, "malloc: %m"); syslog(LOG_ERR, "malloc: %m");
exit(EX_OSERR); exit(EX_OSERR);
} }
return p; return p;
} }
/* /*
@ -57,13 +57,12 @@ void *tfmalloc(size_t size)
*/ */
char *tfstrdup(const char *str) char *tfstrdup(const char *str)
{ {
char *p = strdup(str); char *p = strdup(str);
if ( !p ) { if (!p) {
syslog(LOG_ERR, "strdup: %m"); syslog(LOG_ERR, "strdup: %m");
exit(EX_OSERR); exit(EX_OSERR);
} }
return p; return p;
} }

View file

@ -17,11 +17,11 @@
* *
*/ */
#include "config.h" /* Must be included first! */ #include "config.h" /* Must be included first! */
#include "recvfrom.h" #include "recvfrom.h"
#include "common/tftpsubs.h" #include "common/tftpsubs.h"
#ifdef HAVE_MACHINE_PARAM_H #ifdef HAVE_MACHINE_PARAM_H
#include <machine/param.h> /* Needed on some versions of FreeBSD */ #include <machine/param.h> /* Needed on some versions of FreeBSD */
#endif #endif
#if defined(HAVE_RECVMSG) && defined(HAVE_MSGHDR_MSG_CONTROL) #if defined(HAVE_RECVMSG) && defined(HAVE_MSGHDR_MSG_CONTROL)
@ -33,12 +33,12 @@
# ifdef __linux__ # ifdef __linux__
/* Assume this version of glibc simply lacks the definition */ /* Assume this version of glibc simply lacks the definition */
struct in_pktinfo { struct in_pktinfo {
int ipi_ifindex; int ipi_ifindex;
struct in_addr ipi_spec_dst; struct in_addr ipi_spec_dst;
struct in_addr ipi_addr; struct in_addr ipi_addr;
}; };
# else # else
# undef IP_PKTINFO /* No definition, no way to get it */ # undef IP_PKTINFO /* No definition, no way to get it */
# endif # endif
# endif # endif
#endif #endif
@ -57,141 +57,141 @@ struct in_pktinfo {
*/ */
static int address_is_local(const struct sockaddr_in *addr) static int address_is_local(const struct sockaddr_in *addr)
{ {
struct sockaddr_in sin; struct sockaddr_in sin;
int sockfd = -1; int sockfd = -1;
int e; int e;
int rv = 0; int rv = 0;
socklen_t addrlen; socklen_t addrlen;
/* Multicast or universal broadcast address? */ /* Multicast or universal broadcast address? */
if (ntohl(addr->sin_addr.s_addr) >= (224UL << 24)) if (ntohl(addr->sin_addr.s_addr) >= (224UL << 24))
return 0; return 0;
sockfd = socket(PF_INET, SOCK_DGRAM, 0); sockfd = socket(PF_INET, SOCK_DGRAM, 0);
if (sockfd < 0) if (sockfd < 0)
goto err; goto err;
if (connect(sockfd, (const struct sockaddr *)addr, sizeof *addr)) if (connect(sockfd, (const struct sockaddr *)addr, sizeof *addr))
goto err; goto err;
addrlen = sizeof sin; addrlen = sizeof sin;
if (getsockname(sockfd, (struct sockaddr *)&sin, &addrlen)) if (getsockname(sockfd, (struct sockaddr *)&sin, &addrlen))
goto err; goto err;
rv = sin.sin_addr.s_addr == addr->sin_addr.s_addr; rv = sin.sin_addr.s_addr == addr->sin_addr.s_addr;
err: err:
e = errno; e = errno;
if (sockfd >= 0) if (sockfd >= 0)
close(sockfd); close(sockfd);
errno = e; errno = e;
return rv; return rv;
} }
int int
myrecvfrom(int s, void *buf, int len, unsigned int flags, myrecvfrom(int s, void *buf, int len, unsigned int flags,
struct sockaddr *from, socklen_t *fromlen, struct sockaddr *from, socklen_t * fromlen,
struct sockaddr_in *myaddr) struct sockaddr_in *myaddr)
{ {
struct msghdr msg; struct msghdr msg;
struct iovec iov; struct iovec iov;
int n; int n;
struct cmsghdr *cmptr; struct cmsghdr *cmptr;
union { union {
struct cmsghdr cm; struct cmsghdr cm;
#ifdef IP_PKTINFO #ifdef IP_PKTINFO
char control[CMSG_SPACE(sizeof(struct in_addr)) + char control[CMSG_SPACE(sizeof(struct in_addr)) +
CMSG_SPACE(sizeof(struct in_pktinfo))]; CMSG_SPACE(sizeof(struct in_pktinfo))];
#else #else
char control[CMSG_SPACE(sizeof(struct in_addr))]; char control[CMSG_SPACE(sizeof(struct in_addr))];
#endif #endif
} control_un; } control_un;
int on = 1; int on = 1;
#ifdef IP_PKTINFO #ifdef IP_PKTINFO
struct in_pktinfo pktinfo; struct in_pktinfo pktinfo;
#endif #endif
/* Try to enable getting the return address */ /* Try to enable getting the return address */
#ifdef IP_RECVDSTADDR #ifdef IP_RECVDSTADDR
setsockopt(s, IPPROTO_IP, IP_RECVDSTADDR, &on, sizeof(on)); setsockopt(s, IPPROTO_IP, IP_RECVDSTADDR, &on, sizeof(on));
#endif #endif
#ifdef IP_PKTINFO #ifdef IP_PKTINFO
setsockopt(s, IPPROTO_IP, IP_PKTINFO, &on, sizeof(on)); setsockopt(s, IPPROTO_IP, IP_PKTINFO, &on, sizeof(on));
#endif #endif
bzero(&msg, sizeof msg); /* Clear possible system-dependent fields */ bzero(&msg, sizeof msg); /* Clear possible system-dependent fields */
msg.msg_control = control_un.control; msg.msg_control = control_un.control;
msg.msg_controllen = sizeof(control_un.control); msg.msg_controllen = sizeof(control_un.control);
msg.msg_flags = 0; msg.msg_flags = 0;
msg.msg_name = from; msg.msg_name = from;
msg.msg_namelen = *fromlen; msg.msg_namelen = *fromlen;
iov.iov_base = buf; iov.iov_base = buf;
iov.iov_len = len; iov.iov_len = len;
msg.msg_iov = &iov; msg.msg_iov = &iov;
msg.msg_iovlen = 1; msg.msg_iovlen = 1;
if ( (n = recvmsg(s, &msg, flags)) < 0 ) if ((n = recvmsg(s, &msg, flags)) < 0)
return n; /* Error */ return n; /* Error */
*fromlen = msg.msg_namelen; *fromlen = msg.msg_namelen;
if (myaddr) {
bzero(myaddr, sizeof(struct sockaddr_in));
myaddr->sin_family = AF_INET;
if (msg.msg_controllen < sizeof(struct cmsghdr) ||
(msg.msg_flags & MSG_CTRUNC))
return n; /* No information available */
for (cmptr = CMSG_FIRSTHDR(&msg); cmptr != NULL;
cmptr = CMSG_NXTHDR(&msg, cmptr)) {
#ifdef IP_RECVDSTADDR
if (cmptr->cmsg_level == IPPROTO_IP &&
cmptr->cmsg_type == IP_RECVDSTADDR) {
memcpy(&myaddr->sin_addr, CMSG_DATA(cmptr),
sizeof(struct in_addr));
}
#endif
#ifdef IP_PKTINFO
if (cmptr->cmsg_level == IPPROTO_IP &&
cmptr->cmsg_type == IP_PKTINFO) {
memcpy(&pktinfo, CMSG_DATA(cmptr),
sizeof(struct in_pktinfo));
memcpy(&myaddr->sin_addr, &pktinfo.ipi_addr,
sizeof(struct in_addr));
}
#endif
}
}
/* If the address is not a valid local address, then bind to any address... */
if (address_is_local(myaddr) != 1)
myaddr->sin_addr.s_addr = INADDR_ANY;
return n;
}
#else /* pointless... */
int
myrecvfrom(int s, void *buf, int len, unsigned int flags,
struct sockaddr *from, int *fromlen, struct sockaddr_in *myaddr)
{
/* There is no way we can get the local address, fudge it */
if ( myaddr ) {
bzero(myaddr, sizeof(struct sockaddr_in)); bzero(myaddr, sizeof(struct sockaddr_in));
myaddr->sin_family = AF_INET; myaddr->sin_family = AF_INET;
if ( msg.msg_controllen < sizeof(struct cmsghdr) || myaddr->sin_port = htons(IPPORT_TFTP);
(msg.msg_flags & MSG_CTRUNC) ) bzero(&myaddr->sin_addr, sizeof(myaddr->sin_addr));
return n; /* No information available */
for ( cmptr = CMSG_FIRSTHDR(&msg) ; cmptr != NULL ; return recvfrom(s, buf, len, flags, from, fromlen);
cmptr = CMSG_NXTHDR(&msg, cmptr) ) {
#ifdef IP_RECVDSTADDR
if ( cmptr->cmsg_level == IPPROTO_IP &&
cmptr->cmsg_type == IP_RECVDSTADDR ) {
memcpy(&myaddr->sin_addr, CMSG_DATA(cmptr),
sizeof(struct in_addr));
}
#endif
#ifdef IP_PKTINFO
if ( cmptr->cmsg_level == IPPROTO_IP &&
cmptr->cmsg_type == IP_PKTINFO ) {
memcpy(&pktinfo, CMSG_DATA(cmptr), sizeof(struct in_pktinfo));
memcpy(&myaddr->sin_addr, &pktinfo.ipi_addr, sizeof(struct in_addr));
}
#endif
}
}
/* If the address is not a valid local address, then bind to any address... */
if (address_is_local(myaddr) != 1)
myaddr->sin_addr.s_addr = INADDR_ANY;
return n;
}
#else /* pointless... */
int
myrecvfrom(int s, void *buf, int len, unsigned int flags,
struct sockaddr *from, int *fromlen,
struct sockaddr_in *myaddr)
{
/* There is no way we can get the local address, fudge it */
bzero(myaddr, sizeof(struct sockaddr_in));
myaddr->sin_family = AF_INET;
myaddr->sin_port = htons(IPPORT_TFTP);
bzero(&myaddr->sin_addr, sizeof(myaddr->sin_addr));
return recvfrom(s,buf,len,flags,from,fromlen);
} }
#endif #endif

View file

@ -19,5 +19,5 @@
int int
myrecvfrom(int s, void *buf, int len, unsigned int flags, myrecvfrom(int s, void *buf, int len, unsigned int flags,
struct sockaddr *from, socklen_t *fromlen, struct sockaddr *from, socklen_t * fromlen,
struct sockaddr_in *myaddr); struct sockaddr_in *myaddr);

View file

@ -14,7 +14,7 @@
* Perform regular-expression based filename remapping. * Perform regular-expression based filename remapping.
*/ */
#include "config.h" /* Must be included first! */ #include "config.h" /* Must be included first! */
#include <ctype.h> #include <ctype.h>
#include <syslog.h> #include <syslog.h>
#include <regex.h> #include <regex.h>
@ -23,123 +23,131 @@
#include "remap.h" #include "remap.h"
#define DEADMAN_MAX_STEPS 1024 /* Timeout after this many steps */ #define DEADMAN_MAX_STEPS 1024 /* Timeout after this many steps */
#define MAXLINE 16384 /* Truncate a line at this many bytes */ #define MAXLINE 16384 /* Truncate a line at this many bytes */
#define RULE_REWRITE 0x01 /* This is a rewrite rule */ #define RULE_REWRITE 0x01 /* This is a rewrite rule */
#define RULE_GLOBAL 0x02 /* Global rule (repeat until no match) */ #define RULE_GLOBAL 0x02 /* Global rule (repeat until no match) */
#define RULE_EXIT 0x04 /* Exit after matching this rule */ #define RULE_EXIT 0x04 /* Exit after matching this rule */
#define RULE_RESTART 0x08 /* Restart at the top after matching this rule */ #define RULE_RESTART 0x08 /* Restart at the top after matching this rule */
#define RULE_ABORT 0x10 /* Terminate processing with an error */ #define RULE_ABORT 0x10 /* Terminate processing with an error */
#define RULE_GETONLY 0x20 /* Applicable to GET only */ #define RULE_GETONLY 0x20 /* Applicable to GET only */
#define RULE_PUTONLY 0x40 /* Applicable to PUT only */ #define RULE_PUTONLY 0x40 /* Applicable to PUT only */
#define RULE_INVERSE 0x80 /* Execute if regex *doesn't* match */ #define RULE_INVERSE 0x80 /* Execute if regex *doesn't* match */
struct rule { struct rule {
struct rule *next; struct rule *next;
int nrule; int nrule;
int rule_flags; int rule_flags;
regex_t rx; regex_t rx;
const char *pattern; const char *pattern;
}; };
static int xform_null(int c) static int xform_null(int c)
{ {
return c; return c;
} }
static int xform_toupper(int c) static int xform_toupper(int c)
{ {
return toupper(c); return toupper(c);
} }
static int xform_tolower(int c) static int xform_tolower(int c)
{ {
return tolower(c); return tolower(c);
} }
/* Do \-substitution. Call with string == NULL to get length only. */ /* Do \-substitution. Call with string == NULL to get length only. */
static int genmatchstring(char *string, const char *pattern, const char *input, static int genmatchstring(char *string, const char *pattern,
const regmatch_t *pmatch, match_pattern_callback macrosub) const char *input, const regmatch_t * pmatch,
match_pattern_callback macrosub)
{ {
int (*xform)(int) = xform_null; int (*xform) (int) = xform_null;
int len = 0; int len = 0;
int n, mlen, sublen; int n, mlen, sublen;
int endbytes; int endbytes;
/* Get section before match; note pmatch[0] is the whole match */ /* Get section before match; note pmatch[0] is the whole match */
endbytes = strlen(input) - pmatch[0].rm_eo; endbytes = strlen(input) - pmatch[0].rm_eo;
len = pmatch[0].rm_so + endbytes; len = pmatch[0].rm_so + endbytes;
if ( string ) { if (string) {
memcpy(string, input, pmatch[0].rm_so); memcpy(string, input, pmatch[0].rm_so);
string += pmatch[0].rm_so; string += pmatch[0].rm_so;
}
/* Transform matched section */
while ( *pattern ) {
mlen = 0;
if ( *pattern == '\\' && pattern[1] != '\0' ) {
char macro = pattern[1];
switch ( macro ) {
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
n = pattern[1] - '0';
if ( pmatch[n].rm_so != -1 ) {
mlen = pmatch[n].rm_eo - pmatch[n].rm_so;
len += mlen;
if ( string ) {
const char *p = input+pmatch[n].rm_so;
while ( mlen-- )
*string++ = xform(*p++);
}
}
break;
case 'L':
xform = xform_tolower;
break;
case 'U':
xform = xform_toupper;
break;
case 'E':
xform = xform_null;
break;
default:
if ( macrosub &&
(sublen = macrosub(macro, string)) >= 0 ) {
while ( sublen-- ) {
len++;
if ( string ) {
*string = xform(*string);
string++;
}
}
} else {
len++;
if ( string )
*string++ = xform(pattern[1]);
}
}
pattern += 2;
} else {
len++;
if ( string )
*string++ = xform(*pattern);
pattern++;
} }
}
/* Copy section after match */ /* Transform matched section */
if ( string ) { while (*pattern) {
memcpy(string, input+pmatch[0].rm_eo, endbytes); mlen = 0;
string[endbytes] = '\0';
}
return len; if (*pattern == '\\' && pattern[1] != '\0') {
char macro = pattern[1];
switch (macro) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
n = pattern[1] - '0';
if (pmatch[n].rm_so != -1) {
mlen = pmatch[n].rm_eo - pmatch[n].rm_so;
len += mlen;
if (string) {
const char *p = input + pmatch[n].rm_so;
while (mlen--)
*string++ = xform(*p++);
}
}
break;
case 'L':
xform = xform_tolower;
break;
case 'U':
xform = xform_toupper;
break;
case 'E':
xform = xform_null;
break;
default:
if (macrosub && (sublen = macrosub(macro, string)) >= 0) {
while (sublen--) {
len++;
if (string) {
*string = xform(*string);
string++;
}
}
} else {
len++;
if (string)
*string++ = xform(pattern[1]);
}
}
pattern += 2;
} else {
len++;
if (string)
*string++ = xform(*pattern);
pattern++;
}
}
/* Copy section after match */
if (string) {
memcpy(string, input + pmatch[0].rm_eo, endbytes);
string[endbytes] = '\0';
}
return len;
} }
/* /*
@ -149,277 +157,284 @@ static int genmatchstring(char *string, const char *pattern, const char *input,
*/ */
static int readescstring(char *buf, char **str) static int readescstring(char *buf, char **str)
{ {
char *p = *str; char *p = *str;
int wasbs = 0, len = 0; int wasbs = 0, len = 0;
while ( *p && isspace(*p) ) while (*p && isspace(*p))
p++; p++;
if (!*p) {
*buf = '\0';
*str = p;
return 0;
}
while (*p) {
if (!wasbs && (isspace(*p) || *p == '#')) {
*buf = '\0';
*str = p;
return len;
}
/* Important: two backslashes leave us in the !wasbs state! */
wasbs = !wasbs && (*p == '\\');
*buf++ = *p++;
len++;
}
if ( ! *p ) {
*buf = '\0'; *buf = '\0';
*str = p; *str = p;
return 0; return len;
}
while ( *p ) {
if ( !wasbs && (isspace(*p) || *p == '#') ) {
*buf = '\0';
*str = p;
return len;
}
/* Important: two backslashes leave us in the !wasbs state! */
wasbs = !wasbs && ( *p == '\\' );
*buf++ = *p++;
len++;
}
*buf = '\0';
*str = p;
return len;
} }
/* Parse a line into a set of instructions */ /* Parse a line into a set of instructions */
static int parseline(char *line, struct rule *r, int lineno) static int parseline(char *line, struct rule *r, int lineno)
{ {
char buffer[MAXLINE]; char buffer[MAXLINE];
char *p; char *p;
int rv; int rv;
int rxflags = REG_EXTENDED; int rxflags = REG_EXTENDED;
static int nrule; static int nrule;
memset(r, 0, sizeof *r); memset(r, 0, sizeof *r);
r->nrule = nrule; r->nrule = nrule;
if ( !readescstring(buffer, &line) ) if (!readescstring(buffer, &line))
return 0; /* No rule found */ return 0; /* No rule found */
for ( p = buffer ; *p ; p++ ) { for (p = buffer; *p; p++) {
switch(*p) { switch (*p) {
case 'r': case 'r':
r->rule_flags |= RULE_REWRITE; r->rule_flags |= RULE_REWRITE;
break; break;
case 'g': case 'g':
r->rule_flags |= RULE_GLOBAL; r->rule_flags |= RULE_GLOBAL;
break; break;
case 'e': case 'e':
r->rule_flags |= RULE_EXIT; r->rule_flags |= RULE_EXIT;
break; break;
case 's': case 's':
r->rule_flags |= RULE_RESTART; r->rule_flags |= RULE_RESTART;
break; break;
case 'a': case 'a':
r->rule_flags |= RULE_ABORT; r->rule_flags |= RULE_ABORT;
break; break;
case 'i': case 'i':
rxflags |= REG_ICASE; rxflags |= REG_ICASE;
break; break;
case 'G': case 'G':
r->rule_flags |= RULE_GETONLY; r->rule_flags |= RULE_GETONLY;
break; break;
case 'P': case 'P':
r->rule_flags |= RULE_PUTONLY; r->rule_flags |= RULE_PUTONLY;
break; break;
case '~': case '~':
r->rule_flags |= RULE_INVERSE; r->rule_flags |= RULE_INVERSE;
break; break;
default: default:
syslog(LOG_ERR, "Remap command \"%s\" on line %d contains invalid char \"%c\"", syslog(LOG_ERR,
buffer, lineno, *p); "Remap command \"%s\" on line %d contains invalid char \"%c\"",
return -1; /* Error */ buffer, lineno, *p);
break; return -1; /* Error */
break;
}
} }
}
/* RULE_GLOBAL only applies when RULE_REWRITE specified */ /* RULE_GLOBAL only applies when RULE_REWRITE specified */
if ( !(r->rule_flags & RULE_REWRITE) ) if (!(r->rule_flags & RULE_REWRITE))
r->rule_flags &= ~RULE_GLOBAL; r->rule_flags &= ~RULE_GLOBAL;
if ( (r->rule_flags & (RULE_INVERSE|RULE_REWRITE)) == if ((r->rule_flags & (RULE_INVERSE | RULE_REWRITE)) ==
(RULE_INVERSE|RULE_REWRITE) ) { (RULE_INVERSE | RULE_REWRITE)) {
syslog(LOG_ERR, "r rules cannot be inverted, line %d: %s\n", lineno, line); syslog(LOG_ERR, "r rules cannot be inverted, line %d: %s\n",
return -1; /* Error */ lineno, line);
} return -1; /* Error */
}
/* Read and compile the regex */ /* Read and compile the regex */
if ( !readescstring(buffer, &line) ) { if (!readescstring(buffer, &line)) {
syslog(LOG_ERR, "No regex on remap line %d: %s\n", lineno, line); syslog(LOG_ERR, "No regex on remap line %d: %s\n", lineno, line);
return -1; /* Error */ return -1; /* Error */
} }
if ( (rv = regcomp(&r->rx, buffer, rxflags)) != 0 ) { if ((rv = regcomp(&r->rx, buffer, rxflags)) != 0) {
char errbuf[BUFSIZ]; char errbuf[BUFSIZ];
regerror(rv, &r->rx, errbuf, BUFSIZ); regerror(rv, &r->rx, errbuf, BUFSIZ);
syslog(LOG_ERR, "Bad regex in remap line %d: %s\n", lineno, errbuf); syslog(LOG_ERR, "Bad regex in remap line %d: %s\n", lineno,
return -1; /* Error */ errbuf);
} return -1; /* Error */
}
/* Read the rewrite pattern, if any */ /* Read the rewrite pattern, if any */
if ( readescstring(buffer, &line) ) { if (readescstring(buffer, &line)) {
r->pattern = tfstrdup(buffer); r->pattern = tfstrdup(buffer);
} else { } else {
r->pattern = ""; r->pattern = "";
} }
nrule++; nrule++;
return 1; /* Rule found */ return 1; /* Rule found */
} }
/* Read a rule file */ /* Read a rule file */
struct rule *parserulefile(FILE *f) struct rule *parserulefile(FILE * f)
{ {
char line[MAXLINE]; char line[MAXLINE];
struct rule *first_rule = NULL; struct rule *first_rule = NULL;
struct rule **last_rule = &first_rule; struct rule **last_rule = &first_rule;
struct rule *this_rule = tfmalloc(sizeof(struct rule)); struct rule *this_rule = tfmalloc(sizeof(struct rule));
int rv; int rv;
int lineno = 0; int lineno = 0;
int err = 0; int err = 0;
while ( lineno++, fgets(line, MAXLINE, f) ) { while (lineno++, fgets(line, MAXLINE, f)) {
rv = parseline(line, this_rule, lineno); rv = parseline(line, this_rule, lineno);
if ( rv < 0 ) if (rv < 0)
err = 1; err = 1;
if ( rv > 0 ) { if (rv > 0) {
*last_rule = this_rule; *last_rule = this_rule;
last_rule = &this_rule->next; last_rule = &this_rule->next;
this_rule = tfmalloc(sizeof(struct rule)); this_rule = tfmalloc(sizeof(struct rule));
}
} }
}
free(this_rule); /* Last one is always unused */ free(this_rule); /* Last one is always unused */
if ( err ) { if (err) {
/* Bail on error, we have already logged an error message */ /* Bail on error, we have already logged an error message */
exit(EX_CONFIG); exit(EX_CONFIG);
} }
return first_rule; return first_rule;
} }
/* Destroy a rule file data structure */ /* Destroy a rule file data structure */
void freerules(struct rule *r) void freerules(struct rule *r)
{ {
struct rule *next; struct rule *next;
while ( r ) { while (r) {
next = r->next; next = r->next;
regfree(&r->rx); regfree(&r->rx);
/* "" patterns aren't allocated by malloc() */ /* "" patterns aren't allocated by malloc() */
if ( r->pattern && *r->pattern ) if (r->pattern && *r->pattern)
free((void *)r->pattern); free((void *)r->pattern);
free(r); free(r);
r = next; r = next;
} }
} }
/* Execute a rule set on a string; returns a malloc'd new string. */ /* Execute a rule set on a string; returns a malloc'd new string. */
char *rewrite_string(const char *input, const struct rule *rules, char *rewrite_string(const char *input, const struct rule *rules,
int is_put, match_pattern_callback macrosub, int is_put, match_pattern_callback macrosub,
const char **errmsg) const char **errmsg)
{ {
char *current = tfstrdup(input); char *current = tfstrdup(input);
char *newstr; char *newstr;
const struct rule *ruleptr = rules; const struct rule *ruleptr = rules;
regmatch_t pmatch[10]; regmatch_t pmatch[10];
int len; int len;
int was_match = 0; int was_match = 0;
int deadman = DEADMAN_MAX_STEPS; int deadman = DEADMAN_MAX_STEPS;
/* Default error */ /* Default error */
*errmsg = "Remap table failure"; *errmsg = "Remap table failure";
if ( verbosity >= 3 ) { if (verbosity >= 3) {
syslog(LOG_INFO, "remap: input: %s", current); syslog(LOG_INFO, "remap: input: %s", current);
}
for ( ruleptr = rules ; ruleptr ; ruleptr = ruleptr->next ) {
if ( ((ruleptr->rule_flags & RULE_GETONLY) && is_put) ||
((ruleptr->rule_flags & RULE_PUTONLY) && !is_put) ) {
continue; /* Rule not applicable, try next */
} }
if ( ! deadman-- ) { for (ruleptr = rules; ruleptr; ruleptr = ruleptr->next) {
syslog(LOG_WARNING, "remap: Breaking loop, input = %s, last = %s", if (((ruleptr->rule_flags & RULE_GETONLY) && is_put) ||
input, current); ((ruleptr->rule_flags & RULE_PUTONLY) && !is_put)) {
free(current); continue; /* Rule not applicable, try next */
return NULL; /* Did not terminate! */ }
if (!deadman--) {
syslog(LOG_WARNING,
"remap: Breaking loop, input = %s, last = %s", input,
current);
free(current);
return NULL; /* Did not terminate! */
}
do {
if (regexec(&ruleptr->rx, current, 10, pmatch, 0) ==
(ruleptr->rule_flags & RULE_INVERSE ? REG_NOMATCH : 0)) {
/* Match on this rule */
was_match = 1;
if (ruleptr->rule_flags & RULE_INVERSE) {
/* No actual match, so clear out the pmatch array */
int i;
for (i = 0; i < 10; i++)
pmatch[i].rm_so = pmatch[i].rm_eo = -1;
}
if (ruleptr->rule_flags & RULE_ABORT) {
if (verbosity >= 3) {
syslog(LOG_INFO, "remap: rule %d: abort: %s",
ruleptr->nrule, current);
}
if (ruleptr->pattern[0]) {
/* Custom error message */
len =
genmatchstring(NULL, ruleptr->pattern, current,
pmatch, macrosub);
newstr = tfmalloc(len + 1);
genmatchstring(newstr, ruleptr->pattern, current,
pmatch, macrosub);
*errmsg = newstr;
} else {
*errmsg = NULL;
}
free(current);
return (NULL);
}
if (ruleptr->rule_flags & RULE_REWRITE) {
len = genmatchstring(NULL, ruleptr->pattern, current,
pmatch, macrosub);
newstr = tfmalloc(len + 1);
genmatchstring(newstr, ruleptr->pattern, current,
pmatch, macrosub);
free(current);
current = newstr;
if (verbosity >= 3) {
syslog(LOG_INFO, "remap: rule %d: rewrite: %s",
ruleptr->nrule, current);
}
}
} else {
break; /* No match, terminate unconditionally */
}
/* If the rule is global, keep going until no match */
} while (ruleptr->rule_flags & RULE_GLOBAL);
if (was_match) {
was_match = 0;
if (ruleptr->rule_flags & RULE_EXIT) {
if (verbosity >= 3) {
syslog(LOG_INFO, "remap: rule %d: exit",
ruleptr->nrule);
}
return current; /* Exit here, we're done */
} else if (ruleptr->rule_flags & RULE_RESTART) {
ruleptr = rules; /* Start from the top */
if (verbosity >= 3) {
syslog(LOG_INFO, "remap: rule %d: restart",
ruleptr->nrule);
}
}
}
} }
do { if (verbosity >= 3) {
if ( regexec(&ruleptr->rx, current, 10, pmatch, 0) == syslog(LOG_INFO, "remap: done");
(ruleptr->rule_flags & RULE_INVERSE ? REG_NOMATCH : 0) ) {
/* Match on this rule */
was_match = 1;
if ( ruleptr->rule_flags & RULE_INVERSE ) {
/* No actual match, so clear out the pmatch array */
int i;
for ( i = 0 ; i < 10 ; i++ )
pmatch[i].rm_so = pmatch[i].rm_eo = -1;
}
if ( ruleptr->rule_flags & RULE_ABORT ) {
if ( verbosity >= 3 ) {
syslog(LOG_INFO, "remap: rule %d: abort: %s",
ruleptr->nrule, current);
}
if ( ruleptr->pattern[0] ) {
/* Custom error message */
len = genmatchstring(NULL, ruleptr->pattern, current,
pmatch, macrosub);
newstr = tfmalloc(len+1);
genmatchstring(newstr, ruleptr->pattern, current,
pmatch, macrosub);
*errmsg = newstr;
} else {
*errmsg = NULL;
}
free(current);
return(NULL);
}
if ( ruleptr->rule_flags & RULE_REWRITE ) {
len = genmatchstring(NULL, ruleptr->pattern, current,
pmatch, macrosub);
newstr = tfmalloc(len+1);
genmatchstring(newstr, ruleptr->pattern, current,
pmatch, macrosub);
free(current);
current = newstr;
if ( verbosity >= 3 ) {
syslog(LOG_INFO, "remap: rule %d: rewrite: %s",
ruleptr->nrule, current);
}
}
} else {
break; /* No match, terminate unconditionally */
}
/* If the rule is global, keep going until no match */
} while ( ruleptr->rule_flags & RULE_GLOBAL );
if ( was_match ) {
was_match = 0;
if ( ruleptr->rule_flags & RULE_EXIT ) {
if ( verbosity >= 3 ) {
syslog(LOG_INFO, "remap: rule %d: exit", ruleptr->nrule);
}
return current; /* Exit here, we're done */
} else if ( ruleptr->rule_flags & RULE_RESTART ) {
ruleptr = rules; /* Start from the top */
if ( verbosity >= 3 ) {
syslog(LOG_INFO, "remap: rule %d: restart", ruleptr->nrule);
}
}
} }
} return current;
if ( verbosity >= 3 ) {
syslog(LOG_INFO, "remap: done");
}
return current;
} }

View file

@ -26,7 +26,7 @@ struct rule;
macro character is passed as the first argument; the output buffer, macro character is passed as the first argument; the output buffer,
if any, is passed as the second argument. The function should return if any, is passed as the second argument. The function should return
the number of characters output, or -1 on failure. */ the number of characters output, or -1 on failure. */
typedef int (*match_pattern_callback)(char, char *); typedef int (*match_pattern_callback) (char, char *);
/* Read a rule file */ /* Read a rule file */
struct rule *parserulefile(FILE *); struct rule *parserulefile(FILE *);
@ -36,8 +36,7 @@ void freerules(struct rule *);
/* Execute a rule set on a string; returns a malloc'd new string. */ /* Execute a rule set on a string; returns a malloc'd new string. */
char *rewrite_string(const char *, const struct rule *, int, char *rewrite_string(const char *, const struct rule *, int,
match_pattern_callback, const char **); match_pattern_callback, const char **);
#endif /* WITH_REGEX */
#endif /* TFTPD_REMAP_H */
#endif /* WITH_REGEX */
#endif /* TFTPD_REMAP_H */

File diff suppressed because it is too large Load diff