1 /* This file is part of GNU tar.
2 Copyright 2007-2024 Free Software Foundation, Inc.
4 Written by Sergey Poznyakoff.
6 GNU tar is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 3, or (at your option) any later
11 GNU tar is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
14 Public License for more details.
16 You should have received a copy of the GNU General Public License along
17 with GNU tar. If not, see <http://www.gnu.org/licenses/>. */
22 struct compression_suffix
24 char suffix
[sizeof "tbz2"]; /* "tbz2" is tied for longest. */
25 char program
[max (max (max (sizeof GZIP_PROGRAM
, sizeof COMPRESS_PROGRAM
),
26 max (sizeof BZIP2_PROGRAM
, sizeof LZIP_PROGRAM
)),
27 max (max (sizeof LZMA_PROGRAM
, sizeof LZOP_PROGRAM
),
28 max (sizeof XZ_PROGRAM
, sizeof ZSTD_PROGRAM
)))];
31 static struct compression_suffix
const compression_suffixes
[] = {
32 #define __CAT2__(a,b) a ## b
33 #define S(s, p) #s, __CAT2__(p,_PROGRAM)
51 { S(txz
, XZ
) }, /* Slackware */
58 /* Extract the suffix from archive file NAME, and return a pointer to
59 compression_suffix associated with it or NULL if none is found.
60 No matter what is the return value, if RET_LEN is not NULL, store
61 there the length of NAME with that suffix stripped, or 0 if NAME has
63 static struct compression_suffix
const *
64 find_compression_suffix (char const *name
, idx_t
*ret_len
)
66 char const *suf
= strrchr (name
, '.');
68 if (suf
&& suf
[1] != 0 && suf
[1] != '/')
71 *ret_len
= suf
- name
;
74 for (struct compression_suffix
const *p
= compression_suffixes
;
75 p
< (compression_suffixes
76 + sizeof compression_suffixes
/ sizeof *compression_suffixes
);
78 if (strcmp (p
->suffix
, suf
) == 0)
86 /* Select compression program using the suffix of the archive file NAME.
87 Use DEFPROG, if there is no suffix, or if no program is associated with
88 the suffix. In the latter case, if VERBOSE is true, issue a warning.
91 set_compression_program_by_suffix (const char *name
, const char *defprog
,
95 struct compression_suffix
const *p
= find_compression_suffix (name
, &len
);
97 use_compress_program_option
= p
->program
[0] ? p
->program
: NULL
;
100 use_compress_program_option
= defprog
;
101 if (len
> 0 && verbose
)
103 _("no compression program is defined for suffix '%s';"
106 defprog
? defprog
: "uncompressed archive");
111 strip_compression_suffix (const char *name
)
115 struct compression_suffix
const *p
= find_compression_suffix (name
, &len
);
119 /* Strip an additional ".tar" suffix, but only if the just-stripped
120 "outer" suffix did not begin with "t". */
121 if (len
> 4 && strncmp (name
+ len
- 4, ".tar", 4) == 0
122 && p
->suffix
[0] != 't')
126 s
= xmalloc (len
+ 1);
127 memcpy (s
, name
, len
);