Blob Blame History Raw
--- 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) {