aboutsummaryrefslogtreecommitdiff
path: root/networking/ftpd.c
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2009-03-09 04:13:59 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2009-03-09 04:13:59 +0000
commitf1a11b5a4eca1e296a9557655c2a93fb01d5be46 (patch)
treea74f5bf0debf890fd7a32adf7cc15b4ba5b7ad37 /networking/ftpd.c
parent9e95920efd3b8c0c1fa949795fed7a5cbcee3d0c (diff)
downloadbusybox-w32-f1a11b5a4eca1e296a9557655c2a93fb01d5be46.tar.gz
busybox-w32-f1a11b5a4eca1e296a9557655c2a93fb01d5be46.tar.bz2
busybox-w32-f1a11b5a4eca1e296a9557655c2a93fb01d5be46.zip
ftp: code shrink
text data bss dec hex filename 809078 476 7864 817418 c790a busybox_old 808590 476 7864 816930 c7722 busybox_unstripped
Diffstat (limited to 'networking/ftpd.c')
-rw-r--r--networking/ftpd.c251
1 files changed, 119 insertions, 132 deletions
diff --git a/networking/ftpd.c b/networking/ftpd.c
index b794a24c3..ec9683adb 100644
--- a/networking/ftpd.c
+++ b/networking/ftpd.c
@@ -17,49 +17,52 @@
17#include <syslog.h> 17#include <syslog.h>
18#include <netinet/tcp.h> 18#include <netinet/tcp.h>
19 19
20#define FTP_DATACONN 150
21#define FTP_NOOPOK 200
22#define FTP_TYPEOK 200
23#define FTP_PORTOK 200
24#define FTP_STRUOK 200
25#define FTP_MODEOK 200
26#define FTP_ALLOOK 202
27#define FTP_STATOK 211
28#define FTP_STATFILE_OK 213
29#define FTP_HELP 214
30#define FTP_SYSTOK 215
31#define FTP_GREET 220
32#define FTP_GOODBYE 221
33#define FTP_TRANSFEROK 226
34#define FTP_PASVOK 227
35#define FTP_LOGINOK 230
36#define FTP_CWDOK 250
37#define FTP_RMDIROK 250
38#define FTP_DELEOK 250
39#define FTP_RENAMEOK 250
40#define FTP_PWDOK 257
41#define FTP_MKDIROK 257
42#define FTP_GIVEPWORD 331
43#define FTP_RESTOK 350
44#define FTP_RNFROK 350
45#define FTP_BADSENDCONN 425
46#define FTP_BADSENDNET 426
47#define FTP_BADSENDFILE 451
48#define FTP_BADCMD 500
49#define FTP_COMMANDNOTIMPL 502
50#define FTP_NEEDUSER 503
51#define FTP_NEEDRNFR 503
52#define FTP_BADSTRU 504
53#define FTP_BADMODE 504
54#define FTP_LOGINERR 530
55#define FTP_FILEFAIL 550
56#define FTP_NOPERM 550
57#define FTP_UPLOADFAIL 553
58
59#define STR1(s) #s
60#define STR(s) STR1(s)
61
20enum { 62enum {
21 OPT_v = (1 << 0), 63 OPT_v = (1 << 0),
22 OPT_w = (1 << 1), 64 OPT_w = (1 << 1),
23 65
24 FTP_DATACONN = 150,
25 FTP_NOOPOK = 200,
26 FTP_TYPEOK = 200,
27 FTP_PORTOK = 200,
28 FTP_STRUOK = 200,
29 FTP_MODEOK = 200,
30 FTP_ALLOOK = 202,
31 FTP_STATOK = 211,
32 FTP_STATFILE_OK = 213,
33 FTP_HELP = 214,
34 FTP_SYSTOK = 215,
35 FTP_GREET = 220,
36 FTP_GOODBYE = 221,
37 FTP_TRANSFEROK = 226,
38 FTP_PASVOK = 227,
39 FTP_LOGINOK = 230,
40 FTP_CWDOK = 250,
41 FTP_RMDIROK = 250,
42 FTP_DELEOK = 250,
43 FTP_RENAMEOK = 250,
44 FTP_PWDOK = 257,
45 FTP_MKDIROK = 257,
46 FTP_GIVEPWORD = 331,
47 FTP_RESTOK = 350,
48 FTP_RNFROK = 350,
49 FTP_BADSENDCONN = 425,
50 FTP_BADSENDNET = 426,
51 FTP_BADSENDFILE = 451,
52 FTP_BADCMD = 500,
53 FTP_COMMANDNOTIMPL = 502,
54 FTP_NEEDUSER = 503,
55 FTP_NEEDRNFR = 503,
56 FTP_BADSTRU = 504,
57 FTP_BADMODE = 504,
58 FTP_LOGINERR = 530,
59 FTP_FILEFAIL = 550,
60 FTP_NOPERM = 550,
61 FTP_UPLOADFAIL = 553,
62
63#define mk_const4(a,b,c,d) (((a * 0x100 + b) * 0x100 + c) * 0x100 + d) 66#define mk_const4(a,b,c,d) (((a * 0x100 + b) * 0x100 + c) * 0x100 + d)
64#define mk_const3(a,b,c) ((a * 0x100 + b) * 0x100 + c) 67#define mk_const3(a,b,c) ((a * 0x100 + b) * 0x100 + c)
65 const_ALLO = mk_const4('A', 'L', 'L', 'O'), 68 const_ALLO = mk_const4('A', 'L', 'L', 'O'),
@@ -158,7 +161,7 @@ replace_char(char *str, char from, char to)
158} 161}
159 162
160static void 163static void
161ftp_write_str_common(unsigned status, const char *str, char sep) 164cmdio_write(unsigned status, const char *str)
162{ 165{
163 char *escaped_str, *response; 166 char *escaped_str, *response;
164 int len; 167 int len;
@@ -167,7 +170,7 @@ ftp_write_str_common(unsigned status, const char *str, char sep)
167 * In telnet, 0xff is an escape char, and needs to be escaped: */ 170 * In telnet, 0xff is an escape char, and needs to be escaped: */
168 escaped_str = replace_text(str, '\xff', "\xff\xff"); 171 escaped_str = replace_text(str, '\xff', "\xff\xff");
169 172
170 response = xasprintf("%u%c%s\r", status, sep, escaped_str); 173 response = xasprintf("%u%s\r", status, escaped_str);
171 free(escaped_str); 174 free(escaped_str);
172 175
173 /* ?! does FTP send embedded LFs as NULs? wow */ 176 /* ?! does FTP send embedded LFs as NULs? wow */
@@ -175,32 +178,27 @@ ftp_write_str_common(unsigned status, const char *str, char sep)
175 replace_char(response, '\n', '\0'); 178 replace_char(response, '\n', '\0');
176 179
177 response[len++] = '\n'; /* tack on trailing '\n' */ 180 response[len++] = '\n'; /* tack on trailing '\n' */
178 xwrite(STDIN_FILENO, response, len); 181 xwrite(STDOUT_FILENO, response, len);
179 free(response); 182 free(response);
180} 183}
181 184
182static void 185static void
183cmdio_write(int status, const char *p_text)
184{
185 ftp_write_str_common(status, p_text, ' ');
186}
187
188static void
189cmdio_write_ok(int status) 186cmdio_write_ok(int status)
190{ 187{
191 ftp_write_str_common(status, "Operation successful", ' '); 188 fdprintf(STDOUT_FILENO, "%u Operation successful\r\n", status);
192} 189}
193 190
191/* TODO: output strerr(errno) if errno != 0? */
194static void 192static void
195cmdio_write_hyphen(int status, const char *p_text) 193cmdio_write_error(int status)
196{ 194{
197 ftp_write_str_common(status, p_text, '-'); 195 fdprintf(STDOUT_FILENO, "%u Error\r\n", status);
198} 196}
199 197
200static void 198static void
201cmdio_write_raw(const char *p_text) 199cmdio_write_raw(const char *p_text)
202{ 200{
203 xwrite_str(STDIN_FILENO, p_text); 201 xwrite_str(STDOUT_FILENO, p_text);
204} 202}
205 203
206/* Simple commands */ 204/* Simple commands */
@@ -217,7 +215,7 @@ handle_pwd(void)
217 /* We have to promote each " to "" */ 215 /* We have to promote each " to "" */
218 promoted_cwd = replace_text(cwd, '\"', "\"\""); 216 promoted_cwd = replace_text(cwd, '\"', "\"\"");
219 free(cwd); 217 free(cwd);
220 response = xasprintf("\"%s\"", promoted_cwd); 218 response = xasprintf(" \"%s\"", promoted_cwd);
221 free(promoted_cwd); 219 free(promoted_cwd);
222 cmdio_write(FTP_PWDOK, response); 220 cmdio_write(FTP_PWDOK, response);
223 free(response); 221 free(response);
@@ -227,7 +225,7 @@ static void
227handle_cwd(void) 225handle_cwd(void)
228{ 226{
229 if (!G.ftp_arg || chdir(G.ftp_arg) != 0) { 227 if (!G.ftp_arg || chdir(G.ftp_arg) != 0) {
230 cmdio_write(FTP_FILEFAIL, "Can't change directory"); 228 cmdio_write_error(FTP_FILEFAIL);
231 return; 229 return;
232 } 230 }
233 cmdio_write_ok(FTP_CWDOK); 231 cmdio_write_ok(FTP_CWDOK);
@@ -240,41 +238,40 @@ handle_cdup(void)
240 handle_cwd(); 238 handle_cwd();
241} 239}
242 240
243static void 241//static void
244handle_type(void) 242//handle_type(void)
245{ 243//{
246 if (G.ftp_arg 244// if (G.ftp_arg
247 && ( ((G.ftp_arg[0] | 0x20) == 'i' && G.ftp_arg[1] == '\0') 245// && ( ((G.ftp_arg[0] | 0x20) == 'i' && G.ftp_arg[1] == '\0')
248 || !strcasecmp(G.ftp_arg, "L8") 246// || !strcasecmp(G.ftp_arg, "L8")
249 || !strcasecmp(G.ftp_arg, "L 8") 247// || !strcasecmp(G.ftp_arg, "L 8")
250 ) 248// )
251 ) { 249// ) {
252 cmdio_write_ok(FTP_TYPEOK); 250// cmdio_write_ok(FTP_TYPEOK);
253 } else { 251// } else {
254 cmdio_write(FTP_BADCMD, "Unrecognised TYPE command"); 252// cmdio_write_error(FTP_BADCMD);
255 } 253// }
256} 254//}
257 255
258static void 256static void
259handle_stat(void) 257handle_stat(void)
260{ 258{
261 cmdio_write_hyphen(FTP_STATOK, "FTP server status:"); 259 cmdio_write_raw(STR(FTP_STATOK)"-FTP server status:\r\n"
262 cmdio_write_raw(" TYPE: BINARY\r\n"); 260 "TYPE: BINARY\r\n"
263 cmdio_write_ok(FTP_STATOK); 261 STR(FTP_STATOK)" Ok\r\n");
264} 262}
265 263
266static void 264static void
267handle_help(void) 265handle_help(void)
268{ 266{
269 cmdio_write_hyphen(FTP_HELP, "Recognized commands:"); 267 cmdio_write_raw(STR(FTP_HELP)"-Commands:\r\n"
270 cmdio_write_raw(" ALLO CDUP CWD HELP LIST\r\n" 268 "ALLO CDUP CWD HELP LIST\r\n"
271 " MODE NLST NOOP PASS PASV PORT PWD QUIT\r\n" 269 "MODE NLST NOOP PASS PASV PORT PWD QUIT\r\n"
272 " REST RETR STAT STRU SYST TYPE USER\r\n" 270 "REST RETR STAT STRU SYST TYPE USER\r\n"
273#if ENABLE_FEATURE_FTP_WRITE 271#if ENABLE_FEATURE_FTP_WRITE
274 " APPE DELE MKD RMD RNFR RNTO STOR STOU\r\n" 272 "APPE DELE MKD RMD RNFR RNTO STOR STOU\r\n"
275#endif 273#endif
276 ); 274 STR(FTP_HELP)" Ok\r\n");
277 cmdio_write(FTP_HELP, "Help OK");
278} 275}
279 276
280/* Download commands */ 277/* Download commands */
@@ -302,7 +299,7 @@ ftpdataio_get_pasv_fd(void)
302 remote_fd = accept(G.pasv_listen_fd, NULL, 0); 299 remote_fd = accept(G.pasv_listen_fd, NULL, 0);
303 300
304 if (remote_fd < 0) { 301 if (remote_fd < 0) {
305 cmdio_write(FTP_BADSENDCONN, "Can't establish connection"); 302 cmdio_write_error(FTP_BADSENDCONN);
306 return remote_fd; 303 return remote_fd;
307 } 304 }
308 305
@@ -372,7 +369,7 @@ static int
372data_transfer_checks_ok(void) 369data_transfer_checks_ok(void)
373{ 370{
374 if (!pasv_active() && !port_active()) { 371 if (!pasv_active() && !port_active()) {
375 cmdio_write(FTP_BADSENDCONN, "Use PORT or PASV first"); 372 cmdio_write_raw(STR(FTP_BADSENDCONN)" Use PORT or PASV first\r\n");
376 return 0; 373 return 0;
377 } 374 }
378 375
@@ -425,7 +422,7 @@ handle_pasv(void)
425 addr = xmalloc_sockaddr2dotted_noport(&G.local_addr->u.sa); 422 addr = xmalloc_sockaddr2dotted_noport(&G.local_addr->u.sa);
426 replace_char(addr, '.', ','); 423 replace_char(addr, '.', ',');
427 424
428 response = xasprintf("Entering Passive Mode (%s,%u,%u)", 425 response = xasprintf(" Entering Passive Mode (%s,%u,%u)",
429 addr, (int)(port >> 8), (int)(port & 255)); 426 addr, (int)(port >> 8), (int)(port & 255));
430 free(addr); 427 free(addr);
431 428
@@ -466,7 +463,7 @@ handle_port(void)
466 463
467 if (lsa == NULL) { 464 if (lsa == NULL) {
468 bail: 465 bail:
469 cmdio_write(FTP_BADCMD, "Illegal PORT command"); 466 cmdio_write_error(FTP_BADCMD);
470 return; 467 return;
471 } 468 }
472 469
@@ -500,14 +497,14 @@ handle_retr(void)
500 /* O_NONBLOCK is useful if file happens to be a device node */ 497 /* O_NONBLOCK is useful if file happens to be a device node */
501 opened_file = G.ftp_arg ? open(G.ftp_arg, O_RDONLY | O_NONBLOCK) : -1; 498 opened_file = G.ftp_arg ? open(G.ftp_arg, O_RDONLY | O_NONBLOCK) : -1;
502 if (opened_file < 0) { 499 if (opened_file < 0) {
503 cmdio_write(FTP_FILEFAIL, "Can't open file"); 500 cmdio_write_error(FTP_FILEFAIL);
504 return; 501 return;
505 } 502 }
506 503
507 retval = fstat(opened_file, &statbuf); 504 retval = fstat(opened_file, &statbuf);
508 if (retval < 0 || !S_ISREG(statbuf.st_mode)) { 505 if (retval < 0 || !S_ISREG(statbuf.st_mode)) {
509 /* Note - pretend open failed */ 506 /* Note - pretend open failed */
510 cmdio_write(FTP_FILEFAIL, "Can't open file"); 507 cmdio_write_error(FTP_FILEFAIL);
511 goto file_close_out; 508 goto file_close_out;
512 } 509 }
513 510
@@ -521,7 +518,7 @@ handle_retr(void)
521 xlseek(opened_file, offset, SEEK_SET); 518 xlseek(opened_file, offset, SEEK_SET);
522 519
523 response = xasprintf( 520 response = xasprintf(
524 "Opening BINARY mode data connection for %s (%"OFF_FMT"u bytes)", 521 " Opening BINARY mode data connection for %s (%"OFF_FMT"u bytes)",
525 G.ftp_arg, statbuf.st_size); 522 G.ftp_arg, statbuf.st_size);
526 remote_fd = get_remote_transfer_fd(response); 523 remote_fd = get_remote_transfer_fd(response);
527 free(response); 524 free(response);
@@ -531,7 +528,7 @@ handle_retr(void)
531 trans_ret = bb_copyfd_eof(opened_file, remote_fd); 528 trans_ret = bb_copyfd_eof(opened_file, remote_fd);
532 ftpdataio_dispose_transfer_fd(); 529 ftpdataio_dispose_transfer_fd();
533 if (trans_ret < 0) 530 if (trans_ret < 0)
534 cmdio_write(FTP_BADSENDFILE, "Error sending local file"); 531 cmdio_write_error(FTP_BADSENDFILE);
535 else 532 else
536 cmdio_write_ok(FTP_TRANSFEROK); 533 cmdio_write_ok(FTP_TRANSFEROK);
537 534
@@ -681,9 +678,9 @@ handle_dir_common(int full_details, int stat_cmd)
681 678
682 if (stat_cmd) { 679 if (stat_cmd) {
683 fd = STDIN_FILENO; 680 fd = STDIN_FILENO;
684 cmdio_write_hyphen(FTP_STATFILE_OK, "Status follows:"); 681 cmdio_write_raw(STR(FTP_STATFILE_OK)"-Status follows:\r\n");
685 } else { 682 } else {
686 fd = get_remote_transfer_fd("Here comes the directory listing"); 683 fd = get_remote_transfer_fd(" Here comes the directory listing");
687 if (fd < 0) 684 if (fd < 0)
688 goto bail; 685 goto bail;
689 } 686 }
@@ -735,7 +732,7 @@ static void
735handle_mkd(void) 732handle_mkd(void)
736{ 733{
737 if (!G.ftp_arg || mkdir(G.ftp_arg, 0777) != 0) { 734 if (!G.ftp_arg || mkdir(G.ftp_arg, 0777) != 0) {
738 cmdio_write(FTP_FILEFAIL, "Create directory operation failed"); 735 cmdio_write_error(FTP_FILEFAIL);
739 return; 736 return;
740 } 737 }
741 cmdio_write_ok(FTP_MKDIROK); 738 cmdio_write_ok(FTP_MKDIROK);
@@ -745,7 +742,7 @@ static void
745handle_rmd(void) 742handle_rmd(void)
746{ 743{
747 if (!G.ftp_arg || rmdir(G.ftp_arg) != 0) { 744 if (!G.ftp_arg || rmdir(G.ftp_arg) != 0) {
748 cmdio_write(FTP_FILEFAIL, "Deletion failed"); 745 cmdio_write_error(FTP_FILEFAIL);
749 return; 746 return;
750 } 747 }
751 cmdio_write_ok(FTP_RMDIROK); 748 cmdio_write_ok(FTP_RMDIROK);
@@ -755,7 +752,7 @@ static void
755handle_dele(void) 752handle_dele(void)
756{ 753{
757 if (!G.ftp_arg || unlink(G.ftp_arg) != 0) { 754 if (!G.ftp_arg || unlink(G.ftp_arg) != 0) {
758 cmdio_write(FTP_FILEFAIL, "Deletion failed"); 755 cmdio_write_error(FTP_FILEFAIL);
759 return; 756 return;
760 } 757 }
761 cmdio_write_ok(FTP_DELEOK); 758 cmdio_write_ok(FTP_DELEOK);
@@ -764,19 +761,7 @@ handle_dele(void)
764static void 761static void
765handle_rnfr(void) 762handle_rnfr(void)
766{ 763{
767 struct stat statbuf;
768
769 /* Clear old value */
770 free(G.rnfr_filename); 764 free(G.rnfr_filename);
771 G.rnfr_filename = NULL;
772
773 if (!G.ftp_arg
774 || stat(G.ftp_arg, &statbuf) != 0
775 /* || it isn't a regular file or a directory? */
776 ) {
777 cmdio_write(FTP_FILEFAIL, "RNFR command failed");
778 return;
779 }
780 G.rnfr_filename = xstrdup(G.ftp_arg); 765 G.rnfr_filename = xstrdup(G.ftp_arg);
781 cmdio_write_ok(FTP_RNFROK); 766 cmdio_write_ok(FTP_RNFROK);
782} 767}
@@ -788,7 +773,7 @@ handle_rnto(void)
788 773
789 /* If we didn't get a RNFR, throw a wobbly */ 774 /* If we didn't get a RNFR, throw a wobbly */
790 if (G.rnfr_filename == NULL || G.ftp_arg == NULL) { 775 if (G.rnfr_filename == NULL || G.ftp_arg == NULL) {
791 cmdio_write(FTP_NEEDRNFR, "RNFR required first"); 776 cmdio_write_raw(STR(FTP_NEEDRNFR)" RNFR required first\r\n");
792 return; 777 return;
793 } 778 }
794 779
@@ -797,7 +782,7 @@ handle_rnto(void)
797 G.rnfr_filename = NULL; 782 G.rnfr_filename = NULL;
798 783
799 if (retval) { 784 if (retval) {
800 cmdio_write(FTP_FILEFAIL, "Rename failed"); 785 cmdio_write_error(FTP_FILEFAIL);
801 return; 786 return;
802 } 787 }
803 cmdio_write_ok(FTP_RENAMEOK); 788 cmdio_write_ok(FTP_RENAMEOK);
@@ -820,8 +805,8 @@ handle_upload_common(int is_append, int is_unique)
820 805
821 local_file_fd = -1; 806 local_file_fd = -1;
822 if (is_unique) { 807 if (is_unique) {
823 tempname = xstrdup("FILE: uniq.XXXXXX"); 808 tempname = xstrdup(" FILE: uniq.XXXXXX");
824 local_file_fd = mkstemp(tempname + 6); 809 local_file_fd = mkstemp(tempname + 7);
825 } else if (G.ftp_arg) { 810 } else if (G.ftp_arg) {
826 int flags = O_WRONLY | O_CREAT | O_TRUNC; 811 int flags = O_WRONLY | O_CREAT | O_TRUNC;
827 if (is_append) 812 if (is_append)
@@ -831,7 +816,7 @@ handle_upload_common(int is_append, int is_unique)
831 local_file_fd = open(G.ftp_arg, flags, 0666); 816 local_file_fd = open(G.ftp_arg, flags, 0666);
832 } 817 }
833 if (local_file_fd < 0) { 818 if (local_file_fd < 0) {
834 cmdio_write(FTP_UPLOADFAIL, "Can't create file"); 819 cmdio_write_error(FTP_UPLOADFAIL);
835 return; 820 return;
836 } 821 }
837 822
@@ -840,7 +825,7 @@ handle_upload_common(int is_append, int is_unique)
840 if (offset) 825 if (offset)
841 xlseek(local_file_fd, offset, SEEK_SET); 826 xlseek(local_file_fd, offset, SEEK_SET);
842 827
843 remote_fd = get_remote_transfer_fd(tempname ? tempname : "Ok to send data"); 828 remote_fd = get_remote_transfer_fd(tempname ? tempname : " Ok to send data");
844 free(tempname); 829 free(tempname);
845 830
846 if (remote_fd < 0) 831 if (remote_fd < 0)
@@ -850,7 +835,7 @@ handle_upload_common(int is_append, int is_unique)
850 ftpdataio_dispose_transfer_fd(); 835 ftpdataio_dispose_transfer_fd();
851 836
852 if (trans_ret < 0) 837 if (trans_ret < 0)
853 cmdio_write(FTP_BADSENDFILE, "Failure writing to local file"); 838 cmdio_write_error(FTP_BADSENDFILE);
854 else 839 else
855 cmdio_write_ok(FTP_TRANSFEROK); 840 cmdio_write_ok(FTP_TRANSFEROK);
856 841
@@ -949,7 +934,7 @@ int ftpd_main(int argc UNUSED_PARAM, char **argv)
949 setsockopt(STDIN_FILENO, SOL_SOCKET, SO_KEEPALIVE, &const_int_1, sizeof(const_int_1)); 934 setsockopt(STDIN_FILENO, SOL_SOCKET, SO_KEEPALIVE, &const_int_1, sizeof(const_int_1));
950 setsockopt(STDIN_FILENO, SOL_SOCKET, SO_OOBINLINE, &const_int_1, sizeof(const_int_1)); 935 setsockopt(STDIN_FILENO, SOL_SOCKET, SO_OOBINLINE, &const_int_1, sizeof(const_int_1));
951 936
952 cmdio_write(FTP_GREET, "Welcome"); 937 cmdio_write_raw(STR(FTP_GREET)" Welcome\r\n");
953 938
954#ifdef IF_WE_WANT_TO_REQUIRE_LOGIN 939#ifdef IF_WE_WANT_TO_REQUIRE_LOGIN
955 { 940 {
@@ -959,20 +944,20 @@ int ftpd_main(int argc UNUSED_PARAM, char **argv)
959 944
960 if (cmdval == const_USER) { 945 if (cmdval == const_USER) {
961 if (G.ftp_arg == NULL || strcasecmp(G.ftp_arg, "anonymous") != 0) 946 if (G.ftp_arg == NULL || strcasecmp(G.ftp_arg, "anonymous") != 0)
962 cmdio_write(FTP_LOGINERR, "Server is anonymous only"); 947 cmdio_write_raw(STR(FTP_LOGINERR)" Server is anonymous only\r\n");
963 else { 948 else {
964 user_was_specified = 1; 949 user_was_specified = 1;
965 cmdio_write(FTP_GIVEPWORD, "Please specify the password"); 950 cmdio_write_raw(STR(FTP_GIVEPWORD)" Please specify the password\r\n");
966 } 951 }
967 } else if (cmdval == const_PASS) { 952 } else if (cmdval == const_PASS) {
968 if (user_was_specified) 953 if (user_was_specified)
969 break; 954 break;
970 cmdio_write(FTP_NEEDUSER, "Login with USER"); 955 cmdio_write_raw(STR(FTP_NEEDUSER)" Login with USER\r\n");
971 } else if (cmdval == const_QUIT) { 956 } else if (cmdval == const_QUIT) {
972 cmdio_write(FTP_GOODBYE, "Goodbye"); 957 cmdio_write_raw(STR(FTP_GOODBYE)" Goodbye\r\n");
973 return 0; 958 return 0;
974 } else { 959 } else {
975 cmdio_write(FTP_LOGINERR, "Login with USER and PASS"); 960 cmdio_write_raw(STR(FTP_LOGINERR)" Login with USER and PASS\r\n");
976 } 961 }
977 } 962 }
978 } 963 }
@@ -1021,7 +1006,7 @@ int ftpd_main(int argc UNUSED_PARAM, char **argv)
1021 uint32_t cmdval = cmdio_get_cmd_and_arg(); 1006 uint32_t cmdval = cmdio_get_cmd_and_arg();
1022 1007
1023 if (cmdval == const_QUIT) { 1008 if (cmdval == const_QUIT) {
1024 cmdio_write(FTP_GOODBYE, "Goodbye"); 1009 cmdio_write_raw(STR(FTP_GOODBYE)" Goodbye\r\n");
1025 return 0; 1010 return 0;
1026 } 1011 }
1027 if (cmdval == const_PWD) 1012 if (cmdval == const_PWD)
@@ -1037,13 +1022,14 @@ int ftpd_main(int argc UNUSED_PARAM, char **argv)
1037 else if (cmdval == const_NOOP) 1022 else if (cmdval == const_NOOP)
1038 cmdio_write_ok(FTP_NOOPOK); 1023 cmdio_write_ok(FTP_NOOPOK);
1039 else if (cmdval == const_SYST) 1024 else if (cmdval == const_SYST)
1040 cmdio_write(FTP_SYSTOK, "UNIX Type: L8"); 1025 cmdio_write_raw(STR(FTP_SYSTOK)" UNIX Type: L8\r\n");
1041 else if (cmdval == const_HELP) 1026 else if (cmdval == const_HELP)
1042 handle_help(); 1027 handle_help();
1043 else if (cmdval == const_LIST) /* ls -l */ 1028 else if (cmdval == const_LIST) /* ls -l */
1044 handle_list(); 1029 handle_list();
1045 else if (cmdval == const_TYPE) 1030 else if (cmdval == const_TYPE)
1046 handle_type(); 1031 //handle_type();
1032 cmdio_write_ok(FTP_TYPEOK);
1047 else if (cmdval == const_PORT) 1033 else if (cmdval == const_PORT)
1048 handle_port(); 1034 handle_port();
1049 else if (cmdval == const_REST) 1035 else if (cmdval == const_REST)
@@ -1055,20 +1041,20 @@ int ftpd_main(int argc UNUSED_PARAM, char **argv)
1055 // && (G.ftp_arg[0] | 0x20) == 'f' 1041 // && (G.ftp_arg[0] | 0x20) == 'f'
1056 // && G.ftp_arg[1] == '\0' 1042 // && G.ftp_arg[1] == '\0'
1057 //) { 1043 //) {
1058 cmdio_write(FTP_STRUOK, "Command ignored"); 1044 cmdio_write_ok(FTP_STRUOK);
1059 //} else 1045 //} else
1060 // cmdio_write(FTP_BADSTRU, "Bad STRU command"); 1046 // cmdio_write_raw(STR(FTP_BADSTRU)" Bad STRU command\r\n");
1061 } else if (cmdval == const_MODE) { 1047 } else if (cmdval == const_MODE) {
1062 //if (G.ftp_arg 1048 //if (G.ftp_arg
1063 // && (G.ftp_arg[0] | 0x20) == 's' 1049 // && (G.ftp_arg[0] | 0x20) == 's'
1064 // && G.ftp_arg[1] == '\0' 1050 // && G.ftp_arg[1] == '\0'
1065 //) { 1051 //) {
1066 cmdio_write(FTP_MODEOK, "Command ignored"); 1052 cmdio_write_ok(FTP_MODEOK);
1067 //} else 1053 //} else
1068 // cmdio_write(FTP_BADMODE, "Bad MODE command"); 1054 // cmdio_write_raw(STR(FTP_BADMODE)" Bad MODE command\r\n");
1069 } 1055 }
1070 else if (cmdval == const_ALLO) 1056 else if (cmdval == const_ALLO)
1071 cmdio_write(FTP_ALLOOK, "Command ignored"); 1057 cmdio_write_ok(FTP_ALLOOK);
1072 else if (cmdval == const_STAT) { 1058 else if (cmdval == const_STAT) {
1073 if (G.ftp_arg == NULL) 1059 if (G.ftp_arg == NULL)
1074 handle_stat(); 1060 handle_stat();
@@ -1076,10 +1062,10 @@ int ftpd_main(int argc UNUSED_PARAM, char **argv)
1076 handle_stat_file(); 1062 handle_stat_file();
1077 } else if (cmdval == const_USER) { 1063 } else if (cmdval == const_USER) {
1078 /* FTP_LOGINERR confuses clients: */ 1064 /* FTP_LOGINERR confuses clients: */
1079 /* cmdio_write(FTP_LOGINERR, "Can't change to another user"); */ 1065 /* cmdio_write_raw(STR(FTP_LOGINERR)" Can't change to another user\r\n"); */
1080 cmdio_write(FTP_GIVEPWORD, "Command ignored"); 1066 cmdio_write_ok(FTP_GIVEPWORD);
1081 } else if (cmdval == const_PASS) 1067 } else if (cmdval == const_PASS)
1082 cmdio_write(FTP_LOGINOK, "Command ignored"); 1068 cmdio_write_ok(FTP_LOGINOK);
1083#if ENABLE_FEATURE_FTP_WRITE 1069#if ENABLE_FEATURE_FTP_WRITE
1084 else if (G.opts & OPT_w) { 1070 else if (G.opts & OPT_w) {
1085 if (cmdval == const_STOR) 1071 if (cmdval == const_STOR)
@@ -1110,17 +1096,18 @@ int ftpd_main(int argc UNUSED_PARAM, char **argv)
1110 || cmdval == const_APPE 1096 || cmdval == const_APPE
1111 || cmdval == const_STOU 1097 || cmdval == const_STOU
1112 ) { 1098 ) {
1113 cmdio_write(FTP_NOPERM, "Permission denied"); 1099 cmdio_write_raw(STR(FTP_NOPERM)" Permission denied\r\n");
1114 } 1100 }
1115#endif 1101#endif
1116 else { 1102 else {
1117 /* Which unsupported commands were seen in the wild? 1103 /* Which unsupported commands were seen in the wild?
1118 * (doesn't necessarily mean "we must support them") 1104 * (doesn't necessarily mean "we must support them")
1119 * wget 1.11.4: SIZE - todo. 1105 * wget 1.11.4: SIZE - todo
1120 * lftp 3.6.3: MDTM - works fine without it anyway. 1106 * lftp 3.6.3: FEAT - is it useful?
1121 * IPv6-style PASV: "EPSV 2" 1107 * MDTM - works fine without it anyway
1108 * IPv6-style PASV: "EPSV 2" - todo
1122 */ 1109 */
1123 cmdio_write(FTP_BADCMD, "Unknown command"); 1110 cmdio_write_raw(STR(FTP_BADCMD)" Unknown command\r\n");
1124 } 1111 }
1125 } 1112 }
1126} 1113}