[Git][debian-proftpd-team/proftpd-mod-procfs][upstream] New upstream version 0.2

Hilmar Preuße (@hilmar) gitlab at salsa.debian.org
Sun Jul 26 21:50:10 BST 2026



Hilmar Preuße pushed to branch upstream at Debian ProFTPD Team / proftpd-mod-procfs


Commits:
7493599e by Hilmar Preuße at 2026-07-26T22:43:41+02:00
New upstream version 0.2
- - - - -


4 changed files:

- mod_procfs.c
- mod_procfs.html
- t/lib/ProFTPD/Tests/Modules/mod_procfs.pm
- t/lib/ProFTPD/Tests/Modules/mod_procfs/sftp.pm


Changes:

=====================================
mod_procfs.c
=====================================
@@ -29,11 +29,30 @@
 #include "conf.h"
 #include "privs.h"
 
+#if !defined(HAVE_MNTENT_H)
+/* Older ProFTPD versions did not check for the <mntent.h> header, so we
+ * will use heuristics to guess whether it is present.  Some platforms,
+ * such as Mac OSX, do not have this header.
+ *
+ * If/when I get access to BSD platforms, I can add heuristics to handle them
+ * appropriately in the future.
+ */
+# if defined(__GLIBC__)
+#   define HAVE_MNTENT_H 1
+# elif defined(LINUX)
+#   define HAVE_MNTENT_H 1
+# endif /* LINUX */
+#endif /* HAVE_MNTENT_H */
+
+#if defined(HAVE_MNTENT_H)
+# include <mntent.h>
+#endif /* HAVE_MNTENT_H */
+
 #if PROFTPD_VERSION_NUMBER < 0x0001030602
 # error "ProFTPD 1.3.6rc2 or later required"
 #endif
 
-#define MOD_PROCFS_VERSION	"mod_procfs/0.1"
+#define MOD_PROCFS_VERSION	"mod_procfs/0.2"
 
 module procfs_module;
 
@@ -41,25 +60,142 @@ static int procfs_engine = FALSE;
 static int procfs_logfd = -1;
 static pool *procfs_pool = NULL;
 
-static int have_procfs = FALSE;
-
 static const char *trace_channel = "procfs";
 
+struct procfs_mount {
+  const char *path;
+  size_t path_len;
+};
+
+static array_header *procfs_mounts = NULL;
+
+static int get_procfs_mounts(pool *p) {
+#if defined(HAVE_MNTENT_H)
+  FILE *mountf = NULL;
+  struct mntent *mnt = NULL;
+
+  mountf = setmntent("/etc/mtab", "r");
+  if (mountf == NULL) {
+    int xerrno = errno;
+
+    pr_trace_msg(trace_channel, 1, "unable to read /etc/mtab: %s",
+      strerror(xerrno));
+    errno = xerrno;
+    return -1;
+  }
+
+  mnt = getmntent(mountf);
+  while (mnt != NULL) {
+    pr_signals_handle();
+
+    if (strcmp(mnt->mnt_type, "proc") == 0) {
+      struct procfs_mount *mount;
+      size_t path_len;
+
+      pr_log_debug(DEBUG0, MOD_PROCFS_VERSION
+        ": discovered procfs mounted at '%s'", mnt->mnt_dir);
+
+      mount = palloc(p, sizeof(struct procfs_mount));
+
+      /* If the mount point path does not end with a trailing slash, add it.
+       * We use this property when checking paths that reference this procfs
+       * mount point.
+       */
+      path_len = strlen(mnt->mnt_dir);
+      if (mnt->mnt_dir[path_len-1] != '/') {
+        mount->path = pstrcat(p, mnt->mnt_dir, "/", NULL);
+        mount->path_len = path_len + 1;
+
+      } else {
+        mount->path = pstrdup(p, mnt->mnt_dir);
+        mount->path_len = path_len;
+      }
+
+      if (procfs_mounts == NULL) {
+        procfs_mounts = make_array(p, 0, sizeof(struct procfs_mount *));
+      }
+
+      *((struct procfs_mount **) push_array(procfs_mounts)) = mount;
+    }
+
+    mnt = getmntent(mountf);
+  }
+
+  if (endmntent(mountf) != 1) {
+    pr_trace_msg(trace_channel, 1, "error closing /etc/mtab: %s",
+      strerror(errno));
+  }
+
+#else
+  struct stat st;
+
+  /* Check for the presence of the /proc filesystem on this host.  If it
+   * is not present, then we need do nothing else.
+   */
+  if (lstat("/proc/", &st) == 0) {
+    pr_log_debug(DEBUG10, MOD_PROCFS_VERSION ": found /proc/ filesystem");
+
+    if (S_ISDIR(st.st_mode)) {
+      struct procfs_mount *mount;
+
+      mount = palloc(p, sizeof(struct procfs_mount));
+      mount->path = pstrdup(p, "/proc/");
+      mount->path_len = 6;
+
+      procfs_mounts = make_array(p, 0, sizeof(struct procfs_mount *));
+      *((struct procfs_mount **) push_array(procfs_mounts)) = mount;
+
+    } else {
+      pr_log_debug(DEBUG10, MOD_PROCFS_VERSION ": /proc/ is not a directory");
+    }
+  }
+#endif /* HAVE_MNTENT_H */
+
+  if (procfs_mounts != NULL) {
+    /* Automatically enable ProcfsEngine on in such cases. */
+    procfs_engine = TRUE;
+
+  } else {
+    pr_log_debug(DEBUG5, MOD_PROCFS_VERSION
+      ": did not find /proc filesystem: %s", strerror(errno));
+  }
+
+  return 0;
+}
+
 static int is_procfs_path(pool *p, const char *path) {
+  register unsigned int i;
   int res = FALSE;
   char *abs_path;
   size_t abs_pathlen;
+  struct procfs_mount **mounts;
 
   abs_path = dir_abs_path(p, path, FALSE);
   abs_pathlen = strlen(abs_path);
 
-  if (abs_pathlen >= 6 &&
-      strncmp(abs_path, "/proc/", 6) == 0) {
-    res = TRUE;
+  mounts = procfs_mounts->elts;
+  for (i = 0; i < procfs_mounts->nelts; i++) {
+    struct procfs_mount *mount;
+
+    pr_signals_handle();
+
+    mount = mounts[i];
+
+    pr_trace_msg(trace_channel, 19,
+      "checking path '%s' against procfs mount '%s'", abs_path, mount->path);
+
+    if (abs_pathlen >= mount->path_len &&
+        strncmp(abs_path, mount->path, mount->path_len) == 0) {
+      res = TRUE;
+
+    } else if (abs_pathlen == (mount->path_len - 1) &&
+               strncmp(abs_path, mount->path, mount->path_len - 1) == 0) {
+      res = TRUE;
+    }
 
-  } else if (abs_pathlen == 5 &&
-             strcmp(abs_path, "/proc") == 0) {
-    res = TRUE;
+    if (res == TRUE) {
+      break;
+    }
   }
 
   return res;
@@ -101,12 +237,24 @@ MODRET set_procfslog(cmd_rec *cmd) {
   return PR_HANDLED(cmd);
 }
 
+static const char *get_cmd_resp_code(cmd_rec *cmd) {
+  const char *resp_code = R_550;
+
+  if (pr_cmd_cmp(cmd, PR_CMD_LIST_ID) == 0 ||
+      pr_cmd_cmp(cmd, PR_CMD_NLST_ID) == 0 ||
+      pr_cmd_cmp(cmd, PR_CMD_STAT_ID) == 0) {
+    resp_code = R_450;
+  }
+
+  return resp_code;
+}
+
 static modret_t *handle_path(cmd_rec *cmd, const char *cmd_name,
     const char *path) {
   pr_trace_msg(trace_channel, 19, "checking path '%s' for %s", path, cmd_name);
 
   if (is_procfs_path(cmd->tmp_pool, path) == TRUE) {
-    const char *proto;
+    const char *proto, *resp_code;
 
     proto = pr_session_get_protocol(0);
 
@@ -116,7 +264,9 @@ static modret_t *handle_path(cmd_rec *cmd, const char *cmd_name,
       pr_netaddr_get_ipstr(session.c->remote_addr), proto);
     pr_log_pri(PR_LOG_NOTICE, "%s %s denied by mod_procfs", cmd_name, path);
 
-    pr_response_add_err(R_550, _("%s: %s"), path, strerror(ENOENT));
+    /* The response code to use depends on the command. */
+    resp_code = get_cmd_resp_code(cmd);
+    pr_response_add_err(resp_code, _("%s: %s"), path, strerror(ENOENT));
 
     pr_cmd_set_errno(cmd, ENOENT);
     errno = ENOENT;
@@ -310,7 +460,7 @@ MODRET procfs_sftp_pre_symlink(cmd_rec *cmd) {
 MODRET procfs_post_pass(cmd_rec *cmd) {
   config_rec *c;
 
-  if (have_procfs == FALSE) {
+  if (procfs_mounts == NULL) {
     procfs_engine = FALSE;
     return PR_DECLINED(cmd);
   }
@@ -354,10 +504,10 @@ static void procfs_mod_unload_ev(const void *event_data, void *user_data) {
   if (procfs_pool != NULL) {
     destroy_pool(procfs_pool);
     procfs_pool = NULL;
+    procfs_mounts = NULL;
   }
 
   procfs_engine = FALSE;
-  have_procfs = FALSE;
 }
 #endif /* PR_SHARED_MODULE */
 
@@ -373,12 +523,21 @@ static void procfs_restart_ev(const void *event_data, void *user_data) {
   pr_pool_tag(procfs_pool, MOD_PROCFS_VERSION);
 }
 
+static void procfs_shutdown_ev(const void *event_data, void *user_data) {
+  (void) close(procfs_logfd);
+  procfs_logfd = -1;
+
+  if (procfs_pool != NULL) {
+    destroy_pool(procfs_pool);
+    procfs_pool = NULL;
+    procfs_mounts = NULL;
+  }
+}
+
 /* Initialization functions
  */
 
 static int procfs_init(void) {
-  struct stat st;
-
   if (procfs_pool != NULL) {
     destroy_pool(procfs_pool);
   }
@@ -391,26 +550,11 @@ static int procfs_init(void) {
     NULL);
 #endif /* PR_SHARED_MODULE */
   pr_event_register(&procfs_module, "core.restart", procfs_restart_ev, NULL);
+  pr_event_register(&procfs_module, "core.shutdown", procfs_shutdown_ev, NULL);
 
-  /* Check for the presence of the /proc filesystem on this host.  If it
-   * is not present, then we need do nothing else.
-   */
-  if (lstat("/proc/", &st) == 0) {
-    pr_log_debug(DEBUG10, MOD_PROCFS_VERSION ": found /proc/ filesystem");
-
-    if (S_ISDIR(st.st_mode)) {
-      have_procfs = TRUE;
-
-      /* Automatically enable ProcfsEngine on in such cases. */
-      procfs_engine = TRUE;
-
-    } else {
-      pr_log_debug(DEBUG10, MOD_PROCFS_VERSION ": /proc/ is not a directory");
-    }
-
-  } else {
-    pr_log_debug(DEBUG5, MOD_PROCFS_VERSION
-      ": did not find /proc filesystem: %s", strerror(errno));
+  if (get_procfs_mounts(procfs_pool) < 0) {
+    pr_trace_msg(trace_channel, 1, "unable to discover procfs mounts: %s",
+      strerror(errno));
   }
 
   return 0;


=====================================
mod_procfs.html
=====================================
@@ -119,15 +119,17 @@ your existing server:
 <h2><a name="Usage">Usage</a></h2>
 
 <p>
-The <code>mod_procfs</code> module works by using the ProFTPD FSIO API to
-intercept all <code>stat(2)</code> and <code>lstat(2)</code> system calls;
-if the paths being checked reference the <code>/proc</code> filesystem,
-those system calls will fail with a "No such file or directory" error.
+The <code>mod_procfs</code> module works by using the ProFTPD command dispatch
+system to intercept all commands/requests that use paths; if the paths
+being used reference the <code>/proc</code> filesystem, those commands will
+fail with a "No such file or directory" error.
 
 <p>
 Example configuration:
 <pre>
   <IfModule mod_procfs.c>
+    # This is not required; the module automatically determines when it is
+    # needed.
     ProcfsEngine on
     ProcfsLog /var/log/proftpd/procfs.log
   </IfModule>
@@ -150,7 +152,7 @@ Thus for trace logging, to aid in debugging, you would use the following in
 your <code>proftpd.conf</code>:
 <pre>
   TraceLog /path/to/proftpd-trace.log
-  Trace fsio:20 procfs:20
+  Trace command:10 response:10 procfs:20
 </pre>
 This trace logging can generate large files; it is intended for debugging
 use only, and should be removed from any production configuration.


=====================================
t/lib/ProFTPD/Tests/Modules/mod_procfs.pm
=====================================
@@ -452,7 +452,7 @@ sub procfs_chrooted_rootfs {
       my $resp_code = $client->response_code();
       my $resp_msg = $client->response_msg();
 
-      my $expected = 550;
+      my $expected = 450;
       $self->assert($expected == $resp_code,
         test_msg("Expected response code $expected, got $resp_code"));
 
@@ -468,7 +468,7 @@ sub procfs_chrooted_rootfs {
       $resp_code = $client->response_code();
       $resp_msg = $client->response_msg();
 
-      $expected = 550;
+      $expected = 450;
       $self->assert($expected == $resp_code,
         test_msg("Expected response code $expected, got $resp_code"));
 
@@ -988,7 +988,6 @@ sub procfs_list_rejected {
       },
 
       'mod_procfs.c' => {
-        ProcfsEngine => 'on',
         ProcfsLog => $setup->{log_file},
       },
     },
@@ -1026,7 +1025,7 @@ sub procfs_list_rejected {
       my $resp_code = $client->response_code();
       my $resp_msg = $client->response_msg();
 
-      my $expected = 550;
+      my $expected = 450;
       $self->assert($expected == $resp_code,
         test_msg("Expected response code $expected, got $resp_code"));
 
@@ -1042,7 +1041,7 @@ sub procfs_list_rejected {
       $resp_code = $client->response_code();
       $resp_msg = $client->response_msg();
 
-      $expected = 550;
+      $expected = 450;
       $self->assert($expected == $resp_code,
         test_msg("Expected response code $expected, got $resp_code"));
 
@@ -1597,7 +1596,6 @@ sub procfs_mlst_rejected {
       },
 
       'mod_procfs.c' => {
-        ProcfsEngine => 'on',
         ProcfsLog => $setup->{log_file},
       },
     },
@@ -1639,8 +1637,8 @@ sub procfs_mlst_rejected {
       $self->assert($expected == $resp_code,
         test_msg("Expected response code $expected, got $resp_code"));
 
-      $expected = "/proc: No such file or directory";
-      $self->assert($expected eq $resp_msg,
+      $expected = '(No such file or directory|cannot be listed)';
+      $self->assert(qr/$expected/, $resp_msg,
         test_msg("Expected response message '$expected', got '$resp_msg'"));
 
       eval { $client->mlst('/proc/') };
@@ -1655,8 +1653,8 @@ sub procfs_mlst_rejected {
       $self->assert($expected == $resp_code,
         test_msg("Expected response code $expected, got $resp_code"));
 
-      $expected = "/proc/: No such file or directory";
-      $self->assert($expected eq $resp_msg,
+      $expected = '(No such file or directory|cannot be listed)';
+      $self->assert(qr/$expected/, $resp_msg,
         test_msg("Expected response message '$expected', got '$resp_msg'"));
 
       $client->quit();
@@ -1707,7 +1705,6 @@ sub procfs_nlst_rejected {
       },
 
       'mod_procfs.c' => {
-        ProcfsEngine => 'on',
         ProcfsLog => $setup->{log_file},
       },
     },
@@ -1745,7 +1742,7 @@ sub procfs_nlst_rejected {
       my $resp_code = $client->response_code();
       my $resp_msg = $client->response_msg();
 
-      my $expected = 550;
+      my $expected = 450;
       $self->assert($expected == $resp_code,
         test_msg("Expected response code $expected, got $resp_code"));
 
@@ -1761,12 +1758,12 @@ sub procfs_nlst_rejected {
       $resp_code = $client->response_code();
       $resp_msg = $client->response_msg();
 
-      $expected = 550;
+      $expected = 450;
       $self->assert($expected == $resp_code,
         test_msg("Expected response code $expected, got $resp_code"));
 
-      $expected = "/proc/: No such file or directory";
-      $self->assert($expected eq $resp_msg,
+      $expected = '/proc(\/)?: No such file or directory';
+      $self->assert(qr/$expected/, $resp_msg,
         test_msg("Expected response message '$expected', got '$resp_msg'"));
 
       $client->quit();
@@ -2003,7 +2000,24 @@ sub procfs_rnto_rejected {
   my $tmpdir = $self->{tmpdir};
   my $setup = test_setup($tmpdir, 'procfs');
 
-  my $test_file = File::Spec->rel2abs("/proc/test.txt");
+  my $src_file = File::Spec->rel2abs("$tmpdir/src.txt");
+  if (open(my $fh, "> $src_file")) {
+    print $fh "Hello, World!\n";
+    unless (close($fh)) {
+      die("Can't write $src_file: $!");
+    }
+
+  } else {
+    die("Can't open $src_file: $!");
+  }
+
+  if ($< == 0) {
+    unless (chown($setup->{uid}, $setup->{gid}, $src_file)) {
+      die("Can't set owner of $src_file to $setup->{uid}/$setup->{gid}: $!");
+    }
+  }
+
+  my $dst_file = File::Spec->rel2abs("/proc/test.txt");
 
   my $config = {
     PidFile => $setup->{pid_file},
@@ -2022,7 +2036,6 @@ sub procfs_rnto_rejected {
       },
 
       'mod_procfs.c' => {
-        ProcfsEngine => 'on',
         ProcfsLog => $setup->{log_file},
       },
     },
@@ -2052,7 +2065,8 @@ sub procfs_rnto_rejected {
       my $client = ProFTPD::TestSuite::FTP->new('127.0.0.1', $port);
       $client->login($setup->{user}, $setup->{passwd});
 
-      eval { $client->rnto($test_file) };
+      $client->rnfr($src_file);
+      eval { $client->rnto($dst_file) };
       unless ($@) {
         die("RNTO succeeded unexpectedly");
       }
@@ -2066,7 +2080,7 @@ sub procfs_rnto_rejected {
       $self->assert($expected == $resp_code,
         test_msg("Expected response code $expected, got $resp_code"));
 
-      $expected = "$test_file: No such file or directory";
+      $expected = "$dst_file: No such file or directory";
       $self->assert($expected eq $resp_msg,
         test_msg("Expected response message '$expected', got '$resp_msg'"));
     };
@@ -2145,6 +2159,7 @@ sub procfs_size_rejected {
 
       my $client = ProFTPD::TestSuite::FTP->new('127.0.0.1', $port);
       $client->login($setup->{user}, $setup->{passwd});
+      $client->type('binary');
 
       eval { $client->size('/proc/test.txt') };
       unless ($@) {
@@ -2209,7 +2224,6 @@ sub procfs_stat_rejected {
       },
 
       'mod_procfs.c' => {
-        ProcfsEngine => 'on',
         ProcfsLog => $setup->{log_file},
       },
     },
@@ -2248,7 +2262,7 @@ sub procfs_stat_rejected {
       my $resp_msg = $client->response_msg();
       $client->quit();
 
-      my $expected = 550;
+      my $expected = 450;
       $self->assert($expected == $resp_code,
         test_msg("Expected response code $expected, got $resp_code"));
 
@@ -2581,7 +2595,6 @@ sub procfs_site_mkdir_rejected {
       },
 
       'mod_procfs.c' => {
-        ProcfsEngine => 'on',
         ProcfsLog => $setup->{log_file},
       },
     },
@@ -2624,8 +2637,8 @@ sub procfs_site_mkdir_rejected {
       $self->assert($expected == $resp_code,
         test_msg("Expected response code $expected, got $resp_code"));
 
-      $expected = "/proc/test.d: No such file or directory";
-      $self->assert($expected eq $resp_msg,
+      $expected = '(No such file or directory|Read-only file system)';
+      $self->assert(qr/$expected/, $resp_msg,
         test_msg("Expected response message '$expected', got '$resp_msg'"));
     };
     if ($@) {
@@ -2674,7 +2687,6 @@ sub procfs_site_rmdir_rejected {
       },
 
       'mod_procfs.c' => {
-        ProcfsEngine => 'on',
         ProcfsLog => $setup->{log_file},
       },
     },
@@ -2717,8 +2729,8 @@ sub procfs_site_rmdir_rejected {
       $self->assert($expected == $resp_code,
         test_msg("Expected response code $expected, got $resp_code"));
 
-      $expected = "/proc: No such file or directory";
-      $self->assert($expected eq $resp_msg,
+      $expected = 'No such file or directory';
+      $self->assert(qr/$expected/, $resp_msg,
         test_msg("Expected response message '$expected', got '$resp_msg'"));
     };
     if ($@) {
@@ -2767,7 +2779,6 @@ sub procfs_site_symlink_rejected {
       },
 
       'mod_procfs.c' => {
-        ProcfsEngine => 'on',
         ProcfsLog => $setup->{log_file},
       },
     },
@@ -2809,8 +2820,8 @@ sub procfs_site_symlink_rejected {
       $self->assert($expected == $resp_code,
         test_msg("Expected response code $expected, got $resp_code"));
 
-      $expected = "/proc/from.txt: No such file or directory";
-      $self->assert($expected eq $resp_msg,
+      $expected = 'No such file or directory';
+      $self->assert(qr/$expected/, $resp_msg,
         test_msg("Expected response message '$expected', got '$resp_msg'"));
 
       eval { $client->site('SYMLINK', 'from.txt', '/proc/to.txt') };
@@ -2825,8 +2836,8 @@ sub procfs_site_symlink_rejected {
       $self->assert($expected == $resp_code,
         test_msg("Expected response code $expected, got $resp_code"));
 
-      $expected = "/proc/to.txt: No such file or directory";
-      $self->assert($expected eq $resp_msg,
+      $expected = 'No such file or directory';
+      $self->assert(qr/$expected/, $resp_msg,
         test_msg("Expected response message '$expected', got '$resp_msg'"));
 
       $client->quit();
@@ -2877,7 +2888,6 @@ sub procfs_site_utime_rejected {
       },
 
       'mod_procfs.c' => {
-        ProcfsEngine => 'on',
         ProcfsLog => $setup->{log_file},
       },
     },
@@ -2920,8 +2930,8 @@ sub procfs_site_utime_rejected {
       $self->assert($expected == $resp_code,
         test_msg("Expected response code $expected, got $resp_code"));
 
-      $expected = "/proc/test.txt: No such file or directory";
-      $self->assert($expected eq $resp_msg,
+      $expected = 'No such file or directory';
+      $self->assert(qr/$expected/, $resp_msg,
         test_msg("Expected response message '$expected', got '$resp_msg'"));
     };
     if ($@) {
@@ -3046,6 +3056,25 @@ sub procfs_site_cpto_rejected {
   my $tmpdir = $self->{tmpdir};
   my $setup = test_setup($tmpdir, 'procfs');
 
+  my $src_file = File::Spec->rel2abs("$tmpdir/src.txt");
+  if (open(my $fh, "> $src_file")) {
+    print $fh "Hello, World!\n";
+    unless (close($fh)) {
+      die("Can't write $src_file: $!");
+    }
+
+  } else {
+    die("Can't open $src_file: $!");
+  }
+
+  if ($< == 0) {
+    unless (chown($setup->{uid}, $setup->{gid}, $src_file)) {
+      die("Can't set owner of $src_file to $setup->{uid}/$setup->{gid}: $!");
+    }
+  }
+
+  my $dst_file = '/proc/test.txt';
+
   my $config = {
     PidFile => $setup->{pid_file},
     ScoreboardFile => $setup->{scoreboard_file},
@@ -3063,7 +3092,6 @@ sub procfs_site_cpto_rejected {
       },
 
       'mod_procfs.c' => {
-        ProcfsEngine => 'on',
         ProcfsLog => $setup->{log_file},
       },
     },
@@ -3093,7 +3121,8 @@ sub procfs_site_cpto_rejected {
       my $client = ProFTPD::TestSuite::FTP->new('127.0.0.1', $port);
       $client->login($setup->{user}, $setup->{passwd});
 
-      eval { $client->site('CPTO', '/proc/test.txt') };
+      $client->site('CPFR', $src_file);
+      eval { $client->site('CPTO', $dst_file) };
       unless ($@) {
         die("SITE CPTO succeeded unexpectedly");
       }
@@ -3106,8 +3135,8 @@ sub procfs_site_cpto_rejected {
       $self->assert($expected == $resp_code,
         test_msg("Expected response code $expected, got $resp_code"));
 
-      $expected = "/proc/test.txt: No such file or directory";
-      $self->assert($expected eq $resp_msg,
+      $expected = 'No such file or directory';
+      $self->assert(qr/$expected/, $resp_msg,
         test_msg("Expected response message '$expected', got '$resp_msg'"));
     };
     if ($@) {
@@ -3156,7 +3185,6 @@ sub procfs_site_copy_rejected {
       },
 
       'mod_procfs.c' => {
-        ProcfsEngine => 'on',
         ProcfsLog => $setup->{log_file},
       },
     },
@@ -3198,8 +3226,8 @@ sub procfs_site_copy_rejected {
       $self->assert($expected == $resp_code,
         test_msg("Expected response code $expected, got $resp_code"));
 
-      $expected = "/proc/from.txt: No such file or directory";
-      $self->assert($expected eq $resp_msg,
+      $expected = 'No such file or directory';
+      $self->assert(qr/$expected/, $resp_msg,
         test_msg("Expected response message '$expected', got '$resp_msg'"));
 
       eval { $client->site('COPY', 'from.txt', '/proc/to.txt') };
@@ -3214,8 +3242,8 @@ sub procfs_site_copy_rejected {
       $self->assert($expected == $resp_code,
         test_msg("Expected response code $expected, got $resp_code"));
 
-      $expected = "/proc/to.txt: No such file or directory";
-      $self->assert($expected eq $resp_msg,
+      $expected = 'No such file or directory';
+      $self->assert(qr/$expected/, $resp_msg,
         test_msg("Expected response message '$expected', got '$resp_msg'"));
 
       $client->quit();


=====================================
t/lib/ProFTPD/Tests/Modules/mod_procfs/sftp.pm
=====================================
@@ -1480,7 +1480,7 @@ sub procfs_sftp_rename {
 
       ($err_code, $err_name) = $sftp->error();
 
-      my $expected = 'SSH_FX_PERMISSION_DENIED';
+      $expected = 'SSH_FX_PERMISSION_DENIED';
       $self->assert($expected eq $err_name,
         test_msg("Expected error name '$expected', got '$err_name'"));
 
@@ -2128,7 +2128,7 @@ sub procfs_sftp_symlink {
 
       ($err_code, $err_name) = $sftp->error();
 
-      my $expected = 'SSH_FX_PERMISSION_DENIED';
+      $expected = 'SSH_FX_PERMISSION_DENIED';
       $self->assert($expected eq $err_name,
         test_msg("Expected error name '$expected', got '$err_name'"));
 



View it on GitLab: https://salsa.debian.org/debian-proftpd-team/proftpd-mod-procfs/-/commit/7493599eb8ad101610bf7a2a598c8b5655903084

-- 
View it on GitLab: https://salsa.debian.org/debian-proftpd-team/proftpd-mod-procfs/-/commit/7493599eb8ad101610bf7a2a598c8b5655903084
You're receiving this email because of your account on salsa.debian.org. Manage all notifications: https://salsa.debian.org/-/profile/notifications | Help: https://salsa.debian.org/help




More information about the Pkg-proftpd-maintainers mailing list