Index: modules/mod_ls.c
===================================================================
RCS file: /cvsroot/proftp/proftpd/modules/mod_ls.c,v
retrieving revision 1.187
diff -u -r1.187 mod_ls.c
--- modules/mod_ls.c 5 Nov 2011 23:01:58 -0000 1.187
+++ modules/mod_ls.c 1 Feb 2012 18:57:20 -0000
@@ -81,6 +81,7 @@
/* ls options */
static int
+ opt_1 = 0,
opt_a = 0,
opt_A = 0,
opt_B = 0,
@@ -395,7 +396,6 @@
p = cmd->tmp_pool;
if (pr_fsio_lstat(name, &st) == 0) {
-
char *display_name = NULL;
suffix[0] = suffix[1] = '\0';
@@ -493,21 +493,24 @@
break;
}
- if (list_times_gmt)
+ if (list_times_gmt) {
t = pr_gmtime(p, (time_t *) &sort_time);
- else
+
+ } else {
t = pr_localtime(p, (time_t *) &sort_time);
+ }
if (opt_F) {
- if (S_ISLNK(st.st_mode))
+ if (S_ISLNK(st.st_mode)) {
suffix[0] = '@';
- else if (S_ISDIR(st.st_mode)) {
+ } else if (S_ISDIR(st.st_mode)) {
suffix[0] = '/';
rval = 1;
- } else if (st.st_mode & 0111)
+ } else if (st.st_mode & 0111) {
suffix[0] = '*';
+ }
}
if (opt_l) {
@@ -576,32 +579,38 @@
m[2] = (mode & S_IWUSR) ? 'w' : '-';
m[1] = (mode & S_IRUSR) ? 'r' : '-';
- if (ls_curtime - sort_time > 180 * 24 * 60 * 60)
+ if (ls_curtime - sort_time > 180 * 24 * 60 * 60) {
snprintf(timeline, sizeof(timeline), "%5d", t->tm_year+1900);
- else
+ } else {
snprintf(timeline, sizeof(timeline), "%02d:%02d", t->tm_hour,
t->tm_min);
+ }
ls_fmt_filesize(s, sizeof(s), st.st_size);
- if (!opt_n) {
-
- /* Format nameline using user/group names. */
- snprintf(nameline, sizeof(nameline)-1,
- "%s %3d %-8s %-8s %s %s %2d %s %s", m, (int) st.st_nlink,
- MAP_UID(st.st_uid), MAP_GID(st.st_gid), s,
- months[t->tm_mon], t->tm_mday, timeline,
+ if (opt_1) {
+ /* One file per line, with no info other than the file name. Easy. */
+ snprintf(nameline, sizeof(nameline)-1, "%s",
pr_fs_encode_path(cmd->tmp_pool, display_name));
} else {
-
- /* Format nameline using user/group IDs. */
- snprintf(nameline, sizeof(nameline)-1,
- "%s %3d %-8u %-8u %s %s %2d %s %s", m, (int) st.st_nlink,
- (unsigned) st.st_uid, (unsigned) st.st_gid, s,
- months[t->tm_mon], t->tm_mday, timeline,
- pr_fs_encode_path(cmd->tmp_pool, name));
+ if (!opt_n) {
+ /* Format nameline using user/group names. */
+ snprintf(nameline, sizeof(nameline)-1,
+ "%s %3d %-8s %-8s %s %s %2d %s %s", m, (int) st.st_nlink,
+ MAP_UID(st.st_uid), MAP_GID(st.st_gid), s,
+ months[t->tm_mon], t->tm_mday, timeline,
+ pr_fs_encode_path(cmd->tmp_pool, display_name));
+
+ } else {
+ /* Format nameline using user/group IDs. */
+ snprintf(nameline, sizeof(nameline)-1,
+ "%s %3d %-8u %-8u %s %s %2d %s %s", m, (int) st.st_nlink,
+ (unsigned) st.st_uid, (unsigned) st.st_gid, s,
+ months[t->tm_mon], t->tm_mday, timeline,
+ pr_fs_encode_path(cmd->tmp_pool, name));
+ }
}
nameline[sizeof(nameline)-1] = '\0';
@@ -611,40 +620,45 @@
suffix[0] = '\0';
if (opt_F && pr_fsio_stat(name, &st) == 0) {
- if (S_ISLNK(st.st_mode))
+ if (S_ISLNK(st.st_mode)) {
suffix[0] = '@';
- else if (S_ISDIR(st.st_mode))
+ } else if (S_ISDIR(st.st_mode)) {
suffix[0] = '/';
- else if (st.st_mode & 0111)
+ } else if (st.st_mode & 0111) {
suffix[0] = '*';
+ }
}
if (!opt_L && list_show_symlinks) {
- if (sizeof(nameline) - strlen(nameline) > 4)
+ if (sizeof(nameline) - strlen(nameline) > 4) {
snprintf(buf, sizeof(nameline) - strlen(nameline) - 4,
" -> %s", l);
- else
+ } else {
pr_log_pri(PR_LOG_NOTICE, "notice: symlink '%s' yields an "
"excessive string, ignoring", name);
+ }
}
nameline[sizeof(nameline)-1] = '\0';
}
- if (opt_STAT)
+ if (opt_STAT) {
pr_response_add(R_211, "%s%s", nameline, suffix);
- else
+
+ } else {
addfile(cmd, nameline, suffix, sort_time, st.st_size);
+ }
}
} else {
if (S_ISREG(st.st_mode) ||
S_ISDIR(st.st_mode) ||
- S_ISLNK(st.st_mode))
+ S_ISLNK(st.st_mode)) {
addfile(cmd, pr_fs_encode_path(cmd->tmp_pool, name), suffix,
sort_time, st.st_size);
+ }
}
}
@@ -1302,6 +1316,7 @@
switch (**opt) {
case '1':
if (strcmp(session.curr_cmd, C_STAT) != 0) {
+ opt_1 = 1;
opt_l = opt_C = 0;
}
break;
@@ -1354,6 +1369,7 @@
if (strcmp(session.curr_cmd, C_NLST) != 0) {
opt_l = 1;
opt_C = 0;
+ opt_1 = 0;
}
break;
@@ -1422,7 +1438,7 @@
while ((*opt)++ && isalnum((int) **opt)) {
switch (**opt) {
case '1':
- opt_l = opt_C = 0;
+ opt_1 = opt_l = opt_C = 0;
break;
case 'A':
@@ -1571,8 +1587,8 @@
ls_curtime = time(NULL);
if (clearflags) {
- opt_A = opt_a = opt_B = opt_C = opt_d = opt_F = opt_h = opt_n = opt_r =
- opt_R = opt_S = opt_t = opt_STAT = opt_L = 0;
+ opt_1 = opt_A = opt_a = opt_B = opt_C = opt_d = opt_F = opt_h = opt_n =
+ opt_r = opt_R = opt_S = opt_t = opt_STAT = opt_L = 0;
}
if (have_options(cmd, arg)) {
@@ -1671,8 +1687,10 @@
/* Open data connection */
if (!opt_STAT) {
- if (pr_data_open(NULL, "file list", PR_NETIO_IO_WR, 0) < 0)
+ if (pr_data_open(NULL, "file list", PR_NETIO_IO_WR, 0) < 0) {
return -1;
+ }
+
session.sf_flags |= SF_ASCII_OVERRIDE;
}
@@ -1705,7 +1723,6 @@
skiparg = TRUE;
} else {
-
skiparg = FALSE;
if (use_globbing &&
@@ -1945,6 +1962,10 @@
return -1;
}
+ /* XXX Note that "NLST <glob>" was sent, we might be receiving paths
+ * here, not just file names. And that is not what dir_hide_file() is
+ * expecting.
+ */
if (dir_hide_file(file))
return 1;
@@ -1970,6 +1991,25 @@
}
#endif /* PR_USE_NLS */
+ if (opt_1) {
+ char *ptr;
+
+ /* If the -1 option is configured, we want to make sure that we only
+ * display a file, not a path. And it's possible that we given a path
+ * here.
+ */
+ ptr = strrchr(display_name, '/');
+ if (ptr != NULL) {
+ size_t display_namelen;
+
+ display_namelen = strlen(display_name);
+ if (display_namelen > 1) {
+ /* Make sure that we handle a possible display_name of '/' properly. */
+ display_name = ptr + 1;
+ }
+ }
+ }
+
/* Be sure to flush the output */
res = sendline(0, "%s\n", pr_fs_encode_path(cmd->tmp_pool, display_name));
if (res < 0)
@@ -2098,8 +2138,16 @@
continue;
if (!curdir) {
- char *str = pr_fs_encode_path(cmd->tmp_pool,
- pdircat(cmd->tmp_pool, dir, p, NULL));
+ char *str = NULL;
+
+ if (opt_1) {
+ /* Send just the file name, not the path. */
+ str = pr_fs_encode_path(cmd->tmp_pool, p);
+
+ } else {
+ str = pr_fs_encode_path(cmd->tmp_pool,
+ pdircat(cmd->tmp_pool, dir, p, NULL));
+ }
if (sendline(0, "%s\n", str) < 0) {
count = -1;
@@ -2204,26 +2252,32 @@
fakeuser = get_param_ptr(CURRENT_CONF, "DirFakeUser", FALSE);
/* Check for a configured "logged in user" DirFakeUser. */
- if (fakeuser && strcmp(fakeuser, "~") == 0)
+ if (fakeuser != NULL &&
+ strcmp(fakeuser, "~") == 0) {
fakeuser = session.user;
+ }
fakegroup = get_param_ptr(CURRENT_CONF, "DirFakeGroup", FALSE);
/* Check for a configured "logged in user" DirFakeGroup. */
- if (fakegroup && strcmp(fakegroup, "~") == 0)
+ if (fakegroup != NULL &&
+ strcmp(fakegroup, "~") == 0) {
fakegroup = session.group;
+ }
fake_mode = get_param_ptr(CURRENT_CONF, "DirFakeMode", FALSE);
if (fake_mode) {
fakemode = *fake_mode;
have_fake_mode = TRUE;
- } else
+ } else {
have_fake_mode = FALSE;
+ }
tmp = get_param_ptr(TOPLEVEL_CONF, "TimesGMT", FALSE);
- if (tmp != NULL)
+ if (tmp != NULL) {
list_times_gmt = *tmp;
+ }
res = dolist(cmd, pr_fs_decode_path(cmd->tmp_pool, cmd->arg), TRUE);
@@ -2231,8 +2285,9 @@
pr_data_abort(0, 0);
res = -1;
- } else if (session.sf_flags & SF_XFER)
+ } else if (session.sf_flags & SF_XFER) {
ls_done(cmd);
+ }
opt_l = 0;
@@ -2415,8 +2470,9 @@
list_nfiles.logged = list_ndirs.logged = list_ndepth.logged = FALSE;
tmp = get_param_ptr(TOPLEVEL_CONF, "ShowSymlinks", FALSE);
- if (tmp != NULL)
+ if (tmp != NULL) {
list_show_symlinks = *tmp;
+ }
target = cmd->argc == 1 ? "." :
pr_fs_decode_path(cmd->tmp_pool, cmd->arg);
@@ -2444,8 +2500,8 @@
}
/* Clear the listing option flags. */
- opt_A = opt_a = opt_B = opt_C = opt_d = opt_F = opt_n = opt_r = opt_R =
- opt_S = opt_t = opt_STAT = opt_L = 0;
+ opt_1 = opt_A = opt_a = opt_B = opt_C = opt_d = opt_F = opt_n = opt_r =
+ opt_R = opt_S = opt_t = opt_STAT = opt_L = 0;
if (have_options(cmd, target)) {
if (!list_strict_opts) {
@@ -2602,8 +2658,10 @@
} else {
if (list_flags & LS_FL_NO_ERROR_IF_ABSENT) {
- if (pr_data_open(NULL, "file list", PR_NETIO_IO_WR, 0) < 0)
+ if (pr_data_open(NULL, "file list", PR_NETIO_IO_WR, 0) < 0) {
return PR_ERROR(cmd);
+ }
+
session.sf_flags |= SF_ASCII_OVERRIDE;
pr_response_add(R_226, _("Transfer complete"));
ls_done(cmd);
@@ -2617,8 +2675,10 @@
} else {
if (list_flags & LS_FL_NO_ERROR_IF_ABSENT) {
- if (pr_data_open(NULL, "file list", PR_NETIO_IO_WR, 0) < 0)
+ if (pr_data_open(NULL, "file list", PR_NETIO_IO_WR, 0) < 0) {
return PR_ERROR(cmd);
+ }
+
session.sf_flags |= SF_ASCII_OVERRIDE;
pr_response_add(R_226, _("Transfer complete"));
ls_done(cmd);
@@ -2631,8 +2691,10 @@
}
}
- if (pr_data_open(NULL, "file list", PR_NETIO_IO_WR, 0) < 0)
+ if (pr_data_open(NULL, "file list", PR_NETIO_IO_WR, 0) < 0) {
return PR_ERROR(cmd);
+ }
+
session.sf_flags |= SF_ASCII_OVERRIDE;
/* Iterate through each matching entry */