262 lines
6.7 KiB
Plaintext
262 lines
6.7 KiB
Plaintext
---
|
|
config.h.in | 3 +
|
|
configure.ac | 52 +++++++++++++++++++++++++++++++++
|
|
src/decompress.c | 86 +++++++++++++++++++++++++++++++++++++++++++++++++++++--
|
|
3 files changed, 138 insertions(+), 3 deletions(-)
|
|
|
|
--- config.h.in
|
|
+++ config.h.in 2024-11-11 10:43:01.369880933 +0000
|
|
@@ -1148,6 +1148,9 @@
|
|
/* Define to 1 if you have the `z' library (-lz). */
|
|
#undef HAVE_LIBZ
|
|
|
|
+/* Define to 1 if you have libzio for opening compressed manuals */
|
|
+#undef HAVE_ZIO
|
|
+
|
|
/* Define to 1 if the bcrypt library is guaranteed to be present. */
|
|
#undef HAVE_LIB_BCRYPT
|
|
|
|
--- configure.ac
|
|
+++ configure.ac 2024-11-11 10:43:01.369880933 +0000
|
|
@@ -35,6 +35,18 @@ MAN_ARG_DEVICE
|
|
MAN_ARG_DB
|
|
MAN_ARG_CONFIG_FILE
|
|
MAN_ARG_SECTIONS
|
|
+AC_ARG_WITH([zio],
|
|
+[AS_HELP_STRING([--with-zio=LIBRARY], [use zlib/libbz2 wrapper library LIBRARY (libzio)])],
|
|
+ [if test -z "$withval" -o "$withval" = "yes"
|
|
+ then
|
|
+ zio=libzio
|
|
+ elif test "$withval" = "no"
|
|
+ then
|
|
+ AC_MSG_ERROR(--with-zio requires an argument)
|
|
+ else
|
|
+ zio=$withval
|
|
+ fi],
|
|
+ [: ${zio=no}])
|
|
MAN_ARG_AUTOMATIC_CREATE
|
|
MAN_ARG_AUTOMATIC_UPDATE
|
|
MAN_ARG_CATS
|
|
@@ -374,6 +386,46 @@ AC_DEFINE_UNQUOTED([PROG_UNXZ], ["$unxz"
|
|
AC_DEFINE_UNQUOTED([PROG_UNLZIP], ["$unlzip"], [Program to use as unlzip.])
|
|
AC_DEFINE_UNQUOTED([PROG_UNZSTD], ["$unzstd"], [Program to use as unzstd.])
|
|
MAN_COMPRESS_LIB([z], [gzopen])
|
|
+dnl Check for zlib and libbz2 libraries to use this together
|
|
+dnl with SUSE's libzio to open compressed info files.
|
|
+dnl
|
|
+if test "$zio" = "no" || test -n "$zio"
|
|
+then
|
|
+ AC_CHECK_HEADER(zio.h,[
|
|
+ for lib in ${zio#lib} zio
|
|
+ do
|
|
+ AC_CHECK_LIB($lib, fzopen, [LIBS="-l$lib $LIBS"; am_cv_libzio=yes])
|
|
+ done
|
|
+ ])
|
|
+ if test "$am_cv_libzio" = yes; then
|
|
+ AC_DEFINE([COMP_SRC],[],[Define if you have compressors and want to support compressed cat files.])
|
|
+ AC_DEFINE([HAVE_ZIO],[],[Define to 1 if you have libzio for opening compressed manuals])
|
|
+ AC_CHECK_HEADER(zlib.h,[
|
|
+ for lib in z gz
|
|
+ do
|
|
+ AC_CHECK_LIB($lib, gzopen, [LIBS="$LIBS -Wl,--no-as-needed -l$lib"; break])
|
|
+ done
|
|
+ ])
|
|
+ AC_CHECK_HEADER(bzlib.h,[
|
|
+ for lib in bz2 bzip2
|
|
+ do
|
|
+ AC_CHECK_LIB($lib, BZ2_bzopen, [LIBS="$LIBS -Wl,--no-as-needed -l$lib"; break])
|
|
+ done
|
|
+ ])
|
|
+ AC_CHECK_HEADER(lzmadec.h, [
|
|
+ for lib in lzma lzmadec
|
|
+ do
|
|
+ AC_CHECK_LIB($lib, lzmadec_open, [LIBS="$LIBS -Wl,--no-as-needed -l$lib"; break])
|
|
+ done
|
|
+ ])
|
|
+ AC_CHECK_HEADER(lzma.h, [
|
|
+ for lib in lzma
|
|
+ do
|
|
+ AC_CHECK_LIB($lib, lzma_easy_encoder, [LIBS="$LIBS -Wl,--no-as-needed -l$lib"; break])
|
|
+ done
|
|
+ ])
|
|
+ fi
|
|
+fi
|
|
dnl To add more decompressors just follow the scheme above.
|
|
|
|
# Check for various header files and associated libraries.
|
|
--- src/decompress.c
|
|
+++ src/decompress.c 2024-11-11 10:44:24.036386441 +0000
|
|
@@ -40,12 +40,17 @@
|
|
|
|
#include "pipeline.h"
|
|
|
|
+#include "appendstr.h"
|
|
#include "attribute.h"
|
|
#include "minmax.h"
|
|
#include "xalloc.h"
|
|
#include "xstrndup.h"
|
|
#include "xvasprintf.h"
|
|
|
|
+#ifdef HAVE_ZIO
|
|
+# include "zio.h"
|
|
+#endif /* HAVE_ZIO */
|
|
+
|
|
#include "manconfig.h"
|
|
|
|
#include "compression.h"
|
|
@@ -146,7 +151,11 @@ static void decompress_zlib (void *data
|
|
|
|
static decompress *decompress_try_zlib (const char *filename)
|
|
{
|
|
+#ifdef HAVE_ZIO
|
|
+ FILE *file;
|
|
+#else
|
|
gzFile zlibfile;
|
|
+#endif
|
|
/* We only ever call this from the parent process (and don't
|
|
* currently use threads), and this lets us skip per-file memory
|
|
* allocation.
|
|
@@ -154,18 +163,32 @@ static decompress *decompress_try_zlib (
|
|
static char buffer[MAX_INPROCESS];
|
|
int len = 0;
|
|
|
|
+#ifdef HAVE_ZIO
|
|
+ file = fzopen(filename, "r");
|
|
+ if (!file)
|
|
+ return NULL;
|
|
+#else
|
|
zlibfile = gzopen (filename, "r");
|
|
if (!zlibfile)
|
|
return NULL;
|
|
+#endif
|
|
|
|
while (len < MAX_INPROCESS) {
|
|
/* Read one more byte than we're prepared to return, in
|
|
* order to detect EOF at the right position. The "len >=
|
|
* MAX_INPROCESS" check below catches the boundary case.
|
|
*/
|
|
+#ifdef HAVE_ZIO
|
|
+ int r = fread(buffer + len, sizeof(char), MAX_INPROCESS - len, file);
|
|
+#else
|
|
int r = gzread (zlibfile, buffer + len, MAX_INPROCESS - len);
|
|
+#endif
|
|
if (r < 0) {
|
|
+#ifdef HAVE_ZIO
|
|
+ fclose(file);
|
|
+#else
|
|
gzclose (zlibfile);
|
|
+#endif
|
|
return NULL;
|
|
} else if (r == 0)
|
|
break;
|
|
@@ -173,7 +196,11 @@ static decompress *decompress_try_zlib (
|
|
len += r;
|
|
}
|
|
|
|
+#ifdef HAVE_ZIO
|
|
+ fclose(file);
|
|
+#else
|
|
gzclose (zlibfile);
|
|
+#endif
|
|
if (len >= MAX_INPROCESS)
|
|
return NULL;
|
|
/* Copy input data so that we don't have potential data corruption
|
|
@@ -189,33 +216,86 @@ static decompress *decompress_try_zlib (
|
|
# define OPEN_FLAGS_UNUSED MAYBE_UNUSED
|
|
#endif /* HAVE_LIBZ */
|
|
|
|
+#ifdef HAVE_ZIO
|
|
+static void decompress_zio (void *data)
|
|
+{
|
|
+ const char *what = (const char*)data;
|
|
+ FILE *file;
|
|
+
|
|
+ file = fdzopen(dup (fileno (stdin)), "r", what);
|
|
+ if (!file)
|
|
+ return;
|
|
+
|
|
+ for (;;) {
|
|
+ char buffer[4096];
|
|
+ int r = fread(buffer, sizeof(char), sizeof(buffer), file);
|
|
+ if (r <= 0)
|
|
+ break;
|
|
+ if (fwrite (buffer, 1, (size_t) r, stdout) < (size_t) r)
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ fclose(file);
|
|
+ return;
|
|
+}
|
|
+#endif /* HAVE_ZIO */
|
|
+
|
|
decompress *decompress_open (const char *filename, int flags OPEN_FLAGS_UNUSED)
|
|
{
|
|
pipecmd *cmd;
|
|
pipeline *p;
|
|
struct stat st;
|
|
#ifdef HAVE_LIBZ
|
|
+# ifdef HAVE_ZIO
|
|
+ char *ext;
|
|
+# else
|
|
size_t filename_len;
|
|
+# endif
|
|
#endif /* HAVE_LIBZ */
|
|
- char *ext;
|
|
struct compression *comp;
|
|
|
|
if (stat (filename, &st) < 0 || S_ISDIR (st.st_mode))
|
|
return NULL;
|
|
|
|
#ifdef HAVE_LIBZ
|
|
+# ifdef HAVE_ZIO
|
|
+ ext = strrchr (filename, '.');
|
|
+ if (ext && (
|
|
+ STREQ (ext, ".gz") ||
|
|
+ STREQ (ext, ".z") ||
|
|
+ STREQ (ext, ".bz2") ||
|
|
+ STREQ (ext, ".xz") ||
|
|
+ STREQ (ext, ".lzma") ||
|
|
+ STREQ (ext, ".Z")
|
|
+ )) {
|
|
+# else
|
|
filename_len = strlen (filename);
|
|
if (filename_len > 3 && STREQ (filename + filename_len - 3, ".gz")) {
|
|
+# endif
|
|
if (flags & DECOMPRESS_ALLOW_INPROCESS) {
|
|
decompress *d = decompress_try_zlib (filename);
|
|
if (d)
|
|
return d;
|
|
}
|
|
-
|
|
+# ifdef HAVE_ZIO
|
|
+ static char opt[2] = {'\0','\0'};
|
|
+ char *name = NULL;
|
|
+
|
|
+ opt[0] = ext[1];
|
|
+
|
|
+ /* informational only; no shell quoting concerns */
|
|
+ name = appendstr (NULL, "libzio < ", filename, (void *) 0);
|
|
+ cmd = pipecmd_new_function (name, &decompress_zio, NULL,
|
|
+ (void *)opt);
|
|
+# else
|
|
cmd = pipecmd_new_function ("zcat", &decompress_zlib, NULL,
|
|
NULL);
|
|
+# endif
|
|
pipecmd_pre_exec (cmd, sandbox_load, sandbox_free, sandbox);
|
|
p = pipeline_new_commands (cmd, nullptr);
|
|
+# ifdef HAVE_ZIO
|
|
+ free (name);
|
|
+# endif
|
|
goto got_pipeline;
|
|
}
|
|
#endif /* HAVE_LIBZ */
|
|
@@ -313,7 +393,7 @@ void decompress_inprocess_replace (decom
|
|
|
|
void decompress_start (decompress *d)
|
|
{
|
|
- if (d->tag == DECOMPRESS_PIPELINE)
|
|
+ if (d && d->tag == DECOMPRESS_PIPELINE)
|
|
pipeline_start (d->u.p);
|
|
}
|
|
|