diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2009-03-16 20:54:45 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2009-03-16 20:54:45 +0000 |
commit | fbf5846ce1e6c34caa1853d9c1fa9ccac16a52c9 (patch) | |
tree | a2d32484d31c3459e06231fb17c5b159ee7c43a3 /networking/ftpd.c | |
parent | 43bb7bba3b09f9beddb07417fa4997a599f5c6d1 (diff) | |
download | busybox-w32-fbf5846ce1e6c34caa1853d9c1fa9ccac16a52c9.tar.gz busybox-w32-fbf5846ce1e6c34caa1853d9c1fa9ccac16a52c9.tar.bz2 busybox-w32-fbf5846ce1e6c34caa1853d9c1fa9ccac16a52c9.zip |
ftpd: dont use fdprintf for simple status messages
function old new delta
ftpd_main 2025 2055 +30
cmdio_write_ok 17 25 +8
cmdio_write_error 17 25 +8
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 3/0 up/down: 46/0) Total: 46 bytes
Diffstat (limited to 'networking/ftpd.c')
-rw-r--r-- | networking/ftpd.c | 109 |
1 files changed, 65 insertions, 44 deletions
diff --git a/networking/ftpd.c b/networking/ftpd.c index 675324803..3b98bacf4 100644 --- a/networking/ftpd.c +++ b/networking/ftpd.c | |||
@@ -62,15 +62,26 @@ | |||
62 | /* Convert a constant to 3-digit string, packed into uint32_t */ | 62 | /* Convert a constant to 3-digit string, packed into uint32_t */ |
63 | enum { | 63 | enum { |
64 | /* Shift for Nth decimal digit */ | 64 | /* Shift for Nth decimal digit */ |
65 | SHIFT2 = 0 * BB_LITTLE_ENDIAN + 24 * BB_BIG_ENDIAN, | 65 | SHIFT2 = 0 * BB_LITTLE_ENDIAN + 24 * BB_BIG_ENDIAN, |
66 | SHIFT1 = 8 * BB_LITTLE_ENDIAN + 16 * BB_BIG_ENDIAN, | 66 | SHIFT1 = 8 * BB_LITTLE_ENDIAN + 16 * BB_BIG_ENDIAN, |
67 | SHIFT0 = 16 * BB_LITTLE_ENDIAN + 8 * BB_BIG_ENDIAN, | 67 | SHIFT0 = 16 * BB_LITTLE_ENDIAN + 8 * BB_BIG_ENDIAN, |
68 | /* And for 4th position (space) */ | ||
69 | SHIFTsp = 24 * BB_LITTLE_ENDIAN + 0 * BB_BIG_ENDIAN, | ||
68 | }; | 70 | }; |
69 | #define STRNUM32(s) (uint32_t)(0 \ | 71 | #define STRNUM32(s) (uint32_t)(0 \ |
70 | | (('0' + ((s) / 1 % 10)) << SHIFT0) \ | 72 | | (('0' + ((s) / 1 % 10)) << SHIFT0) \ |
71 | | (('0' + ((s) / 10 % 10)) << SHIFT1) \ | 73 | | (('0' + ((s) / 10 % 10)) << SHIFT1) \ |
72 | | (('0' + ((s) / 100 % 10)) << SHIFT2) \ | 74 | | (('0' + ((s) / 100 % 10)) << SHIFT2) \ |
73 | ) | 75 | ) |
76 | #define STRNUM32sp(s) (uint32_t)(0 \ | ||
77 | | (' ' << SHIFTsp) \ | ||
78 | | (('0' + ((s) / 1 % 10)) << SHIFT0) \ | ||
79 | | (('0' + ((s) / 10 % 10)) << SHIFT1) \ | ||
80 | | (('0' + ((s) / 100 % 10)) << SHIFT2) \ | ||
81 | ) | ||
82 | |||
83 | #define MSG_OK "Operation successful\r\n" | ||
84 | #define MSG_ERR "Error\r\n" | ||
74 | 85 | ||
75 | struct globals { | 86 | struct globals { |
76 | int pasv_listen_fd; | 87 | int pasv_listen_fd; |
@@ -88,9 +99,15 @@ struct globals { | |||
88 | #if ENABLE_FEATURE_FTP_WRITE | 99 | #if ENABLE_FEATURE_FTP_WRITE |
89 | char *rnfr_filename; | 100 | char *rnfr_filename; |
90 | #endif | 101 | #endif |
102 | /* We need these aligned to uint32_t */ | ||
103 | char msg_ok [(sizeof("NNN " MSG_OK ) + 3) & 0xfffc]; | ||
104 | char msg_err[(sizeof("NNN " MSG_ERR) + 3) & 0xfffc]; | ||
91 | }; | 105 | }; |
92 | #define G (*(struct globals*)&bb_common_bufsiz1) | 106 | #define G (*(struct globals*)&bb_common_bufsiz1) |
93 | #define INIT_G() do { } while (0) | 107 | #define INIT_G() do { \ |
108 | strcpy(G.msg_ok + 4, MSG_OK ); \ | ||
109 | strcpy(G.msg_err + 4, MSG_ERR); \ | ||
110 | } while (0) | ||
94 | 111 | ||
95 | 112 | ||
96 | static char * | 113 | static char * |
@@ -161,17 +178,21 @@ cmdio_write(uint32_t status_str, const char *str) | |||
161 | } | 178 | } |
162 | 179 | ||
163 | static void | 180 | static void |
164 | cmdio_write_ok(int status) | 181 | cmdio_write_ok(unsigned status) |
165 | { | 182 | { |
166 | fdprintf(STDOUT_FILENO, "%u Operation successful\r\n", status); | 183 | *(uint32_t *) G.msg_ok = status; |
184 | xwrite(STDOUT_FILENO, G.msg_ok, sizeof("NNN " MSG_OK) - 1); | ||
167 | } | 185 | } |
186 | #define WRITE_OK(a) cmdio_write_ok(STRNUM32sp(a)) | ||
168 | 187 | ||
169 | /* TODO: output strerr(errno) if errno != 0? */ | 188 | /* TODO: output strerr(errno) if errno != 0? */ |
170 | static void | 189 | static void |
171 | cmdio_write_error(int status) | 190 | cmdio_write_error(unsigned status) |
172 | { | 191 | { |
173 | fdprintf(STDOUT_FILENO, "%u Error\r\n", status); | 192 | *(uint32_t *) G.msg_err = status; |
193 | xwrite(STDOUT_FILENO, G.msg_err, sizeof("NNN " MSG_ERR) - 1); | ||
174 | } | 194 | } |
195 | #define WRITE_ERR(a) cmdio_write_error(STRNUM32sp(a)) | ||
175 | 196 | ||
176 | static void | 197 | static void |
177 | cmdio_write_raw(const char *p_text) | 198 | cmdio_write_raw(const char *p_text) |
@@ -228,10 +249,10 @@ static void | |||
228 | handle_cwd(void) | 249 | handle_cwd(void) |
229 | { | 250 | { |
230 | if (!G.ftp_arg || chdir(G.ftp_arg) != 0) { | 251 | if (!G.ftp_arg || chdir(G.ftp_arg) != 0) { |
231 | cmdio_write_error(FTP_FILEFAIL); | 252 | WRITE_ERR(FTP_FILEFAIL); |
232 | return; | 253 | return; |
233 | } | 254 | } |
234 | cmdio_write_ok(FTP_CWDOK); | 255 | WRITE_OK(FTP_CWDOK); |
235 | } | 256 | } |
236 | 257 | ||
237 | static void | 258 | static void |
@@ -318,7 +339,7 @@ ftpdataio_get_pasv_fd(void) | |||
318 | remote_fd = accept(G.pasv_listen_fd, NULL, 0); | 339 | remote_fd = accept(G.pasv_listen_fd, NULL, 0); |
319 | 340 | ||
320 | if (remote_fd < 0) { | 341 | if (remote_fd < 0) { |
321 | cmdio_write_error(FTP_BADSENDCONN); | 342 | WRITE_ERR(FTP_BADSENDCONN); |
322 | return remote_fd; | 343 | return remote_fd; |
323 | } | 344 | } |
324 | 345 | ||
@@ -459,7 +480,7 @@ handle_port(void) | |||
459 | #endif | 480 | #endif |
460 | ) { | 481 | ) { |
461 | bail: | 482 | bail: |
462 | cmdio_write_error(FTP_BADCMD); | 483 | WRITE_ERR(FTP_BADCMD); |
463 | return; | 484 | return; |
464 | } | 485 | } |
465 | 486 | ||
@@ -503,7 +524,7 @@ handle_port(void) | |||
503 | G.port_addr = get_peer_lsa(STDIN_FILENO); | 524 | G.port_addr = get_peer_lsa(STDIN_FILENO); |
504 | set_nport(G.port_addr, port); | 525 | set_nport(G.port_addr, port); |
505 | #endif | 526 | #endif |
506 | cmdio_write_ok(FTP_PORTOK); | 527 | WRITE_OK(FTP_PORTOK); |
507 | } | 528 | } |
508 | 529 | ||
509 | static void | 530 | static void |
@@ -511,7 +532,7 @@ handle_rest(void) | |||
511 | { | 532 | { |
512 | /* When ftp_arg == NULL simply restart from beginning */ | 533 | /* When ftp_arg == NULL simply restart from beginning */ |
513 | G.restart_pos = G.ftp_arg ? xatoi_u(G.ftp_arg) : 0; | 534 | G.restart_pos = G.ftp_arg ? xatoi_u(G.ftp_arg) : 0; |
514 | cmdio_write_ok(FTP_RESTOK); | 535 | WRITE_OK(FTP_RESTOK); |
515 | } | 536 | } |
516 | 537 | ||
517 | static void | 538 | static void |
@@ -532,13 +553,13 @@ handle_retr(void) | |||
532 | /* O_NONBLOCK is useful if file happens to be a device node */ | 553 | /* O_NONBLOCK is useful if file happens to be a device node */ |
533 | local_file_fd = G.ftp_arg ? open(G.ftp_arg, O_RDONLY | O_NONBLOCK) : -1; | 554 | local_file_fd = G.ftp_arg ? open(G.ftp_arg, O_RDONLY | O_NONBLOCK) : -1; |
534 | if (local_file_fd < 0) { | 555 | if (local_file_fd < 0) { |
535 | cmdio_write_error(FTP_FILEFAIL); | 556 | WRITE_ERR(FTP_FILEFAIL); |
536 | return; | 557 | return; |
537 | } | 558 | } |
538 | 559 | ||
539 | if (fstat(local_file_fd, &statbuf) != 0 || !S_ISREG(statbuf.st_mode)) { | 560 | if (fstat(local_file_fd, &statbuf) != 0 || !S_ISREG(statbuf.st_mode)) { |
540 | /* Note - pretend open failed */ | 561 | /* Note - pretend open failed */ |
541 | cmdio_write_error(FTP_FILEFAIL); | 562 | WRITE_ERR(FTP_FILEFAIL); |
542 | goto file_close_out; | 563 | goto file_close_out; |
543 | } | 564 | } |
544 | G.local_file_fd = local_file_fd; | 565 | G.local_file_fd = local_file_fd; |
@@ -563,9 +584,9 @@ handle_retr(void) | |||
563 | bytes_transferred = bb_copyfd_eof(local_file_fd, remote_fd); | 584 | bytes_transferred = bb_copyfd_eof(local_file_fd, remote_fd); |
564 | close(remote_fd); | 585 | close(remote_fd); |
565 | if (bytes_transferred < 0) | 586 | if (bytes_transferred < 0) |
566 | cmdio_write_error(FTP_BADSENDFILE); | 587 | WRITE_ERR(FTP_BADSENDFILE); |
567 | else | 588 | else |
568 | cmdio_write_ok(FTP_TRANSFEROK); | 589 | WRITE_OK(FTP_TRANSFEROK); |
569 | 590 | ||
570 | file_close_out: | 591 | file_close_out: |
571 | close(local_file_fd); | 592 | close(local_file_fd); |
@@ -645,7 +666,7 @@ handle_dir_common(int opts) | |||
645 | cmdio_write(0, line); /* hack: 0 results in no status at all */ | 666 | cmdio_write(0, line); /* hack: 0 results in no status at all */ |
646 | free(line); | 667 | free(line); |
647 | } | 668 | } |
648 | cmdio_write_ok(FTP_STATFILE_OK); | 669 | WRITE_OK(FTP_STATFILE_OK); |
649 | } else { | 670 | } else { |
650 | /* LIST/NLST [<filename>] */ | 671 | /* LIST/NLST [<filename>] */ |
651 | int remote_fd = get_remote_transfer_fd(" Here comes the directory listing"); | 672 | int remote_fd = get_remote_transfer_fd(" Here comes the directory listing"); |
@@ -664,7 +685,7 @@ handle_dir_common(int opts) | |||
664 | } | 685 | } |
665 | } | 686 | } |
666 | close(remote_fd); | 687 | close(remote_fd); |
667 | cmdio_write_ok(FTP_TRANSFEROK); | 688 | WRITE_OK(FTP_TRANSFEROK); |
668 | } | 689 | } |
669 | fclose(ls_fp); /* closes ls_fd too */ | 690 | fclose(ls_fp); /* closes ls_fd too */ |
670 | } | 691 | } |
@@ -694,7 +715,7 @@ handle_size(void) | |||
694 | || stat(G.ftp_arg, &statbuf) != 0 | 715 | || stat(G.ftp_arg, &statbuf) != 0 |
695 | || !S_ISREG(statbuf.st_mode) | 716 | || !S_ISREG(statbuf.st_mode) |
696 | ) { | 717 | ) { |
697 | cmdio_write_error(FTP_FILEFAIL); | 718 | WRITE_ERR(FTP_FILEFAIL); |
698 | return; | 719 | return; |
699 | } | 720 | } |
700 | sprintf(buf, STR(FTP_STATFILE_OK)" %"OFF_FMT"u\r\n", statbuf.st_size); | 721 | sprintf(buf, STR(FTP_STATFILE_OK)" %"OFF_FMT"u\r\n", statbuf.st_size); |
@@ -708,30 +729,30 @@ static void | |||
708 | handle_mkd(void) | 729 | handle_mkd(void) |
709 | { | 730 | { |
710 | if (!G.ftp_arg || mkdir(G.ftp_arg, 0777) != 0) { | 731 | if (!G.ftp_arg || mkdir(G.ftp_arg, 0777) != 0) { |
711 | cmdio_write_error(FTP_FILEFAIL); | 732 | WRITE_ERR(FTP_FILEFAIL); |
712 | return; | 733 | return; |
713 | } | 734 | } |
714 | cmdio_write_ok(FTP_MKDIROK); | 735 | WRITE_OK(FTP_MKDIROK); |
715 | } | 736 | } |
716 | 737 | ||
717 | static void | 738 | static void |
718 | handle_rmd(void) | 739 | handle_rmd(void) |
719 | { | 740 | { |
720 | if (!G.ftp_arg || rmdir(G.ftp_arg) != 0) { | 741 | if (!G.ftp_arg || rmdir(G.ftp_arg) != 0) { |
721 | cmdio_write_error(FTP_FILEFAIL); | 742 | WRITE_ERR(FTP_FILEFAIL); |
722 | return; | 743 | return; |
723 | } | 744 | } |
724 | cmdio_write_ok(FTP_RMDIROK); | 745 | WRITE_OK(FTP_RMDIROK); |
725 | } | 746 | } |
726 | 747 | ||
727 | static void | 748 | static void |
728 | handle_dele(void) | 749 | handle_dele(void) |
729 | { | 750 | { |
730 | if (!G.ftp_arg || unlink(G.ftp_arg) != 0) { | 751 | if (!G.ftp_arg || unlink(G.ftp_arg) != 0) { |
731 | cmdio_write_error(FTP_FILEFAIL); | 752 | WRITE_ERR(FTP_FILEFAIL); |
732 | return; | 753 | return; |
733 | } | 754 | } |
734 | cmdio_write_ok(FTP_DELEOK); | 755 | WRITE_OK(FTP_DELEOK); |
735 | } | 756 | } |
736 | 757 | ||
737 | static void | 758 | static void |
@@ -739,7 +760,7 @@ handle_rnfr(void) | |||
739 | { | 760 | { |
740 | free(G.rnfr_filename); | 761 | free(G.rnfr_filename); |
741 | G.rnfr_filename = xstrdup(G.ftp_arg); | 762 | G.rnfr_filename = xstrdup(G.ftp_arg); |
742 | cmdio_write_ok(FTP_RNFROK); | 763 | WRITE_OK(FTP_RNFROK); |
743 | } | 764 | } |
744 | 765 | ||
745 | static void | 766 | static void |
@@ -758,10 +779,10 @@ handle_rnto(void) | |||
758 | G.rnfr_filename = NULL; | 779 | G.rnfr_filename = NULL; |
759 | 780 | ||
760 | if (retval) { | 781 | if (retval) { |
761 | cmdio_write_error(FTP_FILEFAIL); | 782 | WRITE_ERR(FTP_FILEFAIL); |
762 | return; | 783 | return; |
763 | } | 784 | } |
764 | cmdio_write_ok(FTP_RENAMEOK); | 785 | WRITE_OK(FTP_RENAMEOK); |
765 | } | 786 | } |
766 | 787 | ||
767 | static void | 788 | static void |
@@ -798,7 +819,7 @@ handle_upload_common(int is_append, int is_unique) | |||
798 | || fstat(local_file_fd, &statbuf) != 0 | 819 | || fstat(local_file_fd, &statbuf) != 0 |
799 | || !S_ISREG(statbuf.st_mode) | 820 | || !S_ISREG(statbuf.st_mode) |
800 | ) { | 821 | ) { |
801 | cmdio_write_error(FTP_UPLOADFAIL); | 822 | WRITE_ERR(FTP_UPLOADFAIL); |
802 | if (local_file_fd >= 0) | 823 | if (local_file_fd >= 0) |
803 | goto close_local_and_bail; | 824 | goto close_local_and_bail; |
804 | return; | 825 | return; |
@@ -817,9 +838,9 @@ handle_upload_common(int is_append, int is_unique) | |||
817 | bytes_transferred = bb_copyfd_eof(remote_fd, local_file_fd); | 838 | bytes_transferred = bb_copyfd_eof(remote_fd, local_file_fd); |
818 | close(remote_fd); | 839 | close(remote_fd); |
819 | if (bytes_transferred < 0) | 840 | if (bytes_transferred < 0) |
820 | cmdio_write_error(FTP_BADSENDFILE); | 841 | WRITE_ERR(FTP_BADSENDFILE); |
821 | else | 842 | else |
822 | cmdio_write_ok(FTP_TRANSFEROK); | 843 | WRITE_OK(FTP_TRANSFEROK); |
823 | 844 | ||
824 | close_local_and_bail: | 845 | close_local_and_bail: |
825 | close(local_file_fd); | 846 | close(local_file_fd); |
@@ -981,7 +1002,7 @@ int ftpd_main(int argc, char **argv) | |||
981 | setsockopt(STDIN_FILENO, SOL_SOCKET, SO_KEEPALIVE, &const_int_1, sizeof(const_int_1)); | 1002 | setsockopt(STDIN_FILENO, SOL_SOCKET, SO_KEEPALIVE, &const_int_1, sizeof(const_int_1)); |
982 | setsockopt(STDIN_FILENO, SOL_SOCKET, SO_OOBINLINE, &const_int_1, sizeof(const_int_1)); | 1003 | setsockopt(STDIN_FILENO, SOL_SOCKET, SO_OOBINLINE, &const_int_1, sizeof(const_int_1)); |
983 | 1004 | ||
984 | cmdio_write_ok(FTP_GREET); | 1005 | WRITE_OK(FTP_GREET); |
985 | signal(SIGALRM, timeout_handler); | 1006 | signal(SIGALRM, timeout_handler); |
986 | 1007 | ||
987 | #ifdef IF_WE_WANT_TO_REQUIRE_LOGIN | 1008 | #ifdef IF_WE_WANT_TO_REQUIRE_LOGIN |
@@ -1002,14 +1023,14 @@ int ftpd_main(int argc, char **argv) | |||
1002 | break; | 1023 | break; |
1003 | cmdio_write_raw(STR(FTP_NEEDUSER)" Login with USER\r\n"); | 1024 | cmdio_write_raw(STR(FTP_NEEDUSER)" Login with USER\r\n"); |
1004 | } else if (cmdval == const_QUIT) { | 1025 | } else if (cmdval == const_QUIT) { |
1005 | cmdio_write_ok(FTP_GOODBYE); | 1026 | WRITE_OK(FTP_GOODBYE); |
1006 | return 0; | 1027 | return 0; |
1007 | } else { | 1028 | } else { |
1008 | cmdio_write_raw(STR(FTP_LOGINERR)" Login with USER and PASS\r\n"); | 1029 | cmdio_write_raw(STR(FTP_LOGINERR)" Login with USER and PASS\r\n"); |
1009 | } | 1030 | } |
1010 | } | 1031 | } |
1011 | } | 1032 | } |
1012 | cmdio_write_ok(FTP_LOGINOK); | 1033 | WRITE_OK(FTP_LOGINOK); |
1013 | #endif | 1034 | #endif |
1014 | 1035 | ||
1015 | /* RFC-959 Section 5.1 | 1036 | /* RFC-959 Section 5.1 |
@@ -1054,23 +1075,23 @@ int ftpd_main(int argc, char **argv) | |||
1054 | uint32_t cmdval = cmdio_get_cmd_and_arg(); | 1075 | uint32_t cmdval = cmdio_get_cmd_and_arg(); |
1055 | 1076 | ||
1056 | if (cmdval == const_QUIT) { | 1077 | if (cmdval == const_QUIT) { |
1057 | cmdio_write_ok(FTP_GOODBYE); | 1078 | WRITE_OK(FTP_GOODBYE); |
1058 | return 0; | 1079 | return 0; |
1059 | } | 1080 | } |
1060 | else if (cmdval == const_USER) | 1081 | else if (cmdval == const_USER) |
1061 | cmdio_write_ok(FTP_GIVEPWORD); | 1082 | WRITE_OK(FTP_GIVEPWORD); |
1062 | else if (cmdval == const_PASS) | 1083 | else if (cmdval == const_PASS) |
1063 | cmdio_write_ok(FTP_LOGINOK); | 1084 | WRITE_OK(FTP_LOGINOK); |
1064 | else if (cmdval == const_NOOP) | 1085 | else if (cmdval == const_NOOP) |
1065 | cmdio_write_ok(FTP_NOOPOK); | 1086 | WRITE_OK(FTP_NOOPOK); |
1066 | else if (cmdval == const_TYPE) | 1087 | else if (cmdval == const_TYPE) |
1067 | cmdio_write_ok(FTP_TYPEOK); | 1088 | WRITE_OK(FTP_TYPEOK); |
1068 | else if (cmdval == const_STRU) | 1089 | else if (cmdval == const_STRU) |
1069 | cmdio_write_ok(FTP_STRUOK); | 1090 | WRITE_OK(FTP_STRUOK); |
1070 | else if (cmdval == const_MODE) | 1091 | else if (cmdval == const_MODE) |
1071 | cmdio_write_ok(FTP_MODEOK); | 1092 | WRITE_OK(FTP_MODEOK); |
1072 | else if (cmdval == const_ALLO) | 1093 | else if (cmdval == const_ALLO) |
1073 | cmdio_write_ok(FTP_ALLOOK); | 1094 | WRITE_OK(FTP_ALLOOK); |
1074 | else if (cmdval == const_SYST) | 1095 | else if (cmdval == const_SYST) |
1075 | cmdio_write_raw(STR(FTP_SYSTOK)" UNIX Type: L8\r\n"); | 1096 | cmdio_write_raw(STR(FTP_SYSTOK)" UNIX Type: L8\r\n"); |
1076 | else if (cmdval == const_PWD) | 1097 | else if (cmdval == const_PWD) |