diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2014-06-26 14:07:48 +0400 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2014-06-26 14:07:48 +0400 |
commit | 0b0ccd457016d6a4eaa3e79bd65a852ea7d4294b (patch) | |
tree | 88a66fea6596f6ef6426b8590e2ca348da7ba50c /networking | |
parent | 2a870d091e86687c8b7b9e14b9c75815d40d7053 (diff) |
ftpd: optimize writes of LIST results a bit
function old new delta
handle_dir_common 201 207 +6
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'networking')
-rw-r--r-- | networking/ftpd.c | 15 |
1 files changed, 10 insertions, 5 deletions
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 <filename> */ @@ -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); } } |