svn commit: [25581] trunk/busybox/networking

vda at busybox.net vda at busybox.net
Mon Mar 9 04:38:38 UTC 2009


Author: vda
Date: 2009-03-09 04:38:37 +0000 (Mon, 09 Mar 2009)
New Revision: 25581

Log:
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



Modified:
   trunk/busybox/networking/ftpd.c


Changeset:
Modified: trunk/busybox/networking/ftpd.c
===================================================================
--- trunk/busybox/networking/ftpd.c	2009-03-09 04:22:52 UTC (rev 25580)
+++ trunk/busybox/networking/ftpd.c	2009-03-09 04:38:37 UTC (rev 25581)
@@ -102,7 +102,7 @@
 	int pasv_listen_fd;
 	int data_fd;
 	off_t restart_pos;
-	char *ftp_cmp;
+	char *ftp_cmd;
 	char *ftp_arg;
 #if ENABLE_FEATURE_FTP_WRITE
 	char *rnfr_filename;
@@ -112,8 +112,9 @@
 #define G (*(struct globals*)&bb_common_bufsiz1)
 #define INIT_G() do { } while (0)
 
+
 static char *
-replace_text(const char *str, const char from, const char *to)
+escape_text(const char *prepend, const char *str, char from, const char *to, char append)
 {
 	size_t retlen, remainlen, chunklen, tolen;
 	const char *remain;
@@ -124,29 +125,27 @@
 	tolen = strlen(to);
 
 	/* Simply alloc strlen(str)*strlen(to). "to" is max 2 so it's ok */
-	ret = xmalloc(remainlen * tolen + 1);
-	retlen = 0;
+	retlen = strlen(prepend);
+	ret = xmalloc(retlen + remainlen * tolen + 1 + 1);
+	strcpy(ret, prepend);
 
 	for (;;) {
-		found = strchr(remain, from);
-		if (found != NULL) {
-			chunklen = found - remain;
+		found = strchrnul(remain, from);
+		chunklen = found - remain;
 
-			/* Copy chunk which doesn't contain 'from' to ret */
-			memcpy(&ret[retlen], remain, chunklen);
-			retlen += chunklen;
+		/* Copy chunk which doesn't contain 'from' to ret */
+		memcpy(&ret[retlen], remain, chunklen);
+		retlen += chunklen;
 
+		if (*found != '\0') {
 			/* Now copy 'to' instead of 'from' */
 			memcpy(&ret[retlen], to, tolen);
 			retlen += tolen;
 
 			remain = found + 1;
 		} else {
-			/*
-			 * The last chunk. We are already sure that we have enough space
-			 * so we can use strcpy.
-			 */
-			strcpy(&ret[retlen], remain);
+			ret[retlen] = append;
+			ret[retlen+1] = '\0';
 			break;
 		}
 	}
@@ -163,16 +162,13 @@
 static void
 cmdio_write(unsigned status, const char *str)
 {
-	char *escaped_str, *response;
+	char *response;
 	int len;
 
 	/* FTP allegedly uses telnet protocol for command link.
 	 * In telnet, 0xff is an escape char, and needs to be escaped: */
-	escaped_str = replace_text(str, '\xff', "\xff\xff");
+	response = escape_text(utoa(status), str, '\xff', "\xff\xff", '\r');
 
-	response = xasprintf("%u%s\r", status, escaped_str);
-	free(escaped_str);
-
 	/* ?! does FTP send embedded LFs as NULs? wow */
 	len = strlen(response);
 	replace_char(response, '\n', '\0');
@@ -206,17 +202,15 @@
 static void
 handle_pwd(void)
 {
-	char *cwd, *promoted_cwd, *response;
+	char *cwd, *response;
 
 	cwd = xrealloc_getcwd_or_warn(NULL);
 	if (cwd == NULL)
 		cwd = xstrdup("");
 
 	/* We have to promote each " to "" */
-	promoted_cwd = replace_text(cwd, '\"', "\"\"");
+	response = escape_text(" \"", cwd, '\"', "\"\"", '\"');
 	free(cwd);
-	response = xasprintf(" \"%s\"", promoted_cwd);
-	free(promoted_cwd);
 	cmdio_write(FTP_PWDOK, response);
 	free(response);
 }
@@ -872,9 +866,9 @@
 	uint32_t cmdval;
 	char *cmd;
 
-	free(G.ftp_cmp);
+	free(G.ftp_cmd);
 	len = 8 * 1024; /* Paranoia. Peer may send 1 gigabyte long cmd... */
-	G.ftp_cmp = cmd = xmalloc_reads(STDIN_FILENO, NULL, &len);
+	G.ftp_cmd = cmd = xmalloc_reads(STDIN_FILENO, NULL, &len);
 	if (!cmd)
 		exit(0);
 



More information about the busybox-cvs mailing list