--- modules/mod_ls.c
+++ modules/mod_ls.c
@@ -81,6 +81,7 @@ static struct list_limit_rec list_nfiles
/* ls options */
static int
+ opt_1 = 0,
opt_a = 0,
opt_A = 0,
opt_B = 0,
@@ -419,7 +420,6 @@ static int listfile(cmd_rec *cmd, pool *
p = cmd->tmp_pool;
if (pr_fsio_lstat(name, &st) == 0) {
-
char *display_name = NULL;
suffix[0] = suffix[1] = '\0';
@@ -531,21 +531,24 @@ static int listfile(cmd_rec *cmd, pool *
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) {
@@ -614,32 +617,38 @@ static int listfile(cmd_rec *cmd, pool *
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';
@@ -649,40 +658,45 @@ static int listfile(cmd_rec *cmd, pool *
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);
+ }
}
}
@@ -1340,6 +1354,7 @@ static void parse_list_opts(char **opt,
switch (**opt) {
case '1':
if (strcmp(session.curr_cmd, C_STAT) != 0) {
+ opt_1 = 1;
opt_l = opt_C = 0;
}
break;
@@ -1392,6 +1407,7 @@ static void parse_list_opts(char **opt,
if (strcmp(session.curr_cmd, C_NLST) != 0) {
opt_l = 1;
opt_C = 0;
+ opt_1 = 0;
}
break;
@@ -1460,7 +1476,7 @@ static void parse_list_opts(char **opt,
while ((*opt)++ && isalnum((int) **opt)) {
switch (**opt) {
case '1':
- opt_l = opt_C = 0;
+ opt_1 = opt_l = opt_C = 0;
break;
case 'A':
@@ -1609,8 +1625,8 @@ static int dolist(cmd_rec *cmd, const ch
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)) {
@@ -1745,7 +1761,6 @@ static int dolist(cmd_rec *cmd, const ch
skiparg = TRUE;
} else {
-
skiparg = FALSE;
if (use_globbing &&
@@ -1987,6 +2002,10 @@ static int nlstfile(cmd_rec *cmd, const
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;
@@ -2012,6 +2031,25 @@ static int nlstfile(cmd_rec *cmd, const
}
#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\r\n", pr_fs_encode_path(cmd->tmp_pool, display_name));
if (res < 0)
@@ -2140,8 +2178,16 @@ static int nlstdir(cmd_rec *cmd, const c
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\r\n", str) < 0) {
count = -1;
@@ -2246,26 +2292,32 @@ MODRET genericlist(cmd_rec *cmd) {
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);
@@ -2273,8 +2325,9 @@ MODRET genericlist(cmd_rec *cmd) {
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;
@@ -2457,8 +2510,9 @@ MODRET ls_nlst(cmd_rec *cmd) {
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);
@@ -2486,8 +2540,8 @@ MODRET ls_nlst(cmd_rec *cmd) {
}
/* 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) {