This is an automated email from the git hooks/post-receive script.

guillem pushed a commit to branch main
in repository dpkg.

View the commit online:
https://git.dpkg.org/cgit/dpkg/dpkg.git/commit/?id=0fba5af0f97f8e28c4712a0b886069ab0e2c3e13

commit 0fba5af0f97f8e28c4712a0b886069ab0e2c3e13
Author: Guillem Jover <guil...@debian.org>
AuthorDate: Thu Aug 24 12:11:14 2023 +0200

    libdpkg: Generalize command_in_path() from find_command()
    
    This is useful for external users too.
---
 lib/dpkg/Makefile.am                               |  6 ++
 lib/dpkg/command.c                                 | 45 +++++++++++
 lib/dpkg/command.h                                 |  2 +
 lib/dpkg/libdpkg.map                               |  1 +
 .../postinst => lib/dpkg/t/data/command/path-a/cmd |  2 -
 .../dpkg/t/data/command/path-a/cmd-a               |  2 -
 .../postinst => lib/dpkg/t/data/command/path-b/cmd |  2 -
 .../dpkg/t/data/command/path-b/cmd-b               |  2 -
 .../dpkg/t/data/command/path-noexec/cmd            |  2 -
 .../dpkg/t/data/command/path-noexec/cmd-noexec     |  2 -
 lib/dpkg/t/t-command.c                             | 88 +++++++++++++++++++++-
 src/main/help.c                                    | 39 +---------
 src/main/main.h                                    |  1 -
 src/main/unpack.c                                  |  3 +-
 14 files changed, 145 insertions(+), 52 deletions(-)

diff --git a/lib/dpkg/Makefile.am b/lib/dpkg/Makefile.am
index 3403338ce..9482e3261 100644
--- a/lib/dpkg/Makefile.am
+++ b/lib/dpkg/Makefile.am
@@ -254,6 +254,12 @@ test_scripts = \
        # EOL
 
 test_data = \
+       t/data/command/path-a/cmd \
+       t/data/command/path-a/cmd-a \
+       t/data/command/path-b/cmd \
+       t/data/command/path-b/cmd-b \
+       t/data/command/path-noexec/cmd \
+       t/data/command/path-noexec/cmd-noexec \
        t/data/meminfo-no-data \
        t/data/meminfo-no-info \
        t/data/meminfo-no-unit \
diff --git a/lib/dpkg/command.c b/lib/dpkg/command.c
index 73f58f61a..8f6934425 100644
--- a/lib/dpkg/command.c
+++ b/lib/dpkg/command.c
@@ -28,6 +28,8 @@
 #include <dpkg/dpkg.h>
 #include <dpkg/i18n.h>
 #include <dpkg/string.h>
+#include <dpkg/varbuf.h>
+#include <dpkg/file.h>
 #include <dpkg/path.h>
 #include <dpkg/command.h>
 
@@ -209,3 +211,46 @@ command_shell(const char *cmd, const char *name)
        execlp(shell, shell, mode, "--", cmd, NULL);
        ohshite(_("unable to execute %s (%s)"), name, cmd);
 }
+
+/**
+ * Check whether a command can be found in PATH.
+ *
+ * @param cmd The command name to check. This is a relative pathname.
+ *
+ * @return A boolean denoting whether the command has been found.
+ */
+bool
+command_in_path(const char *cmd)
+{
+       struct varbuf filename = VARBUF_INIT;
+       const char *path_list;
+       const char *path, *path_end;
+
+       if (cmd[0] == '/')
+               return file_is_exec(cmd);
+
+       path_list = getenv("PATH");
+       if (!path_list)
+               ohshit(_("PATH is not set"));
+
+       for (path = path_list; path; path = *path_end ? path_end + 1 : NULL) {
+               size_t path_len;
+
+               path_end = strchrnul(path, ':');
+               path_len = (size_t)(path_end - path);
+
+               varbuf_set_buf(&filename, path, path_len);
+               if (path_len)
+                       varbuf_add_char(&filename, '/');
+               varbuf_add_str(&filename, cmd);
+               varbuf_end_str(&filename);
+
+               if (file_is_exec(filename.buf)) {
+                       varbuf_destroy(&filename);
+                       return true;
+               }
+       }
+
+       varbuf_destroy(&filename);
+       return false;
+}
diff --git a/lib/dpkg/command.h b/lib/dpkg/command.h
index 09ec92ac7..768aba437 100644
--- a/lib/dpkg/command.h
+++ b/lib/dpkg/command.h
@@ -58,6 +58,8 @@ void command_exec(struct command *cmd) DPKG_ATTR_NORET;
 
 void command_shell(const char *cmd, const char *name) DPKG_ATTR_NORET;
 
+bool command_in_path(const char *cmd);
+
 /** @} */
 
 DPKG_END_DECLS
diff --git a/lib/dpkg/libdpkg.map b/lib/dpkg/libdpkg.map
index fa4329bb1..e0b11520d 100644
--- a/lib/dpkg/libdpkg.map
+++ b/lib/dpkg/libdpkg.map
@@ -202,6 +202,7 @@ LIBDPKG_PRIVATE {
        command_add_args;
        command_exec;
        command_shell;
+       command_in_path;
        command_destroy;
 
        pager_get_exec;
diff --git a/tests/t-predepends-no-triggers/pkg-trigger/DEBIAN/postinst 
b/lib/dpkg/t/data/command/path-a/cmd
similarity index 55%
copy from tests/t-predepends-no-triggers/pkg-trigger/DEBIAN/postinst
copy to lib/dpkg/t/data/command/path-a/cmd
index c52d3c26b..1a2485251 100755
--- a/tests/t-predepends-no-triggers/pkg-trigger/DEBIAN/postinst
+++ b/lib/dpkg/t/data/command/path-a/cmd
@@ -1,3 +1 @@
 #!/bin/sh
-
-exit 0
diff --git a/tests/t-predepends-no-triggers/pkg-trigger/DEBIAN/postinst 
b/lib/dpkg/t/data/command/path-a/cmd-a
similarity index 55%
copy from tests/t-predepends-no-triggers/pkg-trigger/DEBIAN/postinst
copy to lib/dpkg/t/data/command/path-a/cmd-a
index c52d3c26b..1a2485251 100755
--- a/tests/t-predepends-no-triggers/pkg-trigger/DEBIAN/postinst
+++ b/lib/dpkg/t/data/command/path-a/cmd-a
@@ -1,3 +1 @@
 #!/bin/sh
-
-exit 0
diff --git a/tests/t-predepends-no-triggers/pkg-trigger/DEBIAN/postinst 
b/lib/dpkg/t/data/command/path-b/cmd
similarity index 55%
copy from tests/t-predepends-no-triggers/pkg-trigger/DEBIAN/postinst
copy to lib/dpkg/t/data/command/path-b/cmd
index c52d3c26b..1a2485251 100755
--- a/tests/t-predepends-no-triggers/pkg-trigger/DEBIAN/postinst
+++ b/lib/dpkg/t/data/command/path-b/cmd
@@ -1,3 +1 @@
 #!/bin/sh
-
-exit 0
diff --git a/tests/t-predepends-no-triggers/pkg-trigger/DEBIAN/postinst 
b/lib/dpkg/t/data/command/path-b/cmd-b
similarity index 55%
copy from tests/t-predepends-no-triggers/pkg-trigger/DEBIAN/postinst
copy to lib/dpkg/t/data/command/path-b/cmd-b
index c52d3c26b..1a2485251 100755
--- a/tests/t-predepends-no-triggers/pkg-trigger/DEBIAN/postinst
+++ b/lib/dpkg/t/data/command/path-b/cmd-b
@@ -1,3 +1 @@
 #!/bin/sh
-
-exit 0
diff --git a/tests/t-predepends-no-triggers/pkg-trigger/DEBIAN/postinst 
b/lib/dpkg/t/data/command/path-noexec/cmd
old mode 100755
new mode 100644
similarity index 55%
copy from tests/t-predepends-no-triggers/pkg-trigger/DEBIAN/postinst
copy to lib/dpkg/t/data/command/path-noexec/cmd
index c52d3c26b..1a2485251
--- a/tests/t-predepends-no-triggers/pkg-trigger/DEBIAN/postinst
+++ b/lib/dpkg/t/data/command/path-noexec/cmd
@@ -1,3 +1 @@
 #!/bin/sh
-
-exit 0
diff --git a/tests/t-predepends-no-triggers/pkg-trigger/DEBIAN/postinst 
b/lib/dpkg/t/data/command/path-noexec/cmd-noexec
old mode 100755
new mode 100644
similarity index 55%
copy from tests/t-predepends-no-triggers/pkg-trigger/DEBIAN/postinst
copy to lib/dpkg/t/data/command/path-noexec/cmd-noexec
index c52d3c26b..1a2485251
--- a/tests/t-predepends-no-triggers/pkg-trigger/DEBIAN/postinst
+++ b/lib/dpkg/t/data/command/path-noexec/cmd-noexec
@@ -1,3 +1 @@
 #!/bin/sh
-
-exit 0
diff --git a/lib/dpkg/t/t-command.c b/lib/dpkg/t/t-command.c
index 33e002e12..3a2e64bda 100644
--- a/lib/dpkg/t/t-command.c
+++ b/lib/dpkg/t/t-command.c
@@ -185,6 +185,91 @@ test_command_exec(void)
        command_destroy(&cmd);
 }
 
+static void
+test_command_in_path(void)
+{
+       char *path_a, *path_b, *path_noexec;
+       char *oldpath, *newpath = NULL;
+       bool ret;
+       int rc;
+
+       path_a = test_data_file("command/path-a");
+       path_b = test_data_file("command/path-b");
+       path_noexec = test_data_file("command/path-noexec");
+
+       oldpath = getenv("PATH");
+
+       setenv("PATH", "", 1);
+       ret = command_in_path("cmd");
+       test_pass(ret == false);
+       ret = command_in_path("cmd-a");
+       test_pass(ret == false);
+       ret = command_in_path("cmd-b");
+       test_pass(ret == false);
+       ret = command_in_path("cmd-noexec");
+       test_pass(ret == false);
+
+       setenv("PATH", "/nonexistent", 1);
+       ret = command_in_path("cmd");
+       test_pass(ret == false);
+       ret = command_in_path("cmd-a");
+       test_pass(ret == false);
+       ret = command_in_path("cmd-b");
+       test_pass(ret == false);
+       ret = command_in_path("cmd-noexec");
+       test_pass(ret == false);
+
+       setenv("PATH", path_a, 1);
+       ret = command_in_path("cmd");
+       test_pass(ret == true);
+       ret = command_in_path("cmd-a");
+       test_pass(ret == true);
+       ret = command_in_path("cmd-b");
+       test_pass(ret == false);
+       ret = command_in_path("cmd-noexec");
+       test_pass(ret == false);
+
+       setenv("PATH", path_b, 1);
+       ret = command_in_path("cmd");
+       test_pass(ret == true);
+       ret = command_in_path("cmd-a");
+       test_pass(ret == false);
+       ret = command_in_path("cmd-b");
+       test_pass(ret == true);
+       ret = command_in_path("cmd-noexec");
+       test_pass(ret == false);
+
+       setenv("PATH", path_noexec, 1);
+       ret = command_in_path("cmd");
+       test_pass(ret == false);
+       ret = command_in_path("cmd-a");
+       test_pass(ret == false);
+       ret = command_in_path("cmd-b");
+       test_pass(ret == false);
+       ret = command_in_path("cmd-noexec");
+       test_pass(ret == false);
+
+       rc = asprintf(&newpath, "/nonexistent:%s:%s:%s", path_a, path_b, 
path_noexec);
+       if (rc < 0)
+               test_bail("cannot allocate new PATH variable");
+       setenv("PATH", newpath, 1);
+       ret = command_in_path("cmd");
+       test_pass(ret == true);
+       ret = command_in_path("cmd-a");
+       test_pass(ret == true);
+       ret = command_in_path("cmd-b");
+       test_pass(ret == true);
+       ret = command_in_path("cmd-noexec");
+       test_pass(ret == false);
+
+       setenv("PATH", oldpath, 1);
+
+       free(path_a);
+       free(path_b);
+       free(path_noexec);
+       free(newpath);
+}
+
 static void
 test_command_shell(void)
 {
@@ -213,7 +298,7 @@ test_command_shell(void)
 
 TEST_ENTRY(test)
 {
-       test_plan(49);
+       test_plan(73);
 
        test_command_init();
        test_command_grow_argv();
@@ -221,5 +306,6 @@ TEST_ENTRY(test)
        test_command_add_argl();
        test_command_add_args();
        test_command_exec();
+       test_command_in_path();
        test_command_shell();
 }
diff --git a/src/main/help.c b/src/main/help.c
index cfce1bbce..e81466938 100644
--- a/src/main/help.c
+++ b/src/main/help.c
@@ -35,6 +35,7 @@
 #include <dpkg/dpkg-db.h>
 #include <dpkg/path.h>
 #include <dpkg/file.h>
+#include <dpkg/command.h>
 #include <dpkg/db-fsys.h>
 
 #include "main.h"
@@ -75,42 +76,6 @@ namenodetouse(struct fsys_namenode *namenode, struct pkginfo 
*pkg,
   return fnn;
 }
 
-bool
-find_command(const char *prog)
-{
-  struct varbuf filename = VARBUF_INIT;
-  const char *path_list;
-  const char *path, *path_end;
-
-  if (prog[0] == '/')
-    return file_is_exec(prog);
-
-  path_list = getenv("PATH");
-  if (!path_list)
-    ohshit(_("PATH is not set"));
-
-  for (path = path_list; path; path = *path_end ? path_end + 1 : NULL) {
-    size_t path_len;
-
-    path_end = strchrnul(path, ':');
-    path_len = (size_t)(path_end - path);
-
-    varbuf_set_buf(&filename, path, path_len);
-    if (path_len)
-      varbuf_add_char(&filename, '/');
-    varbuf_add_str(&filename, prog);
-    varbuf_end_str(&filename);
-
-    if (file_is_exec(filename.buf)) {
-      varbuf_destroy(&filename);
-      return true;
-    }
-  }
-
-  varbuf_destroy(&filename);
-  return false;
-}
-
 /**
  * Verify that some programs can be found in the PATH.
  */
@@ -139,7 +104,7 @@ void checkpath(void) {
   int warned= 0;
 
   for (prog = prog_list; *prog; prog++) {
-    if (!find_command(*prog)) {
+    if (!command_in_path(*prog)) {
       warning(_("'%s' not found in PATH or not executable"), *prog);
       warned++;
     }
diff --git a/src/main/main.h b/src/main/main.h
index 9b7d896bd..f841e8d46 100644
--- a/src/main/main.h
+++ b/src/main/main.h
@@ -223,7 +223,6 @@ bool force_conflicts(struct deppossi *possi);
 void
 conffile_mark_obsolete(struct pkginfo *pkg, struct fsys_namenode *namenode);
 void pkg_conffiles_mark_old(struct pkginfo *pkg);
-bool find_command(const char *prog);
 void checkpath(void);
 
 struct fsys_namenode *
diff --git a/src/main/unpack.c b/src/main/unpack.c
index be0a41765..97dd0a0d1 100644
--- a/src/main/unpack.c
+++ b/src/main/unpack.c
@@ -46,6 +46,7 @@
 #include <dpkg/pkg.h>
 #include <dpkg/pkg-queue.h>
 #include <dpkg/path.h>
+#include <dpkg/command.h>
 #include <dpkg/buffer.h>
 #include <dpkg/subproc.h>
 #include <dpkg/dir.h>
@@ -132,7 +133,7 @@ deb_verify(const char *filename)
 
   /* We have to check on every unpack, in case the debsig-verify package
    * gets installed or removed. */
-  if (!find_command(DEBSIGVERIFY))
+  if (!command_in_path(DEBSIGVERIFY))
     return;
 
   printf(_("Authenticating %s ...\n"), filename);

-- 
Dpkg.Org's dpkg

Reply via email to