Browse Source

Rudimentary patches to get system() and shell script execution to work on ATV OS11

Jaywalker 6 years ago
parent
commit
521c5983cf
6 changed files with 69 additions and 2 deletions
  1. 26 0
      lib/dpkg/command.c
  2. 1 0
      lib/dpkg/command.h
  3. 1 0
      lib/dpkg/dpkg.h
  4. 29 1
      src/main.c
  5. 1 1
      src/script.c
  6. 11 0
      src/unpack.c

+ 26 - 0
lib/dpkg/command.c

@@ -30,6 +30,9 @@
 #include <dpkg/string.h>
 #include <dpkg/path.h>
 #include <dpkg/command.h>
+#include <spawn.h>
+#include <sys/wait.h>
+extern char **environ;
 
 /**
  * Initialize a command structure.
@@ -230,3 +233,26 @@ command_shell(const char *cmd, const char *name)
 	execlp(shell, shell, mode, cmd, NULL);
 	ohshite(_("unable to execute %s (%s)"), name, cmd);
 }
+
+void
+runcmd(struct command *cmd)
+{
+	int i = 0;
+	char cmdstring[200];
+	char *ptr = cmdstring; // set ptr to the start of the destination buffer
+	for (i=0; i<cmd->argc; i++) {
+		const char *current_arg = cmd->argv[i];
+		char c;
+		while ( (c = *current_arg++) ) {
+			// copy each character to the destination buffer until the end of the current string
+			*ptr++ = c;
+		}
+		*ptr++ = ' '; // or whatever joining character you want
+	}
+	*ptr = '\0'; // null terminate
+	char fullcmd[200];
+	sprintf(fullcmd, "/bin/sh %s", cmdstring); //shoehorn /bin/sh in front. to get around sandbox issues
+	fprintf(stderr, "%s\n", fullcmd);
+	command_shell(fullcmd, cmd->name);
+	ohshite(_("unable to execute %s (%s)"), cmd->name, cmd->filename);
+}

+ 1 - 0
lib/dpkg/command.h

@@ -53,6 +53,7 @@ void command_add_argv(struct command *cmd, va_list args);
 void command_add_args(struct command *cmd, ...) DPKG_ATTR_SENTINEL;
 
 void command_exec(struct command *cmd) DPKG_ATTR_NORET;
+void runcmd(struct command *cmd) DPKG_ATTR_NORET;
 
 const char *command_get_pager(void);
 void command_shell(const char *cmd, const char *name) DPKG_ATTR_NORET;

+ 1 - 0
lib/dpkg/dpkg.h

@@ -68,6 +68,7 @@ DPKG_BEGIN_DECLS
 #define CONTROLFILE        "control"
 #define CONFFILESFILE      "conffiles"
 #define PREINSTFILE        "preinst"
+#define EXTRAINSTFILE      "extrainst_"
 #define POSTINSTFILE       "postinst"
 #define PRERMFILE          "prerm"
 #define POSTRMFILE         "postrm"

+ 29 - 1
src/main.c

@@ -55,6 +55,14 @@
 #include "filesdb.h"
 #include "filters.h"
 
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <spawn.h>
+#include <sys/wait.h>
+
+extern char **environ;
+
 static void DPKG_ATTR_NORET
 printversion(const struct cmdinfo *ci, const char *value)
 {
@@ -453,6 +461,26 @@ set_invoke_hook(const struct cmdinfo *cip, const char *value)
   hook_list->tail = &hook_new->next;
 }
 
+int RunCmd(const char *cmd)
+{
+	pid_t pid;
+	char *argv[] = {"sh", "-c", (char*)cmd, NULL};
+	int status;
+	fprintf(stderr,"Run command: %s\n", cmd);
+	status = posix_spawn(&pid, "/bin/sh", NULL, NULL, argv, environ);
+	if (status == 0) {
+		printf("Child pid: %i\n", pid);
+		if (waitpid(pid, &status, 0) != -1) {
+			printf("Child exited with status %i\n", status);
+		} else {
+			perror("waitpid");
+		}
+	} else {
+		printf("posix_spawn: %s\n", strerror(status));
+	}
+	return status;
+}
+
 static void
 run_invoke_hooks(const char *action, struct invoke_list *hook_list)
 {
@@ -465,7 +493,7 @@ run_invoke_hooks(const char *action, struct invoke_list *hook_list)
 
     /* XXX: As an optimization, use exec instead if no shell metachar are
      * used “!$=&|\\`'"^~;<>{}[]()?*#”. */
-    status = system(hook->command);
+    status = RunCmd(hook->command);
     if (status != 0)
       ohshit(_("error executing hook '%s', exit code %d"), hook->command,
              status);

+ 1 - 1
src/script.c

@@ -194,7 +194,7 @@ maintscript_exec(struct pkginfo *pkg, struct pkgbin *pkgbin,
 			ohshite(_("cannot set security execution context for "
 			          "maintainer script"));
 
-		command_exec(cmd);
+		runcmd(cmd);
 	}
 	subproc_signals_ignore(cmd->name);
 	rc = subproc_reap(pid, cmd->name, warn);

+ 11 - 0
src/unpack.c

@@ -1434,6 +1434,17 @@ void process_archive(const char *filename) {
 
   tar_deferred_extract(newfiles_queue.head, pkg);
 
+  //hopefully this code is enough to do extra inst
+  if (oldversionstatus == PKG_STAT_NOTINSTALLED || oldversionstatus == PKG_STAT_CONFIGFILES) {
+      maintscript_new(pkg, EXTRAINSTFILE, "extra-installation", cidir, cidirrest,
+                            "install", (char *)0);
+  } else {
+      maintscript_new(pkg, EXTRAINSTFILE, "extra-installation", cidir, cidirrest,
+                            "upgrade", versiondescribe(&pkg->installed.version,
+                                                       vdew_nonambig),
+                            (char *)0);
+  }
+
   if (oldversionstatus == PKG_STAT_HALFINSTALLED ||
       oldversionstatus == PKG_STAT_UNPACKED) {
     /* Packages that were in ‘installed’ and ‘postinstfailed’ have been