|
|
744a63d |
--- modules/mod_ls.c
|
|
|
744a63d |
+++ modules/mod_ls.c
|
|
|
744a63d |
@@ -81,6 +81,7 @@ static struct list_limit_rec list_nfiles
|
|
|
8abab90 |
|
|
|
8abab90 |
/* ls options */
|
|
|
8abab90 |
static int
|
|
|
8abab90 |
+ opt_1 = 0,
|
|
|
8abab90 |
opt_a = 0,
|
|
|
8abab90 |
opt_A = 0,
|
|
|
8abab90 |
opt_B = 0,
|
|
|
744a63d |
@@ -419,7 +420,6 @@ static int listfile(cmd_rec *cmd, pool *
|
|
|
8abab90 |
p = cmd->tmp_pool;
|
|
|
8abab90 |
|
|
|
8abab90 |
if (pr_fsio_lstat(name, &st) == 0) {
|
|
|
8abab90 |
-
|
|
|
8abab90 |
char *display_name = NULL;
|
|
|
8abab90 |
|
|
|
8abab90 |
suffix[0] = suffix[1] = '\0';
|
|
|
744a63d |
@@ -531,21 +531,24 @@ static int listfile(cmd_rec *cmd, pool *
|
|
|
8abab90 |
break;
|
|
|
8abab90 |
}
|
|
|
8abab90 |
|
|
|
8abab90 |
- if (list_times_gmt)
|
|
|
8abab90 |
+ if (list_times_gmt) {
|
|
|
8abab90 |
t = pr_gmtime(p, (time_t *) &sort_time);
|
|
|
8abab90 |
- else
|
|
|
8abab90 |
+
|
|
|
8abab90 |
+ } else {
|
|
|
8abab90 |
t = pr_localtime(p, (time_t *) &sort_time);
|
|
|
8abab90 |
+ }
|
|
|
8abab90 |
|
|
|
8abab90 |
if (opt_F) {
|
|
|
8abab90 |
- if (S_ISLNK(st.st_mode))
|
|
|
8abab90 |
+ if (S_ISLNK(st.st_mode)) {
|
|
|
8abab90 |
suffix[0] = '@';
|
|
|
8abab90 |
|
|
|
8abab90 |
- else if (S_ISDIR(st.st_mode)) {
|
|
|
8abab90 |
+ } else if (S_ISDIR(st.st_mode)) {
|
|
|
8abab90 |
suffix[0] = '/';
|
|
|
8abab90 |
rval = 1;
|
|
|
8abab90 |
|
|
|
8abab90 |
- } else if (st.st_mode & 0111)
|
|
|
8abab90 |
+ } else if (st.st_mode & 0111) {
|
|
|
8abab90 |
suffix[0] = '*';
|
|
|
8abab90 |
+ }
|
|
|
8abab90 |
}
|
|
|
8abab90 |
|
|
|
8abab90 |
if (opt_l) {
|
|
|
744a63d |
@@ -614,32 +617,38 @@ static int listfile(cmd_rec *cmd, pool *
|
|
|
8abab90 |
m[2] = (mode & S_IWUSR) ? 'w' : '-';
|
|
|
8abab90 |
m[1] = (mode & S_IRUSR) ? 'r' : '-';
|
|
|
8abab90 |
|
|
|
8abab90 |
- if (ls_curtime - sort_time > 180 * 24 * 60 * 60)
|
|
|
8abab90 |
+ if (ls_curtime - sort_time > 180 * 24 * 60 * 60) {
|
|
|
8abab90 |
snprintf(timeline, sizeof(timeline), "%5d", t->tm_year+1900);
|
|
|
8abab90 |
|
|
|
8abab90 |
- else
|
|
|
8abab90 |
+ } else {
|
|
|
8abab90 |
snprintf(timeline, sizeof(timeline), "%02d:%02d", t->tm_hour,
|
|
|
8abab90 |
t->tm_min);
|
|
|
8abab90 |
+ }
|
|
|
8abab90 |
|
|
|
8abab90 |
ls_fmt_filesize(s, sizeof(s), st.st_size);
|
|
|
8abab90 |
|
|
|
8abab90 |
- if (!opt_n) {
|
|
|
8abab90 |
-
|
|
|
8abab90 |
- /* Format nameline using user/group names. */
|
|
|
8abab90 |
- snprintf(nameline, sizeof(nameline)-1,
|
|
|
8abab90 |
- "%s %3d %-8s %-8s %s %s %2d %s %s", m, (int) st.st_nlink,
|
|
|
8abab90 |
- MAP_UID(st.st_uid), MAP_GID(st.st_gid), s,
|
|
|
8abab90 |
- months[t->tm_mon], t->tm_mday, timeline,
|
|
|
8abab90 |
+ if (opt_1) {
|
|
|
8abab90 |
+ /* One file per line, with no info other than the file name. Easy. */
|
|
|
8abab90 |
+ snprintf(nameline, sizeof(nameline)-1, "%s",
|
|
|
8abab90 |
pr_fs_encode_path(cmd->tmp_pool, display_name));
|
|
|
8abab90 |
|
|
|
8abab90 |
} else {
|
|
|
8abab90 |
-
|
|
|
8abab90 |
- /* Format nameline using user/group IDs. */
|
|
|
8abab90 |
- snprintf(nameline, sizeof(nameline)-1,
|
|
|
8abab90 |
- "%s %3d %-8u %-8u %s %s %2d %s %s", m, (int) st.st_nlink,
|
|
|
8abab90 |
- (unsigned) st.st_uid, (unsigned) st.st_gid, s,
|
|
|
8abab90 |
- months[t->tm_mon], t->tm_mday, timeline,
|
|
|
8abab90 |
- pr_fs_encode_path(cmd->tmp_pool, name));
|
|
|
8abab90 |
+ if (!opt_n) {
|
|
|
8abab90 |
+ /* Format nameline using user/group names. */
|
|
|
8abab90 |
+ snprintf(nameline, sizeof(nameline)-1,
|
|
|
8abab90 |
+ "%s %3d %-8s %-8s %s %s %2d %s %s", m, (int) st.st_nlink,
|
|
|
8abab90 |
+ MAP_UID(st.st_uid), MAP_GID(st.st_gid), s,
|
|
|
8abab90 |
+ months[t->tm_mon], t->tm_mday, timeline,
|
|
|
8abab90 |
+ pr_fs_encode_path(cmd->tmp_pool, display_name));
|
|
|
8abab90 |
+
|
|
|
8abab90 |
+ } else {
|
|
|
8abab90 |
+ /* Format nameline using user/group IDs. */
|
|
|
8abab90 |
+ snprintf(nameline, sizeof(nameline)-1,
|
|
|
8abab90 |
+ "%s %3d %-8u %-8u %s %s %2d %s %s", m, (int) st.st_nlink,
|
|
|
8abab90 |
+ (unsigned) st.st_uid, (unsigned) st.st_gid, s,
|
|
|
8abab90 |
+ months[t->tm_mon], t->tm_mday, timeline,
|
|
|
8abab90 |
+ pr_fs_encode_path(cmd->tmp_pool, name));
|
|
|
8abab90 |
+ }
|
|
|
8abab90 |
}
|
|
|
8abab90 |
|
|
|
8abab90 |
nameline[sizeof(nameline)-1] = '\0';
|
|
|
744a63d |
@@ -649,40 +658,45 @@ static int listfile(cmd_rec *cmd, pool *
|
|
|
8abab90 |
|
|
|
8abab90 |
suffix[0] = '\0';
|
|
|
8abab90 |
if (opt_F && pr_fsio_stat(name, &st) == 0) {
|
|
|
8abab90 |
- if (S_ISLNK(st.st_mode))
|
|
|
8abab90 |
+ if (S_ISLNK(st.st_mode)) {
|
|
|
8abab90 |
suffix[0] = '@';
|
|
|
8abab90 |
|
|
|
8abab90 |
- else if (S_ISDIR(st.st_mode))
|
|
|
8abab90 |
+ } else if (S_ISDIR(st.st_mode)) {
|
|
|
8abab90 |
suffix[0] = '/';
|
|
|
8abab90 |
|
|
|
8abab90 |
- else if (st.st_mode & 0111)
|
|
|
8abab90 |
+ } else if (st.st_mode & 0111) {
|
|
|
8abab90 |
suffix[0] = '*';
|
|
|
8abab90 |
+ }
|
|
|
8abab90 |
}
|
|
|
8abab90 |
|
|
|
8abab90 |
if (!opt_L && list_show_symlinks) {
|
|
|
8abab90 |
- if (sizeof(nameline) - strlen(nameline) > 4)
|
|
|
8abab90 |
+ if (sizeof(nameline) - strlen(nameline) > 4) {
|
|
|
8abab90 |
snprintf(buf, sizeof(nameline) - strlen(nameline) - 4,
|
|
|
8abab90 |
" -> %s", l);
|
|
|
8abab90 |
- else
|
|
|
8abab90 |
+ } else {
|
|
|
8abab90 |
pr_log_pri(PR_LOG_NOTICE, "notice: symlink '%s' yields an "
|
|
|
8abab90 |
"excessive string, ignoring", name);
|
|
|
8abab90 |
+ }
|
|
|
8abab90 |
}
|
|
|
8abab90 |
|
|
|
8abab90 |
nameline[sizeof(nameline)-1] = '\0';
|
|
|
8abab90 |
}
|
|
|
8abab90 |
|
|
|
8abab90 |
- if (opt_STAT)
|
|
|
8abab90 |
+ if (opt_STAT) {
|
|
|
8abab90 |
pr_response_add(R_211, "%s%s", nameline, suffix);
|
|
|
8abab90 |
- else
|
|
|
8abab90 |
+
|
|
|
8abab90 |
+ } else {
|
|
|
8abab90 |
addfile(cmd, nameline, suffix, sort_time, st.st_size);
|
|
|
8abab90 |
+ }
|
|
|
8abab90 |
}
|
|
|
8abab90 |
|
|
|
8abab90 |
} else {
|
|
|
8abab90 |
if (S_ISREG(st.st_mode) ||
|
|
|
8abab90 |
S_ISDIR(st.st_mode) ||
|
|
|
8abab90 |
- S_ISLNK(st.st_mode))
|
|
|
8abab90 |
+ S_ISLNK(st.st_mode)) {
|
|
|
8abab90 |
addfile(cmd, pr_fs_encode_path(cmd->tmp_pool, name), suffix,
|
|
|
8abab90 |
sort_time, st.st_size);
|
|
|
8abab90 |
+ }
|
|
|
8abab90 |
}
|
|
|
8abab90 |
}
|
|
|
8abab90 |
|
|
|
744a63d |
@@ -1340,6 +1354,7 @@ static void parse_list_opts(char **opt,
|
|
|
8abab90 |
switch (**opt) {
|
|
|
8abab90 |
case '1':
|
|
|
8abab90 |
if (strcmp(session.curr_cmd, C_STAT) != 0) {
|
|
|
8abab90 |
+ opt_1 = 1;
|
|
|
8abab90 |
opt_l = opt_C = 0;
|
|
|
8abab90 |
}
|
|
|
8abab90 |
break;
|
|
|
744a63d |
@@ -1392,6 +1407,7 @@ static void parse_list_opts(char **opt,
|
|
|
8abab90 |
if (strcmp(session.curr_cmd, C_NLST) != 0) {
|
|
|
8abab90 |
opt_l = 1;
|
|
|
8abab90 |
opt_C = 0;
|
|
|
8abab90 |
+ opt_1 = 0;
|
|
|
8abab90 |
}
|
|
|
8abab90 |
break;
|
|
|
8abab90 |
|
|
|
744a63d |
@@ -1460,7 +1476,7 @@ static void parse_list_opts(char **opt,
|
|
|
8abab90 |
while ((*opt)++ && isalnum((int) **opt)) {
|
|
|
8abab90 |
switch (**opt) {
|
|
|
8abab90 |
case '1':
|
|
|
8abab90 |
- opt_l = opt_C = 0;
|
|
|
8abab90 |
+ opt_1 = opt_l = opt_C = 0;
|
|
|
8abab90 |
break;
|
|
|
8abab90 |
|
|
|
8abab90 |
case 'A':
|
|
|
744a63d |
@@ -1609,8 +1625,8 @@ static int dolist(cmd_rec *cmd, const ch
|
|
|
8abab90 |
ls_curtime = time(NULL);
|
|
|
8abab90 |
|
|
|
8abab90 |
if (clearflags) {
|
|
|
8abab90 |
- opt_A = opt_a = opt_B = opt_C = opt_d = opt_F = opt_h = opt_n = opt_r =
|
|
|
8abab90 |
- opt_R = opt_S = opt_t = opt_STAT = opt_L = 0;
|
|
|
8abab90 |
+ opt_1 = opt_A = opt_a = opt_B = opt_C = opt_d = opt_F = opt_h = opt_n =
|
|
|
8abab90 |
+ opt_r = opt_R = opt_S = opt_t = opt_STAT = opt_L = 0;
|
|
|
8abab90 |
}
|
|
|
8abab90 |
|
|
|
8abab90 |
if (have_options(cmd, arg)) {
|
|
|
744a63d |
@@ -1745,7 +1761,6 @@ static int dolist(cmd_rec *cmd, const ch
|
|
|
8abab90 |
skiparg = TRUE;
|
|
|
8abab90 |
|
|
|
8abab90 |
} else {
|
|
|
8abab90 |
-
|
|
|
8abab90 |
skiparg = FALSE;
|
|
|
8abab90 |
|
|
|
8abab90 |
if (use_globbing &&
|
|
|
744a63d |
@@ -1987,6 +2002,10 @@ static int nlstfile(cmd_rec *cmd, const
|
|
|
8abab90 |
return -1;
|
|
|
8abab90 |
}
|
|
|
8abab90 |
|
|
|
8abab90 |
+ /* XXX Note that "NLST <glob>" was sent, we might be receiving paths
|
|
|
8abab90 |
+ * here, not just file names. And that is not what dir_hide_file() is
|
|
|
8abab90 |
+ * expecting.
|
|
|
8abab90 |
+ */
|
|
|
8abab90 |
if (dir_hide_file(file))
|
|
|
8abab90 |
return 1;
|
|
|
8abab90 |
|
|
|
744a63d |
@@ -2012,6 +2031,25 @@ static int nlstfile(cmd_rec *cmd, const
|
|
|
8abab90 |
}
|
|
|
8abab90 |
#endif /* PR_USE_NLS */
|
|
|
8abab90 |
|
|
|
8abab90 |
+ if (opt_1) {
|
|
|
8abab90 |
+ char *ptr;
|
|
|
8abab90 |
+
|
|
|
8abab90 |
+ /* If the -1 option is configured, we want to make sure that we only
|
|
|
8abab90 |
+ * display a file, not a path. And it's possible that we given a path
|
|
|
8abab90 |
+ * here.
|
|
|
8abab90 |
+ */
|
|
|
8abab90 |
+ ptr = strrchr(display_name, '/');
|
|
|
8abab90 |
+ if (ptr != NULL) {
|
|
|
8abab90 |
+ size_t display_namelen;
|
|
|
8abab90 |
+
|
|
|
8abab90 |
+ display_namelen = strlen(display_name);
|
|
|
8abab90 |
+ if (display_namelen > 1) {
|
|
|
8abab90 |
+ /* Make sure that we handle a possible display_name of '/' properly. */
|
|
|
8abab90 |
+ display_name = ptr + 1;
|
|
|
8abab90 |
+ }
|
|
|
8abab90 |
+ }
|
|
|
8abab90 |
+ }
|
|
|
8abab90 |
+
|
|
|
8abab90 |
/* Be sure to flush the output */
|
|
|
744a63d |
res = sendline(0, "%s\r\n", pr_fs_encode_path(cmd->tmp_pool, display_name));
|
|
|
8abab90 |
if (res < 0)
|
|
|
744a63d |
@@ -2140,8 +2178,16 @@ static int nlstdir(cmd_rec *cmd, const c
|
|
|
8abab90 |
continue;
|
|
|
8abab90 |
|
|
|
8abab90 |
if (!curdir) {
|
|
|
8abab90 |
- char *str = pr_fs_encode_path(cmd->tmp_pool,
|
|
|
8abab90 |
- pdircat(cmd->tmp_pool, dir, p, NULL));
|
|
|
8abab90 |
+ char *str = NULL;
|
|
|
8abab90 |
+
|
|
|
8abab90 |
+ if (opt_1) {
|
|
|
8abab90 |
+ /* Send just the file name, not the path. */
|
|
|
8abab90 |
+ str = pr_fs_encode_path(cmd->tmp_pool, p);
|
|
|
8abab90 |
+
|
|
|
8abab90 |
+ } else {
|
|
|
8abab90 |
+ str = pr_fs_encode_path(cmd->tmp_pool,
|
|
|
8abab90 |
+ pdircat(cmd->tmp_pool, dir, p, NULL));
|
|
|
8abab90 |
+ }
|
|
|
8abab90 |
|
|
|
744a63d |
if (sendline(0, "%s\r\n", str) < 0) {
|
|
|
8abab90 |
count = -1;
|
|
|
744a63d |
@@ -2246,26 +2292,32 @@ MODRET genericlist(cmd_rec *cmd) {
|
|
|
8abab90 |
fakeuser = get_param_ptr(CURRENT_CONF, "DirFakeUser", FALSE);
|
|
|
8abab90 |
|
|
|
8abab90 |
/* Check for a configured "logged in user" DirFakeUser. */
|
|
|
8abab90 |
- if (fakeuser && strcmp(fakeuser, "~") == 0)
|
|
|
8abab90 |
+ if (fakeuser != NULL &&
|
|
|
8abab90 |
+ strcmp(fakeuser, "~") == 0) {
|
|
|
8abab90 |
fakeuser = session.user;
|
|
|
8abab90 |
+ }
|
|
|
8abab90 |
|
|
|
8abab90 |
fakegroup = get_param_ptr(CURRENT_CONF, "DirFakeGroup", FALSE);
|
|
|
8abab90 |
|
|
|
8abab90 |
/* Check for a configured "logged in user" DirFakeGroup. */
|
|
|
8abab90 |
- if (fakegroup && strcmp(fakegroup, "~") == 0)
|
|
|
8abab90 |
+ if (fakegroup != NULL &&
|
|
|
8abab90 |
+ strcmp(fakegroup, "~") == 0) {
|
|
|
8abab90 |
fakegroup = session.group;
|
|
|
8abab90 |
+ }
|
|
|
8abab90 |
|
|
|
8abab90 |
fake_mode = get_param_ptr(CURRENT_CONF, "DirFakeMode", FALSE);
|
|
|
8abab90 |
if (fake_mode) {
|
|
|
8abab90 |
fakemode = *fake_mode;
|
|
|
8abab90 |
have_fake_mode = TRUE;
|
|
|
8abab90 |
|
|
|
8abab90 |
- } else
|
|
|
8abab90 |
+ } else {
|
|
|
8abab90 |
have_fake_mode = FALSE;
|
|
|
8abab90 |
+ }
|
|
|
8abab90 |
|
|
|
8abab90 |
tmp = get_param_ptr(TOPLEVEL_CONF, "TimesGMT", FALSE);
|
|
|
8abab90 |
- if (tmp != NULL)
|
|
|
8abab90 |
+ if (tmp != NULL) {
|
|
|
8abab90 |
list_times_gmt = *tmp;
|
|
|
8abab90 |
+ }
|
|
|
8abab90 |
|
|
|
8abab90 |
res = dolist(cmd, pr_fs_decode_path(cmd->tmp_pool, cmd->arg), TRUE);
|
|
|
8abab90 |
|
|
|
744a63d |
@@ -2273,8 +2325,9 @@ MODRET genericlist(cmd_rec *cmd) {
|
|
|
8abab90 |
pr_data_abort(0, 0);
|
|
|
8abab90 |
res = -1;
|
|
|
8abab90 |
|
|
|
8abab90 |
- } else if (session.sf_flags & SF_XFER)
|
|
|
8abab90 |
+ } else if (session.sf_flags & SF_XFER) {
|
|
|
8abab90 |
ls_done(cmd);
|
|
|
8abab90 |
+ }
|
|
|
8abab90 |
|
|
|
8abab90 |
opt_l = 0;
|
|
|
8abab90 |
|
|
|
744a63d |
@@ -2457,8 +2510,9 @@ MODRET ls_nlst(cmd_rec *cmd) {
|
|
|
8abab90 |
list_nfiles.logged = list_ndirs.logged = list_ndepth.logged = FALSE;
|
|
|
8abab90 |
|
|
|
8abab90 |
tmp = get_param_ptr(TOPLEVEL_CONF, "ShowSymlinks", FALSE);
|
|
|
8abab90 |
- if (tmp != NULL)
|
|
|
8abab90 |
+ if (tmp != NULL) {
|
|
|
8abab90 |
list_show_symlinks = *tmp;
|
|
|
8abab90 |
+ }
|
|
|
8abab90 |
|
|
|
8abab90 |
target = cmd->argc == 1 ? "." :
|
|
|
8abab90 |
pr_fs_decode_path(cmd->tmp_pool, cmd->arg);
|
|
|
744a63d |
@@ -2486,8 +2540,8 @@ MODRET ls_nlst(cmd_rec *cmd) {
|
|
|
8abab90 |
}
|
|
|
8abab90 |
|
|
|
8abab90 |
/* Clear the listing option flags. */
|
|
|
8abab90 |
- opt_A = opt_a = opt_B = opt_C = opt_d = opt_F = opt_n = opt_r = opt_R =
|
|
|
8abab90 |
- opt_S = opt_t = opt_STAT = opt_L = 0;
|
|
|
8abab90 |
+ opt_1 = opt_A = opt_a = opt_B = opt_C = opt_d = opt_F = opt_n = opt_r =
|
|
|
8abab90 |
+ opt_R = opt_S = opt_t = opt_STAT = opt_L = 0;
|
|
|
8abab90 |
|
|
|
8abab90 |
if (have_options(cmd, target)) {
|
|
|
8abab90 |
if (!list_strict_opts) {
|