[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Help-tar] tar + lbzip2 proposal
From: |
Sergey Poznyakoff |
Subject: |
Re: [Help-tar] tar + lbzip2 proposal |
Date: |
Wed, 07 Oct 2009 23:02:15 +0300 |
ERSEK Laszlo <address@hidden> ha escrit:
> It doesn't. lbzip2 isn't a drop-in replacement for bzip2.
OK. Then, please find attached a patch that implements an additional
level of indirection between compression type and actual
compression program name. E.g. to invoke lbzip2 whenever the user
types the --bzip2 option, one would use:
tar --standard-compress-program=bzip2:lbzip2 ...
Of course, it is preferable to add this option to TAR_OPTIONS.
That being said, I am still not convinced that the gain
compensates additional complexity introduced in the program.
Your feedback is, as always, welcome.
Regards,
Sergey
diff --git a/src/buffer.c b/src/buffer.c
index dd97682..6e9221d 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -65,7 +65,7 @@ FILE *stdlis;
static void backspace_output (void);
-/* PID of child program, if compress_option or remote archive access. */
+/* PID of child program, if compression_option or remote archive access. */
static pid_t child_pid;
/* Error recovery stuff */
@@ -197,44 +197,31 @@ compute_duration ()
/* Compression detection */
-enum compress_type {
- ct_tar, /* Plain tar file */
- ct_none, /* Unknown compression type */
- ct_compress,
- ct_gzip,
- ct_bzip2,
- ct_lzma,
- ct_lzop,
- ct_xz
-};
-
struct zip_magic
{
- enum compress_type type;
+ enum compression_type type;
size_t length;
char *magic;
- char *program;
char *option;
};
static struct zip_magic const magic[] = {
- { ct_tar },
- { ct_none, },
- { ct_compress, 2, "\037\235", "compress", "-Z" },
- { ct_gzip, 2, "\037\213", "gzip", "-z" },
- { ct_bzip2, 3, "BZh", "bzip2", "-j" },
- { ct_lzma, 6, "\xFFLZMA", "lzma", "--lzma" }, /* FIXME: ???? */
- { ct_lzop, 4, "\211LZO", "lzop", "--lzop" },
- { ct_xz, 6, "\0xFD7zXZ", "-J" },
+ { compression_tar },
+ { compression_none, },
+ { compression_compress, 2, "\037\235", "-Z" },
+ { compression_gzip, 2, "\037\213", "-z" },
+ { compression_bzip2, 3, "BZh", "-j" },
+ { compression_lzma, 6, "\xFFLZMA", "--lzma" }, /* FIXME: ???? */
+ { compression_lzop, 4, "\211LZO", "--lzop" },
+ { compression_xz, 6, "\0xFD7zXZ", "-J" },
};
#define NMAGIC (sizeof(magic)/sizeof(magic[0]))
-#define compress_option(t) magic[t].option
-#define compress_program(t) magic[t].program
+#define compression_option(t) magic[t].option
/* Check if the file ARCHIVE is a compressed archive. */
-enum compress_type
+enum compression_type
check_compressed_archive (bool *pshort)
{
struct zip_magic const *p;
@@ -256,13 +243,13 @@ check_compressed_archive (bool *pshort)
if (tar_checksum (record_start, true) == HEADER_SUCCESS)
/* Probably a valid header */
- return ct_tar;
+ return compression_tar;
for (p = magic + 2; p < magic + NMAGIC; p++)
if (memcmp (record_start->buffer, p->magic, p->length) == 0)
return p->type;
- return ct_none;
+ return compression_none;
}
/* Guess if the archive is seekable. */
@@ -312,25 +299,26 @@ open_compressed_archive ()
if (!use_compress_program_option)
{
bool shortfile;
- enum compress_type type = check_compressed_archive (&shortfile);
+ enum compression_type type = check_compressed_archive (&shortfile);
switch (type)
{
- case ct_tar:
+ case compression_tar:
if (shortfile)
ERROR ((0, 0, _("This does not look like a tar archive")));
return archive;
- case ct_none:
+ case compression_none:
if (shortfile)
ERROR ((0, 0, _("This does not look like a tar archive")));
- set_comression_program_by_suffix (archive_name_array[0], NULL);
+ set_comression_program_by_suffix (archive_name_array[0],
+ compression_tar);
if (!use_compress_program_option)
return archive;
break;
default:
- use_compress_program_option = compress_program (type);
+ use_compress_program_option = compression_to_program_name (type);
break;
}
}
@@ -559,15 +547,15 @@ _open_archive (enum access_mode wanted_access)
case ACCESS_READ:
{
bool shortfile;
- enum compress_type type;
+ enum compression_type type;
archive = STDIN_FILENO;
type = check_compressed_archive (&shortfile);
- if (type != ct_tar && type != ct_none)
+ if (type != compression_tar && type != compression_none)
FATAL_ERROR ((0, 0,
_("Archive is compressed. Use %s option"),
- compress_option (type)));
+ compression_option (type)));
if (shortfile)
ERROR ((0, 0, _("This does not look like a tar archive")));
}
@@ -616,8 +604,8 @@ _open_archive (enum access_mode wanted_access)
switch (check_compressed_archive (NULL))
{
- case ct_none:
- case ct_tar:
+ case compression_none:
+ case compression_tar:
break;
default:
diff --git a/src/common.h b/src/common.h
index 0020f08..f39d594 100644
--- a/src/common.h
+++ b/src/common.h
@@ -782,7 +782,22 @@ bool transform_name_fp (char **pinput, int type,
char *(*fun)(char *, void *), void *);
/* Module suffix.c */
-void set_comression_program_by_suffix (const char *name, const char *defprog);
+enum compression_type
+ {
+ compression_tar, /* Plain tar file */
+ compression_none, /* Unknown compression type */
+ compression_compress,
+ compression_gzip,
+ compression_bzip2,
+ compression_lzma,
+ compression_lzop,
+ compression_xz
+ };
+
+void set_comression_program_by_suffix (const char *name,
+ const char *defname);
+const char *compression_to_program_name (enum compression_type type);
+void set_compression_program_name (char *arg);
/* Module checkpoint.c */
void checkpoint_compile_action (const char *str);
@@ -834,3 +849,5 @@ void finish_deferred_unlinks (void);
/* Module exit.c */
extern void (*fatal_exit_hook) (void);
+
+
diff --git a/src/suffix.c b/src/suffix.c
index 6dbc68e..155f2d7 100644
--- a/src/suffix.c
+++ b/src/suffix.c
@@ -18,16 +18,71 @@
#include <system.h>
#include "common.h"
+#include <argmatch.h>
+static const char *compression_program[] = {
+ NULL,
+ NULL,
+ "compress",
+ "gzip",
+ "bzip2",
+ "lzma",
+ "lzop",
+ "xz",
+};
+
+const char *
+compression_to_program_name (enum compression_type type)
+{
+ return compression_program[type];
+}
+
+static const const char *compression_names[] = {
+ "compress",
+ "gzip",
+ "bzip2",
+ "lzma",
+ "lzop",
+ "xz",
+ NULL
+};
+
+static int compression_types[] = {
+ compression_compress,
+ compression_gzip,
+ compression_bzip2,
+ compression_lzma,
+ compression_lzop,
+ compression_xz,
+};
+
+ARGMATCH_VERIFY (compression_names, compression_types);
+
+void
+set_compression_program_name (char *arg)
+{
+ int t;
+ char *p = strchr (arg, ':');
+ if (!p)
+ USAGE_ERROR ((0, 0, _("Invalid value for --standard-compress-program")));
+
+ *p++ = 0;
+ t = XARGMATCH ("--standard-compress-program", arg,
+ compression_names, compression_types);
+ compression_program[t] = p;
+}
+
+
struct compression_suffix
{
const char *suffix;
size_t length;
- const char *program;
+ enum compression_type type;
};
-struct compression_suffix compression_suffixes[] = {
-#define S(s,p) #s, sizeof (#s) - 1, #p
+static struct compression_suffix compression_suffixes[] = {
+#define __tar_cat2__(a,b) a ## b
+#define S(s,p) #s, sizeof (#s) - 1, __tar_cat2__(compression_,p)
{ S(gz, gzip) },
{ S(tgz, gzip) },
{ S(taz, gzip) },
@@ -47,8 +102,8 @@ struct compression_suffix compression_suffixes[] = {
int nsuffixes = sizeof (compression_suffixes) /
sizeof (compression_suffixes[0]);
-static const char *
-find_compression_program (const char *name, const char *defprog)
+static enum compression_type
+archive_name_to_compression_type (const char *name)
{
char *suf = strrchr (name, '.');
@@ -64,16 +119,19 @@ find_compression_program (const char *name, const char
*defprog)
{
if (compression_suffixes[i].length == len
&& memcmp (compression_suffixes[i].suffix, suf, len) == 0)
- return compression_suffixes[i].program;
+ return compression_suffixes[i].type;
}
}
- return defprog;
+ return compression_none;
}
void
-set_comression_program_by_suffix (const char *name, const char *defprog)
+set_comression_program_by_suffix (const char *name, const char *defname)
{
- const char *program = find_compression_program (name, defprog);
+ enum compression_type type = archive_name_to_compression_type (name);
+ const char *program =
+ (type == compression_none) ? defname
+ : compression_to_program_name (type);
if (program)
use_compress_program_option = program;
}
diff --git a/src/tar.c b/src/tar.c
index a639974..8fb1509 100644
--- a/src/tar.c
+++ b/src/tar.c
@@ -326,6 +326,7 @@ enum
SHOW_OMITTED_DIRS_OPTION,
SHOW_TRANSFORMED_NAMES_OPTION,
SPARSE_VERSION_OPTION,
+ STANDARD_COMPRESS_PROGRAM_OPTION,
STRIP_COMPONENTS_OPTION,
SUFFIX_OPTION,
TEST_LABEL_OPTION,
@@ -629,6 +630,10 @@ static struct argp_option options[] = {
N_("filter the archive through lzop"), GRID+8 },
{"xz", 'J', 0, 0,
N_("filter the archive through xz"), GRID+8 },
+ {"standard-compress-program", STANDARD_COMPRESS_PROGRAM_OPTION,
+ N_("COMPR:PROGRAM"), 0,
+ N_("use PROGRAM when --COMPR option is given; COMPR is one of "
+ "compress, gzip, bzip2, lzma, lzop, or xz"), GRID+8 },
{"use-compress-program", 'I', N_("PROG"), 0,
N_("filter through PROG (must accept -d)"), GRID+1 },
#undef GRID
@@ -1588,6 +1593,10 @@ parse_opt (int key, char *arg, struct argp_state *state)
}
}
break;
+
+ case STANDARD_COMPRESS_PROGRAM_OPTION:
+ set_compression_program_name (arg);
+ break;
case 't':
set_subcommand_option (LIST_SUBCOMMAND);