aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2012-03-06 16:23:50 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2012-03-06 16:23:50 +0100
commit59655077c5bf176f01d8d277665ebb92263704ed (patch)
tree0d4393ea09ebe90e35866d27041faf6372f6e87e
parent17eedcad9406c43beddab3906c8c693626c351fb (diff)
downloadbusybox-w32-59655077c5bf176f01d8d277665ebb92263704ed.tar.gz
busybox-w32-59655077c5bf176f01d8d277665ebb92263704ed.tar.bz2
busybox-w32-59655077c5bf176f01d8d277665ebb92263704ed.zip
preparatory cleanups for seamless uncompression improvements
unpack_gz_stream_with_info: fix buggy error check man: fix possible accesses past the end of a string move seamless uncompression helpers from read_printf.c to open_transformer.c function old new delta show_manpage 153 212 +59 unpack_gz_stream_with_info 520 539 +19 Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--archival/libarchive/decompress_uncompress.c12
-rw-r--r--archival/libarchive/decompress_unzip.c26
-rw-r--r--archival/libarchive/open_transformer.c140
-rw-r--r--include/libbb.h8
-rw-r--r--libbb/read_printf.c139
-rw-r--r--miscutils/man.c41
6 files changed, 187 insertions, 179 deletions
diff --git a/archival/libarchive/decompress_uncompress.c b/archival/libarchive/decompress_uncompress.c
index c6040d04b..289f9e233 100644
--- a/archival/libarchive/decompress_uncompress.c
+++ b/archival/libarchive/decompress_uncompress.c
@@ -73,7 +73,7 @@
73 */ 73 */
74 74
75IF_DESKTOP(long long) int FAST_FUNC 75IF_DESKTOP(long long) int FAST_FUNC
76unpack_Z_stream(int fd_in, int fd_out) 76unpack_Z_stream(int src_fd, int dst_fd)
77{ 77{
78 IF_DESKTOP(long long total_written = 0;) 78 IF_DESKTOP(long long total_written = 0;)
79 IF_DESKTOP(long long) int retval = -1; 79 IF_DESKTOP(long long) int retval = -1;
@@ -105,14 +105,14 @@ unpack_Z_stream(int fd_in, int fd_out)
105 105
106 inbuf = xzalloc(IBUFSIZ + 64); 106 inbuf = xzalloc(IBUFSIZ + 64);
107 outbuf = xzalloc(OBUFSIZ + 2048); 107 outbuf = xzalloc(OBUFSIZ + 2048);
108 htab = xzalloc(HSIZE); /* wsn't zeroed out before, maybe can xmalloc? */ 108 htab = xzalloc(HSIZE); /* wasn't zeroed out before, maybe can xmalloc? */
109 codetab = xzalloc(HSIZE * sizeof(codetab[0])); 109 codetab = xzalloc(HSIZE * sizeof(codetab[0]));
110 110
111 insize = 0; 111 insize = 0;
112 112
113 /* xread isn't good here, we have to return - caller may want 113 /* xread isn't good here, we have to return - caller may want
114 * to do some cleanup (e.g. delete incomplete unpacked file etc) */ 114 * to do some cleanup (e.g. delete incomplete unpacked file etc) */
115 if (full_read(fd_in, inbuf, 1) != 1) { 115 if (full_read(src_fd, inbuf, 1) != 1) {
116 bb_error_msg("short read"); 116 bb_error_msg("short read");
117 goto err; 117 goto err;
118 } 118 }
@@ -162,7 +162,7 @@ unpack_Z_stream(int fd_in, int fd_out)
162 } 162 }
163 163
164 if (insize < (int) (IBUFSIZ + 64) - IBUFSIZ) { 164 if (insize < (int) (IBUFSIZ + 64) - IBUFSIZ) {
165 rsize = safe_read(fd_in, inbuf + insize, IBUFSIZ); 165 rsize = safe_read(src_fd, inbuf + insize, IBUFSIZ);
166 if (rsize < 0) 166 if (rsize < 0)
167 bb_error_msg_and_die(bb_msg_read_error); 167 bb_error_msg_and_die(bb_msg_read_error);
168 insize += rsize; 168 insize += rsize;
@@ -268,7 +268,7 @@ unpack_Z_stream(int fd_in, int fd_out)
268 } 268 }
269 269
270 if (outpos >= OBUFSIZ) { 270 if (outpos >= OBUFSIZ) {
271 xwrite(fd_out, outbuf, outpos); 271 xwrite(dst_fd, outbuf, outpos);
272 IF_DESKTOP(total_written += outpos;) 272 IF_DESKTOP(total_written += outpos;)
273 outpos = 0; 273 outpos = 0;
274 } 274 }
@@ -296,7 +296,7 @@ unpack_Z_stream(int fd_in, int fd_out)
296 } while (rsize > 0); 296 } while (rsize > 0);
297 297
298 if (outpos > 0) { 298 if (outpos > 0) {
299 xwrite(fd_out, outbuf, outpos); 299 xwrite(dst_fd, outbuf, outpos);
300 IF_DESKTOP(total_written += outpos;) 300 IF_DESKTOP(total_written += outpos;)
301 } 301 }
302 302
diff --git a/archival/libarchive/decompress_unzip.c b/archival/libarchive/decompress_unzip.c
index aa5d22d0a..50873e3f6 100644
--- a/archival/libarchive/decompress_unzip.c
+++ b/archival/libarchive/decompress_unzip.c
@@ -1182,33 +1182,37 @@ static int check_header_gzip(STATE_PARAM unpack_info_t *info)
1182} 1182}
1183 1183
1184IF_DESKTOP(long long) int FAST_FUNC 1184IF_DESKTOP(long long) int FAST_FUNC
1185unpack_gz_stream_with_info(int in, int out, unpack_info_t *info) 1185unpack_gz_stream_with_info(int src_fd, int dst_fd, unpack_info_t *info)
1186{ 1186{
1187 uint32_t v32; 1187 uint32_t v32;
1188 IF_DESKTOP(long long) int n; 1188 IF_DESKTOP(long long) int total, n;
1189 DECLARE_STATE; 1189 DECLARE_STATE;
1190 1190
1191 n = 0; 1191 total = 0;
1192 1192
1193 ALLOC_STATE; 1193 ALLOC_STATE;
1194 to_read = -1; 1194 to_read = -1;
1195// bytebuffer_max = 0x8000; 1195// bytebuffer_max = 0x8000;
1196 bytebuffer = xmalloc(bytebuffer_max); 1196 bytebuffer = xmalloc(bytebuffer_max);
1197 gunzip_src_fd = in; 1197 gunzip_src_fd = src_fd;
1198 1198
1199 again: 1199 again:
1200 if (!check_header_gzip(PASS_STATE info)) { 1200 if (!check_header_gzip(PASS_STATE info)) {
1201 bb_error_msg("corrupted data"); 1201 bb_error_msg("corrupted data");
1202 n = -1; 1202 total = -1;
1203 goto ret; 1203 goto ret;
1204 } 1204 }
1205 n += inflate_unzip_internal(PASS_STATE in, out); 1205
1206 if (n < 0) 1206 n = inflate_unzip_internal(PASS_STATE src_fd, dst_fd);
1207 if (n < 0) {
1208 total = -1;
1207 goto ret; 1209 goto ret;
1210 }
1211 total += n;
1208 1212
1209 if (!top_up(PASS_STATE 8)) { 1213 if (!top_up(PASS_STATE 8)) {
1210 bb_error_msg("corrupted data"); 1214 bb_error_msg("corrupted data");
1211 n = -1; 1215 total = -1;
1212 goto ret; 1216 goto ret;
1213 } 1217 }
1214 1218
@@ -1216,7 +1220,7 @@ unpack_gz_stream_with_info(int in, int out, unpack_info_t *info)
1216 v32 = buffer_read_le_u32(PASS_STATE_ONLY); 1220 v32 = buffer_read_le_u32(PASS_STATE_ONLY);
1217 if ((~gunzip_crc) != v32) { 1221 if ((~gunzip_crc) != v32) {
1218 bb_error_msg("crc error"); 1222 bb_error_msg("crc error");
1219 n = -1; 1223 total = -1;
1220 goto ret; 1224 goto ret;
1221 } 1225 }
1222 1226
@@ -1224,7 +1228,7 @@ unpack_gz_stream_with_info(int in, int out, unpack_info_t *info)
1224 v32 = buffer_read_le_u32(PASS_STATE_ONLY); 1228 v32 = buffer_read_le_u32(PASS_STATE_ONLY);
1225 if ((uint32_t)gunzip_bytes_out != v32) { 1229 if ((uint32_t)gunzip_bytes_out != v32) {
1226 bb_error_msg("incorrect length"); 1230 bb_error_msg("incorrect length");
1227 n = -1; 1231 total = -1;
1228 } 1232 }
1229 1233
1230 if (!top_up(PASS_STATE 2)) 1234 if (!top_up(PASS_STATE 2))
@@ -1242,7 +1246,7 @@ unpack_gz_stream_with_info(int in, int out, unpack_info_t *info)
1242 ret: 1246 ret:
1243 free(bytebuffer); 1247 free(bytebuffer);
1244 DEALLOC_STATE; 1248 DEALLOC_STATE;
1245 return n; 1249 return total;
1246} 1250}
1247 1251
1248IF_DESKTOP(long long) int FAST_FUNC 1252IF_DESKTOP(long long) int FAST_FUNC
diff --git a/archival/libarchive/open_transformer.c b/archival/libarchive/open_transformer.c
index aa8c1021c..743ffee02 100644
--- a/archival/libarchive/open_transformer.c
+++ b/archival/libarchive/open_transformer.c
@@ -6,6 +6,16 @@
6#include "libbb.h" 6#include "libbb.h"
7#include "bb_archive.h" 7#include "bb_archive.h"
8 8
9#define ZIPPED (ENABLE_FEATURE_SEAMLESS_LZMA \
10 || ENABLE_FEATURE_SEAMLESS_BZ2 \
11 || ENABLE_FEATURE_SEAMLESS_GZ \
12 /* || ENABLE_FEATURE_SEAMLESS_Z */ \
13)
14
15#if ZIPPED
16# include "bb_archive.h"
17#endif
18
9/* transformer(), more than meets the eye */ 19/* transformer(), more than meets the eye */
10/* 20/*
11 * On MMU machine, the transform_prog is removed by macro magic 21 * On MMU machine, the transform_prog is removed by macro magic
@@ -52,3 +62,133 @@ void FAST_FUNC open_transformer(int fd,
52 close(fd_pipe.wr); /* don't want to write to the child */ 62 close(fd_pipe.wr); /* don't want to write to the child */
53 xmove_fd(fd_pipe.rd, fd); 63 xmove_fd(fd_pipe.rd, fd);
54} 64}
65
66
67/* Used by e.g. rpm which gives us a fd without filename,
68 * thus we can't guess the format from filename's extension.
69 */
70#if ZIPPED
71void FAST_FUNC setup_unzip_on_fd(int fd /*, int fail_if_not_detected*/)
72{
73 const int fail_if_not_detected = 1;
74 union {
75 uint8_t b[4];
76 uint16_t b16[2];
77 uint32_t b32[1];
78 } magic;
79 int offset = -2;
80# if BB_MMU
81 IF_DESKTOP(long long) int FAST_FUNC (*xformer)(int src_fd, int dst_fd);
82 enum { xformer_prog = 0 };
83# else
84 enum { xformer = 0 };
85 const char *xformer_prog;
86# endif
87
88 /* .gz and .bz2 both have 2-byte signature, and their
89 * unpack_XXX_stream wants this header skipped. */
90 xread(fd, magic.b16, sizeof(magic.b16[0]));
91 if (ENABLE_FEATURE_SEAMLESS_GZ
92 && magic.b16[0] == GZIP_MAGIC
93 ) {
94# if BB_MMU
95 xformer = unpack_gz_stream;
96# else
97 xformer_prog = "gunzip";
98# endif
99 goto found_magic;
100 }
101 if (ENABLE_FEATURE_SEAMLESS_BZ2
102 && magic.b16[0] == BZIP2_MAGIC
103 ) {
104# if BB_MMU
105 xformer = unpack_bz2_stream;
106# else
107 xformer_prog = "bunzip2";
108# endif
109 goto found_magic;
110 }
111 if (ENABLE_FEATURE_SEAMLESS_XZ
112 && magic.b16[0] == XZ_MAGIC1
113 ) {
114 offset = -6;
115 xread(fd, magic.b32, sizeof(magic.b32[0]));
116 if (magic.b32[0] == XZ_MAGIC2) {
117# if BB_MMU
118 xformer = unpack_xz_stream;
119 /* unpack_xz_stream wants fd at position 6, no need to seek */
120 //xlseek(fd, offset, SEEK_CUR);
121# else
122 xformer_prog = "unxz";
123# endif
124 goto found_magic;
125 }
126 }
127
128 /* No known magic seen */
129 if (fail_if_not_detected)
130 bb_error_msg_and_die("no gzip"
131 IF_FEATURE_SEAMLESS_BZ2("/bzip2")
132 IF_FEATURE_SEAMLESS_XZ("/xz")
133 " magic");
134 xlseek(fd, offset, SEEK_CUR);
135 return;
136
137 found_magic:
138# if !BB_MMU
139 /* NOMMU version of open_transformer execs
140 * an external unzipper that wants
141 * file position at the start of the file */
142 xlseek(fd, offset, SEEK_CUR);
143# endif
144 open_transformer(fd, xformer, xformer_prog);
145}
146#endif /* ZIPPED */
147
148int FAST_FUNC open_zipped(const char *fname)
149{
150#if !ZIPPED
151 return open(fname, O_RDONLY);
152#else
153 char *sfx;
154 int fd;
155
156 fd = open(fname, O_RDONLY);
157 if (fd < 0)
158 return fd;
159
160 sfx = strrchr(fname, '.');
161 if (sfx) {
162 sfx++;
163 if (ENABLE_FEATURE_SEAMLESS_LZMA && strcmp(sfx, "lzma") == 0)
164 /* .lzma has no header/signature, just trust it */
165 open_transformer(fd, unpack_lzma_stream, "unlzma");
166 else
167 if ((ENABLE_FEATURE_SEAMLESS_GZ && strcmp(sfx, "gz") == 0)
168 || (ENABLE_FEATURE_SEAMLESS_BZ2 && strcmp(sfx, "bz2") == 0)
169 || (ENABLE_FEATURE_SEAMLESS_XZ && strcmp(sfx, "xz") == 0)
170 ) {
171 setup_unzip_on_fd(fd /*, fail_if_not_detected: 1*/);
172 }
173 }
174
175 return fd;
176#endif
177}
178
179void* FAST_FUNC xmalloc_open_zipped_read_close(const char *fname, size_t *maxsz_p)
180{
181 int fd;
182 char *image;
183
184 fd = open_zipped(fname);
185 if (fd < 0)
186 return NULL;
187
188 image = xmalloc_read(fd, maxsz_p);
189 if (!image)
190 bb_perror_msg("read error from '%s'", fname);
191 close(fd);
192
193 return image;
194}
diff --git a/include/libbb.h b/include/libbb.h
index f743bdfc6..c896e5484 100644
--- a/include/libbb.h
+++ b/include/libbb.h
@@ -713,6 +713,14 @@ extern void *xmalloc_read(int fd, size_t *maxsz_p) FAST_FUNC RETURNS_MALLOC;
713extern void *xmalloc_open_read_close(const char *filename, size_t *maxsz_p) FAST_FUNC RETURNS_MALLOC; 713extern void *xmalloc_open_read_close(const char *filename, size_t *maxsz_p) FAST_FUNC RETURNS_MALLOC;
714/* Never returns NULL */ 714/* Never returns NULL */
715extern void *xmalloc_xopen_read_close(const char *filename, size_t *maxsz_p) FAST_FUNC RETURNS_MALLOC; 715extern void *xmalloc_xopen_read_close(const char *filename, size_t *maxsz_p) FAST_FUNC RETURNS_MALLOC;
716
717#define SEAMLESS_COMPRESSION (0 \
718 || ENABLE_FEATURE_SEAMLESS_XZ \
719 || ENABLE_FEATURE_SEAMLESS_LZMA \
720 || ENABLE_FEATURE_SEAMLESS_BZ2 \
721 || ENABLE_FEATURE_SEAMLESS_GZ \
722 || ENABLE_FEATURE_SEAMLESS_Z)
723
716/* Autodetects gzip/bzip2 formats. fd may be in the middle of the file! */ 724/* Autodetects gzip/bzip2 formats. fd may be in the middle of the file! */
717#if ENABLE_FEATURE_SEAMLESS_LZMA \ 725#if ENABLE_FEATURE_SEAMLESS_LZMA \
718 || ENABLE_FEATURE_SEAMLESS_BZ2 \ 726 || ENABLE_FEATURE_SEAMLESS_BZ2 \
diff --git a/libbb/read_printf.c b/libbb/read_printf.c
index 0bbf7802a..5ed6e3632 100644
--- a/libbb/read_printf.c
+++ b/libbb/read_printf.c
@@ -8,16 +8,6 @@
8 */ 8 */
9#include "libbb.h" 9#include "libbb.h"
10 10
11#define ZIPPED (ENABLE_FEATURE_SEAMLESS_LZMA \
12 || ENABLE_FEATURE_SEAMLESS_BZ2 \
13 || ENABLE_FEATURE_SEAMLESS_GZ \
14 /* || ENABLE_FEATURE_SEAMLESS_Z */ \
15)
16
17#if ZIPPED
18# include "bb_archive.h"
19#endif
20
21 11
22/* Suppose that you are a shell. You start child processes. 12/* Suppose that you are a shell. You start child processes.
23 * They work and eventually exit. You want to get user input. 13 * They work and eventually exit. You want to get user input.
@@ -244,132 +234,3 @@ void* FAST_FUNC xmalloc_xopen_read_close(const char *filename, size_t *maxsz_p)
244 bb_perror_msg_and_die("can't read '%s'", filename); 234 bb_perror_msg_and_die("can't read '%s'", filename);
245 return buf; 235 return buf;
246} 236}
247
248/* Used by e.g. rpm which gives us a fd without filename,
249 * thus we can't guess the format from filename's extension.
250 */
251#if ZIPPED
252void FAST_FUNC setup_unzip_on_fd(int fd /*, int fail_if_not_detected*/)
253{
254 const int fail_if_not_detected = 1;
255 union {
256 uint8_t b[4];
257 uint16_t b16[2];
258 uint32_t b32[1];
259 } magic;
260 int offset = -2;
261# if BB_MMU
262 IF_DESKTOP(long long) int FAST_FUNC (*xformer)(int src_fd, int dst_fd);
263 enum { xformer_prog = 0 };
264# else
265 enum { xformer = 0 };
266 const char *xformer_prog;
267# endif
268
269 /* .gz and .bz2 both have 2-byte signature, and their
270 * unpack_XXX_stream wants this header skipped. */
271 xread(fd, magic.b16, sizeof(magic.b16[0]));
272 if (ENABLE_FEATURE_SEAMLESS_GZ
273 && magic.b16[0] == GZIP_MAGIC
274 ) {
275# if BB_MMU
276 xformer = unpack_gz_stream;
277# else
278 xformer_prog = "gunzip";
279# endif
280 goto found_magic;
281 }
282 if (ENABLE_FEATURE_SEAMLESS_BZ2
283 && magic.b16[0] == BZIP2_MAGIC
284 ) {
285# if BB_MMU
286 xformer = unpack_bz2_stream;
287# else
288 xformer_prog = "bunzip2";
289# endif
290 goto found_magic;
291 }
292 if (ENABLE_FEATURE_SEAMLESS_XZ
293 && magic.b16[0] == XZ_MAGIC1
294 ) {
295 offset = -6;
296 xread(fd, magic.b32, sizeof(magic.b32[0]));
297 if (magic.b32[0] == XZ_MAGIC2) {
298# if BB_MMU
299 xformer = unpack_xz_stream;
300 /* unpack_xz_stream wants fd at position 6, no need to seek */
301 //xlseek(fd, offset, SEEK_CUR);
302# else
303 xformer_prog = "unxz";
304# endif
305 goto found_magic;
306 }
307 }
308
309 /* No known magic seen */
310 if (fail_if_not_detected)
311 bb_error_msg_and_die("no gzip"
312 IF_FEATURE_SEAMLESS_BZ2("/bzip2")
313 IF_FEATURE_SEAMLESS_XZ("/xz")
314 " magic");
315 xlseek(fd, offset, SEEK_CUR);
316 return;
317
318 found_magic:
319# if !BB_MMU
320 /* NOMMU version of open_transformer execs
321 * an external unzipper that wants
322 * file position at the start of the file */
323 xlseek(fd, offset, SEEK_CUR);
324# endif
325 open_transformer(fd, xformer, xformer_prog);
326}
327#endif /* ZIPPED */
328
329int FAST_FUNC open_zipped(const char *fname)
330{
331#if !ZIPPED
332 return open(fname, O_RDONLY);
333#else
334 char *sfx;
335 int fd;
336
337 fd = open(fname, O_RDONLY);
338 if (fd < 0)
339 return fd;
340
341 sfx = strrchr(fname, '.');
342 if (sfx) {
343 sfx++;
344 if (ENABLE_FEATURE_SEAMLESS_LZMA && strcmp(sfx, "lzma") == 0)
345 /* .lzma has no header/signature, just trust it */
346 open_transformer(fd, unpack_lzma_stream, "unlzma");
347 else
348 if ((ENABLE_FEATURE_SEAMLESS_GZ && strcmp(sfx, "gz") == 0)
349 || (ENABLE_FEATURE_SEAMLESS_BZ2 && strcmp(sfx, "bz2") == 0)
350 || (ENABLE_FEATURE_SEAMLESS_XZ && strcmp(sfx, "xz") == 0)
351 ) {
352 setup_unzip_on_fd(fd /*, fail_if_not_detected: 1*/);
353 }
354 }
355
356 return fd;
357#endif
358}
359
360void* FAST_FUNC xmalloc_open_zipped_read_close(const char *fname, size_t *maxsz_p)
361{
362 int fd;
363 char *image;
364
365 fd = open_zipped(fname);
366 if (fd < 0)
367 return NULL;
368
369 image = xmalloc_read(fd, maxsz_p);
370 if (!image)
371 bb_perror_msg("read error from '%s'", fname);
372 close(fd);
373
374 return image;
375}
diff --git a/miscutils/man.c b/miscutils/man.c
index 3bf7e84b6..611466349 100644
--- a/miscutils/man.c
+++ b/miscutils/man.c
@@ -30,16 +30,6 @@ echo ".pl \n(nlu+10"
30 30
31*/ 31*/
32 32
33#if ENABLE_FEATURE_SEAMLESS_LZMA
34#define Z_SUFFIX ".lzma"
35#elif ENABLE_FEATURE_SEAMLESS_BZ2
36#define Z_SUFFIX ".bz2"
37#elif ENABLE_FEATURE_SEAMLESS_GZ
38#define Z_SUFFIX ".gz"
39#else
40#define Z_SUFFIX ""
41#endif
42
43static int show_manpage(const char *pager, char *man_filename, int man, int level); 33static int show_manpage(const char *pager, char *man_filename, int man, int level);
44 34
45static int run_pipe(const char *pager, char *man_filename, int man, int level) 35static int run_pipe(const char *pager, char *man_filename, int man, int level)
@@ -102,7 +92,7 @@ static int run_pipe(const char *pager, char *man_filename, int man, int level)
102 92
103 /* Links do not have .gz extensions, even if manpage 93 /* Links do not have .gz extensions, even if manpage
104 * is compressed */ 94 * is compressed */
105 man_filename = xasprintf("%s/%s" Z_SUFFIX, man_filename, linkname); 95 man_filename = xasprintf("%s/%s", man_filename, linkname);
106 free(line); 96 free(line);
107 /* Note: we leak "new" man_filename string as well... */ 97 /* Note: we leak "new" man_filename string as well... */
108 if (show_manpage(pager, man_filename, man, level + 1)) 98 if (show_manpage(pager, man_filename, man, level + 1))
@@ -124,32 +114,37 @@ static int run_pipe(const char *pager, char *man_filename, int man, int level)
124 return 1; 114 return 1;
125} 115}
126 116
127/* man_filename is of the form "/dir/dir/dir/name.s" Z_SUFFIX */ 117/* man_filename is of the form "/dir/dir/dir/name.s" */
128static int show_manpage(const char *pager, char *man_filename, int man, int level) 118static int show_manpage(const char *pager, char *man_filename, int man, int level)
129{ 119{
120#if SEAMLESS_COMPRESSION
121 /* We leak this allocation... */
122 char *filename_with_zext = xasprintf("%s.lzma", man_filename);
123 char *ext = strrchr(filename_with_zext, '.') + 1;
124#endif
125
130#if ENABLE_FEATURE_SEAMLESS_LZMA 126#if ENABLE_FEATURE_SEAMLESS_LZMA
127 if (run_pipe(pager, filename_with_zext, man, level))
128 return 1;
129#endif
130#if ENABLE_FEATURE_SEAMLESS_XZ
131 strcpy(ext, "xz");
131 if (run_pipe(pager, man_filename, man, level)) 132 if (run_pipe(pager, man_filename, man, level))
132 return 1; 133 return 1;
133#endif 134#endif
134
135#if ENABLE_FEATURE_SEAMLESS_BZ2 135#if ENABLE_FEATURE_SEAMLESS_BZ2
136#if ENABLE_FEATURE_SEAMLESS_LZMA 136 strcpy(ext, "bz2");
137 strcpy(strrchr(man_filename, '.') + 1, "bz2");
138#endif
139 if (run_pipe(pager, man_filename, man, level)) 137 if (run_pipe(pager, man_filename, man, level))
140 return 1; 138 return 1;
141#endif 139#endif
142
143#if ENABLE_FEATURE_SEAMLESS_GZ 140#if ENABLE_FEATURE_SEAMLESS_GZ
144#if ENABLE_FEATURE_SEAMLESS_LZMA || ENABLE_FEATURE_SEAMLESS_BZ2 141 strcpy(ext, "gz");
145 strcpy(strrchr(man_filename, '.') + 1, "gz");
146#endif
147 if (run_pipe(pager, man_filename, man, level)) 142 if (run_pipe(pager, man_filename, man, level))
148 return 1; 143 return 1;
149#endif 144#endif
150 145
151#if ENABLE_FEATURE_SEAMLESS_LZMA || ENABLE_FEATURE_SEAMLESS_BZ2 || ENABLE_FEATURE_SEAMLESS_GZ 146#if SEAMLESS_COMPRESSION
152 *strrchr(man_filename, '.') = '\0'; 147 ext[-1] = '\0';
153#endif 148#endif
154 if (run_pipe(pager, man_filename, man, level)) 149 if (run_pipe(pager, man_filename, man, level))
155 return 1; 150 return 1;
@@ -262,7 +257,7 @@ int man_main(int argc UNUSED_PARAM, char **argv)
262 /* Search for cat, then man page */ 257 /* Search for cat, then man page */
263 while (cat0man1 < 2) { 258 while (cat0man1 < 2) {
264 int found_here; 259 int found_here;
265 man_filename = xasprintf("%s/%s%.*s/%s.%.*s" Z_SUFFIX, 260 man_filename = xasprintf("%s/%s%.*s/%s.%.*s",
266 cur_path, 261 cur_path,
267 "cat\0man" + (cat0man1 * 4), 262 "cat\0man" + (cat0man1 * 4),
268 sect_len, cur_sect, 263 sect_len, cur_sect,