Sync from SUSE:ALP:Source:Standard:1.0 man revision baf19bad303249c0074b0efe686baf7d

This commit is contained in:
Adrian Schröter 2023-10-18 20:41:03 +02:00
commit ca0606471c
24 changed files with 4712 additions and 0 deletions

23
.gitattributes vendored Normal file
View File

@ -0,0 +1,23 @@
## Default LFS
*.7z filter=lfs diff=lfs merge=lfs -text
*.bsp filter=lfs diff=lfs merge=lfs -text
*.bz2 filter=lfs diff=lfs merge=lfs -text
*.gem filter=lfs diff=lfs merge=lfs -text
*.gz filter=lfs diff=lfs merge=lfs -text
*.jar filter=lfs diff=lfs merge=lfs -text
*.lz filter=lfs diff=lfs merge=lfs -text
*.lzma filter=lfs diff=lfs merge=lfs -text
*.obscpio filter=lfs diff=lfs merge=lfs -text
*.oxt filter=lfs diff=lfs merge=lfs -text
*.pdf filter=lfs diff=lfs merge=lfs -text
*.png filter=lfs diff=lfs merge=lfs -text
*.rpm filter=lfs diff=lfs merge=lfs -text
*.tbz filter=lfs diff=lfs merge=lfs -text
*.tbz2 filter=lfs diff=lfs merge=lfs -text
*.tgz filter=lfs diff=lfs merge=lfs -text
*.ttf filter=lfs diff=lfs merge=lfs -text
*.txz filter=lfs diff=lfs merge=lfs -text
*.whl filter=lfs diff=lfs merge=lfs -text
*.xz filter=lfs diff=lfs merge=lfs -text
*.zip filter=lfs diff=lfs merge=lfs -text
*.zst filter=lfs diff=lfs merge=lfs -text

71
cron.daily.do_mandb Normal file
View File

@ -0,0 +1,71 @@
#!/bin/bash
#
#
# do_mandb. This script was split off cron.daily.
# Please add your local changes to cron.daily.local
# since this file will be overwritten, when updating your system.
#
# Copyright (c) 1996-2002 SuSE GmbH Nuernberg, Germany.
# Copyright (c) 2008 SuSE LINUX Products GmbH Nuernberg, Germany.
#
# please send bugfixes or comments to feedback@suse.de.
#
# Author: Werner Fink <feedback@suse.de>, 2008, 2019
# Burchard Steinbild <feedback@suse.de>, 1996
# Florian La Roche <feedback@suse.de>, 1996
#
#
# paranoia settings
#
umask 022
PATH=/sbin:/bin:/usr/sbin:/usr/bin
export PATH
#
# get information from /etc/sysconfig/cron
#
if test -f /etc/sysconfig/cron ; then
. /etc/sysconfig/cron
fi
#
# now we do the man page stuff
#
if test "$REINIT_MANDB" = yes ; then
if type -p mandb > /dev/null 2>&1 ; then
typeset -r manpaths=$(manpath -g)
typeset -i errors=0
renice +5 -p $$ > /dev/null || true
ionice -c 3 -p $$ > /dev/null || true
unset MANPATH
IFS=:
for mp in $manpaths; do
test -d "${mp}" || continue
cp=$(MANPATH=$mp manpath -qc)
test -n "${cp}" || continue
test -d "${cp}" || continue
db=${cp}/index.db
if test -e ${db} ; then
path="$(find $mp -follow -newer $db 2>/dev/null)"
test -n "$path" || continue
fi
nice -n 5 ionice -c 3 mandb -qs ${mp} > /dev/null 2>&1 || let errors++
done
if test $errors -ne 0 ; then
echo There seem to be trouble with mandb.
echo
echo please run mandb and check the output...
fi
fi
#
# some applications need whatis database. If makewhatis exists, call it
#
if type -p makewhatis > /dev/null 2>&1 ; then
makewhatis
fi
fi
exit 0

BIN
man-db-2.11.2.tar.xz (Stored with Git LFS) Normal file

Binary file not shown.

16
man-db-2.11.2.tar.xz.asc Normal file
View File

@ -0,0 +1,16 @@
-----BEGIN PGP SIGNATURE-----
iQIzBAABCAAdFiEErApP8SYRtvzPAcEROTWH2X2GUAsFAmO7P18ACgkQOTWH2X2G
UAsAVxAAjbkxD9Ji+FhO8VoJ40FnSlK7vwaX+1REswSBmaSCmrt7ey9s60r6sAcM
OjphmTMHNJqxmBS/fsvKnuRiaUv/a+PPKOxEZg85F9uUmArnDphaTH9PzXPpxHgV
jwda7v3BSxPV0YjFyj1FzfpTQjhZX9+0NwVUXUga0ViCExi8yAk3lS+Vhkz3JdkK
PWY9QjD7GwH5G+8ojHOZralBNCEQdcej9/3B1FGPq9EoZ270emybJBmHAF9K+2Y9
2jH4HWcSjhwCAxEXYkzmBtmkYvfE4HdDTCzo5TR51PflizD2RylIYmNO4vdyETIP
KPYK2fzpkSODTUgeSfLfupv1sq9MqIDLEtpWLgZT5BTJCHjG14KAgDfnUmqZB2Iv
w4wHyfAJ+7MrVqCHbLtjcdVVfAxDajhrRLwZZkQrd/lT6ykZ0q0wQjXP+xL2yTxR
70lRgMFnEzezHtiEiW2xjWQDehNiQ+7NK1vNUgnugXBdsb7MO6dwtL/30JMtapOA
60vlGlDejGvfae9OYeNCQc/b7GYJwFQ7vQ3iM2c1PVF1KfaqY71WrrC3hP03gs9j
EzmrA9xLdfkKGmALD8579KukEiWitcIikm8NlkQ/0mLF7CKIjXVSJmGjz4xrsDAg
zN2qdp8cJG6R4PmKQdCFS+YNlBp07xkqO/CCqKjBpLNBN+r9lAQ=
=uREj
-----END PGP SIGNATURE-----

View File

@ -0,0 +1,61 @@
--- groff/tmac.andb
+++ groff/tmac.andb Fri Apr 6 19:08:58 2001
@@ -0,0 +1,29 @@
+.\" tmac.(m)andb
+.\"
+.\" This is part of the man(db) package of SuSE Linux
+.\" Author: Werner Fink
+.\"
+.\" Load tmac.an
+.\"
+.mso tmac.an
+.\"
+.\" Remember the original macros for headers and footers
+.\" and Overwrite them. The original footers macros will
+.\" be called at the bitter end.
+.\"
+.rn an-header db@header
+.de an-header
+. if (\\n% == 1) \
+. db@header
+..
+.rn an-footer db@footer
+.de an-footer
+..
+.rn an-p-footer db@p-footer
+.de an-p-footer
+..
+.de db@end
+. wh -1i db@footer
+. wh -.5i db@p-footer
+..
+.em db@end
--- groff/tmac.andocdb
+++ groff/tmac.andocdb Fri Apr 6 19:08:58 2001
@@ -0,0 +1,26 @@
+.\" tmac.(m)andocdb
+.\"
+.\" This is part of the man(db) package of SuSE Linux
+.\" Author: Werner Fink
+.\"
+.\" Just like tmac.andoc but
+.\" load either tmac.andb or tmac.doc
+.\"
+.if !\n(.g .ab These macros require groff.
+.de Dd
+.rm Dd
+.do mso tmac.doc
+\\*(Dd\\
+..
+.de TH
+.rm TH
+.do mso tmac.andb
+\\*(TH\\
+..
+.if '\*[.T]'utf8' \{\
+. char \- \N'45'
+. char - \N'45'
+. char ' \N'39'
+. char ` \N'96'
+.\}
+..

54
man-db-2.6.3-chinese.dif Normal file
View File

@ -0,0 +1,54 @@
---
lib/encodings.c | 13 +++++++++++--
1 file changed, 11 insertions(+), 2 deletions(-)
--- lib/encodings.c
+++ lib/encodings.c 2016-12-15 14:07:01.072034899 +0000
@@ -227,6 +227,7 @@ static struct charset_entry charset_tabl
{ "EUC-CN", "nippon" },
{ "EUC-JP", "nippon" },
{ "EUC-TW", "nippon" },
+ { "GB18030", "nippon" },
{ "GBK", "nippon" },
# else /* !MULTIBYTE_GROFF */
/* If we have a smarter version of groff, this is better dealt with
@@ -314,6 +315,7 @@ static struct less_charset_entry less_ch
#ifdef MULTIBYTE_GROFF
{ "CP1251", "windows", NULL },
+ { "GB18030", "zh", NULL },
{ "EUC-JP", "iso8859", "japanese-ujis" },
{ "KOI8-R", "koi8-r", NULL },
/* close enough? */
@@ -452,6 +454,13 @@ char *get_page_encoding (const char *lan
* roff encoding = ISO-8859-15
* output encoding = ISO-8859-15
* ISO-8859-15 -> groff -Tascii8 -> ISO-8859-15 -> iconv -> UTF-8
+ *
+ * /usr/share/man/zh_CN.GB18030, locale zh_CN.UTF-8
+ * page encoding = GB18030
+ * source encoding = GB18030
+ * roff encoding = UTF-8
+ * output encoding = UTF-8
+ * GB18030 -> iconv -> UTF-8 -> groff -Tutf8 -> UTF-8
*/
const char *get_source_encoding (const char *lang)
{
@@ -620,7 +629,7 @@ static int compatible_encodings (const c
*/
if ((STREQ (input, "BIG5") || STREQ (input, "BIG5HKSCS") ||
STREQ (input, "EUC-JP") ||
- STREQ (input, "EUC-CN") || STREQ (input, "GBK") ||
+ STREQ (input, "EUC-CN") || STREQ (input, "GB18030") || STREQ (input, "GBK") ||
STREQ (input, "EUC-KR") ||
STREQ (input, "EUC-TW")) &&
STREQ (output, "UTF-8"))
@@ -724,7 +733,7 @@ const char *get_roff_encoding (const cha
STRNEQ (ctype, "zh_HK", 5) ||
STRNEQ (ctype, "zh_SG", 5) ||
STRNEQ (ctype, "zh_TW", 5))
- roff_encoding = "UTF-8";
+ roff_encoding = source_encoding; /* "UTF-8"; */
}
#endif /* MULTIBYTE_GROFF */

225
man-db-2.6.3-listall.dif Normal file
View File

@ -0,0 +1,225 @@
---
man/man1/man.man1 | 8 ++
src/man.c | 180 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 186 insertions(+), 2 deletions(-)
--- man/man1/man.man1
+++ man/man1/man.man1 2022-08-17 13:11:29.974677243 +0000
@@ -1226,6 +1226,14 @@ However, some users want to see them any
.RB $ MAN_KEEP_STDERR
is set to any non-empty value, error output will be displayed as usual.
.TP
+.if !'po4a'hide' .BR MAN_POSIXLY_CORRECT
+If many man pages are available corresponding to the requested one,
+.B %man%
+will display them in a list, unless
+.RB $ MAN_POSIXLY_CORRECT
+is set, in which case the first page in the list will be displayed
+automatically.
+.TP
.if !'po4a'hide' .B MAN_DISABLE_SECCOMP
On Linux,
.B %man%
--- src/man.c
+++ src/man.c 2022-08-17 13:10:07.436205495 +0000
@@ -3641,12 +3641,141 @@ static int locate_page (const char *manp
return found;
}
+#ifndef PROMPT_IF_MULTIPLE_SECTIONS
+#define PROMPT_IF_MULTIPLE_SECTIONS 2 /* 0: No prompt; 1: Show possible sections; 2: Do prompt for */
+#endif
+
+#if defined(PROMPT_IF_MULTIPLE_SECTIONS) && (PROMPT_IF_MULTIPLE_SECTIONS > 1)
+static sig_atomic_t expired;
+static void handler(int sig)
+{
+ (void)sig;
+ expired++;
+}
+#endif
+
static int display_pages (struct candidate *candidates)
{
struct candidate *candp;
int found = 0;
+ int plain = 0;
+
+#if defined(PROMPT_IF_MULTIPLE_SECTIONS) && (PROMPT_IF_MULTIPLE_SECTIONS > 1)
+ char reqsect[64] = { 0 };
+ ssize_t len = 0;
+ int index = -1;
+ const char *lext;
+ do {
+ struct sigaction sa;
+ int used = 0x2A;
+
+ if (findall)
+ break;
+ if (external)
+ break;
+ if ((troff + catman + (print_where || print_where_cat)))
+ break;
+ if (getenv("MAN_POSIXLY_CORRECT"))
+ break;
+ if (!isatty(STDOUT_FILENO))
+ break;
+ if (!isatty(STDERR_FILENO))
+ break;
+ if (!isatty(STDIN_FILENO))
+ break;
+ if (candidates->next == (struct candidate*)0)
+ break;
+
+ fputs("Man: ", stderr);
+ fputs(_("find all matching manual pages"), stderr);
+ fputs(" (set MAN_POSIXLY_CORRECT to avoid this)", stderr);
+ fputc('\n', stderr);
+
+ lext = NULL;
+ for (candp = candidates; candp; candp = candp->next) {
+ const struct mandata *info = candp->source;
+
+ if (lext && STREQ(lext, info->ext))
+ fprintf(stderr, " %c %s (%s+%d)", used, info->name, info->ext, candp->add_index);
+ else
+ fprintf(stderr, " %c %s (%s)", used, info->name, info->ext);
+
+ if (info->whatis)
+ fprintf(stderr, "\t%s", info->whatis);
+ fputc('\n', stderr);
+ lext = info->ext;
+ used = ' ';
+ }
+ fputs("Man: ", stderr);
+ fputs(_("What manual page do you want?\n"), stderr);
+ fputs("Man: ", stderr);
+ fflush(stderr);
+
+ sigemptyset(&sa.sa_mask);
+ sa.sa_flags = SA_RESETHAND;
+ sa.sa_handler = handler;
+
+ sigaction(SIGALRM, &sa, (struct sigaction*)0);
+
+ alarm(7);
+ len = read(STDIN_FILENO, reqsect, sizeof(reqsect)-1);
+ alarm(0);
+
+ if (expired) {
+ tcflush(STDIN_FILENO, TCIFLUSH);
+ fputc('\n', stderr);
+ fflush(stderr);
+ len = 0;
+ break;
+ }
+ if (len > 0) {
+ char * end;
+ if ((end = strchr(reqsect, '\n')))
+ *end = '\0';
+ if ((end = strchr(reqsect, '+'))) {
+ plain = 1;
+ *end = '\0';
+ if (*++end)
+ index = atoi(end);
+ }
+ reqsect[len] = '\0';
+ len = (ssize_t)strlen(reqsect);
+
+ for (candp = candidates; candp; candp = candp->next) {
+ if (len == 0)
+ break;
+ if (plain) {
+ const char *base = strrchr(candp->path, '/');
+ if (base && !STREQ(base, "/man"))
+ continue;
+ }
+ if (index >= 0 && index != candp->add_index)
+ continue;
+ if ((found = STREQ(reqsect, candp->source->ext)))
+ break;
+ }
+ if (!found)
+ len = 0;
+ found = 0;
+ }
+ } while (0);
+#endif
for (candp = candidates; candp; candp = candp->next) {
+
+#if defined(PROMPT_IF_MULTIPLE_SECTIONS) && (PROMPT_IF_MULTIPLE_SECTIONS > 1)
+ if (plain) {
+ const char *base = strrchr(candp->path, '/');
+ if (base && !STREQ(base, "/man"))
+ continue;
+ }
+ if (len) {
+ if (!STREQ(reqsect, candp->source->ext))
+ continue;
+ if (index >= 0 && index != candp->add_index)
+ continue;
+ }
+#endif
global_manpath = is_global_mandir (candp->path);
if (!global_manpath)
drop_effective_privs ();
@@ -3668,9 +3797,56 @@ static int display_pages (struct candida
regain_effective_privs ();
if (found && !findall)
- return found;
+ {
+#if defined(PROMPT_IF_MULTIPLE_SECTIONS) && (PROMPT_IF_MULTIPLE_SECTIONS > 0)
+ if (external)
+ goto out;
+ if ((troff + catman + (print_where || print_where_cat)))
+ goto out;
+# if defined(PROMPT_IF_MULTIPLE_SECTIONS) && (PROMPT_IF_MULTIPLE_SECTIONS == 1)
+ if (getenv("MAN_POSIXLY_CORRECT"))
+ goto out;
+# endif
+ if (!isatty(STDOUT_FILENO))
+ goto out;
+ if (!isatty(STDERR_FILENO))
+ goto out;
+ /*
+ * Should be able to use the output as done by whatis(1)
+ */
+# if defined(PROMPT_IF_MULTIPLE_SECTIONS) && (PROMPT_IF_MULTIPLE_SECTIONS == 1)
+ if (candp->next)
+# else
+ if (candp->next && getenv("MAN_POSIXLY_CORRECT"))
+# endif
+ {
+ int used = 0x2A;
+
+ fputs("Man: ", stderr);
+ fputs(_("find all matching manual pages"), stderr);
+ fputc('\n', stderr);
+
+ lext = NULL;
+ do {
+ struct mandata *info = candp->source;
+ if (lext && STREQ(lext, info->ext))
+ fprintf(stderr, " %c %s (%s+%d)", used, info->name, info->ext, candp->add_index);
+ else
+ fprintf(stderr, " %c %s (%s)", used, info->name, info->ext);
+ if (info->whatis) {
+ fprintf(stderr, "\t%s", info->whatis);
+ }
+ fputc('\n', stderr);
+ lext = info->ext;
+ used = ' ';
+ } while ((candp = candp->next));
+ fflush(stderr);
+ }
+#endif
+ goto out;
+ }
}
-
+out:
return found;
}

12
man-db-2.6.3-man0.dif Normal file
View File

@ -0,0 +1,12 @@
--- man/man1/man.man1
+++ man/man1/man.man1 2018-11-23 14:23:22.531297359 +0000
@@ -93,6 +93,9 @@ numbers of the manual followed by the ty
.TS
tab (@);
l lx.
+0@T{
+Header files (usually found in \fI/usr/include\fR)
+T}
1@T{
Executable programs or shell commands
T}

200
man-db-2.7.1-zio.dif Normal file
View File

@ -0,0 +1,200 @@
---
config.h.in | 3 +
configure.ac | 52 ++++++++++++++++++++++++++++++
src/decompress.c | 70 ++++++++++++++++++++++++++++++++++++++++-
3 files changed, 124 insertions(+), 1 deletion(-)
--- config.h.in
+++ config.h.in 2023-08-15 08:21:20.473974597 +0000
@@ -1015,6 +1015,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 2023-08-15 08:21:20.473974597 +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
@@ -401,6 +413,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 2023-08-15 08:23:12.947968440 +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"
@@ -189,6 +194,33 @@ 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 */
+
+
extern man_sandbox *sandbox;
decompress *decompress_open (const char *filename, int flags OPEN_FLAGS_UNUSED)
@@ -205,6 +237,38 @@ decompress *decompress_open (const char
if (stat (filename, &st) < 0 || S_ISDIR (st.st_mode))
return NULL;
+#ifdef HAVE_ZIO
+ ext = strrchr (filename, '.');
+ if (ext) {
+ const char *opt;
+ char *name = NULL;
+
+ if (STREQ (ext, ".gz"))
+ opt = "g";
+ else if (STREQ (ext, ".z"))
+ opt = "z";
+ else if (STREQ (ext, ".bz2"))
+ opt = "b";
+ else if (STREQ (ext, ".xz"))
+ opt = "x";
+ else if (STREQ (ext, ".lzma"))
+ opt = "l";
+ else if (STREQ (ext, ".Z"))
+ opt = "Z";
+ else
+ goto nozio;
+
+ /* informational only; no shell quoting concerns */
+ name = appendstr (NULL, "libzio < ", filename, (void *) 0);
+ cmd = pipecmd_new_function (name, &decompress_zio, NULL,
+ (void *)opt);
+ pipecmd_pre_exec (cmd, sandbox_load, sandbox_free, sandbox);
+ p = pipeline_new_commands (cmd, (void *) 0);
+ free (name);
+ goto got_pipeline;
+ }
+#endif /* HAVE_ZIO */
+
#ifdef HAVE_LIBZ
filename_len = strlen (filename);
if (filename_len > 3 && STREQ (filename + filename_len - 3, ".gz")) {
@@ -222,7 +286,11 @@ decompress *decompress_open (const char
}
#endif /* HAVE_LIBZ */
+#ifdef HAVE_ZIO
+nozio:
+#else
ext = strrchr (filename, '.');
+#endif /* HAVE_LIBZ */
if (ext) {
++ext;
@@ -315,7 +383,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);
}

View File

@ -0,0 +1,43 @@
---
src/man.c | 23 ++++++++++++++++++++---
1 file changed, 20 insertions(+), 3 deletions(-)
--- src/man.c
+++ src/man.c 2022-08-17 13:59:26.937398386 +0000
@@ -57,6 +57,7 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/time.h>
+#include <libalternatives.h>
#include "argp.h"
#include "attribute.h"
@@ -4171,9 +4172,25 @@ static void locate_page_in_manpath (cons
{
char *mp;
- GL_LIST_FOREACH (manpathlist, mp)
- *found += locate_page (mp, page_section, page_name,
- candidates);
+ GL_LIST_FOREACH (manpathlist, mp) {
+ int count = locate_page (mp, page_section, page_name, candidates);
+ if (count == 0) {
+ /* Checking if there has been defined another manpage defined in the
+ * priorities of libalternatives.
+ */
+ char **alternitives = libalts_get_default_manpages(page_name);
+ for (char **alter = alternitives; *alter; alter++) {
+ char *p_name, *p_section;
+ split_page_name (*alter, &p_name, &p_section);
+ if (p_name && strlen(p_name) > 0 &&
+ p_section && strlen(p_section) > 0)
+ count = locate_page (mp, p_section, p_name, candidates);
+ free(*alter);
+ }
+ free(alternitives);
+ }
+ *found += count;
+ }
}
/*

View File

@ -0,0 +1,26 @@
Index: man-db-2.10.2/src/Makefile.am
===================================================================
---
man-db-2.11.2/src/Makefile.am | 11 +----------
1 file changed, 1 insertion(+), 10 deletions(-)
--- man-db-2.11.2/src/Makefile.am
+++ man-db-2.11.2/src/Makefile.am 2023-08-15 09:13:30.418162015 +0000
@@ -196,16 +196,7 @@ apropos$(EXEEXT): whatis$(EXEEXT)
all-am: apropos$(EXEEXT)
install-exec-hook:
- if [ "$(man_owner)" ] && [ "$(man_mode)" = 6755 ]; then \
- chown $(man_owner):$(man_owner) \
- $(DESTDIR)$(bindir)/$(TRANS_MAN)$(EXEEXT) \
- $(DESTDIR)$(bindir)/$(TRANS_MANDB)$(EXEEXT); \
- fi
- chmod $(man_mode) \
- $(DESTDIR)$(bindir)/$(TRANS_MAN)$(EXEEXT) \
- $(DESTDIR)$(bindir)/$(TRANS_MANDB)$(EXEEXT)
- cd $(DESTDIR)$(bindir) && rm -f $(TRANS_APROPOS)$(EXEEXT) && \
- $(LN_S) $(TRANS_WHATIS)$(EXEEXT) $(TRANS_APROPOS)$(EXEEXT)
+ $(LN_S) $(TRANS_WHATIS) $(DESTDIR)$(bindir)/$(TRANS_APROPOS)
install-data-hook:
@if test -f $(DESTDIR)$(config_file); then \

698
man-db-2.9.4.patch Normal file
View File

@ -0,0 +1,698 @@
---
configure.ac | 18 +++++++++-
lib/security.c | 30 +++++++++++++++++
mk_catdirs | 30 +++++++++++++++++
src/check_mandirs.c | 33 ++++++++++++-------
src/lexgrog.l | 64 +++++++++++++++++++++++++++-----------
src/man.c | 60 +++++++++++++++++++++++++++++++++++++++++++-----
src/man_db.conf.in | 17 ++++++++--
src/mandb.c | 18 ++++++++--
src/manp.c | 2 -
src/straycats.c | 1
src/ult_src.c | 9 ++++-
11 files changed, 235 insertions(+), 47 deletions(-)
--- a/configure.ac
+++ b/configure.ac 2023-08-15 08:31:31.135097942 +0000
@@ -302,6 +302,14 @@ fi
MAN_CHECK_PROGS([eqn], [EQN], [use EQN to preprocess equations], [eqn geqn])
AC_DEFINE_UNQUOTED([PROG_EQN], ["$eqn"], [Program to use as eqn.])
+MAN_CHECK_PROGS([geqn], [GEQN], [use GEQN to preprocess equations], [geqn])
+dnl
+dnl if geqn is found and geqn is identical with eqn we use a GNU eqn
+dnl which its self can use -Tlatin1
+dnl
+if test -n "$geqn" -a -n "$eqn" ; then
+ test $geqn -ef $eqn && neqn="$eqn -T$nroff_device"
+fi
MAN_CHECK_PROGS([neqn], [NEQN], [use NEQN to preprocess equations for character devices], [neqn gneqn])
# If we fail to find an neqn, use eqn and try to force it to output for an
# ascii device. As this is only relevant for equations (?), not using latin1
@@ -352,9 +360,15 @@ then
compress_ext="gz"
fi
MAN_CHECK_PROGS([compress], [COMPRESS], [use COMPRESS as UNIX compression utility], [compress])
-if test -n "$compress"
+if test -n "$compress" || test -n "$gzip"
then
- uncompress="$compress -dc"
+ if test -n "$gzip"
+ then
+ uncompress="$gzip -dc"
+ elif test -n "$compress"
+ then
+ uncompress="$compress -dc"
+ fi
if test -z "$gzip"
then
compressor="$compress -c"
--- a/lib/security.c
+++ b/lib/security.c 2023-08-15 08:31:31.135097942 +0000
@@ -80,6 +80,11 @@ static void gripe_set_euid (void)
fatal (errno, _("can't set effective uid"));
}
+static inline void gripe_set_egid (void)
+{
+ error (FATAL, errno, _("can't set effective gid"));
+}
+
#endif /* MAN_OWNER */
void init_security (void)
@@ -164,6 +169,31 @@ void regain_effective_privs (void)
uid = euid;
gid = egid;
}
+ if (gid != rgid) {
+# if defined(HAVE_SETRESGID)
+ if (setresgid (rgid, egid, -1) < 0)
+# elif defined(HAVE_SETREGID)
+ if (setregid (rgid, egid) < 0)
+# elif defined(HAVE_SETEGID)
+ if (setegid (rgid) < 0)
+# endif
+ gripe_set_egid();
+
+ gid = rgid;
+ }
+
+ if (gid != egid) {
+# if defined(HAVE_SETRESGID)
+ if (setresgid (egid, rgid, -1))
+# elif defined(HAVE_SETREGID)
+ if (setregid (egid, rgid) < 0)
+# elif defined(HAVE_SETEGID)
+ if (setegid (egid))
+# endif
+ gripe_set_egid();
+
+ gid = egid;
+ }
#endif /* MAN_OWNER */
}
--- a/mk_catdirs
+++ b/mk_catdirs 2023-08-15 08:31:31.135097942 +0000
@@ -0,0 +1,30 @@
+#!/bin/sh
+
+OLDPWD="`pwd`"
+CACHE="$1/var/cache/man"
+
+ cats="cat{0,1,2,3,4,5,6,7,8,9,n}"
+locale="{ca,cs,da,de,en,es,et,fi,fr,ga,hu,is,it,ja,ko,nl,no,pl,pt,ru,sk,sr,sv,uk}"
+ dirs="{local,opt}"
+
+umask 022
+test -d ${CACHE} && rm -rf ${CACHE}
+mkdir -p ${CACHE}
+
+catman=false
+grep -qE '#[[:blank:]]*define[[:blank:]]+MAN_CATS' include/manconfig.h && catman=true
+cd ${CACHE}
+if $catman ; then
+ eval echo ${cats} \
+ ${locale}/${cats} \
+ ${dirs}/${cats} \
+ ${dirs}/${locale}/${cats}
+else
+ eval echo ${locale} \
+ ${dirs} \
+ ${dirs}/${locale}
+fi | xargs mkdir -p
+sync
+cd ${OLDPWD}
+
+test "$(id -u)" -ne 0 || chown man:man -R ${CACHE}
--- a/src/check_mandirs.c
+++ b/src/check_mandirs.c 2023-08-15 08:31:31.139097869 +0000
@@ -381,7 +381,7 @@ void chown_if_possible (const char *path
#endif /* MAN_OWNER */
/* create the catman hierarchy if it doesn't exist */
-static void mkcatdirs (const char *mandir, const char *catdir)
+void mkcatdirs (const char *mandir, const char *catdir)
{
char *manname, *catname;
@@ -409,9 +409,14 @@ static void mkcatdirs (const char *mandi
int j;
regain_effective_privs ();
debug ("creating catdir hierarchy %s ", catdir);
- for (j = 1; j <= 9; j++) {
- catname[strlen (catname) - 1] = '0' + j;
- manname[strlen (manname) - 1] = '0' + j;
+ for (j = 0; j <= 10; j++) {
+ char c;
+ if (j < 10)
+ c = '0' + j;
+ else
+ c = 'n';
+ catname[strlen (catname) - 1] = c;
+ manname[strlen (manname) - 1] = c;
if ((is_directory (manname) == 1)
&& (is_directory (catname) != 1)) {
if (mkdir (catname, 0755) < 0) {
@@ -419,7 +424,7 @@ static void mkcatdirs (const char *mandi
error (0, 0, _("warning: cannot create catdir %s"), catname);
debug ("warning: cannot create catdir %s\n", catname);
} else
- debug (" cat%d", j);
+ debug (" cat%c", c);
chown_if_possible (catname);
}
}
@@ -562,15 +567,10 @@ static int testmandirs (MYDBM_FILE dbf,
}
if (!quiet) {
- int tty = isatty (STDERR_FILENO);
-
- if (tty)
- fprintf (stderr, "\r");
fprintf (stderr,
_("Updating index cache for path "
"`%s/%s'. Wait..."), path, mandir->d_name);
- if (!tty)
- fprintf (stderr, "\n");
+ fprintf (stderr, "\n");
}
add_dir_entries (dbf, path, mandir->d_name);
amount++;
@@ -639,7 +639,7 @@ int update_db (MYDBM_FILE dbf, const cha
int new;
if (!ensure_db_open (dbf) || !sanity_check_db (dbf)) {
- debug ("failed to open %s O_RDONLY\n", dbf->name);
+ debug ("failed to open database %s O_RDONLY\n", dbf->name);
return -1;
}
mtime = MYDBM_GET_TIME (dbf);
@@ -847,6 +847,7 @@ static int purge_whatis (MYDBM_FILE dbf,
"would delete\n", name, info->ext);
return 1;
}
+ return 1;
}
/* Check that multi keys are correctly constructed. */
@@ -944,6 +945,14 @@ int purge_missing (MYDBM_FILE dbf, const
}
#pragma GCC diagnostic pop
+ /* Ignore db identifier keys. */
+ if (*MYDBM_DPTR (key) == '.' && *(key.dptr+1) == 0) {
+ nextkey = MYDBM_NEXTKEY (dbf, key);
+ MYDBM_FREE_DPTR (key);
+ key = nextkey;
+ continue;
+ }
+
content = MYDBM_FETCH (dbf, key);
if (!MYDBM_DPTR (content)) {
nextkey = MYDBM_NEXTKEY (dbf, key);
--- a/src/lexgrog.l
+++ b/src/lexgrog.l 2023-08-15 08:33:23.053105426 +0000
@@ -70,7 +70,7 @@
#include "manconv.h"
#include "manconv_client.h"
-#define YY_READ_BUF_SIZE 1024
+#define YY_READ_BUF_SIZE YY_BUF_SIZE
#define MAX_NAME 8192
/* defines the ordered list of filters detected by lexgrog */
@@ -229,15 +229,15 @@ static const struct macro perldocs[] = {
{ "R\"", "\"" }
};
-static void add_str_to_whatis (const char *string, size_t length);
-static void add_char_to_whatis (unsigned char c);
-static void add_separator_to_whatis (void);
-static void add_wordn_to_whatis (const char *string, size_t length);
-static void add_word_to_whatis (const char *string);
-static void add_glyph_to_whatis (const char *string, size_t length);
-static void add_perldoc_to_whatis (const char *string, size_t length);
-static void mdoc_text (const char *string);
-static void newline_found (void);
+static __inline__ void add_str_to_whatis (const char *string, size_t length);
+static __inline__ void add_char_to_whatis (unsigned char c);
+static __inline__ void add_separator_to_whatis (void);
+static __inline__ void add_wordn_to_whatis (const char *string, size_t length);
+static __inline__ void add_word_to_whatis (const char *string);
+static __inline__ void add_glyph_to_whatis (const char *string, size_t length);
+static __inline__ void add_perldoc_to_whatis (const char *string, size_t length);
+static __inline__ void mdoc_text (const char *string);
+static __inline__ void newline_found (void);
static char newname[MAX_NAME];
static char *p_name;
@@ -246,6 +246,7 @@ static char filters[MAX_FILTERS];
static bool fill_mode;
static bool waiting_for_quote;
+static int have_separator;
static decompress *decomp;
@@ -263,7 +264,7 @@ static decompress *decomp;
%}
%option ecs meta-ecs
-%option 8bit batch caseful never-interactive
+%option 8bit batch caseful never-interactive align
%option nostdinit
%option warn
%option noyywrap nounput
@@ -302,8 +303,9 @@ font_change \\f([[:upper:]1-4]|\({upper}
size_change \\s[+-]?{digit}
style_change ({font_change}{size_change}?|{size_change}{font_change}?)
typeface \.(B[IR]?|I[BR]?|R[BI]|S[BM])
+paragr \.[PITLH][Pp]
sec_request \.[Ss][HhYySs]
-comment ['.]\\{dbl_quote}
+comment (['.]\\{dbl_quote}|\'\-+|\\&)
/* Please add to this list if you know how. */
/* Note that, since flex only supports UTF-8 by accident, character classes
@@ -345,7 +347,26 @@ vi_name T(Ê|ê)[Nn]
zh_CN_name 名{blank}?(称|字){blank}?.*
zh_TW_name (名{blank}?(稱|字)|命令名){blank}?.*
name ({ar_name}|{bg_name}|{cs_name}|{da_name}|{de_name}|{en_name}|{eo_name}|{es_name}|{fa_name}|{fi_name}|{fr_name}|{hu_name}|{id_name}|{it_name}|{ja_name}|{ko_name}|{latin_name}|{lt_name}|{nl_name}|{pl_name}|{ro_name}|{ru_name}|{sk_name}|{sr_name}|{srlatin_name}|{sv_name}|{ta_name}|{tr_name}|{uk_name}|{vi_name}|{zh_CN_name}|{zh_TW_name})
-name_sec {dbl_quote}?{style_change}?{name}{style_change}?({blank}*{dbl_quote})?
+name_sec {dbl_quote}?{style_change}?{name}{style_change}?({blank}*{dbl_quote})?\r?
+start {sec_request}{blank_eol}+{name_sec}
+
+N N(\bN)?
+n (N(\bN)?|n(\bn)?)
+a (A(\bA)?|a(\ba)?)
+o (O(\bO)?|o(\bo)?)
+m (M(\bM)?|M(\bM)?)
+e (E(\bE)?|e(\be)?)
+B B(\bB)
+b (B(\bB)?|b(\bb)?)
+r (R(\bR)?|r(\br)?)
+z (Z(\bZ)?|z(\bz)?)
+i (I(\bI)?|i(\bi)?)
+c (C(\bC)?|c(\bc)?)
+h (H(\bH)?|h(\bh)?)
+u (U(\bU)?|u(\bu)?)
+g (G(\bG)?|g(\bg)?)
+
+cname (({N}({a}|{o}){m}({n}|{e})|{N}{o}{m}|{N}{o}{m}{b}{r}{e}|{B}{e}{z}{e}{i}{c}{h}{n}{u}{n}{g})|{bg_name}|{cs_name}|{hu_name}|{ko_name}|{ru_name}|{sr_name}|{tr_name}|{vi_name}|{ja_name}|{zh_CN_name}|{zh_TW_name})
/* eptgrv : eqn, pic, tbl, grap, refer, vgrind */
tbl_request \.TS
@@ -359,8 +380,13 @@ vgrind_request \.vS
%%
/* begin NAME section processing */
-<MAN_FILE>{sec_request}{blank_eol}+{name_sec}{blank}* BEGIN (MAN_PRENAME);
-<CAT_FILE>{empty}{2,}{name}{blank}*{indent} BEGIN (CAT_NAME);
+<MAN_FILE>{
+ {start}{blank}*{bol}{blank}*{paragr} | /* strange format */
+ {start}{blank}* { /* default */
+ BEGIN (MAN_PRENAME);
+ }
+}
+<CAT_FILE>{empty}{2,}{cname}{blank}*{indent} BEGIN (CAT_NAME);
/* general text matching */
<MAN_FILE>{
@@ -435,6 +461,7 @@ vgrind_request \.vS
{bol}\.sp{blank}* | /* vertical spacing */
{bol}\.ig{blank}* | /* block comment */
{bol}\.de[1i]?{blank}* | /* macro definition */
+ {bol}\.V[be]{blank}* | /* special in perl pages */
{bol}\.i[ef]{blank}* | /* conditional */
{empty}{bol}.+ |
<<EOF>> { /* terminate the string */
@@ -482,8 +509,8 @@ vgrind_request \.vS
/* Toggle fill mode */
<MAN_NAME,MAN_DESC>{
- {bol}\.nf.* fill_mode = false;
- {bol}\.fi.* fill_mode = true;
+ {bol}\.(nf|de).* fill_mode = false;
+ {bol}\.(fi|\.).* fill_mode = true;
}
<CAT_NAME>-{eol}{blank_eol}* /* strip continuations */
@@ -492,6 +519,9 @@ vgrind_request \.vS
<MAN_NAME>{
{next}{blank}*\\\((mi|hy|em|en){blank}* |
{next}{blank}*\\\[(mi|hy|em|en)\]{blank}* |
+ {bol}\.sp{bol}{blank}+\\-{blank}* | /* strange spacing in NAME section */
+ {blank}+[-\\]?-{bol} | /* dash at end of line */
+ {next}{blank_eol}+(\\?-){2}{blank}+ | /* some man pages use -- as dash */
{next}{blank_eol}+[-\\]-{blank}* |
{next}{blank_eol}*[-\\]-{blank}+ |
{bol}\.Nd{blank}* {
--- a/src/man.c
+++ b/src/man.c 2023-08-15 08:45:27.956189368 +0000
@@ -56,6 +56,7 @@
#include <time.h>
#include <sys/types.h>
#include <sys/stat.h>
+#include <sys/time.h>
#include "argp.h"
#include "attribute.h"
@@ -116,6 +117,8 @@
#ifdef MAN_OWNER
extern uid_t ruid;
extern uid_t euid;
+extern gid_t rgid;
+extern gid_t egid;
#endif /* MAN_OWNER */
/* the default preprocessor sequence */
@@ -239,10 +242,10 @@ static int first_arg;
#ifdef MAN_CATS
static char *tmp_cat_file; /* for open_cat_stream(), close_cat_stream() */
static bool created_tmp_cat; /* dto. */
-#endif
static int tmp_cat_fd;
static struct timespec man_modtime; /* modtime of man page, for
* commit_tmp_cat() */
+#endif
# ifdef TROFF_IS_GROFF
static bool ditroff;
@@ -1561,6 +1564,18 @@ static void setenv_less (pipecmd *cmd, c
free (less_opts);
}
+static void disable_x(void)
+{
+ char *bname = basename((char*)pager);
+ if (bname) {
+ if (!strcmp(bname, "less"))
+ unsetenv("DISPLAY");
+#if 0
+ free(bname);
+#endif
+ }
+}
+
static void add_output_iconv (pipeline *p,
const char *source, const char *target)
{
@@ -1691,6 +1706,8 @@ static pipeline *make_display_command (c
if (pager_cmd) {
setenv_less (pager_cmd, title);
+ if (!htmlout)
+ disable_x();
pipeline_command (p, pager_cmd);
}
pipeline_ignore_signals (p, 1);
@@ -1701,7 +1718,7 @@ static pipeline *make_display_command (c
return p;
}
-
+#ifdef MAN_CATS
/* return a (malloced) temporary name in cat_file's directory */
static char *tmp_cat_filename (const char *cat_file)
{
@@ -1729,7 +1746,6 @@ static char *tmp_cat_filename (const cha
return name;
}
-
/* If delete unlink tmp_cat, else commit tmp_cat to cat_file.
Return non-zero on error.
*/
@@ -1802,6 +1818,7 @@ static int commit_tmp_cat (const char *c
return status;
}
+#endif /* MAN_CATS */
/* TODO: This should all be refactored after work on the decompression
* library is complete.
@@ -1838,7 +1855,6 @@ static void cleanup_unlink (void *arg)
}
#ifdef MAN_CATS
-
/* Return pipeline to write formatted manual page to for saving as cat file. */
static pipeline *open_cat_stream (const char *cat_file, const char *encoding)
{
@@ -2070,6 +2086,7 @@ static void format_display (decompress *
regain_effective_privs ();
}
+#ifdef MAN_CATS
/* "Display" a page in catman mode, which amounts to saving it. */
/* TODO: merge with format_display_and_save? */
static void display_catman (const char *cat_file, decompress *d,
@@ -2115,6 +2132,7 @@ static void display_catman (const char *
pop_cleanup (cleanup_unlink, tmpcat);
free (tmpcat);
}
+#endif /* MAN_CATS */
static void disable_hyphenation (void *data MAYBE_UNUSED)
{
@@ -2317,7 +2335,7 @@ static int display (const char *dir, con
format_cmd = NULL;
decomp_errno = errno;
}
-
+#ifdef MAN_CATS
/* Get modification time, for commit_tmp_cat(). */
if (man_file && *man_file) {
struct stat stb;
@@ -2327,7 +2345,7 @@ static int display (const char *dir, con
} else
man_modtime = get_stat_mtime (&stb);
}
-
+#endif /* MAN_CATS */
display_to_stdout = troff;
#ifdef TROFF_IS_GROFF
if (htmlout || gxditview)
@@ -2468,6 +2486,7 @@ static int display (const char *dir, con
}
if (printed)
putchar ('\n');
+#ifdef MAN_CATS
} else if (catman) {
if (format) {
if (!save_cat)
@@ -2480,6 +2499,7 @@ static int display (const char *dir, con
format_cmd,
formatted_encoding);
}
+#endif /* MAN_CATS */
} else if (format) {
/* no cat or out of date */
pipeline *disp_cmd;
@@ -4011,17 +4031,20 @@ static int local_man_loop (const char *a
/* Check that the file exists and isn't e.g. a directory */
if (stat (argv, &st)) {
error (0, errno, "%s", argv);
+ regain_effective_privs ();
return NOT_FOUND;
}
if (S_ISDIR (st.st_mode)) {
error (0, EISDIR, "%s", argv);
+ regain_effective_privs ();
return NOT_FOUND;
}
if (S_ISCHR (st.st_mode) || S_ISBLK (st.st_mode)) {
/* EINVAL is about the best I can do. */
error (0, EINVAL, "%s", argv);
+ regain_effective_privs ();
return NOT_FOUND;
}
@@ -4085,6 +4108,11 @@ executable_out:
argv_abs = xstrdup (argv);
}
lang = lang_dir (argv_abs);
+ if (!lang || !*lang) {
+ if (lang)
+ free(lang);
+ lang = xstrdup(internal_locale);
+ }
free (argv_abs);
if (!display (NULL, argv, NULL, argv_base, NULL)) {
if (local_mf)
@@ -4340,7 +4368,16 @@ int main (int argc, char *argv[])
umask (022);
init_locale ();
- internal_locale = setlocale (LC_MESSAGES, NULL);
+ internal_locale = setlocale (LC_MESSAGES, "");
+#if defined(__GLIBC__)
+# if (__GLIBC__ < 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ < 2)
+ if (!internal_locale) {
+ if ( !(internal_locale = getenv ("LC_ALL"))
+ && !(internal_locale = getenv ("LC_MESSAGES")))
+ internal_locale = getenv ("LANG");
+ }
+# endif
+#endif
/* Use LANGUAGE only when LC_MESSAGES locale category is
* neither "C" nor "POSIX". */
if (internal_locale && strcmp (internal_locale, "C") &&
@@ -4385,7 +4422,16 @@ int main (int argc, char *argv[])
if (external)
do_extern (argc, argv);
+#ifdef MAN_OWNER
+ if (isatty(fileno(stdin)) && isatty(fileno(stdout))) {
+ tcgetattr(fileno(stdin), &tms);
+ tms_pid = getpid ();
+ if (!tms_set++)
+ atexit(set_term);
+ }
+#else
get_term (); /* stores terminal settings */
+#endif
/* close this locale and reinitialise if a new locale was
issued as an argument or in $MANOPT */
--- a/src/man_db.conf.in
+++ b/src/man_db.conf.in 2023-08-15 08:31:31.139097869 +0000
@@ -20,6 +20,14 @@
MANDATORY_MANPATH /usr/man
MANDATORY_MANPATH /usr/share/man
MANDATORY_MANPATH /usr/local/share/man
+MANDATORY_MANPATH /opt/man
+MANDATORY_MANPATH /opt/dx/man
+MANDATORY_MANPATH /opt/lsb/man
+MANDATORY_MANPATH /opt/cross/share/man
+MANDATORY_MANPATH /opt/mpich/man
+MANDATORY_MANPATH /opt/lsb-tet3-lite/share/man
+MANDATORY_MANPATH /opt/snavigator/man
+MANDATORY_MANPATH /opt/novell/man
#---------------------------------------------------------
# set up PATH to MANPATH mapping
# ie. what man tree holds man pages for what binary directory.
@@ -34,8 +42,10 @@ MANPATH_MAP /usr/local/bin /usr/local/m
MANPATH_MAP /usr/local/bin /usr/local/share/man
MANPATH_MAP /usr/local/sbin /usr/local/man
MANPATH_MAP /usr/local/sbin /usr/local/share/man
-MANPATH_MAP /usr/X11R6/bin /usr/X11R6/man
-MANPATH_MAP /usr/bin/X11 /usr/X11R6/man
+MANPATH_MAP /usr/X11R6/bin /usr/share/man
+MANPATH_MAP /usr/X11/bin /usr/share/man
+MANPATH_MAP /usr/bin/X11 /usr/share/man
+MANPATH_MAP /usr/bin/mh /usr/share/man
MANPATH_MAP /usr/games /usr/share/man
MANPATH_MAP /opt/bin /opt/man
MANPATH_MAP /opt/sbin /opt/man
@@ -68,7 +78,8 @@ MANDB_MAP /usr/share/man /var/cache/man
MANDB_MAP /usr/local/man /var/cache/man/oldlocal
MANDB_MAP /usr/local/share/man /var/cache/man/local
MANDB_MAP /usr/X11R6/man /var/cache/man/X11R6
-MANDB_MAP /opt/man /var/cache/man/opt
+MANDB_MAP /opt/man /var/cache/man/oldopt
+MANDB_MAP /opt/share/man /var/cache/man/opt
MANDB_MAP @snapdir@/man /var/cache/man/snap
#
#---------------------------------------------------------
--- a/src/mandb.c
+++ b/src/mandb.c 2023-08-15 08:35:07.783240325 +0000
@@ -213,6 +213,8 @@ struct dbpaths {
#ifdef MAN_OWNER
extern uid_t ruid;
extern uid_t euid;
+extern gid_t rgid;
+extern gid_t egid;
#endif /* MAN_OWNER */
static gl_list_t manpathlist;
@@ -638,6 +640,8 @@ static int mandb (struct dbpaths *dbpath
return amount;
}
+extern void mkcatdirs (const char *, const char *);
+
static int process_manpath (const char *manpath, bool global_manpath,
gl_map_t tried_catdirs)
{
@@ -679,6 +683,8 @@ static int process_manpath (const char *
} else
run_mandb = true;
+ mkcatdirs (manpath, catpath);
+
dbpaths = XZALLOC (struct dbpaths);
push_cleanup ((cleanup_fun) dbpaths_free_elements, dbpaths, 0);
push_cleanup ((cleanup_fun) dbpaths_unlink_tmp, dbpaths, 1);
@@ -697,7 +703,7 @@ static int process_manpath (const char *
if (!opt_test && (amount || new_purged || new_strays)) {
dbpaths_rename_from_tmp (dbpaths);
#ifdef MAN_OWNER
- if (global_manpath)
+ if (global_manpath && (euid == 0 || ruid == 0))
dbpaths_chown_if_possible (dbpaths);
#endif /* MAN_OWNER */
reorganize (catpath, global_manpath);
@@ -896,8 +902,14 @@ int main (int argc, char *argv[])
#ifdef MAN_OWNER
man_owner = get_man_owner ();
- if (!user && euid != 0 && euid != man_owner->pw_uid)
- user = true;
+ if (!user) {
+ if (!ruid && euid != man_owner->pw_uid) {
+ seteuid(man_owner->pw_uid);
+ euid = geteuid();
+ }
+ if (euid != man_owner->pw_uid)
+ user = true;
+ }
#endif /* MAN_OWNER */
read_config_file (user);
--- a/src/manp.c
+++ b/src/manp.c 2023-08-15 08:31:31.139097869 +0000
@@ -907,7 +907,7 @@ static char *def_path (enum config_flag
/* If we have complete config file failure... */
if (!manpath)
- return xstrdup ("/usr/man");
+ return xstrdup ("/usr/share/man");
return manpath;
}
--- a/src/straycats.c
+++ b/src/straycats.c 2023-08-15 08:31:31.139097869 +0000
@@ -38,6 +38,7 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
+#include <fcntl.h>
#include <dirent.h>
#include "canonicalize.h"
--- a/src/ult_src.c
+++ b/src/ult_src.c 2023-08-15 08:37:50.940333586 +0000
@@ -160,10 +160,15 @@ static char *find_include_directive (cha
}
decompress_start (decomp);
- /* make sure that we skip over any comments */
+ /*
+ * make sure that we skip over any comments
+ * ... even if we handle TCL/TK manual pages
+ */
do {
buffer = decompress_readline (decomp);
- } while (buffer && STRNEQ (buffer, ".\\\"", 3));
+ } while (buffer && *buffer &&
+ (STRNEQ (buffer, ".\\\"", 3) ||
+ STRNEQ (buffer, "'\\\"", 3)));
directive = xstrdup (buffer ? buffer : "");

30
man-db-create.service Normal file
View File

@ -0,0 +1,30 @@
[Unit]
Description=Initialize /var/cache/man
DefaultDependencies=no
Wants=local-fs.target
After=local-fs.target
After=systemd-tmpfiles-setup.service
ConditionPathExists=/var/cache/man
ConditionPathExists=!/var/cache/man/index.db
[Service]
# added automatically, for details please see
# https://en.opensuse.org/openSUSE:Security_Features#Systemd_hardening_effort
ProtectSystem=full
ProtectHome=true
PrivateDevices=true
ProtectHostname=true
ProtectClock=true
ProtectKernelTunables=true
ProtectKernelModules=true
ProtectKernelLogs=true
ProtectControlGroups=true
RestrictRealtime=true
# end of automatic additions
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/bin/mandb --quiet --create
[Install]
WantedBy=multi-user.target

View File

@ -0,0 +1,29 @@
From b12ffb9df7a6a8956b08206c36be70fac78508bd Mon Sep 17 00:00:00 2001
From: Colin Watson <cjwatson@debian.org>
Date: Thu, 20 Jul 2023 00:18:59 +0100
Subject: [PATCH] Update warning regex for groff 1.23.0
Part of https://gitlab.com/man-db/man-db/-/issues/25.
* man/check-man: groff 1.23.0 says "cannot break line" rather than
"can't break line"; update regular expression.
---
man/check-man | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/man/check-man b/man/check-man
index a58b7f9d..f8985a0d 100755
--- a/man/check-man
+++ b/man/check-man
@@ -31,7 +31,7 @@ errors="$(LC_ALL=C MANWIDTH=80 MAN_KEEP_FORMATTING=1 "$top_builddir/libtool" \
# Indeed, even for other languages we're going to get "cannot adjust line"
# if %manpath_config_file% expands to something long. Hmm. We'll just ignore
# this across the board for now.
-errors="$(echo "$errors" | $EGREP -v "(cannot adjust line|can't break line)")" || true
+errors="$(echo "$errors" | $EGREP -v "(cannot adjust line|(can't|cannot) break line)")" || true
if [ "$code" != 0 ]; then
echo "man -E UTF-8 -l $1 failed with exit status $code and error output:"
--
GitLab

34
man-propose-online.patch Normal file
View File

@ -0,0 +1,34 @@
diff -ur man-db-2.10.2/src/man.c man-db-2.10.2.patch/src/man.c
--- man-db-2.10.2/src/man.c 2022-03-17 19:41:27.000000000 +0100
+++ man-db-2.10.2.patch/src/man.c 2023-04-03 17:13:05.944119389 +0200
@@ -775,11 +775,16 @@
}
#endif
- if (sec)
+ if (sec) {
fprintf (stderr, _("No manual entry for %s in section %s\n"),
name, sec);
- else
+ fprintf (stderr, _("Possibly, man page is not installed, try online at: "));
+ fprintf (stderr, _("https://manpages.opensuse.org/%s.%s\n"), name, sec);
+ } else {
fprintf (stderr, _("No manual entry for %s\n"), name);
+ fprintf (stderr, _("Possibly, man page is not installed, try online at: "));
+ fprintf (stderr, _("https://manpages.opensuse.org/%s\n"), name);
+ }
#ifdef UNDOC_COMMAND
if (getenv ("MAN_TEST_DISABLE_UNDOCUMENTED") == NULL &&
diff -ur man-db-2.10.2/src/tests/man-invalid-db-entry man-db-2.10.2.patch/src/tests/man-invalid-db-entry
--- man-db-2.10.2/src/tests/man-invalid-db-entry 2022-03-17 19:41:27.000000000 +0100
+++ man-db-2.10.2.patch/src/tests/man-invalid-db-entry 2023-04-03 17:13:55.256508193 +0200
@@ -25,6 +25,8 @@
rm -f "$tmpdir/usr/share/man/man1/test.1"
echo "No manual entry for test" > "$tmpdir/1.exp"
+echo "Possibly, man page is not installed, try online at: https://manpages.opensuse.org/test" >> "$tmpdir/1.exp"
+
LC_ALL=C run $MAN -C "$tmpdir/manpath.config" test 2> "$tmpdir/1.out"
expect_files_equal 'invalid DB entry' "$tmpdir/1.exp" "$tmpdir/1.out"

4
man-rpmlintrc Normal file
View File

@ -0,0 +1,4 @@
# We use %posttrans
addFilter(".*W:.*post-without-tmpfile-creation.*/usr/lib/tmpfiles\.d/man-db\.conf.*")
addFilter(".*W:.*name-repeated-in-summary.*man.*")
addFilter(".*E:.*missing-call-to-setgroups-before-setuid.*/usr/lib64/libman-.*\.so.*")

1922
man.changes Normal file

File diff suppressed because it is too large Load Diff

648
man.keyring Normal file
View File

@ -0,0 +1,648 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: GnuPG v1.4.9 (GNU/Linux)
Comment: Colin Watson <cjwatson@debian.org> -- Debian developer
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
3VAe
=JloC
-----END PGP PUBLIC KEY BLOCK-----

381
man.spec Normal file
View File

@ -0,0 +1,381 @@
#
# spec file for package man
#
# Copyright (c) 2023 SUSE LLC
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
# upon. The license for this file, and modifications and additions to the
# file, is the same license as for the pristine package itself (unless the
# license for the pristine package is not an Open Source License, in which
# case the license is the MIT License). An "Open Source License" is a
# license that conforms to the Open Source Definition (Version 1.9)
# published by the Open Source Initiative.
# Please submit bugfixes or comments via https://bugs.opensuse.org/
#
%global _sysconfdir %{_sysconfdir}
%global _has_tmpfiled %(rpm -q -f %{_prefix}/lib/tmpfiles.d | grep -c filesystem)
#Compat macro for new _fillupdir macro introduced in Nov 2017
%if ! %{defined _fillupdir}
%define _fillupdir %{_localstatedir}/adm/fillup-templates
%endif
%define add_optflags(a:f:t:p:w:W:d:g:O:A:C:D:E:H:i:M:n:P:U:u:l:s:X:B:I:L:b:V:m:x:c:S:E:o:v:) \
%global optflags %{optflags} %{**}
%bcond_without sdtimer
Name: man
Version: 2.11.2
Release: 0
Summary: A Program for Displaying man Pages
License: GPL-2.0-or-later
Group: System/Base
URL: https://savannah.nongnu.org/projects/man-db
Source0: https://download.savannah.gnu.org/releases/man-db/man-db-%{version}.tar.xz
Source1: https://download.savannah.gnu.org/releases/man-db/man-db-%{version}.tar.xz.asc
Source2: https://savannah.nongnu.org/people/viewgpg.php?user_id=10653#/%{name}.keyring
Source3: sysconfig.cron-man
Source4: cron.daily.do_mandb
Source5: wrapper.c
Source6: man-rpmlintrc
Source7: man-db-create.service
Source8: manpath.csh
Source9: manpath.sh
Patch0: man-db-2.3.19deb4.0-groff.dif
Patch3: man-db-2.6.3-chinese.dif
# PATCH-FEATURE-OPENSUSE man-db-2.7.1-zio.dif -- Allow using libzio for decompression
Patch4: man-db-2.7.1-zio.dif
# PATCH-FEATURE-OPENSUSE man-db-2.6.3-listall.dif -- If multiple matching pages are found show a list bnc#786679
Patch5: man-db-2.6.3-listall.dif
# PATCH-FIX-SUSE Fixes build-compare bnc#971922
Patch6: reproducible.patch
# PATCH-FIX-OPENSUSE man-db-2.9.4-no-chown.patch -- chown is not allowed as non-root
Patch7: man-db-2.9.4-no-chown.patch
# PATCH-FIX-SUSE collections of changes
Patch8: man-db-2.9.4.patch
# PATCH-FEATURE-OPENSUSE -- Add documentation about man0 section (header files)
Patch9: man-db-2.6.3-man0.dif
Patch10: man-db-2.9.4-alternitive.dif
# PATCH-FEATURE-OPENSUSE -- Propose to read man pages online
Patch12: man-propose-online.patch
# PATCH-FIX-UPSTREAM -- Update warning regex for groff 1.23.0
Patch13: man-db-groff-1.23.0-warnings.patch
BuildRequires: automake
BuildRequires: flex
BuildRequires: gdbm-devel
BuildRequires: gettext-runtime
BuildRequires: gettext-tools
BuildRequires: groff
BuildRequires: less
BuildRequires: libalternatives-devel
BuildRequires: libpipeline-devel >= 1.5.0
BuildRequires: libzio-devel
BuildRequires: lzip
BuildRequires: man-pages
BuildRequires: pkgconfig
BuildRequires: po4a
BuildRequires: zlib-devel
BuildRequires: zstd
BuildRequires: pkgconfig(systemd)
Conflicts: mandoc
Requires: glibc-locale-base
Suggests: glibc-locale
Requires: groff >= 1.18
Requires: less
# FIXME: use proper Requires(pre/post/preun/...)
PreReq: coreutils
PreReq: fillup
Requires(posttrans):systemd
Requires(pre): group(man)
Requires(pre): user(man)
Provides: man_db
%if 0%{?suse_version} < 1500
Requires: cron
%endif
%description
A program for displaying man pages on the screen or sending them to a
printer (using groff).
%prep
%setup -q -n man-db-%{version}
%patch0 -b .groff
%patch3 -b .chinese
%patch4 -b .zio
%patch5 -b .listall
%patch6 -p1 -b .p6
%patch7 -p1 -b .p7
%patch8 -p1 -b .p8
%patch9 -b .p9
%patch10 -b .libalernative
rm -f configure
%patch12 -p1 -b .p12
%patch13 -p1 -b .p13
%build
%global optflags %{optflags} -funroll-loops -pipe -Wall
gettextize --force --copy --no-changelog
SEC=(0 1 n l 8 3 2 5 4 9 6 7
1x 3x 4x 5x 6x 8x
1bind 3bind 5bind 7bind 8bind
1cn 8cn
1m 1mh 5mh 8mh
1netpbm 3netpbm 5netpbm
0p 1p 3p 3posix
1pgsql 3pgsql 5pgsql
3C++ 8C++
3blt
3curses 3ncurses 3form 3menu
3db 3gdbm 3f 3gk 3paper
3mm 5mm
3perl 3pm 3pq
3qt 3pub 3readline
1ssl 3ssl 5ssl 7ssl
3t 3tk 3tcl 3tclx 3tix
7l 7nr
8c
Cg g s m
)
SEC="${SEC[@]}"
for d in $(cat man/LINGUAS*) ; do
test -d %{_datadir}/locale/$d || continue
LINGUAS="${LINGUAS:+$LINGUAS }$d"
done
LIBS="-lalternatives"
export LINGUAS LIBS
# Hack as otherwise
# BuildRequires: groff-full
# is required
mkdir bin
ln -sf /bin/true bin/refer
ln -sf /bin/true bin/w3m
PATH=$PATH:${PWD}/bin
export PATH
# Create configure
aclocal -I ${PWD} -I ${PWD}/m4 -I ${PWD}/gl/m4
autoconf -B ${PWD} -B ${PWD}/m4 -B ${PWD}/gl/m4
automake --add-missing
find -name 'Makefile.*' | xargs \
sed -ri -e '/^pkglibdir/{ s@^(pkglibdir[[:blank:]]+=[[:blank:]]+\$\(libdir\)).*@\1@p }'
# Configure
%add_optflags -D_GNU_SOURCE -D_DEFAULT_SOURCE -D_XOPEN_SOURCE=500
%configure \
%if %{without sdtimer}
--with-systemdtmpfilesdir=no \
--with-systemdsystemunitdir=no \
%endif
--enable-cache-owner=man \
--with-device=utf8 \
--with-zio \
--with-gnu-ld \
--disable-rpath \
--disable-automatic-create \
--enable-automatic-update \
--enable-mandirs=GNU \
--disable-cats \
--enable-threads=posix \
--enable-mb-groff \
--with-db=gdbm \
--enable-nls \
--with-config-file=%{_sysconfdir}/manpath.config \
--with-sections="${SEC}"
%make_build nls=all LOCALE_FR_UTF8=fr_FR.UTF-8
# Fix coding
for man in $(find man/ -type f -a -name '*.[0-9]'); do
pp="$(head -n 1 $man)"
case "$pp" in
\'\\\"*\ -\*-\ coding:\ *\ -\*-)
continue
;;
\'\\\"*)
sed -ri "1{ s/('\\\\\".*)/\\1 -\*- coding: UTF-8 -\*-/ }" $man
;;
*)
sed -ri "1 i\
'\\\\\" -\*- coding: UTF-8 -\*-\
" $man
esac
done
#
gcc $CFLAGS -I gl/lib/ -I include/ --include config.h \
-D LOCALEDIR="\"%{_datarootdir}/locale\"" \
-D LIBEXECDIR="\"%{_libexecdir}\"" -o wrapper %{SOURCE5} -L gl/lib/.libs/ -lgnu
%check
if ! make check; then
cat src/tests/test-suite.log
exit 1
fi
%install
%if 0%{?suse_version} <= 1030
export MKDIR_P="mkdir -p"
%endif
rm -rf %{buildroot}%{_localstatedir}/cache/man
%make_install nls=all LOCALE_FR_UTF8=fr_FR.UTF-8
find %{buildroot} -type f -name "*.la" -delete -print
# Move manual
mkdir -p %{buildroot}%{_docdir}
mv %{buildroot}%{_datadir}/doc/man-db %{buildroot}%{_docdir}/man/
# wrapper which drops roots privileges if root executes mandb
mv -vf %{buildroot}%{_bindir}/mandb %{buildroot}%{_libexecdir}/man-db/
install -D -m 0755 wrapper %{buildroot}%{_libexecdir}/man-db/
ln -sf %{_libexecdir}/man-db/wrapper %{buildroot}%{_bindir}/mandb
# Fix man pages
pushd %{buildroot}%{_mandir}/
rm -rf *.ascii/
for d in *.UTF-8 ; do
find -name '*.[1-9nlop]' | xargs gzip -9f
done
for d in $(find -name manpath.5%{?ext_man} -printf '%%h ') ; do
ln -sf manpath.5%{?ext_man} $d/manpath.config.5%{?ext_man}
done
# remove japanese pages, as they are in man-pages-ja
# (need to cross verify at some point that they are up to date there)
rm -rf ja
popd
install -m 644 src/man_db.conf %{buildroot}%{_sysconfdir}/manpath.config
sh ./mk_catdirs %{buildroot}
mkdir -p %{buildroot}%{_datadir}/groff/site-tmac
install -m 0644 groff/tmac.andb %{buildroot}%{_datadir}/groff/site-tmac/
install -m 0644 groff/tmac.andocdb %{buildroot}%{_datadir}/groff/site-tmac/
mkdir -p %{buildroot}%{_fillupdir}
mkdir -p %{buildroot}%{_unitdir}/
%if 0%{?suse_version} < 1500
mkdir -p %{buildroot}%{_sysconfdir}/cron.daily
%endif
install -m 0644 %{SOURCE3} %{buildroot}%{_fillupdir}
%if 0%{?suse_version} < 1500
install -m 0744 %{SOURCE4} %{buildroot}%{_sysconfdir}/cron.daily/suse-do_mandb
%else
install -m 0744 %{SOURCE4} %{buildroot}/%{_libexecdir}/man-db/do_mandb
%endif
%if %{with sdtimer}
install -m 0644 %{SOURCE7} %{buildroot}%{_unitdir}/
%endif
mkdir -p %{buildroot}%{_prefix}/etc/profile.d
install -m 644 %{SOURCE8} %{buildroot}%{_prefix}/etc/profile.d/
install -m 644 %{SOURCE9} %{buildroot}%{_prefix}/etc/profile.d/
%find_lang man-db --all-name --with-man
%pre
test -d var/catman/ && rm -rf var/catman/ || true
%if %{with sdtimer}
%if 0%{?suse_version} >= 1500
%service_add_pre man-db-create.service man-db.service man-db.timer
%else
%service_add_pre man-db-create.service
%endif
%endif
if test "$1" -gt 0 -a -h %{_sysconfdir}/alternatives/man
then
for ua in man apropos whatis man.1%{ext_man} apropos.1%{ext_man} whatis.1%{ext_man}
do
rm -f %{_sysconfdir}/alternatives/$ua
case "$ua" in
*.1*)
rm -f %{_mandir}/man1/$ua
;;
*)
rm -f %{_bindir}/$ua
;;
esac
done
fi
%post
%{fillup_only -an cron}
/sbin/ldconfig
%if %{with sdtimer}
%service_add_post man-db-create.service
%if 0%{?suse_version} >= 1500
%service_add_post man-db.service man-db.timer
%endif
%endif
%preun
%if %{with sdtimer}
%service_del_preun man-db-create.service
%if 0%{?suse_version} >= 1500
%service_del_preun man-db.service man-db.timer
%endif
%endif
%postun
/sbin/ldconfig
%if %{with sdtimer}
%service_del_postun man-db-create.service
%if 0%{?suse_version} >= 1500
%service_del_postun man-db.service man-db.timer
%endif
%endif
%posttrans
%{?tmpfiles_create:%tmpfiles_create %{_prefix}/lib/tmpfiles.d/man-db.conf}
if test -d %{_localstatedir}/cache/man
then
mandb --quiet --create || :
fi
%files -f man-db.lang
%license COPYING
%doc ChangeLog
%doc %{_docdir}/man/man-db-manual*
%config %{_sysconfdir}/manpath.config
%if 0%{?suse_version} < 1500
%attr(0744,root,root) %{_sysconfdir}/cron.daily/suse-do_mandb
%endif
%dir %{_prefix}/etc/profile.d/
%{_prefix}/etc/profile.d/manpath.*
%{_bindir}/apropos
%{_bindir}/catman
%{_bindir}/lexgrog
%{_bindir}/man
%{_bindir}/mandb
%{_bindir}/manpath
%{_bindir}/man-recode
%{_bindir}/whatis
%dir %attr(0755,root,root) %{_libexecdir}/man-db
%attr(0755,root,root) %{_libexecdir}/man-db/mandb
%attr(0755,root,root) %{_libexecdir}/man-db/manconv
%attr(0755,root,root) %{_libexecdir}/man-db/globbing
%attr(0755,root,root) %{_libexecdir}/man-db/wrapper
%if 0%{?suse_version} >= 1500
%attr(0755,root,root) %{_libexecdir}/man-db/do_mandb
%endif
%{_sbindir}/accessdb
%{_libdir}/libman*.so
%{_libexecdir}/man-db/zsoelim
%if 0%{?_has_tmpfiled} == 0
%dir %{_prefix}/lib/tmpfiles.d
%endif
%{_prefix}/lib/tmpfiles.d/man-db.conf
%if %{with sdtimer}
%{_unitdir}/man-db-create.service
%if 0%{?suse_version} >= 1500
%{_unitdir}/man-db.service
%{_unitdir}/man-db.timer
%endif
%endif
%dir %{_datadir}/groff/site-tmac
%{_datadir}/groff/site-tmac/tmac.andb
%{_datadir}/groff/site-tmac/tmac.andocdb
%{_mandir}/man1/*.1%{?ext_man}
%{_mandir}/man5/*.5%{?ext_man}
%{_mandir}/man8/*.8%{?ext_man}
%dir %{_mandir}/id
%dir %{_mandir}/sr
%dir %{_mandir}/ro
%dir %{_mandir}/tr
%{_fillupdir}/sysconfig.cron-man
%defattr(-,man,man)
%ghost %{_localstatedir}/cache/man
%changelog

16
manpath.csh Normal file
View File

@ -0,0 +1,16 @@
#
# Current manpath
#
if (-x /usr/bin/manpath && ! ${?MANPATHISSET}) then
set _tmpman=`(unsetenv MANPATH; /usr/bin/manpath -q)`
if ( ${?MANPATH} ) then
if (${MANPATH} != ${_tmpman}) then
setenv MANPATH "${MANPATH}:${_tmpman}"
else
setenv MANPATH "${_tmpman}"
endif
else
setenv MANPATH "${_tmpman}"
endif
setenv MANPATHISSET yes
endif

17
manpath.sh Normal file
View File

@ -0,0 +1,17 @@
#
# Current manpath
#
if test -x /usr/bin/manpath -a -z "$MANPATHISSET"
then
_tmpenv="$MANPATH"
unset MANPATH
_tmpman="$(/usr/bin/manpath -q)"
if test -n "$_tmpenv" -a "$_tmpenv" != ${_tmpman} ; then
MANPATH="${_tmpenv}:${_tmpman}"
else
MANPATH="${_tmpman}"
fi
unset _tmpenv _tmpman
MANPATHISSET=yes
export MANPATH MANPATHISSET
fi

16
reproducible.patch Normal file
View File

@ -0,0 +1,16 @@
Index: man-db-2.7.1/manual/man_db.me
===================================================================
---
man-db-2.10.0/manual/man_db.me | 1 +
1 file changed, 1 insertion(+)
--- man-db-2.10.0/manual/man_db.me
+++ man-db-2.10.0/manual/man_db.me 2022-08-17 13:19:13.782077593 +0000
@@ -8,6 +8,7 @@
.\" Thu Sep 21 19:22:47 BST 1995 Wilf. (G.Wilford@ee.surrey.ac.uk)
.\"
.so version
+.ds td -
.ds U \s-1\fBUNIX\fR\s+1
.ds N \s-1\fBNROFF\fR\s+1
.ds T \s-1\fBTROFF\fR\s+1

8
sysconfig.cron-man Normal file
View File

@ -0,0 +1,8 @@
## Path: System/Cron/Man
## Description: cron configuration for man utility
## Type: yesno
## Default: yes
#
# Should mandb and whatis be recreated by cron.daily ("yes" or "no")
#
REINIT_MANDB=yes

175
wrapper.c Normal file
View File

@ -0,0 +1,175 @@
/*
* wrapper.c - wrapper program around man and mandb
*
* Copyright (C) 2000 Fabrizio Polacco <fpolacco@debian.org>
* Copyright (C) 2001, 2002 Colin Watson.
*
* This file is part of man-db.
*
* man-db is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* man-db is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with man-db; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif /* HAVE_CONFIG_H */
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <grp.h>
#include <pwd.h>
#include <grp.h>
#include <sys/types.h>
#include <stdlib.h>
#include <string.h>
#include "dirname.h"
#include "gettext.h"
#include <locale.h>
#define _(Text) gettext (Text)
#include "manconfig.h"
#ifndef LIBEXECDIR
# define LIBEXECDIR "/usr/lib"
#endif
/* this list is used to authenticate the program running.
* it is fixed at compile time to avoid a full class of
* dangers ...
*/
static struct {
const char *prog;
const char *run;
const char *user;
} *wlp, wrapped_list[] =
{ /* prog run user */
#ifdef DEBUG
{ "_man", "src/man", "man" },
{ "_mandb", "src/mandb", "man" },
#endif
{ "man", LIBEXECDIR "/man-db/man", "man" },
{ "mandb", LIBEXECDIR "/man-db/mandb", "man" },
{ 0, 0, 0, }};
char *program_name;
int main (int argc, char **argv, char *envp[])
{
extern char **environ;
uid_t ruid, euid;
gid_t rgid;
argc = argc; /* not used */
/* We don't warn about this setlocale() call failing, as the program
* we call will do that.
*/
setlocale (LC_ALL, "");
bindtextdomain (PACKAGE, LOCALEDIR);
bindtextdomain (PACKAGE "-gnulib", LOCALEDIR);
textdomain (PACKAGE);
/* this wrapper can be run as "man" or as "mandb" */
program_name = base_name (argv[0]);
ruid = getuid ();
euid = geteuid();
rgid = getgid ();
/* The various preprocessors should be in standard path */
environ = envp;
setenv("PATH", "/bin:/usr/bin", 1);
envp = environ;
#ifdef DEBUG
printf ("%s:\n", program_name);
#endif
for (wlp = wrapped_list; wlp->prog && strcmp (program_name, wlp->prog); ++wlp)
/* __asm__ __volatile__("": : :"memory") */;
if (!wlp->prog) {
fprintf (stderr, _("Don't know which program should I run being >%s<\n"),
program_name);
return -ENOENT;
}
#ifdef DEBUG
printf ("%s\n", wlp->run);
#endif
if (strcmp("man", wlp->prog) == 0)
/* Short cut: do not map man command to an other user */
goto man;
if (ruid == 0 || euid == 0) {
static char *dummy_environ[] = { NULL };
extern char **environ;
struct passwd *pwd;
char *cwd;
pwd = getpwnam (wlp->user);
if (!pwd) {
fprintf (stderr, _("%s: Failed su to user %s\n"), wlp->prog, wlp->user);
return -EACCES;
}
if (ruid == 0) {
ruid = pwd->pw_uid;
rgid = pwd->pw_gid;
} else {
#ifndef MAN_CATS
/* No permissions required to create files
* under the sub directories of /var/cache/man */
pwd->pw_uid = ruid;
pwd->pw_gid = rgid;
#endif
}
if ((cwd = get_current_dir_name()) == NULL) {
fprintf (stderr, _("%s: Failed su to user %s\n"), wlp->prog, wlp->user);
return -EACCES;
}
if (setregid (rgid, pwd->pw_gid)) {
fprintf (stderr, _("%s: Failed su to user %s\n"), wlp->prog, wlp->user);
return -EACCES;
}
if (initgroups (wlp->user, rgid)) {
fprintf (stderr, _("%s: Failed su to user %s\n"), wlp->prog, wlp->user);
return -EACCES;
}
if (setreuid (ruid, pwd->pw_uid)) {
fprintf (stderr, _("%s: Failed su to user %s\n"), wlp->prog, wlp->user);
return -EACCES;
}
if (access(cwd, X_OK) < 0 && chdir(pwd->pw_dir)) {
fprintf (stderr, _("%s: Failed su to user %s\n"), wlp->prog, wlp->user);
return -EACCES;
}
free(cwd);
cwd = getenv("TERM");
environ = dummy_environ;
setenv("HOME", pwd->pw_dir, 1);
setenv("PATH", "/bin:/usr/bin", 1);
setenv("USER", pwd->pw_name, 1);
setenv("LOGNAME", pwd->pw_name, 1);
if (cwd)
setenv("PWD", cwd, 1);
envp = environ;
}
man:
execve (wlp->run, argv, envp);
perror ("execve");
return -errno;
}