8abab90
Index: modules/mod_ls.c
8abab90
===================================================================
8abab90
RCS file: /cvsroot/proftp/proftpd/modules/mod_ls.c,v
8abab90
retrieving revision 1.192
8abab90
diff -u -r1.192 mod_ls.c
8abab90
--- modules/mod_ls.c	1 Feb 2012 22:03:50 -0000	1.192
8abab90
+++ modules/mod_ls.c	1 Feb 2012 23:13:14 -0000
8abab90
@@ -54,8 +54,10 @@
8abab90
 #endif
8abab90
 #define LS_SENDLINE_FL_FLUSH	0x0001
8abab90
 
8abab90
-static unsigned long list_flags = 0;
8abab90
 #define LS_FL_NO_ERROR_IF_ABSENT	0x0001
8abab90
+#define LS_FL_LIST_ONLY			0x0002
8abab90
+#define LS_FL_NLST_ONLY			0x0004
8abab90
+static unsigned long list_flags = 0;
8abab90
 
8abab90
 static unsigned char list_strict_opts = FALSE;
8abab90
 static char *list_options = NULL;
8abab90
@@ -2273,15 +2275,28 @@
8abab90
   config_rec *c = NULL;
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
   list_strict_opts = FALSE;
8abab90
-
8abab90
   list_nfiles.max = list_ndirs.max = list_ndepth.max = 0;
8abab90
 
8abab90
   c = find_config(CURRENT_CONF, CONF_PARAM, "ListOptions", FALSE);
8abab90
-  if (c != NULL) {
8abab90
+  while (c != NULL) {
8abab90
+    pr_signals_handle();
8abab90
+
8abab90
+    list_flags = *((unsigned long *) c->argv[5]);
8abab90
+
8abab90
+    /* Make sure that this ListOptions can be applied to the LIST command.
8abab90
+     * If not, keep looking for other applicable ListOptions.
8abab90
+     */
8abab90
+    if (list_flags & LS_FL_NLST_ONLY) {
8abab90
+      pr_log_debug(DEBUG10, "%s: skipping NLSTOnly ListOptions", cmd->argv[0]);
8abab90
+      c = find_config_next(c, c->next, CONF_PARAM, "ListOptions", FALSE);
8abab90
+      continue;
8abab90
+    }
8abab90
+
8abab90
     list_options = c->argv[0];
8abab90
     list_strict_opts = *((unsigned char *) c->argv[1]);
8abab90
 
8abab90
@@ -2299,7 +2314,7 @@
8abab90
     list_nfiles.max = *((unsigned int *) c->argv[3]);
8abab90
     list_ndirs.max = *((unsigned int *) c->argv[4]);
8abab90
 
8abab90
-    list_flags = *((unsigned long *) c->argv[5]);
8abab90
+    break;
8abab90
   }
8abab90
 
8abab90
   fakeuser = get_param_ptr(CURRENT_CONF, "DirFakeUser", FALSE);
8abab90
@@ -2440,7 +2455,26 @@
8abab90
   list_ndepth.max = list_nfiles.max = list_ndirs.max = 0;
8abab90
 
8abab90
   c = find_config(CURRENT_CONF, CONF_PARAM, "ListOptions", FALSE);
8abab90
-  if (c != NULL) {
8abab90
+  while (c != NULL) {
8abab90
+    pr_signals_handle();
8abab90
+
8abab90
+    list_flags = *((unsigned long *) c->argv[5]);
8abab90
+
8abab90
+    /* Make sure that this ListOptions can be applied to the STAT command.
8abab90
+     * If not, keep looking for other applicable ListOptions.
8abab90
+     */
8abab90
+    if (list_flags & LS_FL_LIST_ONLY) {
8abab90
+      pr_log_debug(DEBUG10, "%s: skipping LISTOnly ListOptions", cmd->argv[0]);
8abab90
+      c = find_config_next(c, c->next, CONF_PARAM, "ListOptions", FALSE);
8abab90
+      continue;
8abab90
+    }
8abab90
+
8abab90
+    if (list_flags & LS_FL_NLST_ONLY) {
8abab90
+      pr_log_debug(DEBUG10, "%s: skipping NLSTOnly ListOptions", cmd->argv[0]);
8abab90
+      c = find_config_next(c, c->next, CONF_PARAM, "ListOptions", FALSE);
8abab90
+      continue;
8abab90
+    }
8abab90
+
8abab90
     list_options = c->argv[0];
8abab90
     list_strict_opts = *((unsigned char *) c->argv[1]);
8abab90
 
8abab90
@@ -2458,7 +2492,7 @@
8abab90
     list_nfiles.max = *((unsigned int *) c->argv[3]);
8abab90
     list_ndirs.max = *((unsigned int *) c->argv[4]);
8abab90
 
8abab90
-    list_flags = *((unsigned long *) c->argv[5]);
8abab90
+    break;
8abab90
   }
8abab90
 
8abab90
   fakeuser = get_param_ptr(CURRENT_CONF, "DirFakeUser", FALSE);
8abab90
@@ -2535,7 +2569,20 @@
8abab90
     pr_fs_decode_path(cmd->tmp_pool, cmd->arg);
8abab90
 
8abab90
   c = find_config(CURRENT_CONF, CONF_PARAM, "ListOptions", FALSE);
8abab90
-  if (c != NULL) {
8abab90
+  while (c != NULL) {
8abab90
+    pr_signals_handle();
8abab90
+
8abab90
+    list_flags = *((unsigned long *) c->argv[5]);
8abab90
+    
8abab90
+    /* Make sure that this ListOptions can be applied to the NLST command.
8abab90
+     * If not, keep looking for other applicable ListOptions.
8abab90
+     */
8abab90
+    if (list_flags & LS_FL_LIST_ONLY) {
8abab90
+      pr_log_debug(DEBUG10, "%s: skipping LISTOnly ListOptions", cmd->argv[0]);
8abab90
+      c = find_config_next(c, c->next, CONF_PARAM, "ListOptions", FALSE);
8abab90
+      continue;
8abab90
+    }
8abab90
+
8abab90
     list_options = c->argv[0];
8abab90
     list_strict_opts = *((unsigned char *) c->argv[1]);
8abab90
 
8abab90
@@ -2554,6 +2601,8 @@
8abab90
     list_ndirs.max = *((unsigned int *) c->argv[4]);
8abab90
 
8abab90
     list_flags = *((unsigned long *) c->argv[5]);
8abab90
+
8abab90
+    break;
8abab90
   }
8abab90
 
8abab90
   /* Clear the listing option flags. */
8abab90
@@ -3019,7 +3068,6 @@
8abab90
 
8abab90
   /* The default flags */
8abab90
   c->argv[5] = pcalloc(c->pool, sizeof(unsigned long));
8abab90
-  *((unsigned int *) c->argv[5]) = 0;
8abab90
  
8abab90
   /* Check for, and handle, optional arguments. */
8abab90
   if (cmd->argc-1 >= 2) {
8abab90
@@ -3060,6 +3108,12 @@
8abab90
 
8abab90
           *((unsigned int *) c->argv[4]) = maxdirs;
8abab90
 
8abab90
+      } else if (strcasecmp(cmd->argv[i], "LISTOnly") == 0) {
8abab90
+          flags |= LS_FL_LIST_ONLY;
8abab90
+
8abab90
+      } else if (strcasecmp(cmd->argv[i], "NLSTOnly") == 0) {
8abab90
+          flags |= LS_FL_NLST_ONLY;
8abab90
+
8abab90
       } else if (strcasecmp(cmd->argv[i], "NoErrorIfAbsent") == 0) {
8abab90
           flags |= LS_FL_NO_ERROR_IF_ABSENT;
8abab90
 
8abab90
@@ -3071,7 +3125,6 @@
8abab90
   }
8abab90
 
8abab90
   *((unsigned long *) c->argv[5]) = flags;
8abab90
-
8abab90
   return PR_HANDLED(cmd);
8abab90
 }
8abab90