aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2009-03-16 20:54:45 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2009-03-16 20:54:45 +0000
commitfbf5846ce1e6c34caa1853d9c1fa9ccac16a52c9 (patch)
treea2d32484d31c3459e06231fb17c5b159ee7c43a3
parent43bb7bba3b09f9beddb07417fa4997a599f5c6d1 (diff)
downloadbusybox-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
-rw-r--r--networking/ftpd.c109
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 */
63enum { 63enum {
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
75struct globals { 86struct 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
96static char * 113static char *
@@ -161,17 +178,21 @@ cmdio_write(uint32_t status_str, const char *str)
161} 178}
162 179
163static void 180static void
164cmdio_write_ok(int status) 181cmdio_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? */
170static void 189static void
171cmdio_write_error(int status) 190cmdio_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
176static void 197static void
177cmdio_write_raw(const char *p_text) 198cmdio_write_raw(const char *p_text)
@@ -228,10 +249,10 @@ static void
228handle_cwd(void) 249handle_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
237static void 258static 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
509static void 530static 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
517static void 538static 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
708handle_mkd(void) 729handle_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
717static void 738static void
718handle_rmd(void) 739handle_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
727static void 748static void
728handle_dele(void) 749handle_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
737static void 758static 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
745static void 766static 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
767static void 788static 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)