Signed-off-by: Rémy Oudompheng <[email protected]>
---
 src/pacman/callback.c |   75 ++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 74 insertions(+), 1 deletions(-)

diff --git a/src/pacman/callback.c b/src/pacman/callback.c
index 1ff9a47..06f161c 100644
--- a/src/pacman/callback.c
+++ b/src/pacman/callback.c
@@ -25,6 +25,7 @@
 #include <string.h>
 #include <sys/time.h>
 #include <sys/types.h> /* off_t */
+#include <sys/wait.h>  /* waitpid */
 #include <unistd.h>
 #include <wchar.h>
 
@@ -689,7 +690,79 @@ void cb_log(pmloglevel_t level, const char *fmt, va_list 
args)
 
 /* Callback to check signatures with an external command */
 int cb_checksig(const char *path, const pmpgpsig_t *sig) {
-       return 0;
+       int ret = 0;
+       int retval;
+       int childpid;
+       char *parsedcmd;
+       int pipefd[2];
+
+       if(!config->checksigcommand) {
+               return -1;
+       }
+
+       parsedcmd = strdup(config->checksigcommand);
+       /* replace all occurrences of %f with the filename */
+       if(strstr(parsedcmd, "%f")) {
+               char *tempcmd = strreplace(parsedcmd, "%f", path);
+               free(parsedcmd);
+               parsedcmd = tempcmd;
+       }
+
+       /* execute the parsed command via /bin/sh -c */
+       pipe(pipefd);
+       childpid = fork();
+
+       if (childpid < 0) {
+               pm_printf(PM_LOG_ERROR, _("running ChecksigCommand: fork 
failed!\n"));
+               ret = -1;
+               goto cleanup;
+       } else if (childpid == 0) {
+               /* we are in the child */
+               close(pipefd[1]);
+               /* read from the pipe */
+               dup2(pipefd[0], 0);
+               pm_printf(PM_LOG_DEBUG, "child: running command: %s\n", 
parsedcmd);
+               if (execl("/bin/sh", "/bin/sh", "-c", parsedcmd, NULL) == -1)
+                       exit(127);
+       } else {
+               /* we are still in pacman */
+               close(pipefd[0]);
+               size_t remaining;
+               const char *signature = alpm_pgpsig_get_raw(sig, &remaining);
+               if (! signature) {
+                       close(pipefd[1]);
+                       ret = -1;
+                       goto wait;
+               }
+               while(remaining > 0) {
+                       /* write signature into pipe */
+                       ssize_t written = write(pipefd[1], signature, 
remaining);
+                       if (written < 0) {
+                               pm_printf(PM_LOG_ERROR, _("running 
ChecksigCommand: broken pipe!\n"));
+                               ret = -1;
+                         break;
+                       }
+                       signature += written;
+                       remaining -= written;
+               }
+               close(pipefd[1]);
+       }
+
+wait:
+       waitpid(childpid, &retval, 0);
+
+       if(!WIFEXITED(retval)) {
+               /* exited abnormally */
+               pm_printf(PM_LOG_DEBUG, "ChecksigCommand exited abnormally "
+                               "status (%d,%d)\n", retval >> 8, retval & 0xff);
+               ret = -1;
+       } else {
+               ret = (WEXITSTATUS(retval) == 0) ? 0 : 1;
+       }
+
+cleanup:
+       free(parsedcmd);
+       return ret;
 }
 
 /* vim: set ts=2 sw=2 noet: */
-- 
1.7.4.4


Reply via email to