aboutsummaryrefslogtreecommitdiff
path: root/networking/ftpd.c
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2009-03-09 04:38:37 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2009-03-09 04:38:37 +0000
commit57a3b174989c7778fb255f716e090d5be807b9b7 (patch)
tree5f2aeaede8073e72176a4d63f533a2c203570d8f /networking/ftpd.c
parentd42eb81206dba25b01f68f98272daa34f61531d0 (diff)
downloadbusybox-w32-57a3b174989c7778fb255f716e090d5be807b9b7.tar.gz
busybox-w32-57a3b174989c7778fb255f716e090d5be807b9b7.tar.bz2
busybox-w32-57a3b174989c7778fb255f716e090d5be807b9b7.zip
ftp: reduce amount of realloc's done in cmdio_write
text data bss dec hex filename 808562 476 7864 816902 c7706 busybox_old 808568 476 7864 816908 c770c busybox_unstripped
Diffstat (limited to 'networking/ftpd.c')
-rw-r--r--networking/ftpd.c46
1 files changed, 20 insertions, 26 deletions
diff --git a/networking/ftpd.c b/networking/ftpd.c
index 4988ce02e..b2d6ef2d2 100644
--- a/networking/ftpd.c
+++ b/networking/ftpd.c
@@ -102,7 +102,7 @@ struct globals {
102 int pasv_listen_fd; 102 int pasv_listen_fd;
103 int data_fd; 103 int data_fd;
104 off_t restart_pos; 104 off_t restart_pos;
105 char *ftp_cmp; 105 char *ftp_cmd;
106 char *ftp_arg; 106 char *ftp_arg;
107#if ENABLE_FEATURE_FTP_WRITE 107#if ENABLE_FEATURE_FTP_WRITE
108 char *rnfr_filename; 108 char *rnfr_filename;
@@ -112,8 +112,9 @@ struct globals {
112#define G (*(struct globals*)&bb_common_bufsiz1) 112#define G (*(struct globals*)&bb_common_bufsiz1)
113#define INIT_G() do { } while (0) 113#define INIT_G() do { } while (0)
114 114
115
115static char * 116static char *
116replace_text(const char *str, const char from, const char *to) 117escape_text(const char *prepend, const char *str, char from, const char *to, char append)
117{ 118{
118 size_t retlen, remainlen, chunklen, tolen; 119 size_t retlen, remainlen, chunklen, tolen;
119 const char *remain; 120 const char *remain;
@@ -124,29 +125,27 @@ replace_text(const char *str, const char from, const char *to)
124 tolen = strlen(to); 125 tolen = strlen(to);
125 126
126 /* Simply alloc strlen(str)*strlen(to). "to" is max 2 so it's ok */ 127 /* Simply alloc strlen(str)*strlen(to). "to" is max 2 so it's ok */
127 ret = xmalloc(remainlen * tolen + 1); 128 retlen = strlen(prepend);
128 retlen = 0; 129 ret = xmalloc(retlen + remainlen * tolen + 1 + 1);
130 strcpy(ret, prepend);
129 131
130 for (;;) { 132 for (;;) {
131 found = strchr(remain, from); 133 found = strchrnul(remain, from);
132 if (found != NULL) { 134 chunklen = found - remain;
133 chunklen = found - remain;
134 135
135 /* Copy chunk which doesn't contain 'from' to ret */ 136 /* Copy chunk which doesn't contain 'from' to ret */
136 memcpy(&ret[retlen], remain, chunklen); 137 memcpy(&ret[retlen], remain, chunklen);
137 retlen += chunklen; 138 retlen += chunklen;
138 139
140 if (*found != '\0') {
139 /* Now copy 'to' instead of 'from' */ 141 /* Now copy 'to' instead of 'from' */
140 memcpy(&ret[retlen], to, tolen); 142 memcpy(&ret[retlen], to, tolen);
141 retlen += tolen; 143 retlen += tolen;
142 144
143 remain = found + 1; 145 remain = found + 1;
144 } else { 146 } else {
145 /* 147 ret[retlen] = append;
146 * The last chunk. We are already sure that we have enough space 148 ret[retlen+1] = '\0';
147 * so we can use strcpy.
148 */
149 strcpy(&ret[retlen], remain);
150 break; 149 break;
151 } 150 }
152 } 151 }
@@ -163,15 +162,12 @@ replace_char(char *str, char from, char to)
163static void 162static void
164cmdio_write(unsigned status, const char *str) 163cmdio_write(unsigned status, const char *str)
165{ 164{
166 char *escaped_str, *response; 165 char *response;
167 int len; 166 int len;
168 167
169 /* FTP allegedly uses telnet protocol for command link. 168 /* FTP allegedly uses telnet protocol for command link.
170 * In telnet, 0xff is an escape char, and needs to be escaped: */ 169 * In telnet, 0xff is an escape char, and needs to be escaped: */
171 escaped_str = replace_text(str, '\xff', "\xff\xff"); 170 response = escape_text(utoa(status), str, '\xff', "\xff\xff", '\r');
172
173 response = xasprintf("%u%s\r", status, escaped_str);
174 free(escaped_str);
175 171
176 /* ?! does FTP send embedded LFs as NULs? wow */ 172 /* ?! does FTP send embedded LFs as NULs? wow */
177 len = strlen(response); 173 len = strlen(response);
@@ -206,17 +202,15 @@ cmdio_write_raw(const char *p_text)
206static void 202static void
207handle_pwd(void) 203handle_pwd(void)
208{ 204{
209 char *cwd, *promoted_cwd, *response; 205 char *cwd, *response;
210 206
211 cwd = xrealloc_getcwd_or_warn(NULL); 207 cwd = xrealloc_getcwd_or_warn(NULL);
212 if (cwd == NULL) 208 if (cwd == NULL)
213 cwd = xstrdup(""); 209 cwd = xstrdup("");
214 210
215 /* We have to promote each " to "" */ 211 /* We have to promote each " to "" */
216 promoted_cwd = replace_text(cwd, '\"', "\"\""); 212 response = escape_text(" \"", cwd, '\"', "\"\"", '\"');
217 free(cwd); 213 free(cwd);
218 response = xasprintf(" \"%s\"", promoted_cwd);
219 free(promoted_cwd);
220 cmdio_write(FTP_PWDOK, response); 214 cmdio_write(FTP_PWDOK, response);
221 free(response); 215 free(response);
222} 216}
@@ -872,9 +866,9 @@ cmdio_get_cmd_and_arg(void)
872 uint32_t cmdval; 866 uint32_t cmdval;
873 char *cmd; 867 char *cmd;
874 868
875 free(G.ftp_cmp); 869 free(G.ftp_cmd);
876 len = 8 * 1024; /* Paranoia. Peer may send 1 gigabyte long cmd... */ 870 len = 8 * 1024; /* Paranoia. Peer may send 1 gigabyte long cmd... */
877 G.ftp_cmp = cmd = xmalloc_reads(STDIN_FILENO, NULL, &len); 871 G.ftp_cmd = cmd = xmalloc_reads(STDIN_FILENO, NULL, &len);
878 if (!cmd) 872 if (!cmd)
879 exit(0); 873 exit(0);
880 874