tftp: optional tftp-hpa compat

function                                             old     new   delta
tftp_main                                            276     394    +118

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
Denys Vlasenko 2019-06-09 11:12:02 +02:00
parent 48eebc8d5c
commit 3b8025f132
2 changed files with 43 additions and 3 deletions

View File

@ -133,6 +133,7 @@ unsigned FAST_FUNC bb_lookup_port(const char *port, const char *protocol, unsign
port_nr = default_port;
if (tserv)
port_nr = ntohs(tserv->s_port);
//FIXME: else: port string was garbage, but we don't report that???
}
errno = old_errno;
}

View File

@ -31,6 +31,11 @@
//config: default y
//config: depends on TFTP
//config:
//config:config FEATURE_TFTP_HPA_COMPAT
//config: bool "tftp-hpa compat (support -c get/put FILE)"
//config: default y
//config: depends on TFTP
//config:
//config:config TFTPD
//config: bool "tftpd (10 kb)"
//config: default y
@ -101,9 +106,10 @@
//usage: IF_FEATURE_TFTP_BLOCKSIZE(
//usage: "\n -b SIZE Transfer blocks of SIZE octets"
//usage: )
///////: "\n -m STR Accepted and ignored ('-m binary' compat with tftp-hpa 5.2)"
//usage:
//usage:#define tftpd_trivial_usage
//usage: "[-cr] [-u USER] [DIR]"
//usage: "[-crl] [-u USER] [DIR]"
//usage:#define tftpd_full_usage "\n\n"
//usage: "Transfer a file on tftp client's request\n"
//usage: "\n"
@ -759,15 +765,46 @@ int tftp_main(int argc UNUSED_PARAM, char **argv)
INIT_G();
if (ENABLE_FEATURE_TFTP_HPA_COMPAT) {
/* As of 2019, common tftp client in Linux distros
* is one maintained by H. Peter Anvin:
* I've seen "tftp-hpa 5.2" version.
* Make the following command work:
* "tftp HOST [PORT] -m binary -c get/put FILE"
* by mangling it into "....... -g/-p -r FILE"
* and accepting and ignoring -m STR option.
*/
unsigned i = 1;
while (argv[i]) {
if (strcmp(argv[i], "-c") == 0) {
if (!argv[++i])
break;
if (strcmp(argv[i], "get") == 0) {
argv[i-1] = (char*)"-g";
argv[i] = (char*)"-r";
break;
}
if (strcmp(argv[i], "put") == 0) {
argv[i-1] = (char*)"-p";
argv[i] = (char*)"-r";
break;
}
}
i++;
}
}
IF_GETPUT(opt =) getopt32(argv, "^"
IF_FEATURE_TFTP_GET("g") IF_FEATURE_TFTP_PUT("p")
"l:r:" IF_FEATURE_TFTP_BLOCKSIZE("b:")
IF_FEATURE_TFTP_HPA_COMPAT("m:")
"\0"
/* -p or -g is mandatory, and they are mutually exclusive */
IF_FEATURE_TFTP_GET("g:") IF_FEATURE_TFTP_PUT("p:")
IF_GETPUT("g--p:p--g:"),
&local_file, &remote_file
IF_FEATURE_TFTP_BLOCKSIZE(, &blksize_str)
IF_FEATURE_TFTP_HPA_COMPAT(, NULL)
);
argv += optind;
@ -851,7 +888,7 @@ int tftpd_main(int argc UNUSED_PARAM, char **argv)
peer_lsa->len = our_lsa->len;
/* Shifting to not collide with TFTP_OPTs */
opt = option_mask32 = TFTPD_OPT | (getopt32(argv, "rcu:l", &user_opt) << 8);
opt = option_mask32 = TFTPD_OPT | (getopt32(argv, "rcu:lm:", &user_opt, NULL) << 8);
argv += optind;
if (opt & TFTPD_OPT_l) {
openlog(applet_name, LOG_PID, LOG_DAEMON);
@ -897,6 +934,7 @@ int tftpd_main(int argc UNUSED_PARAM, char **argv)
mode = local_file + strlen(local_file) + 1;
/* RFC 1350 says mode string is case independent */
if (mode >= G.block_buf + result || strcasecmp(mode, "octet") != 0) {
error_msg = "mode is not 'octet'";
goto err;
}
# if ENABLE_FEATURE_TFTP_BLOCKSIZE
@ -944,7 +982,8 @@ int tftpd_main(int argc UNUSED_PARAM, char **argv)
/* tftp_protocol() will create new one, bound to particular local IP */
result = tftp_protocol(
our_lsa, peer_lsa,
local_file IF_TFTP(, NULL /*remote_file*/)
local_file
IF_TFTP(, NULL /*remote_file*/)
IF_FEATURE_TFTP_BLOCKSIZE(, want_transfer_size)
IF_FEATURE_TFTP_BLOCKSIZE(, blksize)
);