Recognize suffixes .z (gzip) and .tzo (lzop)
[tar.git] / src / suffix.c
blob6128ec0ba399f98b877d6af279db3bb0f9b23b56
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
9 version.
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/>. */
19 #include <system.h>
20 #include "common.h"
22 struct compression_suffix
24 const char *suffix;
25 size_t length;
26 const char *program;
29 static struct compression_suffix compression_suffixes[] = {
30 #define __CAT2__(a,b) a ## b
31 #define S(s,p) #s, sizeof (#s) - 1, __CAT2__(p,_PROGRAM)
32 { "tar", 3, NULL },
33 { S(gz, GZIP) },
34 { S(z, GZIP) },
35 { S(tgz, GZIP) },
36 { S(taz, GZIP) },
37 { S(Z, COMPRESS) },
38 { S(taZ, COMPRESS) },
39 { S(bz2, BZIP2) },
40 { S(tbz, BZIP2) },
41 { S(tbz2, BZIP2) },
42 { S(tz2, BZIP2) },
43 { S(lz, LZIP) },
44 { S(lzma, LZMA) },
45 { S(tlz, LZMA) },
46 { S(lzo, LZOP) },
47 { S(tzo, LZOP) },
48 { S(xz, XZ) },
49 { S(txz, XZ) }, /* Slackware */
50 { S(zst, ZSTD) },
51 { S(tzst, ZSTD) },
52 { NULL }
53 #undef S
54 #undef __CAT2__
57 /* Extract the suffix from archive file NAME, and return a pointer to
58 compression_suffix associated with it or NULL if none is found.
59 No matter what is the return value, if RET_LEN is not NULL, store
60 there the length of NAME with that suffix stripped, or 0 if NAME has
61 no suffix. */
62 static struct compression_suffix const *
63 find_compression_suffix (const char *name, size_t *ret_len)
65 char *suf = strrchr (name, '.');
67 if (suf && suf[1] != 0 && suf[1] != '/')
69 size_t len;
70 struct compression_suffix *p;
72 suf++;
73 len = strlen (suf);
74 if (ret_len)
75 *ret_len = strlen (name) - len - 1;
77 for (p = compression_suffixes; p->suffix; p++)
79 if (p->length == len && memcmp (p->suffix, suf, len) == 0)
81 return p;
85 else if (ret_len)
86 *ret_len = 0;
87 return NULL;
90 /* Select compression program using the suffix of the archive file NAME.
91 Use DEFPROG, if there is no suffix, or if no program is associated with
92 the suffix. In the latter case, if VERBOSE is true, issue a warning.
94 void
95 set_compression_program_by_suffix (const char *name, const char *defprog,
96 bool verbose)
98 size_t len;
99 struct compression_suffix const *p = find_compression_suffix (name, &len);
100 if (p)
101 use_compress_program_option = p->program;
102 else
104 use_compress_program_option = defprog;
105 if (len > 0 && verbose)
106 WARN ((0, 0,
107 _("no compression program is defined for suffix '%s';"
108 " assuming %s"),
109 name + len,
110 defprog ? defprog : "uncompressed archive"));
114 char *
115 strip_compression_suffix (const char *name)
117 char *s = NULL;
118 size_t len;
119 struct compression_suffix const *p = find_compression_suffix (name, &len);
121 if (p)
123 /* Strip an additional ".tar" suffix, but only if the just-stripped
124 "outer" suffix did not begin with "t". */
125 if (len > 4 && strncmp (name + len - 4, ".tar", 4) == 0
126 && p->suffix[0] != 't')
127 len -= 4;
128 if (len == 0)
129 return NULL;
130 s = xmalloc (len + 1);
131 memcpy (s, name, len);
132 s[len] = 0;
134 return s;