From 0b0ccd457016d6a4eaa3e79bd65a852ea7d4294b Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Thu, 26 Jun 2014 12:07:48 +0200 Subject: ftpd: optimize writes of LIST results a bit function old new delta handle_dir_common 201 207 +6 Signed-off-by: Denys Vlasenko --- networking/ftpd.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'networking/ftpd.c') diff --git a/networking/ftpd.c b/networking/ftpd.c index b4d73e55d..e724734df 100644 --- a/networking/ftpd.c +++ b/networking/ftpd.c @@ -709,6 +709,7 @@ handle_dir_common(int opts) * which can be problematic in chroot */ ls_fd = popen_ls((opts & LONG_LISTING) ? "-l" : "-1"); ls_fp = xfdopen_for_read(ls_fd); +/* FIXME: filenames with embedded newlines are mishandled */ if (opts & USE_CTRL_CONN) { /* STAT */ @@ -729,16 +730,20 @@ handle_dir_common(int opts) int remote_fd = get_remote_transfer_fd(" Directory listing"); if (remote_fd >= 0) { while (1) { - line = xmalloc_fgetline(ls_fp); + unsigned len; + + line = xmalloc_fgets(ls_fp); if (!line) break; /* I've seen clients complaining when they * are fed with ls output with bare '\n'. - * Pity... that would be much simpler. + * Replace trailing "\n\0" with "\r\n". */ -/* TODO: need to s/LF/NUL/g here */ - xwrite_str(remote_fd, line); - xwrite(remote_fd, "\r\n", 2); + len = strlen(line); + if (len != 0) /* paranoia check */ + line[len - 1] = '\r'; + line[len] = '\n'; + xwrite(remote_fd, line, len + 1); free(line); } } -- cgit v1.2.3