diff -Naur busybox.orig/include/usage.h busybox/include/usage.h
--- busybox.orig/include/usage.h	2008-03-17 18:23:32 +0000
+++ busybox/include/usage.h	2008-03-17 21:21:09 +0000
@@ -3966,6 +3966,7 @@
      "\nOptions:" \
      "\n	-l FILE	Local FILE" \
      "\n	-r FILE	Remote FILE" \
+     "\n	-v	Be verbose" \
 	USE_FEATURE_TFTP_GET( \
      "\n	-g	Get file" \
 	) \
@@ -3974,7 +3975,9 @@
 	) \
 	USE_FEATURE_TFTP_BLOCKSIZE( \
      "\n	-b SIZE	Transfer blocks of SIZE octets" \
-	)
+	) \
+     "\n	-n RETRIES Set retries counter" \
+     "\n	-t MS	Set timeout, milliseconds"
 
 #define tftpd_trivial_usage \
        "[DIR]"
diff -Naur busybox.orig/networking/tftp.c busybox/networking/tftp.c
--- busybox.orig/networking/tftp.c	2008-03-17 18:23:14 +0000
+++ busybox/networking/tftp.c	2008-03-17 21:19:06 +0000
@@ -26,9 +26,9 @@
 #if ENABLE_FEATURE_TFTP_GET || ENABLE_FEATURE_TFTP_PUT
 
 #define TFTP_BLOCKSIZE_DEFAULT 512      /* according to RFC 1350, don't change */
-#define TFTP_TIMEOUT_MS         50
+#define TFTP_TIMEOUT_MS         5000 // WOW! Another pure arbitrary timeout! Should be cmdline option then!
 #define TFTP_MAXTIMEOUT_MS    2000
-#define TFTP_NUM_RETRIES        12      /* number of backed-off retries */
+#define TFTP_NUM_RETRIES 	12      /* DEFAULT number of backed-off retries */
 
 /* opcodes we support */
 #define TFTP_RRQ   1
@@ -51,6 +51,7 @@
 /* masks coming from getopt32 */
 #define CMD_GET(cmd) ((cmd) & 1)
 #define CMD_PUT(cmd) ((cmd) & 2)
+#define VERBOSE(cmd) ((cmd) & 4)
 #endif
 /* NB: in the code below
  * CMD_GET(cmd) and CMD_PUT(cmd) are mutually exclusive
@@ -118,7 +119,8 @@
 		len_and_sockaddr *peer_lsa,
 		USE_TFTP(const char *remote_file,)
 		int local_fd,
-		int blocksize)
+		int blocksize,
+		unsigned opt_retries, unsigned opt_timeout)
 {
 #if !ENABLE_TFTP
 #define remote_file NULL
@@ -248,15 +250,17 @@
 		/* NB: send_len value is preserved in code below
 		 * for potential resend */
 
-		retries = TFTP_NUM_RETRIES;	/* re-initialize */
-		waittime_ms = TFTP_TIMEOUT_MS;
+		retries = opt_retries;	/* re-initialize */
+		waittime_ms = opt_timeout;
 
  send_again:
 #if ENABLE_DEBUG_TFTP
-		fprintf(stderr, "sending %u bytes\n", send_len);
-		for (cp = xbuf; cp < &xbuf[send_len]; cp++)
-			fprintf(stderr, "%02x ", (unsigned char) *cp);
-		fprintf(stderr, "\n");
+		if (VERBOSE(cmd)) {
+			fprintf(stderr, "sending %u bytes\n", send_len);
+			for (cp = xbuf; cp < &xbuf[send_len]; cp++)
+				fprintf(stderr, "%02x ", (unsigned char) *cp);
+			fprintf(stderr, "\n");
+		}
 #endif
 		xsendto(socket_fd, xbuf, send_len, &peer_lsa->u.sa, peer_lsa->len);
 		/* Was it final ACK? then exit */
@@ -313,7 +317,9 @@
 		recv_blk = ntohs( ((uint16_t*)rbuf)[1] );
 
 #if ENABLE_DEBUG_TFTP
-		fprintf(stderr, "received %d bytes: %04x %04x\n", len, opcode, recv_blk);
+		if (VERBOSE(cmd)) {
+			fprintf(stderr, "received %d bytes: %04x %04x\n", len, opcode, recv_blk);
+		}
 #endif
 
 		if (opcode == TFTP_ERROR) {
@@ -363,8 +369,10 @@
 						goto ret;
 					}
 #if ENABLE_DEBUG_TFTP
-					fprintf(stderr, "using blksize %u\n",
-							blksize);
+					if (VERBOSE(cmd)) {
+						fprintf(stderr, "using blksize %u\n",
+								blksize);
+					}
 #endif
 					tftp_bufsize = blksize + 4;
 					/* Send ACK for OACK ("block" no: 0) */
@@ -447,17 +455,22 @@
 	int flags = 0;
 	int result;
 	int blocksize = TFTP_BLOCKSIZE_DEFAULT;
+	unsigned opt_retries = TFTP_NUM_RETRIES;
+	unsigned opt_timeout = TFTP_TIMEOUT_MS;
 
 	/* -p or -g is mandatory, and they are mutually exclusive */
 	opt_complementary = "" USE_FEATURE_TFTP_GET("g:") USE_FEATURE_TFTP_PUT("p:")
 			USE_GETPUT("g--p:p--g:")
-			USE_FEATURE_TFTP_BLOCKSIZE("b+");
+			USE_FEATURE_TFTP_BLOCKSIZE("b+")
+			"n+:t+";
 
 	USE_GETPUT(cmd =) getopt32(argv,
 			USE_FEATURE_TFTP_GET("g") USE_FEATURE_TFTP_PUT("p")
-				"l:r:" USE_FEATURE_TFTP_BLOCKSIZE("b:"),
+				"vl:r:" USE_FEATURE_TFTP_BLOCKSIZE("b:") "n:t:",
 			&local_file, &remote_file
-			USE_FEATURE_TFTP_BLOCKSIZE(, &blocksize));
+			USE_FEATURE_TFTP_BLOCKSIZE(, &blocksize)
+			, &opt_retries, &opt_timeout
+	);
 	argv += optind;
 
 	flags = O_RDONLY;
@@ -486,16 +499,19 @@
 	peer_lsa = xhost2sockaddr(argv[0], port);
 
 #if ENABLE_DEBUG_TFTP
-	fprintf(stderr, "using server '%s', remote_file '%s', local_file '%s'\n",
+	if (VERBOSE(cmd)) {
+		fprintf(stderr, "using server '%s', remote_file '%s', local_file '%s'\n",
 			xmalloc_sockaddr2dotted(&peer_lsa->u.sa),
 			remote_file, local_file);
+	}
 #endif
 
 	result = tftp_protocol(
 			USE_GETPUT(cmd,)
 			NULL /* our_lsa*/,
 			peer_lsa,
-			remote_file, local_fd, blocksize);
+			remote_file, local_fd, blocksize,
+			opt_retries, opt_timeout);
 
 	if (ENABLE_FEATURE_CLEAN_UP)
 		close(local_fd);
@@ -575,22 +591,29 @@
 		}
 	}
 #endif
-	xstat(filename, &statbuf);
 	/* if opcode == TFTP_WRQ: */
 	cmd = 1; /* CMD_GET: we will receive file's data */
 	req_modebits = 0222; /* writable by anyone */
-	open_mode = O_WRONLY | O_TRUNC;
+	result = stat(filename, &statbuf); // file exists?
+	open_mode = O_WRONLY;
 	if (opcode == TFTP_RRQ) {
 		cmd = 2; /* CMD_PUT */
 		req_modebits = 0444; /* readable by anyone */
 		open_mode = O_RDONLY;
+	// write request -> order to create new file if and only if no file exists!
+	} else if (result) {
+		open_mode = O_CREAT | O_WRONLY | O_TRUNC;
 	}
-	if (!S_ISREG(statbuf.st_mode)
-	 || (statbuf.st_mode & req_modebits) != req_modebits
+	// open/create new file
+	local_fd = xopen(filename, open_mode);
+	// check permissions, but only for preexisting files!
+	// or else we can not upload new files at all!
+	if (!result &&
+		(!S_ISREG(statbuf.st_mode) ||
+		(statbuf.st_mode & req_modebits) != req_modebits)
 	) {
 		bb_error_msg_and_die("access to '%s' is denied", filename);
 	}
-	local_fd = xopen(filename, open_mode);
 
 	close(STDIN_FILENO); /* close old, possibly wildcard socket */
 	/* tftp_protocol() will create new one, bound to particular local IP */
@@ -600,6 +623,7 @@
 		USE_TFTP(NULL /*remote_file*/,)
 		local_fd,
 		blksize
+		, TFTP_NUM_RETRIES, TFTP_MAXTIMEOUT_MS
 	);
 
 	return result;
