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