306 lines
8.0 KiB
Plaintext
306 lines
8.0 KiB
Plaintext
--- config.h.in
|
|
+++ config.h.in 2007-12-07 15:50:23.000000000 +0100
|
|
@@ -454,6 +454,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 you have the <limits.h> header file. */
|
|
#undef HAVE_LIMITS_H
|
|
|
|
--- configure.ac
|
|
+++ configure.ac 2008-04-21 13:18:38.854059561 +0200
|
|
@@ -94,7 +94,18 @@ AC_ARG_WITH(sections,
|
|
sections="$withval"
|
|
fi],
|
|
[: ${sections=1 n l 8 3 2 5 4 9 6 7}])
|
|
-
|
|
+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})
|
|
# Finish the argument parsing.
|
|
AC_SUBST(man_owner)dnl
|
|
AC_SUBST(man_mode)dnl
|
|
@@ -294,6 +305,29 @@ AC_SUBST(gunzip)
|
|
AC_SUBST(uncompress)
|
|
AC_SUBST(bunzip2)
|
|
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"
|
|
+ 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])])
|
|
+ done])
|
|
+ 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])
|
|
+fi
|
|
dnl To add more decompressors just follow the scheme above.
|
|
|
|
# Work out which manual page hierarchy scheme might be in use.
|
|
--- lib/decompress.c
|
|
+++ lib/decompress.c 2008-04-23 10:48:04.431353342 +0000
|
|
@@ -36,6 +36,10 @@
|
|
# include "zlib.h"
|
|
#endif /* HAVE_LIBZ */
|
|
|
|
+#ifdef HAVE_ZIO
|
|
+# include "zio.h"
|
|
+#endif /* HAVE_ZIO */
|
|
+
|
|
#include "manconfig.h"
|
|
#include "comp_src.h"
|
|
#include "pipeline.h"
|
|
@@ -66,6 +70,32 @@ static void decompress_zlib (void *data
|
|
|
|
#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 */
|
|
+
|
|
pipeline *decompress_open (const char *filename)
|
|
{
|
|
command *cmd;
|
|
@@ -77,9 +107,53 @@ pipeline *decompress_open (const char *f
|
|
char *ext;
|
|
struct compression *comp;
|
|
|
|
- if (stat (filename, &st) < 0 && !S_ISDIR (st.st_mode))
|
|
+ if (stat (filename, &st) < 0 || S_ISDIR (st.st_mode))
|
|
return NULL;
|
|
|
|
+#ifdef HAVE_ZIO
|
|
+ ext = strrchr(filename, '.');
|
|
+ if (ext && STREQ (ext, ".gz")) {
|
|
+ /* informational only; no shell quoting concerns */
|
|
+ char *name = appendstr (NULL, "zcat < ", filename, NULL);
|
|
+ cmd = command_new_function (name, &decompress_zio, "g");
|
|
+ free (name);
|
|
+ p = pipeline_new_commands (cmd, NULL);
|
|
+ if (strcmp(program_name, "mandb") == 0)
|
|
+ p->libzio = 1;
|
|
+ goto got_pipeline;
|
|
+ }
|
|
+ if (ext && STREQ (ext, ".z")) {
|
|
+ /* informational only; no shell quoting concerns */
|
|
+ char *name = appendstr (NULL, "zcat < ", filename, NULL);
|
|
+ cmd = command_new_function (name, &decompress_zio, "z");
|
|
+ free (name);
|
|
+ p = pipeline_new_commands (cmd, NULL);
|
|
+ if (strcmp(program_name, "mandb") == 0)
|
|
+ p->libzio = 1;
|
|
+ goto got_pipeline;
|
|
+ }
|
|
+ if (ext && STREQ (ext, ".bz2")) {
|
|
+ /* informational only; no shell quoting concerns */
|
|
+ char *name = appendstr (NULL, "bzcat < ", filename, NULL);
|
|
+ cmd = command_new_function (name, &decompress_zio, "b");
|
|
+ free (name);
|
|
+ p = pipeline_new_commands (cmd, NULL);
|
|
+ if (strcmp(program_name, "mandb") == 0)
|
|
+ p->libzio = 1;
|
|
+ goto got_pipeline;
|
|
+ }
|
|
+ if (ext && STREQ (ext, ".Z")) {
|
|
+ /* informational only; no shell quoting concerns */
|
|
+ char *name = appendstr (NULL, "zcat < ", filename, NULL);
|
|
+ cmd = command_new_function (name, &decompress_zio, "Z");
|
|
+ free (name);
|
|
+ p = pipeline_new_commands (cmd, NULL);
|
|
+ if (strcmp(program_name, "mandb") == 0)
|
|
+ p->libzio = 1;
|
|
+ goto got_pipeline;
|
|
+ }
|
|
+#endif /* HAVE_ZIO */
|
|
+
|
|
#ifdef HAVE_LIBZ
|
|
filename_len = strlen (filename);
|
|
if (filename_len > 3 && STREQ (filename + filename_len - 3, ".gz")) {
|
|
--- lib/pipeline.c
|
|
+++ lib/pipeline.c 2008-04-23 10:52:16.655715088 +0000
|
|
@@ -50,6 +50,10 @@
|
|
#include "error.h"
|
|
#include "pipeline.h"
|
|
|
|
+#ifdef HAVE_ZIO
|
|
+# include "zio.h"
|
|
+#endif /* HAVE_ZIO */
|
|
+
|
|
/* ---------------------------------------------------------------------- */
|
|
|
|
/* Functions to build individual commands. */
|
|
@@ -441,6 +445,9 @@ pipeline *pipeline_new (void)
|
|
p->commands = xnmalloc (p->commands_max, sizeof *p->commands);
|
|
p->pids = NULL;
|
|
p->statuses = NULL;
|
|
+#ifdef HAVE_ZIO
|
|
+ p->libzio = 0;
|
|
+#endif
|
|
p->want_in = p->want_out = 0;
|
|
p->want_infile = p->want_outfile = NULL;
|
|
p->infd = p->outfd = -1;
|
|
@@ -479,6 +486,9 @@ pipeline *pipeline_join (pipeline *p1, p
|
|
pipeline *p = XMALLOC (pipeline);
|
|
int i;
|
|
|
|
+#ifdef HAVE_ZIO
|
|
+ assert (p->libzio);
|
|
+#endif
|
|
assert (!p1->pids);
|
|
assert (!p2->pids);
|
|
assert (!p1->statuses);
|
|
@@ -614,6 +624,9 @@ void pipeline_commands (pipeline *p, ...
|
|
|
|
FILE *pipeline_get_infile (pipeline *p)
|
|
{
|
|
+#ifdef HAVE_ZIO
|
|
+ assert (!p->libzio);
|
|
+#endif
|
|
assert (p->pids); /* pipeline started */
|
|
assert (p->statuses);
|
|
if (p->infile)
|
|
@@ -627,6 +640,12 @@ FILE *pipeline_get_infile (pipeline *p)
|
|
|
|
FILE *pipeline_get_outfile (pipeline *p)
|
|
{
|
|
+#ifdef HAVE_ZIO
|
|
+ if (p->libzio) {
|
|
+ assert (p->outfile != (FILE*)0);
|
|
+ return p->outfile;
|
|
+ }
|
|
+#endif
|
|
assert (p->pids); /* pipeline started */
|
|
assert (p->statuses);
|
|
if (p->outfile)
|
|
@@ -707,6 +726,24 @@ void pipeline_start (pipeline *p)
|
|
int infd[2];
|
|
sigset_t set, oset;
|
|
|
|
+#ifdef HAVE_ZIO
|
|
+ if (p->ncommands != 1) /* A pipe to the following commands required */
|
|
+ p->libzio = 0;
|
|
+
|
|
+ if (p->libzio) {
|
|
+ struct command_function *cmdf;
|
|
+
|
|
+ assert (p->ncommands == 1);
|
|
+ assert (p->commands[0]->tag == COMMAND_FUNCTION);
|
|
+ assert (p->want_infile != NULL);
|
|
+
|
|
+ cmdf = &p->commands[0]->u.function;
|
|
+
|
|
+ p->outfile = fzopen(p->want_infile, "r");
|
|
+
|
|
+ return;
|
|
+ }
|
|
+#endif
|
|
/* Flush all pending output so that subprocesses don't inherit it. */
|
|
fflush (NULL);
|
|
|
|
@@ -1009,6 +1046,19 @@ int pipeline_wait (pipeline *p)
|
|
pipeline_dump (p, stderr);
|
|
}
|
|
|
|
+#ifdef HAVE_ZIO
|
|
+ if (p->libzio) {
|
|
+ assert (p->outfile != (FILE*)0);
|
|
+ if (fclose (p->outfile)) {
|
|
+ error (0, errno, _("closing pipeline output stream failed"));
|
|
+ ret = 1;
|
|
+ }
|
|
+ p->outfile = (FILE*)0;
|
|
+ p->outfd = -1;
|
|
+ return ret;
|
|
+ }
|
|
+#endif
|
|
+
|
|
assert (p->pids); /* pipeline started */
|
|
assert (p->statuses);
|
|
|
|
@@ -1549,11 +1599,20 @@ static const char *get_block (pipeline *
|
|
|
|
if (!peek)
|
|
p->peek_offset = 0;
|
|
-
|
|
+#ifdef HAVE_ZIO
|
|
+ if (p->libzio) {
|
|
+ assert (p->outfile != (FILE*)0);
|
|
+ r = fread (p->buffer + readstart, sizeof(char), toread, p->outfile);
|
|
+ goto out;
|
|
+ }
|
|
+#endif
|
|
assert (p->outfd != -1);
|
|
r = read (p->outfd, p->buffer + readstart, toread);
|
|
if (r == -1)
|
|
return NULL;
|
|
+#ifdef HAVE_ZIO
|
|
+out:
|
|
+#endif
|
|
p->buflen = readstart + r;
|
|
if (peek)
|
|
p->peek_offset += r;
|
|
--- lib/pipeline.h
|
|
+++ lib/pipeline.h 2008-04-22 13:52:44.846881571 +0000
|
|
@@ -60,6 +60,14 @@ typedef struct pipeline {
|
|
pid_t *pids;
|
|
int *statuses; /* -1 until command exits */
|
|
|
|
+#ifdef HAVE_ZIO
|
|
+ /*
|
|
+ * Uses for e.g. simple decompression the help of libzio.
|
|
+ * Do not fork in this case but open the compressed files.
|
|
+ */
|
|
+ int libzio;
|
|
+#endif
|
|
+
|
|
/* To be set by the caller. If positive, these contain
|
|
* caller-supplied file descriptors for the input and output of the
|
|
* whole pipeline. If negative, pipeline_start() will create pipes
|