[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: --command-pipe mostly working, transcript below



On Mon, 1 Jan 2001, Adam Heath wrote:

> [snip]

I have tested -L, -s, plus the options listed in the above transcript.  Others
are left to be tested.  --unpack(used with --install) had some side affects,
which are fixed in the below patch.

==
Index: main/archives.c
===================================================================
RCS file: /cvs/dpkg/dpkg/main/archives.c,v
retrieving revision 1.19
diff -u -r1.19 archives.c
--- main/archives.c	2000/12/20 08:47:50	1.19
+++ main/archives.c	2001/01/02 05:12:29
@@ -774,6 +774,10 @@
 
   currenttime= time(0);
 
+  varbufreset(&fnamevb);
+  varbufreset(&fnametmpvb);
+  varbufreset(&fnamenewvb);
+
   varbufaddstr(&fnamevb,instdir); varbufaddc(&fnamevb,'/');
   varbufaddstr(&fnametmpvb,instdir); varbufaddc(&fnametmpvb,'/');
   varbufaddstr(&fnamenewvb,instdir); varbufaddc(&fnamenewvb,'/');
Index: main/main.c
===================================================================
RCS file: /cvs/dpkg/dpkg/main/main.c,v
retrieving revision 1.24
diff -u -r1.24 main.c
--- main/main.c	2000/12/26 14:34:58	1.24
+++ main/main.c	2001/01/02 05:12:30
@@ -324,6 +324,7 @@
 static const char passshortopts[]= "bceIfxX";
 static const char okpassshortopts[]= "D";
 
+void commandpipe(const char *const *argv);
 static const struct cmdinfo cmdinfos[]= {
   /* This table has both the action entries in it and the normal options.
    * The action entries are made with the ACTION macro, as they all
@@ -362,6 +363,7 @@
   ACTION( "print-installation-architecture", 0,  act_printinstarch,        printinstarch   ),
   ACTION( "predep-package",                  0,  act_predeppackage,        predeppackage   ),
   ACTION( "compare-versions",                0,  act_cmpversions,          cmpversions     ),
+  ACTION( "command-pipe",                   'c', act_commandpipe,   commandpipe     ),
   
   { "pending",           'a',  0,  &f_pending,     0,  0,             1              },
   { "recursive",         'R',  0,  &f_recursive,   0,  0,             1              },
@@ -393,6 +395,89 @@
   execvp(BACKEND, (char* const*) argv);
   ohshite(_("failed to exec dpkg-deb"));
 }
+void commandpipe(const char *const *argv) {
+  jmp_buf ejbuf;
+  struct varbuf linevb;
+  const char * pipein;
+  const char **newargs, **oldargs= NULL;
+  char *ptr, *endptr;
+  FILE *in;
+  int argc= 1, mode= 0, c, lno= 0, infd, i;
+  static void (*actionfunction)(const char *const *argv);
+
+  if ((pipein= *argv++) == NULL) badusage(_("--command-pipe takes 1 argument, not 0"));
+  if (*argv) badusage(_("--command-pipe only takes 1 argument"));
+  if ((infd= strtol(pipein, (char **)NULL, 10)) == -1)
+    ohshite(_("invalid number for --command-pipe"));
+  if ((in= fdopen(infd, "r")) == NULL)
+    ohshite(_("couldn't open `%i' for stream"), infd);
+
+  varbufinit(&linevb);
+  for (;;argc= 1,mode= 0) {
+    if (setjmp(ejbuf)) { /* expect warning about possible clobbering of argv */
+      error_unwind(ehflag_bombout); exit(2);
+    }
+    push_error_handler(&ejbuf,print_error_fatal,0);
+
+    do { c= getc(in); if (c == '\n') lno++; } while (c != EOF && isspace(c));
+    if (c == EOF) break;
+    if (c == '#') {
+      do { c= getc(in); if (c == '\n') lno++; } while (c != EOF && c != '\n');
+      continue;
+    }
+    varbufreset(&linevb);
+    do {
+      varbufaddc(&linevb,c);
+      c= getc(in);
+      if (c == '\n') lno++;
+      if (isspace(c)) argc++;  /* This isn't fully accurate, but overestimating can't hurt. */
+    } while (c != EOF && c != '\n');
+    if (c == EOF) ohshit(_("unexpected eof before end of line %d"),lno);
+    if (!argc) continue;
+    oldargs= newargs= realloc(oldargs,sizeof(const char *) * (argc + 1));
+    argc= 1;
+    ptr= linevb.buf;
+    endptr= ptr + linevb.used;
+    while(ptr < endptr) {
+      if (*ptr == '\\') {
+	memmove(ptr, ++ptr, linevb.used - (linevb.buf - ptr));
+	continue;
+      } else if (isspace(*ptr)) {
+	if (mode == 1) {
+	  *ptr= 0;
+	  mode= 0;
+	}
+      } else {
+	if (mode == 0) {
+	  newargs[argc]= ptr;
+	  argc++;
+	  mode= 1;
+	}
+      }
+      ptr++;
+    }
+    *ptr= 0;
+    newargs[++argc] = 0;
+
+/* We strdup each argument, but never free it, because the error messages
+ * contain references back to these strings.  Freeing them, and reusing
+ * the memory, would make those error messages confusing, to say the
+ * least.
+ */
+    for(i=1;i<argc;i++)
+	if (newargs[i]) newargs[i]=strdup(newargs[i]);
+
+    cipaction= NULL;
+    myopt((const char *const**)&newargs,cmdinfos);
+    if (!cipaction) badusage(_("need an action option"));
+
+    actionfunction= (void (*)(const char* const*))cipaction->farg;
+    actionfunction(newargs);
+    set_error_display(0,0);
+    error_unwind(ehflag_normaltidy);
+  }
+}
+
 
 int main(int argc, const char *const *argv) {
   jmp_buf ejbuf;
Index: main/main.h
===================================================================
RCS file: /cvs/dpkg/dpkg/main/main.h,v
retrieving revision 1.9
diff -u -r1.9 main.h
--- main/main.h	2000/11/05 15:06:48	1.9
+++ main/main.h	2001/01/02 05:12:30
@@ -54,7 +54,8 @@
               act_assertpredep, act_printarch, act_predeppackage, act_cmpversions,
               act_printinstarch, act_compareversions, act_printavail, act_avclear,
               act_forgetold, act_getselections, act_setselections, act_printgnuarch,
-              act_assertepoch, act_assertlongfilenames, act_assertmulticonrep };
+              act_assertepoch, act_assertlongfilenames, act_assertmulticonrep,
+	      act_commandpipe };
 
 enum conffopt {
   cfof_prompt        =     001,
==

----BEGIN GEEK CODE BLOCK----
Version: 3.12
GCS d- s: a-- c+++ UL++++ P+ L++++ !E W+ M o+ K- W--- !O M- !V PS--
PE++ Y+ PGP++ t* 5++ X+ tv b+ D++ G e h*! !r z?
-----END GEEK CODE BLOCK-----
----BEGIN PGP INFO----
Adam Heath <doogie@debian.org>        Finger Print | KeyID
67 01 42 93 CA 37 FB 1E    63 C9 80 1D 08 CF 84 0A | DE656B05 PGP
AD46 C888 F587 F8A3 A6DA  3261 8A2C 7DC2 8BD4 A489 | 8BD4A489 GPG
-----END PGP INFO-----



Reply to: