c20b04
From d8a169164cf40fc1cf6448792c1fa991f19bb375 Mon Sep 17 00:00:00 2001
c20b04
From: Florian Festi <ffesti@redhat.com>
c20b04
Date: Thu, 22 Apr 2021 14:50:34 +0200
c20b04
Subject: [PATCH] Add --nocompression option to rpm2archive
c20b04
c20b04
Also use popt for the command line handling. As we are using librpm
c20b04
anyway there is no reason to keep the dependencies low (as with
c20b04
rpm2cpio).
c20b04
c20b04
Resolves: #1530
c20b04
---
c20b04
 doc/rpm2archive.8 | 16 ++++++++++---
c20b04
 rpm2archive.c     | 60 ++++++++++++++++++++++++++++++++++-------------
c20b04
 2 files changed, 57 insertions(+), 19 deletions(-)
c20b04
c20b04
diff --git a/rpm2archive.c b/rpm2archive.c
c20b04
index d96db006ea..cb39c7a712 100644
c20b04
--- a/rpm2archive.c
c20b04
+++ b/rpm2archive.c
c20b04
@@ -10,6 +10,8 @@
c20b04
 
c20b04
 #include <rpm/rpmts.h>
c20b04
 
c20b04
+#include <popt.h>
c20b04
+
c20b04
 #include <archive.h>
c20b04
 #include <archive_entry.h>
c20b04
 #include <unistd.h>
c20b04
@@ -18,6 +20,16 @@
c20b04
 
c20b04
 #define BUFSIZE (128*1024)
c20b04
 
c20b04
+int compress = 1;
c20b04
+
c20b04
+static struct poptOption optionsTable[] = {
c20b04
+    { "nocompression", 'n', POPT_ARG_VAL, &compress, 0,
c20b04
+        N_("create uncompressed tar file"),
c20b04
+        NULL },
c20b04
+    POPT_AUTOHELP
c20b04
+    POPT_TABLEEND
c20b04
+};
c20b04
+
c20b04
 static void fill_archive_entry(struct archive * a, struct archive_entry * entry, rpmfi fi)
c20b04
 {
c20b04
     archive_entry_clear(entry);
c20b04
@@ -60,7 +72,7 @@ static void write_file_content(struct archive * a, char * buf, rpmfi fi)
c20b04
     }
c20b04
 }
c20b04
 
c20b04
-static int process_package(rpmts ts, char * filename)
c20b04
+static int process_package(rpmts ts, const char * filename)
c20b04
 {
c20b04
     FD_t fdi;
c20b04
     FD_t gzdi;
c20b04
@@ -119,9 +131,11 @@ static int process_package(rpmts ts, char * filename)
c20b04
 
c20b04
     /* create archive */
c20b04
     a = archive_write_new();
c20b04
-    if (archive_write_add_filter_gzip(a) != ARCHIVE_OK) {
c20b04
-	fprintf(stderr, "Error: Could not create gzip output filter\n");
c20b04
-	exit(EXIT_FAILURE);
c20b04
+    if (compress) {
c20b04
+	if (archive_write_add_filter_gzip(a) != ARCHIVE_OK) {
c20b04
+	    fprintf(stderr, "%s\n", archive_error_string(a));
c20b04
+	    exit(EXIT_FAILURE);
c20b04
+	}
c20b04
     }
c20b04
     if (archive_write_set_format_pax_restricted(a) != ARCHIVE_OK) {
c20b04
 	fprintf(stderr, "Error: Format pax restricted is not supported\n");
c20b04
@@ -142,7 +156,12 @@ static int process_package(rpmts ts, char * filename)
c20b04
 	}
c20b04
 	archive_write_open_fd(a, STDOUT_FILENO);
c20b04
     } else {
c20b04
-	char * outname = rstrscat(NULL, filename, ".tgz", NULL);
c20b04
+	char * outname = rstrscat(NULL, filename, NULL);
c20b04
+	if (compress) {
c20b04
+	    outname = rstrscat(&outname, ".tgz", NULL);
c20b04
+	} else {
c20b04
+	    outname = rstrscat(&outname, ".tar", NULL);
c20b04
+	}
c20b04
 	if (archive_write_open_filename(a, outname) != ARCHIVE_OK) {
c20b04
 	    fprintf(stderr, "Error: Can't open output file: %s\n", outname);
c20b04
 	    exit(EXIT_FAILURE);
c20b04
@@ -203,21 +222,22 @@ static int process_package(rpmts ts, char * filename)
c20b04
     return rc;
c20b04
 }
c20b04
 
c20b04
-int main(int argc, char *argv[])
c20b04
+int main(int argc, const char *argv[])
c20b04
 {
c20b04
-    int rc = 0, i;
c20b04
+    int rc = 0;
c20b04
+    poptContext optCon;
c20b04
+    const char *fn;
c20b04
 
c20b04
     xsetprogname(argv[0]);	/* Portability call -- see system.h */
c20b04
     rpmReadConfigFiles(NULL, NULL);
c20b04
 
c20b04
-    if (argc > 1 && (rstreq(argv[1], "-h") || rstreq(argv[1], "--help"))) {
c20b04
-	fprintf(stderr, "Usage: %s [file.rpm ...]\n", argv[0]);
c20b04
+    optCon = poptGetContext(NULL, argc, argv, optionsTable, 0);
c20b04
+    poptSetOtherOptionHelp(optCon, "[OPTIONS]* <FILES>");
c20b04
+    if (argc < 2 || poptGetNextOpt(optCon) == 0) {
c20b04
+	poptPrintUsage(optCon, stderr, 0);
c20b04
 	exit(EXIT_FAILURE);
c20b04
     }
c20b04
 
c20b04
-    if (argc == 1)
c20b04
-	argv[argc++] = "-";	/* abuse NULL pointer at the end of argv */
c20b04
-
c20b04
     rpmts ts = rpmtsCreate();
c20b04
     rpmVSFlags vsflags = 0;
c20b04
 
c20b04
@@ -227,13 +247,21 @@ int main(int argc, char *argv[])
c20b04
     vsflags |= RPMVSF_NOHDRCHK;
c20b04
     (void) rpmtsSetVSFlags(ts, vsflags);
c20b04
 
c20b04
-    for (i = 1; i < argc; i++) {
c20b04
+    /* if no file name is given use stdin/stdout */
c20b04
+    if (!poptPeekArg(optCon)) {
c20b04
+	rc = process_package(ts, "-");
c20b04
+	if (rc != 0)
c20b04
+	    goto exit;
c20b04
+    }
c20b04
 
c20b04
-	rc = process_package(ts, argv[i]);
c20b04
+    while ((fn = poptGetArg(optCon)) != NULL) {
c20b04
+	rc = process_package(ts, fn);
c20b04
 	if (rc != 0)
c20b04
-	    return rc;
c20b04
+	    goto exit;
c20b04
     }
c20b04
 
c20b04
+ exit:
c20b04
+    poptFreeContext(optCon);
c20b04
     (void) rpmtsFree(ts);
c20b04
     return rc;
c20b04
 }