* util.h: Rename compression types, add a type for uncompressed

files.
* util.c (is_gunzipable): Rename to ...
(get_compression_type): this.  Don't check archive length, since
it's unreliable if there is padding at the end of the file.
Eliminate prehistoric Linux workaround.  All callers adjusted.

* utilunix.c (close_error_pipe): Use "%s" in message () to
prevent possible crash.
(check_error_pipe): Likewise.
This commit is contained in:
Pavel Roskin 2002-07-02 21:09:25 +00:00
parent c8ef2d7ace
commit 3860ff7b34
4 changed files with 44 additions and 47 deletions

View File

@ -1,8 +1,17 @@
2002-07-02 Pavel Roskin <proski@gnu.org>
* util.h: Rename compression types, add a type for uncompressed
files.
* util.c (is_gunzipable): Rename to ...
(get_compression_type): this. Don't check archive length, since
it's unreliable if there is padding at the end of the file.
Eliminate prehistoric Linux workaround. All callers adjusted.
2002-07-01 Andrew V. Samoilov <kai@cmail.ru> 2002-07-01 Andrew V. Samoilov <kai@cmail.ru>
* utilunix.c (close_error_pipe): Use "%s" in message () to * utilunix.c (close_error_pipe): Use "%s" in message () to
prevent possible crash. prevent possible crash.
(check_error_pipe): Likewise. (check_error_pipe): Likewise.
2002-06-27 Pavel Roskin <proski@gnu.org> 2002-06-27 Pavel Roskin <proski@gnu.org>

View File

@ -855,30 +855,20 @@ get_small_endian_long (int fd)
return (buffer [3] << 24) | (buffer [2] << 16) | (buffer [1] << 8) | buffer [0]; return (buffer [3] << 24) | (buffer [2] << 16) | (buffer [1] << 8) | buffer [0];
} }
/* /* This function returns 0 if the file is not in not compressed by
* This constant makes the magic array on the stack be larger than * one of the supported compressors (gzip, bzip, bzip2). Otherwise,
* it needs because Linux when reading the second byte of /proc/locks * the compression type is returned, as defined in util.h
* for example will write 2 bytes, even if we only asked for one * Warning: this function moves the current file pointer */
*/ int get_compression_type (int fd)
#define LINUX_HAS_PROBLEMS_WHEN_READING_PROC_LOCKS_ON_SOME_KERNELS 40
/* This function returns 0 if the file is not in gunzip format */
/* or how much memory must be allocated to load the gziped file */
/* Warning: this function moves the current file pointer */
long int is_gunzipable (int fd, int *type)
{ {
unsigned char magic [4+LINUX_HAS_PROBLEMS_WHEN_READING_PROC_LOCKS_ON_SOME_KERNELS]; unsigned char magic [4];
*type = ISGUNZIPABLE_GUNZIP;
/* Read the magic signature */ /* Read the magic signature */
CHECK (mc_read (fd, &magic [0], 4)); CHECK (mc_read (fd, &magic [0], 4));
/* GZIP_MAGIC and OLD_GZIP_MAGIC */ /* GZIP_MAGIC and OLD_GZIP_MAGIC */
if (magic [0] == 037 && (magic [1] == 0213 || magic [1] == 0236)){ if (magic [0] == 037 && (magic [1] == 0213 || magic [1] == 0236)){
/* Read the uncompressed size of the file */ return COMPRESSION_GZIP;
mc_lseek (fd, -4, SEEK_END);
return get_small_endian_long (fd);
} }
/* PKZIP_MAGIC */ /* PKZIP_MAGIC */
@ -889,19 +879,16 @@ long int is_gunzipable (int fd, int *type)
/* Gzip can handle only deflated (8) or stored (0) files */ /* Gzip can handle only deflated (8) or stored (0) files */
if ((magic [0] != 8 && magic [0] != 0) || magic [1] != 0) if ((magic [0] != 8 && magic [0] != 0) || magic [1] != 0)
return 0; return COMPRESSION_NONE;
/* Read the uncompressed size of the first file in the archive */
mc_lseek (fd, 22, SEEK_SET); /* Compatible with gzip */
return get_small_endian_long (fd); return COMPRESSION_GZIP;
} }
/* PACK_MAGIC and LZH_MAGIC and compress magic */ /* PACK_MAGIC and LZH_MAGIC and compress magic */
if (magic [0] == 037 && (magic [1] == 036 || magic [1] == 0240 || magic [1] == 0235)){ if (magic [0] == 037 && (magic [1] == 036 || magic [1] == 0240 || magic [1] == 0235)){
/* In case the file is packed, sco lzhed or compress_magic, the */ /* Compatible with gzip */
/* program guesses that the uncompressed size is (at most) four */ return COMPRESSION_GZIP;
/* times the length of the compressed size, if the compression */
/* ratio is more than 4:1 the end of the file is not displayed */
return 4*mc_lseek (fd, 0, SEEK_END);
} }
/* BZIP and BZIP2 files */ /* BZIP and BZIP2 files */
@ -909,11 +896,9 @@ long int is_gunzipable (int fd, int *type)
(magic [3] >= '1') && (magic [3] <= '9')){ (magic [3] >= '1') && (magic [3] <= '9')){
switch (magic[2]) { switch (magic[2]) {
case '0': case '0':
*type = ISGUNZIPABLE_BZIP; return COMPRESSION_BZIP;
return 5*mc_lseek (fd, 0, SEEK_END);
case 'h': case 'h':
*type = ISGUNZIPABLE_BZIP2; return COMPRESSION_BZIP2;
return 5*mc_lseek (fd, 0, SEEK_END);
} }
} }
return 0; return 0;
@ -923,9 +908,9 @@ char *
decompress_extension (int type) decompress_extension (int type)
{ {
switch (type){ switch (type){
case ISGUNZIPABLE_GUNZIP: return "#ugz"; case COMPRESSION_GZIP: return "#ugz";
case ISGUNZIPABLE_BZIP: return "#ubz"; case COMPRESSION_BZIP: return "#ubz";
case ISGUNZIPABLE_BZIP2: return "#ubz2"; case COMPRESSION_BZIP2: return "#ubz2";
} }
/* Should never reach this place */ /* Should never reach this place */
fprintf (stderr, "Fatal: decompress_extension called with an unknown argument\n"); fprintf (stderr, "Fatal: decompress_extension called with an unknown argument\n");
@ -936,13 +921,13 @@ char *
decompress_command (int type) decompress_command (int type)
{ {
switch (type){ switch (type){
case ISGUNZIPABLE_GUNZIP: case COMPRESSION_GZIP:
return "gzip -cdf"; return "gzip -cdf";
case ISGUNZIPABLE_BZIP: case COMPRESSION_BZIP:
return "bzip -d"; return "bzip -d";
case ISGUNZIPABLE_BZIP2: case COMPRESSION_BZIP2:
return "bzip2 -d"; return "bzip2 -d";
} }
/* Should never reach this place */ /* Should never reach this place */
@ -954,18 +939,18 @@ void
decompress_command_and_arg (int type, char **cmd, char **flags) decompress_command_and_arg (int type, char **cmd, char **flags)
{ {
switch (type){ switch (type){
case ISGUNZIPABLE_GUNZIP: case COMPRESSION_GZIP:
*cmd = "gzip"; *cmd = "gzip";
*flags = "-cdf"; *flags = "-cdf";
return; return;
case ISGUNZIPABLE_BZIP: case COMPRESSION_BZIP:
*cmd = "bzip"; *cmd = "bzip";
*flags = "-d"; *flags = "-d";
return; return;
case ISGUNZIPABLE_BZIP2: case COMPRESSION_BZIP2:
*cmd = "bzip2"; *cmd = "bzip2";
*flags = "-d"; *flags = "-d";
return; return;

View File

@ -117,12 +117,13 @@ void init_tmpdir(void);
int mc_mkstemps(char **pname, const char *prefix, const char *suffix); int mc_mkstemps(char **pname, const char *prefix, const char *suffix);
enum { enum {
ISGUNZIPABLE_GUNZIP, COMPRESSION_NONE,
ISGUNZIPABLE_BZIP, COMPRESSION_GZIP,
ISGUNZIPABLE_BZIP2 COMPRESSION_BZIP,
COMPRESSION_BZIP2
}; };
long int is_gunzipable (int fd, int *type); int get_compression_type (int fd);
char *decompress_command (int type); char *decompress_command (int type);
char *decompress_extension (int type); char *decompress_extension (int type);
void decompress_command_and_arg (int type, char **cmd, char **flags); void decompress_command_and_arg (int type, char **cmd, char **flags);

View File

@ -579,7 +579,9 @@ do_view_init (WView *view, char *_command, const char *_file, int start_line)
goto finish; goto finish;
} }
if (view->viewer_magic_flag && (is_gunzipable (fd, &type)) != 0) { type = get_compression_type (fd);
if (view->viewer_magic_flag && (type != COMPRESSION_NONE)) {
g_free (view->filename); g_free (view->filename);
view->filename = g_strconcat (_file, decompress_extension(type), NULL); view->filename = g_strconcat (_file, decompress_extension(type), NULL);
} }