52 #ifdef HAVE_SYS_IOCTL_H 53 #include <sys/ioctl.h> 61 #ifdef HAVE_NETINET_IN_H 62 #include <netinet/in.h> 64 #ifdef HAVE_ARPA_INET_H 65 #include <arpa/inet.h> 67 #ifdef HAVE_ARPA_TFTP_H 68 #include <arpa/tftp.h> 75 #ifdef HAVE_SYS_FILIO_H 77 #include <sys/filio.h> 86 #define ENABLE_CURLX_PRINTF 102 #define PKTSIZE (SEGSIZE + 4) 146 #define opcode_DATA 3 148 #define opcode_ERROR 5 153 #define MIN(x,y) ((x)<(y)?(x):(y)) 155 #ifndef DEFAULT_LOGFILE 156 #define DEFAULT_LOGFILE "log/tftpd.log" 159 #define REQUEST_DUMP "log/server.input" 161 #define DEFAULT_PORT 8999 168 {
EUNDEF,
"Undefined error code" },
170 {
EACCESS,
"Access violation" },
171 {
ENOSPACE,
"Disk full or allocation exceeded" },
172 {
EBADOP,
"Illegal TFTP operation" },
173 {
EBADID,
"Unknown transfer ID" },
174 {
EEXISTS,
"File already exists" },
215 #ifdef HAVE_SIGSETJMP 216 static sigjmp_buf timeoutbuf;
219 #if defined(HAVE_ALARM) && defined(SIGALRM) 220 static const unsigned int rexmtval =
TIMEOUT;
225 #ifndef HAVE_SIGINTERRUPT 226 #define siginterrupt(x,y) do {} while(0) 249 #if defined(SIGBREAK) && defined(WIN32) 285 static void nak(
int error);
287 #if defined(HAVE_ALARM) && defined(SIGALRM) 289 static void mysignal(
int sig,
void (*handler)(
int));
291 static void timer(
int signum);
293 static void justtimeout(
int signum);
307 #if defined(HAVE_ALARM) && defined(SIGALRM) 312 static void mysignal(
int sig,
void (*handler)(
int))
315 memset(&sa, 0,
sizeof(sa));
316 sa.sa_handler = handler;
317 sigaction(sig, &sa, NULL);
320 static void timer(
int signum)
338 #ifdef HAVE_SIGSETJMP 339 siglongjmp(timeoutbuf, 1);
343 static void justtimeout(
int signum)
357 int old_errno = errno;
370 old_sighup_handler = signal(SIGHUP, SIG_IGN);
371 if(old_sighup_handler == SIG_ERR)
372 logmsg(
"cannot install SIGHUP handler: %s", strerror(errno));
376 old_sigpipe_handler = signal(SIGPIPE, SIG_IGN);
377 if(old_sigpipe_handler == SIG_ERR)
378 logmsg(
"cannot install SIGPIPE handler: %s", strerror(errno));
383 if(old_sigint_handler == SIG_ERR)
384 logmsg(
"cannot install SIGINT handler: %s", strerror(errno));
391 if(old_sigterm_handler == SIG_ERR)
392 logmsg(
"cannot install SIGTERM handler: %s", strerror(errno));
396 #if defined(SIGBREAK) && defined(WIN32) 399 if(old_sigbreak_handler == SIG_ERR)
400 logmsg(
"cannot install SIGBREAK handler: %s", strerror(errno));
409 if(SIG_ERR != old_sighup_handler)
410 (void)signal(SIGHUP, old_sighup_handler);
413 if(SIG_ERR != old_sigpipe_handler)
414 (void)signal(SIGPIPE, old_sigpipe_handler);
417 if(SIG_ERR != old_sigint_handler)
418 (void)signal(SIGINT, old_sigint_handler);
421 if(SIG_ERR != old_sigterm_handler)
422 (void)signal(SIGTERM, old_sigterm_handler);
424 #if defined(SIGBREAK) && defined(WIN32) 425 if(SIG_ERR != old_sigbreak_handler)
426 (void)signal(SIGBREAK, old_sigbreak_handler);
502 test->
rptr += copy_n;
508 for(i = 0 ; i <
SEGSIZE; i++) {
524 if(c ==
'\n' || c ==
'\r') {
572 snprintf(outfile,
sizeof(outfile),
"log/upload.%ld", test->
testno);
576 test->
ofile = open(outfile, O_CREAT|O_RDWR, 0777);
578 if(test->
ofile == -1) {
579 logmsg(
"Couldn't create and/or open file %s for upload!", outfile);
594 return write(test->
ofile, writebuf, count);
602 lseek(test->
ofile, -1, SEEK_CUR);
610 if(1 != write(test->
ofile, &c, 1))
632 #if defined(HAVE_IOCTLSOCKET) 643 #if defined(HAVE_IOCTLSOCKET) 644 (void) ioctlsocket(f, FIONREAD, &i);
646 (void) ioctl(f, FIONREAD, &i);
653 fromaddrlen =
sizeof(fromaddr.
sa4);
656 fromaddrlen =
sizeof(fromaddr.sa6);
658 (void)
recvfrom(f, rbuf,
sizeof(rbuf), 0,
659 &fromaddr.
sa, &fromaddrlen);
667 int main(
int argc,
char **argv)
682 memset(&test, 0,
sizeof(test));
685 if(!strcmp(
"--version", argv[arg])) {
695 else if(!strcmp(
"--pidfile", argv[arg])) {
700 else if(!strcmp(
"--logfile", argv[arg])) {
705 else if(!strcmp(
"--ipv4", argv[arg])) {
712 else if(!strcmp(
"--ipv6", argv[arg])) {
719 else if(!strcmp(
"--port", argv[arg])) {
723 unsigned long ulnum = strtoul(argv[arg], &endptr, 10);
724 if((endptr != argv[arg] + strlen(argv[arg])) ||
725 (ulnum < 1025UL) || (ulnum > 65535UL)) {
726 fprintf(stderr,
"tftpd: invalid --port argument (%s)\n",
734 else if(!strcmp(
"--srcdir", argv[arg])) {
742 puts(
"Usage: tftpd [option]\n" 744 " --logfile [file]\n" 745 " --pidfile [file]\n" 761 pid = (long)getpid();
766 sock = socket(AF_INET, SOCK_DGRAM, 0);
769 sock = socket(AF_INET6, SOCK_DGRAM, 0);
774 logmsg(
"Error creating socket: (%d) %s",
775 error, strerror(error));
781 if(0 != setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,
782 (
void *)&flag,
sizeof(flag))) {
784 logmsg(
"setsockopt(SO_REUSEADDR) failed with error: (%d) %s",
785 error, strerror(error));
793 memset(&me.
sa4, 0,
sizeof(me.
sa4));
794 me.
sa4.sin_family = AF_INET;
795 me.
sa4.sin_addr.s_addr = INADDR_ANY;
796 me.
sa4.sin_port = htons(port);
801 memset(&me.sa6, 0,
sizeof(me.sa6));
802 me.sa6.sin6_family = AF_INET6;
803 me.sa6.sin6_addr = in6addr_any;
804 me.sa6.sin6_port = htons(port);
805 rc =
bind(sock, &me.
sa,
sizeof(me.sa6));
810 logmsg(
"Error binding socket on port %hu: (%d) %s",
811 port, error, strerror(error));
850 from.
sa4.sin_family = AF_INET;
851 peer = socket(AF_INET, SOCK_DGRAM, 0);
865 from.sa6.sin6_family = AF_INET6;
866 peer = socket(AF_INET6, SOCK_DGRAM, 0);
885 memset(&test, 0,
sizeof(test));
906 logmsg(
"end of one transfer");
922 logmsg(
"signalled to die");
935 logmsg(
"========> %s tftpd (port: %d pid: %ld) exits with signal (%d)",
945 logmsg(
"========> tftpd quits");
955 int first = 1, ecode;
961 DWORD recvtimeout, recvtimeoutbak;
963 const char *option =
"mode";
970 logmsg(
"fopen() failed with error: %d %s", error, strerror(error));
978 cp = (
char *)&tp->th_stuff;
982 while(cp < &buf.
storage[size]) {
1004 fprintf(server,
"%s: %s\n", option, cp);
1025 for(cp = mode; cp && *cp; cp++)
1027 *cp = (char)tolower((
int)*cp);
1032 for(pf = formata; pf->
f_mode; pf++)
1033 if(strcmp(pf->f_mode, mode) == 0)
1046 recvtimeout =
sizeof(recvtimeoutbak);
1047 getsockopt(
peer, SOL_SOCKET, SO_RCVTIMEO,
1048 (
char *)&recvtimeoutbak, (
int *)&recvtimeout);
1050 setsockopt(
peer, SOL_SOCKET, SO_RCVTIMEO,
1051 (
const char *)&recvtimeout,
sizeof(recvtimeout));
1060 recvtimeout = recvtimeoutbak;
1061 setsockopt(
peer, SOL_SOCKET, SO_RCVTIMEO,
1062 (
const char *)&recvtimeout,
sizeof(recvtimeout));
1077 stream = fopen(filename,
"rb");
1080 logmsg(
"fopen() failed with error: %d %s", error, strerror(error));
1081 logmsg(
" [1] Error opening file: %s", filename);
1086 char *orgcmd = NULL;
1092 error =
getpart(&orgcmd, &cmdsize,
"reply",
"servercmd", stream);
1095 logmsg(
"getpart() failed with error: %d", error);
1100 while(cmd && cmdsize) {
1102 if(1 == sscanf(cmd,
"writedelay: %d", &num)) {
1103 logmsg(
"instructed to delay %d secs between packets", num);
1107 logmsg(
"Unknown <servercmd> instruction found: %s", cmd);
1110 check = strchr(cmd,
'\r');
1112 check = strchr(cmd,
'\n');
1116 while((*check ==
'\r') || (*check ==
'\n'))
1138 const char *filename,
int mode)
1143 char partbuf[80]=
"data";
1145 logmsg(
"trying to get file: %s mode %x", filename, mode);
1147 if(!strncmp(
"verifiedserver", filename, 14)) {
1149 size_t count =
snprintf(weare,
sizeof(weare),
1150 "WE ROOLZ: %ld\r\n", (
long)getpid());
1152 logmsg(
"Are-we-friendly question received");
1161 ptr = strrchr(filename,
'/');
1173 testno = strtol(ptr, &ptr, 10);
1175 if(testno > 10000) {
1176 partno = testno % 10000;
1183 logmsg(
"requested test number %ld part %ld", testno, partno);
1192 snprintf(partbuf,
sizeof(partbuf),
"data%ld", partno);
1195 FILE *stream = fopen(file,
"rb");
1198 logmsg(
"fopen() failed with error: %d %s", error, strerror(error));
1199 logmsg(
"Error opening file: %s", file);
1200 logmsg(
"Couldn't open test file: %s", file);
1205 error =
getpart(&test->
buffer, &count,
"reply", partbuf, stream);
1208 logmsg(
"getpart() failed with error: %d", error);
1225 logmsg(
"no slash found in path");
1229 logmsg(
"file opened and all is good");
1241 volatile unsigned short sendblock;
1246 #if defined(HAVE_ALARM) && defined(SIGALRM) 1247 mysignal(SIGALRM,
timer);
1258 #ifdef HAVE_SIGSETJMP 1259 (void) sigsetjmp(timeoutbuf, 1);
1268 if(swrite(
peer, sdp, size + 4) != size + 4) {
1301 if(sap->
th_block == (sendblock-1)) {
1318 volatile unsigned short recvblock;
1319 struct tftphdr *
volatile rdp;
1324 #if defined(HAVE_ALARM) && defined(SIGALRM) 1325 mysignal(SIGALRM,
timer);
1333 #ifdef HAVE_SIGSETJMP 1334 (void) sigsetjmp(timeoutbuf, 1);
1386 #if defined(HAVE_ALARM) && defined(SIGALRM) 1387 mysignal(SIGALRM, justtimeout);
1418 tp->th_code = htons((
unsigned short)error);
1419 for(pe = errmsgs; pe->
e_code >= 0; pe++)
1423 pe->
e_msg = strerror(error - 100);
1426 length = (int)strlen(pe->
e_msg);
1432 if(swrite(
peer, &buf.
storage[0], length) != length)
static volatile int exit_signal
static ssize_t write_behind(struct testcase *test, int convert)
static unsigned int timeout
static RETSIGTYPE exit_signal_handler(int signum)
RETSIGTYPE(* SIGHANDLER_T)(int)
static void install_signal_handlers(void)
UNITTEST_START char * ptr
SIG_ATOMIC_T got_exit_signal
int write_pidfile(const char *filename)
static int parse_servercmd(struct testcase *req)
static int writeit(struct testcase *test, struct tftphdr *volatile *dpp, int ct, int convert)
static void win32_cleanup(void)
static int convert(char *d, size_t dlen, int dccsid, const char *s, int slen, int sccsid)
void clear_advisor_read_lock(const char *filename)
static int validate_access(struct testcase *test, const char *fname, int mode)
static srvr_sockaddr_union_t from
static void restore_signal_handlers(void)
unsigned short curlx_ultous(unsigned long ulnum)
memcpy(filename, filename1, strlen(filename1))
CURL_TYPEOF_CURL_SOCKLEN_T curl_socklen_t
static int counter[MAX_EASY_HANDLES]
void logmsg(const char *msg,...)
static tftphdr_storage_t buf
static curl_socket_t peer
boost::asio::deadline_timer timer(io_service)
int main(int argc, char **argv)
static struct mg_server * server
static void nak(int error)
static unsigned short port
static int serverlogslocked
static struct tftphdr * rw_init(int)
#define siginterrupt(x, y)
static void recvtftp(struct testcase *test, struct formats *pf)
static curl_socklen_t fromlen
const char * serverlogfile
static CURLcode win32_init(void)
static struct tftphdr * w_init(void)
static int readit(struct testcase *test, struct tftphdr **dpp, int convert)
static tftphdr_storage_t ackbuf
static struct tftphdr * r_init(void)
static struct formats formata[]
static void read_ahead(struct testcase *test, int convert)
TFSIMD_FORCE_INLINE tfScalar length(const Quaternion &q)
static struct errmsg errmsgs[]
char * test2file(long testno)
int getpart(char **outbuf, size_t *outlen, const char *main, const char *sub, FILE *stream)
static const char * pidname
static int do_tftp(struct testcase *test, struct tftphdr *tp, ssize_t size)
static int synchnet(curl_socket_t)
static unsigned int maxtimeout
void set_advisor_read_lock(const char *filename)
static const char * ipv_inuse
static void sendtftp(struct testcase *test, struct formats *pf)