Bläddra i källkod

Use new command module instead of ad-hoc code

Guillem Jover 16 år sedan
förälder
incheckning
5050748f1a
5 ändrade filer med 123 tillägg och 158 borttagningar
  1. 35 32
      dselect/method.cc
  2. 0 1
      lib/dpkg/dpkg.h
  3. 14 19
      src/archives.c
  4. 59 69
      src/help.c
  5. 15 37
      src/main.c

+ 35 - 32
dselect/method.cc

@@ -43,6 +43,7 @@
 #include <dpkg/dpkg.h>
 #include <dpkg/dpkg-db.h>
 #include <dpkg/subproc.h>
+#include <dpkg/command.h>
 
 #include "dselect.h"
 #include "method.h"
@@ -135,23 +136,23 @@ static enum urqresult lockmethod(void) {
   return urqr_normal;
 }
 
-urqresult falliblesubprocess(const char *exepath, const char *name,
-                             const char *const *args) {
+urqresult
+falliblesubprocess(struct command *cmd)
+{
   pid_t c1;
   int status, i, c;
   
   cursesoff();
 
-  subproc_signals_setup(name);
+  subproc_signals_setup(cmd->name);
 
   c1 = subproc_fork();
   if (!c1) {
     subproc_signals_cleanup(0, 0);
-    execvp(exepath,(char* const*) args);
-    ohshite(_("unable to run %.250s process `%.250s'"),name,exepath);
+    command_exec(cmd);
   }
 
-  status = subproc_wait(c1, name);
+  status = subproc_wait(c1, cmd->name);
 
   pop_cleanup(ehflag_normaltidy);
 
@@ -159,7 +160,7 @@ urqresult falliblesubprocess(const char *exepath, const char *name,
     sleep(1);
     return urqr_normal;
   }
-  fprintf(stderr,"\n%s ",name);
+  fprintf(stderr, "\n%s ", cmd->name);
   if (WIFEXITED(status)) {
     i= WEXITSTATUS(status);
     fprintf(stderr,_("returned error exit status %d.\n"),i);
@@ -191,15 +192,15 @@ static urqresult runscript(const char *exepath, const char *name) {
   getcurrentopt();
 
   if (coption) {
+    struct command cmd;
+
     strcpy(coption->meth->pathinmeth,exepath);
-    const char *fallibleargs[] = {
-      exepath,
-      admindir,
-      coption->meth->name,
-      coption->name,
-      0
-      };
-    ur= falliblesubprocess(coption->meth->path,name,fallibleargs);
+
+    command_init(&cmd, coption->meth->path, name);
+    command_add_args(&cmd, exepath, admindir, coption->meth->name,
+                     coption->name, NULL);
+    ur = falliblesubprocess(&cmd);
+    command_destroy(&cmd);
   } else {
     sthfailed("no access method is selected/configured");
     ur= urqr_fail;
@@ -218,18 +219,20 @@ urqresult urq_install(void) {
 }
 
 static urqresult rundpkgauto(const char *name, const char *dpkgmode) {
-  const char *fallibleargs[] = {
-    DPKG,
-	"--admindir",
-	admindir,
-    "--pending",
-    dpkgmode,
-    0
-  };
+  urqresult ur;
+  struct command cmd;
+
+  command_init(&cmd, DPKG, name);
+  command_add_args(&cmd, DPKG, "--admindir", admindir, "--pending",
+                   dpkgmode, NULL);
+
   cursesoff();
   printf("running dpkg --pending %s ...\n",dpkgmode);
   fflush(stdout);
-  return falliblesubprocess(DPKG,name,fallibleargs);
+  ur = falliblesubprocess(&cmd);
+  command_destroy(&cmd);
+
+  return ur;
 }
 
 urqresult urq_remove(void) {
@@ -254,15 +257,15 @@ urqresult urq_setup(void) {
   delete l;
 
   if (qa == qa_quitchecksave) {
+    struct command cmd;
+
     strcpy(coption->meth->pathinmeth,METHODSETUPSCRIPT);
-    const char *fallibleargs[] = {
-      METHODSETUPSCRIPT,
-      admindir,
-      coption->meth->name,
-      coption->name,
-      0
-    };
-    ur= falliblesubprocess(coption->meth->path,_("query/setup script"),fallibleargs);
+
+    command_init(&cmd, coption->meth->path, _("query/setup script"));
+    command_add_args(&cmd, METHODSETUPSCRIPT, admindir, coption->meth->name,
+                     coption->name, NULL);
+    ur = falliblesubprocess(&cmd);
+    command_destroy(&cmd);
     if (ur == urqr_normal) writecurrentopt();
   } else {
     ur= urqr_fail;

+ 0 - 1
lib/dpkg/dpkg.h

@@ -93,7 +93,6 @@ DPKG_BEGIN_DECLS
 #define PAGERENV            "PAGER"
 #define DEFAULTPAGER        "pager"
 
-#define PKGSCRIPTMAXARGS     10
 #define MD5HASHLEN           32
 #define MAXTRIGDIRECTIVE     256
 

+ 14 - 19
src/archives.c

@@ -45,6 +45,7 @@
 #include <dpkg/path.h>
 #include <dpkg/buffer.h>
 #include <dpkg/subproc.h>
+#include <dpkg/command.h>
 #include <dpkg/tarfn.h>
 #include <dpkg/myopt.h>
 
@@ -1067,35 +1068,29 @@ void archivefiles(const char *const *argv) {
     m_pipe(pi);
     fc = subproc_fork();
     if (!fc) {
+      struct command cmd;
       const char *const *ap;
-      int i;
+
       m_dup2(pi[1],1); close(pi[0]); close(pi[1]);
-      for (i=0, ap=argv; *ap; ap++, i++);
-      arglist = m_malloc(sizeof(char *) * (i + 15));
-      arglist[0] = FIND;
-      arglist[1] = "-L";
-      for (i = 2, ap = argv; *ap; ap++, i++) {
+
+      command_init(&cmd, FIND, _("find for dpkg --recursive"));
+      command_add_args(&cmd, FIND, "-L", NULL);
+
+      for (ap = argv; *ap; ap++) {
         if (strchr(FIND_EXPRSTARTCHARS,(*ap)[0])) {
           char *a;
           a= m_malloc(strlen(*ap)+10);
           strcpy(a,"./");
           strcat(a,*ap);
-          arglist[i] = a;
+          command_add_arg(&cmd, a);
         } else {
-          arglist[i] = (const char *)*ap;
+          command_add_arg(&cmd, (const char *)*ap);
         }
       }
-      /* When editing these, make sure that arglist is malloced big enough,
-       * above.
-       */
-      arglist[i++] = "-name";
-      arglist[i++] = "*.deb";
-      arglist[i++] = "-type";
-      arglist[i++] = "f";
-      arglist[i++] = "-print0";
-      arglist[i] = NULL;
-      execvp(FIND, (char *const *)arglist);
-      ohshite(_("failed to exec find for --recursive"));
+
+      command_add_args(&cmd, "-name", "*.deb", "-type", "f", "-print0", NULL);
+
+      command_exec(&cmd);
     }
     close(pi[1]);
 

+ 59 - 69
src/help.c

@@ -38,6 +38,7 @@
 #include <dpkg/dpkg-db.h>
 #include <dpkg/path.h>
 #include <dpkg/subproc.h>
+#include <dpkg/command.h>
 
 #include "filesdb.h"
 #include "main.h"
@@ -168,7 +169,9 @@ force_conflicts(struct deppossi *possi)
   return fc_conflicts;
 }
 
-static const char* preexecscript(const char *path, char *const *argv) {
+static const char *
+preexecscript(struct command *cmd)
+{
   /* returns the path to the script inside the chroot
    * FIXME: none of the stuff here will work if admindir isn't inside
    * instdir as expected.
@@ -182,49 +185,23 @@ static const char* preexecscript(const char *path, char *const *argv) {
   }
   if (f_debug & dbg_scripts) {
     struct varbuf args = VARBUF_INIT;
+    const char **argv = cmd->argv;
 
     while (*++argv) {
       varbufaddc(&args, ' ');
       varbufaddstr(&args, *argv);
     }
     varbufaddc(&args, '\0');
-    debug(dbg_scripts, "fork/exec %s (%s )", path, args.buf);
+    debug(dbg_scripts, "fork/exec %s (%s )", cmd->filename, args.buf);
     varbuf_destroy(&args);
   }
   instdirl= strlen(instdir);
-  if (!instdirl) return path;
-  assert (strlen(path)>=instdirl);
-  return path+instdirl;
+  if (!instdirl)
+    return cmd->filename;
+  assert(strlen(cmd->filename) >= instdirl);
+  return cmd->filename + instdirl;
 }  
 
-static char *const *vbuildarglist(const char *scriptname, va_list ap) {
-  static char *bufs[PKGSCRIPTMAXARGS+1];
-  char *nextarg;
-  int i;
-
-  i=0;
-  if(bufs[0]) free(bufs[0]);
-  /* Yes, cast away const because exec wants it that way */
-  bufs[i++] = m_strdup(scriptname);
-  for (;;) {
-    assert(i < PKGSCRIPTMAXARGS);
-    nextarg= va_arg(ap,char*);
-    if (!nextarg) break;
-    bufs[i++]= nextarg;
-  }
-  bufs[i] = NULL;
-  return bufs;
-}    
-
-static char *const *buildarglist(const char *scriptname, ...) {
-  char *const *arglist;
-  va_list ap;
-  va_start(ap,scriptname);
-  arglist= vbuildarglist(scriptname,ap);
-  va_end(ap);
-  return arglist;
-}
-
 void
 post_postinst_tasks(struct pkginfo *pkg, enum pkgstatus new_status)
 {
@@ -269,33 +246,27 @@ static void setexecute(const char *path, struct stat *stab) {
 
 static int
 do_script(struct pkginfo *pkg, struct pkginfoperfile *pif,
-          const char *scriptpath, struct stat *stab,
-          char *const arglist[], const char *name, int warn)
+          struct command *cmd, struct stat *stab, int warn)
 {
-  const char *scriptexec;
   int c1, r;
-  setexecute(scriptpath,stab);
+
+  setexecute(cmd->filename, stab);
 
   push_cleanup(cu_post_script_tasks, ehflag_bombout, NULL, 0, 0);
 
   c1 = subproc_fork();
   if (!c1) {
-    const char **narglist;
-    for (r=0; arglist[r]; r++) ;
-    narglist=nfmalloc((r+1)*sizeof(char*));
-    for (r=1; arglist[r-1]; r++)
-      narglist[r]= arglist[r];
-    scriptexec= preexecscript(scriptpath,(char * const *)narglist);
-    narglist[0]= scriptexec;
+    cmd->argv[0] = preexecscript(cmd);
+
     if (setenv(MAINTSCRIPTPKGENVVAR, pkg->name, 1) ||
         setenv(MAINTSCRIPTARCHENVVAR, pif->architecture, 1) ||
         setenv(MAINTSCRIPTDPKGENVVAR, PACKAGE_VERSION, 1))
       ohshite(_("unable to setenv for maintainer script"));
-    execv(scriptexec,(char * const *)narglist);
-    ohshite(_("unable to execute %s"), name);
+
+    command_exec(cmd);
   }
-  subproc_signals_setup(name); /* This does a push_cleanup() */
-  r = subproc_wait_check(c1, name, warn);
+  subproc_signals_setup(cmd->name); /* This does a push_cleanup() */
+  r = subproc_wait_check(c1, cmd->name, warn);
   pop_cleanup(ehflag_normaltidy);
 
   pop_cleanup(ehflag_normaltidy);
@@ -307,16 +278,20 @@ static int
 vmaintainer_script_installed(struct pkginfo *pkg, const char *scriptname,
                              const char *desc, va_list ap)
 {
+  struct command cmd;
   const char *scriptpath;
-  char *const *arglist;
   struct stat stab;
   char buf[100];
 
   scriptpath= pkgadminfile(pkg,scriptname);
-  arglist= vbuildarglist(scriptname,ap);
   sprintf(buf, _("installed %s script"), desc);
 
+  command_init(&cmd, scriptpath, buf);
+  command_add_arg(&cmd, scriptname);
+  command_add_argv(&cmd, ap);
+
   if (stat(scriptpath,&stab)) {
+    command_destroy(&cmd);
     if (errno == ENOENT) {
       debug(dbg_scripts, "vmaintainer_script_installed nonexistent %s",
             scriptname);
@@ -324,7 +299,9 @@ vmaintainer_script_installed(struct pkginfo *pkg, const char *scriptname,
     }
     ohshite(_("unable to stat %s `%.250s'"), buf, scriptpath);
   }
-  do_script(pkg, &pkg->installed, scriptpath, &stab, arglist, buf, 0);
+  do_script(pkg, &pkg->installed, &cmd, &stab, 0);
+
+  command_destroy(&cmd);
 
   return 1;
 }
@@ -366,25 +343,31 @@ maintainer_script_new(struct pkginfo *pkg,
                       const char *scriptname, const char *desc,
                       const char *cidir, char *cidirrest, ...)
 {
-  char *const *arglist;
+  struct command cmd;
   struct stat stab;
   va_list ap;
   char buf[100];
   
+  strcpy(cidirrest, scriptname);
+  sprintf(buf, _("new %s script"), desc);
+
   va_start(ap,cidirrest);
-  arglist= vbuildarglist(scriptname,ap);
+  command_init(&cmd, cidir, buf);
+  command_add_arg(&cmd, scriptname);
+  command_add_argv(&cmd, ap);
   va_end(ap);
-  sprintf(buf, _("new %s script"), desc);
 
-  strcpy(cidirrest,scriptname);
   if (stat(cidir,&stab)) {
+    command_destroy(&cmd);
     if (errno == ENOENT) {
       debug(dbg_scripts,"maintainer_script_new nonexistent %s `%s'",scriptname,cidir);
       return 0;
     }
     ohshite(_("unable to stat %s `%.250s'"), buf, cidir);
   }
-  do_script(pkg, &pkg->available, cidir, &stab, arglist, buf, 0);
+  do_script(pkg, &pkg->available, &cmd, &stab, 0);
+
+  command_destroy(&cmd);
   post_script_tasks();
 
   return 1;
@@ -394,51 +377,58 @@ int maintainer_script_alternative(struct pkginfo *pkg,
                                   const char *scriptname, const char *desc,
                                   const char *cidir, char *cidirrest,
                                   const char *ifok, const char *iffallback) {
+  struct command cmd;
   const char *oldscriptpath;
-  char *const *arglist;
   struct stat stab;
   char buf[100];
 
   oldscriptpath= pkgadminfile(pkg,scriptname);
-  arglist= buildarglist(scriptname,
-                        ifok,versiondescribe(&pkg->available.version,
-                                             vdew_nonambig),
-                        NULL);
   sprintf(buf, _("old %s script"), desc);
+
+  command_init(&cmd, oldscriptpath, buf);
+  command_add_args(&cmd, scriptname, ifok,
+                   versiondescribe(&pkg->available.version, vdew_nonambig),
+                   NULL);
+
   if (stat(oldscriptpath,&stab)) {
     if (errno == ENOENT) {
       debug(dbg_scripts,"maintainer_script_alternative nonexistent %s `%s'",
             scriptname,oldscriptpath);
+      command_destroy(&cmd);
       return 0;
     }
     warning(_("unable to stat %s '%.250s': %s"),
-            buf,oldscriptpath,strerror(errno));
+            cmd.name, oldscriptpath, strerror(errno));
   } else {
-    if (!do_script(pkg, &pkg->installed, oldscriptpath, &stab,
-                   arglist, buf, PROCWARN)) {
+    if (!do_script(pkg, &pkg->installed, &cmd, &stab, PROCWARN)) {
+      command_destroy(&cmd);
       post_script_tasks();
       return 1;
     }
   }
   fprintf(stderr, _("dpkg - trying script from the new package instead ...\n"));
 
-  arglist= buildarglist(scriptname,
-                        iffallback,versiondescribe(&pkg->installed.version,
-                                                   vdew_nonambig),
-                        NULL);
   strcpy(cidirrest,scriptname);
   sprintf(buf, _("new %s script"), desc);
 
+  command_destroy(&cmd);
+  command_init(&cmd, cidir, buf);
+  command_add_args(&cmd, scriptname, iffallback,
+                   versiondescribe(&pkg->installed.version, vdew_nonambig),
+                   NULL);
+
   if (stat(cidir,&stab)) {
+    command_destroy(&cmd);
     if (errno == ENOENT)
       ohshit(_("there is no script in the new version of the package - giving up"));
     else
       ohshite(_("unable to stat %s `%.250s'"),buf,cidir);
   }
 
-  do_script(pkg, &pkg->available, cidir, &stab, arglist, buf, 0);
+  do_script(pkg, &pkg->available, &cmd, &stab, 0);
   fprintf(stderr, _("dpkg: ... it looks like that went OK.\n"));
 
+  command_destroy(&cmd);
   post_script_tasks();
 
   return 1;

+ 15 - 37
src/main.c

@@ -44,6 +44,7 @@
 #include <dpkg/i18n.h>
 #include <dpkg/dpkg.h>
 #include <dpkg/dpkg-db.h>
+#include <dpkg/command.h>
 #include <dpkg/myopt.h>
 
 #include "main.h"
@@ -539,16 +540,11 @@ static const struct cmdinfo cmdinfos[]= {
 };
 
 void execbackend(const char *const *argv) {
-  char **nargv;   /* argv for backend command */
-  int i = 0;      /* index for nargv */
-  int offset = 0; /* offset for copying argv strings to nargv */
-  int argc = 1;   /* for nargv */
-  const char *const *arg = argv;
-  int pass_admindir = 0;
-
-  while (*arg != NULL) {
-    arg++; argc++;
-  }
+  struct command cmd;
+  char *arg;
+
+  command_init(&cmd, cipaction->parg, NULL);
+  command_add_arg(&cmd, cipaction->parg);
 
   /*
    * Special case: dpkg-query takes the --admindir option, and if dpkg itself
@@ -556,39 +552,21 @@ void execbackend(const char *const *argv) {
    */
   if (strcmp(cipaction->parg, DPKGQUERY) == 0 &&
       strcmp(admindir, ADMINDIR) != 0) {
-    argc++;
-    pass_admindir = 1;
-  }
-
-  nargv = m_malloc(sizeof(char *) * (argc + 3));
-  nargv[i] = m_strdup(cipaction->parg);
-
-  i++, offset++;
-
-  if (pass_admindir) {
-    nargv[i] = m_malloc((strlen("--admindir=") + strlen(admindir) + 1));
-    sprintf(nargv[i], "--admindir=%s", admindir);
-    i++, offset++;
+    arg = m_malloc((strlen("--admindir=") + strlen(admindir) + 1));
+    sprintf(arg, "--admindir=%s", admindir);
+    command_add_arg(&cmd, arg);
   }
 
-  nargv[i] = m_malloc(2 + strlen(cipaction->olong) + 1);
-  strcpy(nargv[i], "--");
-  strcat(nargv[i], cipaction->olong);
-  i++, offset++;
+  arg = m_malloc(2 + strlen(cipaction->olong) + 1);
+  sprintf(arg, "--%s", cipaction->olong);
+  command_add_arg(&cmd, arg);
 
   /* Exlicitely separate arguments from options as any user-supplied
    * separator got stripped by the option parser */
-  nargv[i] = "--";
-  i++, argc++, offset++;
-
-  /* Copy arguments from argv to nargv. */
-  for (; i <= argc; i++)
-    nargv[i] = m_strdup(argv[i - offset]);
-
-  nargv[i] = NULL;
+  command_add_arg(&cmd, "--");
+  command_add_argl(&cmd, (const char **)argv);
 
-  execvp(cipaction->parg, nargv);
-  ohshite(_("failed to exec %s"), (char *)cipaction->parg);
+  command_exec(&cmd);
 }
 
 void commandfd(const char *const *argv) {