zgz: Don't hardcode /lib, avoid segfaulting on > 128 character paths
authorJoey Hess <joey@kitenet.net>
Sun, 23 Sep 2012 01:53:33 +0000 (21:53 -0400)
committerJoey Hess <joey@kitenet.net>
Sun, 23 Sep 2012 01:53:33 +0000 (21:53 -0400)
There were a number of issues with zgz:

* It had a fixed 128 (!) size limit on paths, and if we happened
  to be installed into one longer than that, the program would
  likely segfault.
* Calling exit(system()) is inefficient; we might as well just
  execve() and avoid having a process just blocked in waitpid()
  on another.
* We should honor LIBDIR, in order to support lib64-style "multilib"
  as well as full Debian-style "multiarch".

Based on a patch from Colin Walters <walters@verbum.org>

Makefile.PL
pristine-tar.spec
zgz/zgz.c

index baef72a9a61c00c283aeb05c8410ed3bcc40ea95..60a5103fcf647619bd045341ac9a1f9584d2d523 100755 (executable)
@@ -49,7 +49,8 @@ $(EXE_FILES): %:
 PHONY+=$(EXE_FILES)
 endif
 
-ZGZ_LIB=$(PREFIX)/lib/zgz
+LIBDIR ?= $(PREFIX)/lib
+PKGLIBDIR ?= $(LIBDIR)/pristine-tar
 
 extra_build: zgz/zgz pristine-tar.spec
        pod2man -c pristine-tar pristine-tar > pristine-tar.1
@@ -61,16 +62,15 @@ extra_build: zgz/zgz pristine-tar.spec
 
 ZGZ_SOURCES = zgz/zgz.c zgz/gzip/*.c zgz/old-bzip2/*.c
 zgz/zgz: $(ZGZ_SOURCES)
-       gcc -Wall -O2 -o $@ $(ZGZ_SOURCES) -lz -DZGZ_LIB=\"$(ZGZ_LIB)\"
+       gcc -Wall -O2 -o $@ $(ZGZ_SOURCES) -lz -DPKGLIBDIR=\"$(PKGLIBDIR)\"
 
 extra_install:
        install -d $(DESTDIR)$(PREFIX)/bin
        install zgz/zgz $(DESTDIR)$(PREFIX)/bin
        install -d $(DESTDIR)$(PREFIX)/share/man/man1
        install -m 0644 *.1 $(DESTDIR)$(PREFIX)/share/man/man1
-       install -d $(DESTDIR)$(ZGZ_LIB)/suse-bzip2
-       install pit/suse-bzip2/bzip2 $(DESTDIR)$(ZGZ_LIB)/suse-bzip2
-       install pit/suse-bzip2/libbz2* $(DESTDIR)$(ZGZ_LIB)/suse-bzip2
+       install -d $(DESTDIR)$(PKGLIBDIR)/suse-bzip2
+       install pit/suse-bzip2/bzip2 pit/suse-bzip2/libbz2* $(DESTDIR)$(PKGLIBDIR)/suse-bzip2
 
 extra_clean:
        $(MAKE) clean -C pit/suse-bzip2 PREFIX=$(PREFIX)
index 2de867af01ad3f5e00bf52ea224e3df2cba8aef6..81d7c299485680dfa188c7116c13678165d33481 100644 (file)
@@ -1,5 +1,5 @@
 Name: pristine-tar
-Version: 1.26
+Version: 1.27
 Release: 2%{?dist}
 Summary: regenerate pristine tarballs
 
index 377b073dcfb0fc93ab16c0b85424a9d4c926f09c..28ba1667befeeac9398e16e901ad963debd8445c 100644 (file)
--- a/zgz/zgz.c
+++ b/zgz/zgz.c
@@ -131,8 +131,8 @@ static      void    gz_compress(int, int, const char *, uint32_t, int, int, int, int, in
 static void    usage(void);
 static void    display_version(void);
 static void    display_license(void);
-static void    shamble(char *, int, char *);
-static void    rebrain(char *, char *, int, char *);
+static void    shamble(char *, int);
+static void    rebrain(char *, char *, int);
 
 int main(int, char **p);
 
@@ -341,9 +341,9 @@ main(int argc, char **argv)
                }
                old_bzip2(level);
        } else if (bzsuse) {
-               shamble("suse-bzip2/bzip2", level, "");
+               shamble("suse-bzip2/bzip2", level);
        } else if (pbzsuse) {
-               rebrain("suse-bzip2", "pbzip2", level, "");
+               rebrain("suse-bzip2", "pbzip2", level);
        } else {
                if (rsync || new_rsync) {
                        fprintf(stderr, "%s: --rsyncable not supported with --zlib\n", progname);
@@ -516,18 +516,34 @@ gz_compress(int in, int out, const char *origname, uint32_t mtime, int level, in
 
 /* runs an external, reanimated compressor program */
 static void
-shamble(char *zombie, int level, char *opts)
+shamble(char *zombie, int level)
 {
-       char buf[128];
-       sprintf(buf, "%s/%s -%i %s", ZGZ_LIB, zombie, level, opts);
-       exit(system(buf));
+       char exec_buf[PATH_MAX];
+       char level_buf[3];
+       char *argv[3];
+       int i;
+
+       snprintf(exec_buf, sizeof(exec_buf), "%s/%s", PKGLIBDIR, zombie);
+       snprintf(level_buf, sizeof(level_buf), "-%i", level);
+
+       i = 0;
+       argv[i++] = exec_buf;
+       argv[i++] = level_buf;
+       argv[i++] = NULL;
+
+       execvp(exec_buf, argv);
+       perror("Failed to run external program");
+       exit(1);
 }
 
 /* swaps in a different library and runs a system program */
 static void
-rebrain(char *zombie, char *program, int level, char *opts)
+rebrain(char *zombie, char *program, int level)
 {
-       char buf[128];
+       char path_buf[PATH_MAX];
+       char level_buf[3];
+       char *argv[3];
+       int i;
 
 #if defined(__APPLE__) && defined(__MACH__)
 #      define LD_PATH_VAR "DYLD_LIBRARY_PATH" 
@@ -535,9 +551,20 @@ rebrain(char *zombie, char *program, int level, char *opts)
 #      define LD_PATH_VAR "LD_LIBRARY_PATH"
 #endif
 
-       sprintf(buf, LD_PATH_VAR "=%s/%s %s -%i %s",
-                       ZGZ_LIB, zombie, program, level, opts);
-       exit(system(buf));
+       snprintf(path_buf, sizeof(path_buf), "%s/%s", PKGLIBDIR, zombie);
+       /* FIXME - should append, not overwrite */
+       setenv(LD_PATH_VAR, path_buf, 1);
+
+       snprintf(level_buf, sizeof(level_buf), "-%i", level);
+
+       i = 0;
+       argv[i++] = program;
+       argv[i++] = level_buf;
+       argv[i++] = NULL;
+
+       execvp(program, argv);
+       perror("Failed to run external program");
+       exit(1);
 }
 
 /* display usage */