File man-db-2.5.2.dif of Package man

--- .pkgextract
+++ .pkgextract	2008-04-21 13:24:22.000000000 +0200
@@ -0,0 +1,10 @@
+bzcat ../man-db_2.5.2-2.diff.bz2 | patch -p1 -s --suffix=.debian
+patch -p0 -s --suffix=.groff  < ../man-db-2.3.19deb4.0-groff.dif
+patch -p0 -s --suffix=.sect   < ../man-db-2.4.3-section.dif
+patch -p0 -s --suffix=.secu4  < ../man-db-2.5.1-security4.dif
+patch -p0 -s --suffix=.firefox< ../man-db-2.4.3-firefox.dif
+patch -p0 -s --suffix=.chinese< ../man-db-2.5.2-chinese.dif
+patch -p0 -s --suffix=.glob   < ../man-db-2.5.1-globbing.dif
+patch -p0 -s --suffix=.zio    < ../man-db-2.5.1-zio.dif
+patch -p0 -s --suffix=.listall< ../man-db-2.5.1-listall.dif
+patch -p0 -s --suffix=.catp   < ../man-db-2.5.2-catp.dif
--- configure.ac
+++ configure.ac	2008-08-12 15:32:24.000000000 +0200
@@ -14,13 +14,26 @@ fi
 
 AC_CONFIG_HEADER(config.h)
 AC_CANONICAL_HOST
-
+dnl
+dnl Check $PATH for the following progs and append suitable options.
+dnl 
+AC_PROG_CC
+AC_PROG_CPP
+AC_GNU_SOURCE
+dnl 
+dnl check for system defaults
+dnl
+AC_AIX
+AC_MINIX
+AC_ISC_POSIX
+dnl
 # Define below date and version information to be put into man pages etc.
 datemark=20080505
 date=`LANG=C date -d $datemark +'%Y-%m-%d'`
 AC_SUBST(date)dnl
 roff_version=`echo AC_PACKAGE_VERSION | sed 's/-/\\-/g'`
 AC_SUBST(roff_version)dnl
+m4_pattern_allow([AC_DEFINE_UNQUOTED])
 
 # We have to be a bit naughty here and supply options.
 # The autoconf literature states that only features that can be separately
@@ -41,12 +54,12 @@ AS_HELP_STRING([--disable-setuid], [don'
 		man_owner=$enableval
 		man_mode="4755"
 		AC_MSG_NOTICE([Man will be installed setuid $enableval])
-	   	AC_DEFINE_UNQUOTED(SECURE_MAN_UID, "$man_owner",
+	   	AC_DEFINE_UNQUOTED([SECURE_MAN_UID], "$man_owner",
 				   [Define as the setuid owner of man or undefine if not installing setuid.])
 	   fi],
 	  [man_owner=man
 	   man_mode="4755"
-	   AC_DEFINE_UNQUOTED(SECURE_MAN_UID, "$man_owner")])
+	   AC_DEFINE_UNQUOTED([SECURE_MAN_UID], "$man_owner")])
 AC_ARG_ENABLE(undoc,
 [AS_HELP_STRING([--enable-undoc=COMMAND], [suggest COMMAND for missing manual pages])],
 	[if test "$enableval" = "yes" || test "$enableval" = "no"
@@ -54,7 +67,7 @@ AC_ARG_ENABLE(undoc,
 		AC_MSG_ERROR(--enable-undoc requires an argument)
 	 else
 		AC_MSG_NOTICE([Suggesting '$enableval' for missing manual pages])
-		AC_DEFINE_UNQUOTED(UNDOC_COMMAND, "$enableval",
+		AC_DEFINE_UNQUOTED([UNDOC_COMMAND], "$enableval",
 				   [Define as the name of a command you want to suggest when a non-existent page is requested.])
 	 fi])
 AC_ARG_WITH(device,
@@ -115,10 +128,7 @@ AC_SUBST(config_file_dirname)dnl
 AC_SUBST(sections)dnl
 
 # Check $PATH for the following programs and append suitable options.
-AC_GNU_SOURCE
-AC_PROG_CC
 gl_EARLY
-AC_PROG_CPP
 CFLAGS="$CFLAGS -Wall"
 if test "$GCC" = yes
 then
@@ -255,6 +265,14 @@ then
 fi
 
 MAN_CHECK_PROGS([eqn], [EQN], [use EQN to preprocess equations], [eqn geqn])
+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
@@ -280,9 +298,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"
@@ -334,7 +358,7 @@ dnl To add more decompressors just follo
 AC_ARG_ENABLE(mandirs,
 [AS_HELP_STRING([--enable-mandirs=OS], [select manual page hierarchy organization (GNU, HPUX, IRIX, Solaris, BSD)])],
 	[AC_MSG_NOTICE([Using $enableval hierarchy organization(s)])
-	 AC_DEFINE_UNQUOTED(MANDIR_LAYOUT, "$enableval",
+	 AC_DEFINE_UNQUOTED([MANDIR_LAYOUT], "$enableval",
 			    [Define to the manual page hierarchy organization(s) in use.])],
 	[case $host in
 		*-gnu)          mandirs=GNU;;
@@ -346,7 +370,7 @@ AC_ARG_ENABLE(mandirs,
 	 esac
 	 if test -n "$mandirs"; then
 		AC_MSG_NOTICE([Using $mandirs hierarchy organization])
-		AC_DEFINE_UNQUOTED(MANDIR_LAYOUT, "$mandirs")
+		AC_DEFINE_UNQUOTED([MANDIR_LAYOUT], "$mandirs")
 	 else
 		AC_MSG_NOTICE([Allowing any hierarchy organization])
 		AC_DEFINE(MANDIR_LAYOUT, "")
@@ -362,8 +386,7 @@ AC_HEADER_DIRENT
 AC_CHECK_HEADERS(fcntl.h sys/file.h)
 
 # Internationalization support.
-AM_GNU_GETTEXT
-AM_GNU_GETTEXT_VERSION([0.17])
+AM_GNU_GETTEXT([external])
 AC_SUBST(LINGUAS)
 AM_ICONV
 AM_CONDITIONAL([NLS], [test "$USE_NLS" = yes])
@@ -491,6 +514,5 @@ AC_CONFIG_FILES(Makefile
 	tools/Makefile
 	include/comp_src.h
 	include/manconfig.h
-	intl/Makefile
 	po/Makefile.in)
 AC_OUTPUT
--- mk_catdirs
+++ mk_catdirs	2009-08-03 13:22:19.201901113 +0200
@@ -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}
--- include/comp_src.h.in
+++ include/comp_src.h.in	2007-12-10 12:51:50.000000000 +0100
@@ -53,7 +53,7 @@ struct compression comp_list[] = {
 #endif /* HAVE_GZIP */
 
 /* If we have compress, incorporate the following */
-#ifdef HAVE_COMPRESS
+#if defined(HAVE_COMPRESS) || defined(HAVE_GZIP)
 	{UNCOMPRESS, "Z", NULL},
 #endif /* HAVE_COMPRESS */
 
--- include/manconfig.h.in
+++ include/manconfig.h.in	2008-08-12 16:59:18.600458442 +0200
@@ -73,7 +73,7 @@
 
 #undef MAN_DB_CREATES
 #define MAN_DB_UPDATES
-#define MAN_CATS
+#undef MAN_CATS
 
 /* By default, man-db will store a whatis referenced manual page in favour
    of a stray cat page when they both share identical namespace. If you
--- intl/Makefile.in
+++ intl/Makefile.in	2007-12-10 12:51:51.000000000 +0100
@@ -181,7 +181,7 @@ libgnuintl.h.msvc-shared Makefile.msvc
 
 all: all-@USE_INCLUDED_LIBINTL@
 all-yes: libintl.$la libintl.h charset.alias ref-add.sed ref-del.sed
-all-no: all-no-@BUILD_INCLUDED_LIBINTL@
+all-no: all-no-@USE_INCLUDED_LIBINTL@
 all-no-yes: libgnuintl.$la
 all-no-no:
 
--- libdb/db_storage.h
+++ libdb/db_storage.h	2008-04-21 15:18:56.000000000 +0200
@@ -70,10 +70,10 @@ struct mandata {
 }; 
 
 /* used by the world */
-extern inline struct mandata *dblookup_all (const char *page,
+extern struct mandata *dblookup_all (const char *page,
 					    const char *section,
 					    int match_case);
-extern inline struct mandata *dblookup_exact (const char *page,
+extern struct mandata *dblookup_exact (const char *page,
 					      const char *section,
 					      int match_case);
 extern int dbstore (struct mandata *in, const char *base);
@@ -85,10 +85,10 @@ extern void split_content (char *cont_pt
 extern int compare_ids (char a, char b);
 
 /* local to db routines */
-extern inline void gripe_lock (char *filename);
-extern inline void gripe_corrupt_data (void);
+extern void gripe_lock (char *filename);
+extern void gripe_corrupt_data (void);
 extern datum make_multi_key (const char *page, const char *ext);
-extern inline struct mandata *infoalloc (void);
+extern struct mandata *infoalloc (void);
 extern char *name_to_key (const char *name);
 extern char **split_data (char *content, char *start[]);
 extern datum make_content (struct mandata *in);
--- libdb/mydbm.h
+++ libdb/mydbm.h	2008-04-21 15:20:08.000000000 +0200
@@ -42,7 +42,7 @@
 #  include <gdbm.h>
 
 #  ifndef HAVE_GDBM_EXISTS
-extern inline int gdbm_exists(GDBM_FILE dbf, datum key);
+extern int gdbm_exists(GDBM_FILE dbf, datum key);
 #  endif /* !HAVE_GDBM_EXISTS */
 
 /* gdbm_nextkey() is not lexicographically sorted, so we need to keep the
@@ -133,14 +133,14 @@ extern int ndbm_flclose(DBM *dbf);
 typedef DBT datum;
 
 extern DB *btree_flopen(char *filename, int flags, int mode);
-extern inline int btree_close(DB *db);
-extern inline int btree_exists(DB *db, datum key);
-extern inline datum btree_fetch(DB *db, datum key);
+extern int btree_close(DB *db);
+extern int btree_exists(DB *db, datum key);
+extern datum btree_fetch(DB *db, datum key);
 extern int btree_insert(DB *db, datum key, datum cont);
-extern inline datum btree_firstkey(DB *db);
-extern inline datum btree_nextkey(DB *db);
-extern inline int btree_replace(DB *db, datum key, datum content);
-extern inline int btree_nextkeydata(DB *db, datum *key, datum *cont);
+extern datum btree_firstkey(DB *db);
+extern datum btree_nextkey(DB *db);
+extern int btree_replace(DB *db, datum key, datum content);
+extern int btree_nextkeydata(DB *db, datum *key, datum *cont);
 
 #  define DB_EXT			".bt"
 #  define MYDBM_FILE			DB*
@@ -148,7 +148,7 @@ extern inline int btree_nextkeydata(DB *
 #  define MYDBM_SET_DPTR(d, value)	((d).data = (char *) (value))
 #  define MYDBM_DSIZE(d)		((d).size)
 #  define MYDBM_CTRWOPEN(file)		btree_flopen(file, O_TRUNC|O_CREAT|O_RDWR, DBMODE)
-#  define MYDBM_CRWOPEN(file)             btree_flopen(file, O_CREAT|O_RDWR, DBMODE)
+#  define MYDBM_CRWOPEN(file)		btree_flopen(file, O_CREAT|O_RDWR, DBMODE)
 #  define MYDBM_RWOPEN(file)		btree_flopen(file, O_RDWR, DBMODE)
 #  define MYDBM_RDOPEN(file)		btree_flopen(file, O_RDONLY, DBMODE)
 #  define MYDBM_INSERT(db, key, cont)	btree_insert(db, key, cont)
--- man/de/man1/man.man1
+++ man/de/man1/man.man1	2008-04-21 13:41:49.000000000 +0200
@@ -97,6 +97,7 @@ der Manualseiten gefolgt vom Typ der dor
 .TS
 tab (@);
 l l.
+0@Dateiheader (gewöhnlich in \fI/usr/include\fR)
 1@Ausführbare Programme oder Shellbefehle
 2@Systemaufrufe (Kernelfunktionen)
 3@Bibliotheksaufrufe (Funktionen in System-Bibliotheken)
--- man/es/man1/man.man1
+++ man/es/man1/man.man1	2008-04-21 13:41:57.000000000 +0200
@@ -101,6 +101,7 @@ del manual y los tipos de páginas que c
 .TS
 tab (@);
 l l.
+0@Ficheros (se encuentran generalmente en \fI/usr/include\fR)
 1@Programas ejecutables y guiones del intérprete de
 @órdenes
 2@Llamadas del sistema (funciones servidas por el núcleo)
--- man/it/man1/man.man1
+++ man/it/man1/man.man1	2008-04-21 13:42:02.000000000 +0200
@@ -124,6 +124,7 @@ del manuale seguiti dai tipi di pagine c
 .TS
 tab (@);
 l l.
+0@File (di solito trovabili in \fI/usr/include\fR)
 1@Programmi eseguibili e comandi della shell
 2@Chiamate al sistema (funzioni fornite dal kernel)
 3@Chiamate alle librerie (funzioni all'interno delle 
--- man/ja/man1/man.man1
+++ man/ja/man1/man.man1	2008-04-21 13:42:05.000000000 +0200
@@ -104,6 +104,7 @@
 .TS
 tab (@);
 l l.
+0@
 1@実行プログラムまたはシェルのコマンド
 2@システムコール (カーネルが提供する関数)
 3@ライブラリコール (システムライブラリに含まれる関数)
--- man/man1/man.man1
+++ man/man1/man.man1	2007-12-10 12:53:31.000000000 +0100
@@ -119,6 +119,7 @@ numbers of the manual followed by the ty
 .TS
 tab (@);
 l l.
+0@Header files (usually found in \fI/usr/include\fR)
 1@Executable programs or shell commands
 2@System calls (functions provided by the kernel)
 3@Library calls (functions within program libraries)
--- src/Makefile.am
+++ src/Makefile.am	2008-04-21 16:44:47.000000000 +0200
@@ -170,15 +170,11 @@ apropos$(EXEEXT): whatis$(EXEEXT)
 all-am: apropos$(EXEEXT)
 
 install-exec-hook:
-	-test -z "$(man_owner)" || \
-	chown $(man_owner) \
-		$(DESTDIR)$(bindir)/$(TRANS_MAN) \
-		$(DESTDIR)$(bindir)/$(TRANS_MANDB)
-	chmod $(man_mode) \
-		$(DESTDIR)$(bindir)/$(TRANS_MAN) \
-		$(DESTDIR)$(bindir)/$(TRANS_MANDB)
-	cd $(DESTDIR)$(bindir) && rm -f $(TRANS_APROPOS)$(EXEEXT) && \
-		$(LN_S) $(TRANS_WHATIS)$(EXEEXT) $(TRANS_APROPOS)$(EXEEXT)
+	$(INSTALL_PROGRAM) $(TRANS_MAN) $(DESTDIR)$(pkglibexecdir)/$(TRANS_MAN)
+	$(INSTALL_PROGRAM) $(TRANS_MANDB) $(DESTDIR)$(pkglibexecdir)/$(TRANS_MANDB)
+	$(INSTALL_PROGRAM) wrapper $(DESTDIR)$(bindir)/$(TRANS_MANDB)
+	ln -f   $(DESTDIR)$(bindir)/$(TRANS_MANDB) $(DESTDIR)$(bindir)/$(TRANS_MAN)
+	$(LN_S) $(TRANS_WHATIS) $(DESTDIR)$(bindir)/$(TRANS_APROPOS)
 
 install-data-hook:
 	@if test -f $(DESTDIR)$(config_file); then \
--- src/check_mandirs.c
+++ src/check_mandirs.c	2007-12-10 13:15:49.000000000 +0100
@@ -379,10 +379,10 @@ static short testmandirs (const char *pa
 		}
 
 		if (!quiet) {
-			fprintf (stderr, "\r");
 			fprintf (stderr,
 				 _("Updating index cache for path "
 				   "`%s/%s'. Wait..."), path, mandir->d_name);
+			putc ('\n', stderr);
 		}
 		add_dir_entries (path, mandir->d_name);
 		MYDBM_CLOSE (dbf);
@@ -571,7 +571,7 @@ short update_db (const char *manpath)
 		return new;
 	}
 		
-	debug ("failed to open %s O_RDONLY\n", database);
+	debug ("failed to open database %s O_RDONLY\n", database);
 		
 	return EOF;
 }
@@ -747,6 +747,7 @@ static short purge_whatis (const char *p
 			       "would delete\n", name, info->ext);
 		return 1;
 	}
+	return 1;
 }
 
 /* Check that multi keys are correctly constructed. */
@@ -809,6 +810,11 @@ short purge_missing (const char *manpath
 		gripe_rwopen_failed ();
 		return 0;
 	}
+	if (dbver_rd (dbf)) {
+		MYDBM_CLOSE (dbf);
+		dbf = NULL;
+		return 0;
+	}
 
 	key = MYDBM_FIRSTKEY (dbf);
 
@@ -827,6 +833,14 @@ short purge_missing (const char *manpath
 			continue;
 		}
 
+		/* Ignore db identifier keys. */
+		if (*key.dptr == '.' && *(key.dptr+1) == 0) {
+			nextkey = MYDBM_NEXTKEY (dbf, key);
+			MYDBM_FREE (key.dptr);
+			key = nextkey;
+			continue;
+		}
+
 		content = MYDBM_FETCH (dbf, key);
 		if (!MYDBM_DPTR (content)) {
 			nextkey = MYDBM_NEXTKEY (dbf, key);
--- src/fake_security.c
+++ src/fake_security.c	2007-12-10 12:53:31.000000000 +0100
@@ -43,6 +43,7 @@
 #include "security.h"
 
 uid_t ruid, euid, uid;
+gid_t rgid, egid;
 
 #ifdef SECURE_MAN_UID
 static struct passwd *man_owner;
--- src/lexgrog.l
+++ src/lexgrog.l	2008-08-12 15:33:28.000000000 +0200
@@ -51,7 +51,7 @@
 #include "security.h"
 #include "encodings.h"
 
-#define YY_READ_BUF_SIZE	1024
+#define YY_READ_BUF_SIZE	YY_BUF_SIZE
 #define MAX_NAME		2048
 
 #ifdef PROFILE
@@ -59,10 +59,10 @@ static int ctr[YY_NUM_RULES];
 #  define YY_USER_ACTION ++ctr[yy_act];
 #endif
 
-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 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 (const char *, size_t);
+static __inline__ void newline_found (void);
 
 static char newname[MAX_NAME];
 static char *p_name;
@@ -71,6 +71,7 @@ static char filters[MAX_FILTERS];
 
 static int fill_mode;
 static int waiting_for_quote;
+static int have_separator;
 
 static pipeline *decomp;
 
@@ -87,7 +88,7 @@ static pipeline *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
@@ -116,8 +117,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])
+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
@@ -150,7 +152,26 @@ vi_name		TÊN
 zh_CN_name	名{blank}?称{blank}?.*
 zh_TW_name	(名{blank}?稱|命令名){blank}?.*
 name		({bg_name}|{cs_name}|{da_name}|{de_name}|{en_name}|{es_name}|{fi_name}|{fr_name}|{hu_name}|{id_name}|{it_name}|{ja_name}|{ko_name}|{latin_name}|{nl_name}|{pl_name}|{ru_name}|{sk_name}|{sr_name}|{sv_name}|{tr_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
@@ -164,8 +185,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>\.[^Ss\r\n].*					|
@@ -216,6 +242,7 @@ vgrind_request	\.vS
 <MAN_NAME>{bol}\.sp{blank}*		|	/* vertical spacing */
 <MAN_NAME>{bol}\.ig{blank}*		|	/* block comment */
 <MAN_NAME>{bol}\.de[1i]?{blank}*	|	/* macro definition */
+<MAN_NAME>{bol}\.V[be]{blank}*		|	/* special in perl pages */
 <MAN_NAME>{bol}\.i[ef]{blank}*		|	/* conditional */
 <MAN_NAME>{empty}{bol}.+		|
 <MAN_NAME><<EOF>>		{	/* terminate the string */
@@ -242,28 +269,31 @@ vgrind_request	\.vS
 	{bol}{typeface}{blank}+		|	/* type face commands */
 	{bol}\.ft{blank}.*		|	/* font change */
 	{bol}\.V[be]{blank}.*		|	/* pod2man, verbatim mode */
-	{bol}\.IX{blank}.*		|	/* .IX line */
+	{bol}\.IX{blank}.*		|	/* index request */
 	{next}{comment}.*		{	/* per line comments */
 						newline_found ();
 					}
 }
 
  /* No-op requests */
-<MAN_NAME>{bol}\.{blank}*$		newline_found ();
-<MAN_NAME>{bol}\.\.$			newline_found ();
+<MAN_NAME>{bol}\.{blank}*/{eol}		newline_found ();
+<MAN_NAME>{bol}\.\./{eol}		newline_found ();
 
  /* Toggle fill mode */
-<MAN_NAME>{bol}\.nf.*			fill_mode = 0;
-<MAN_NAME>{bol}\.fi.*			fill_mode = 1;
+<MAN_NAME>{bol}\.(nf|de).*		fill_mode = 0;
+<MAN_NAME>{bol}\.(fi|\.).*		fill_mode = 1;
 
 <CAT_NAME>-{eol}{blank_eol}*		/* strip continuations */
 
  /* convert to DASH */
 <MAN_NAME>{next}{blank}*\\\((mi|hy|em){blank}*	|
+<MAN_NAME>{bol}\.sp{bol}{blank}+\\-{blank}*	|	/* strange spacing in NAME section */
+<MAN_NAME>{blank}+[-\\]?-{bol}			|	/* dash at end of line */
+<MAN_NAME>{next}{blank_eol}+(\\?-){2}{blank}+	|	/* some man pages use -- as dash */
 <MAN_NAME>{next}{blank_eol}+[-\\]-{blank}*	|
 <MAN_NAME>{next}{blank_eol}*[-\\]-{blank}+	|
 <CAT_NAME>{next}{blank}+-{1,2}{blank_eol}+	|
-<MAN_NAME>{bol}\.Nd{blank}*			add_separator_to_whatis ();
+<MAN_NAME>{bol}\.Nd{blank}*			add_separator_to_whatis (yytext, yyleng);
 
  /* escape sequences and special characters */
 <MAN_NAME>{
@@ -279,6 +309,7 @@ vgrind_request	\.vS
 	{next}\\[|^&!%acdpruz{}\r\n]	/* various useless control chars */
 	{next}\\[bhlLvx]{blank}*'[^']+'	/* various inline functions */
 
+	{next}\\\\\$[1-9]		/* roff macro argument */
 	{next}\\\$[1-9]			/* interpolate arg */
 
 	{next}\\\*(\({alpha})?{alpha}	/* interpolate string */
@@ -307,11 +338,8 @@ vgrind_request	\.vS
     for later processing */
 <MAN_NAME>{
 	{bol}\.br{blank}*		|
-	{bol}\.LP{blank}*		|
-	{bol}\.PP{blank}*		|
+	{bol}{paragr}{blank}*		|
 	{bol}\.P{blank}*		|
-	{bol}\.IP{blank}.*		|
-	{bol}\.HP{blank}.*		|
 	{bol}\.RS{blank}.*		|
 	{bol}\.RE{blank}.*		add_char_to_whatis ((char) 0x11);
 }
@@ -324,7 +352,7 @@ vgrind_request	\.vS
 <MAN_NAME>[[:alnum:]]*		add_str_to_whatis (yytext, yyleng);
 
  /* normalise the period (,) separators */
-<CAT_NAME>{blank}*,[ \t\r\n]*		|
+<CAT_NAME>{blank}*,{blank_eol}*		|
 <MAN_NAME>{blank}*,{blank}*		add_str_to_whatis (", ", 2);
 
 <CAT_NAME,MAN_NAME>{bol}.	{
@@ -340,7 +368,7 @@ vgrind_request	\.vS
 %%
 
 /* print warning and force scanner to terminate */
-static void too_big (void)
+static __inline__ void too_big (void)
 {
 	error (0, 0,
 	       _("warning: whatis for %s exceeds %d bytes, truncating."),
@@ -350,7 +378,7 @@ static void too_big (void)
 }
 
 /* append a string to newname if enough room */
-static void add_str_to_whatis (const char *string, size_t length)
+static __inline__ void add_str_to_whatis (const char *string, size_t length)
 {
 	if (p_name - newname + length >= MAX_NAME)
 		too_big ();
@@ -361,8 +389,10 @@ static void add_str_to_whatis (const cha
 } 
 
 /* append a char to newname if enough room */
-static void add_char_to_whatis (unsigned char c)
+static __inline__ void add_char_to_whatis (unsigned char c)
 {
+	if (c == (char) 0x11 && *p_name == (char) 0x11)
+		return;
 	if (p_name - newname + 1 >= MAX_NAME)
 		too_big ();
 	else if (waiting_for_quote && c == '"')
@@ -374,14 +404,30 @@ static void add_char_to_whatis (unsigned
 /* append the " - " separator to newname, trimming the first space if one's
  * already there
  */
-static void add_separator_to_whatis (void)
+static __inline__ void add_separator_to_whatis (const char *string, size_t len)
 {
+	if (have_separator) {
+		unsigned int n;
+		unsigned char c;
+
+		for (n = 0; (n < len) && (c = string[n]); n++) {
+			switch (c) {
+			case '-':
+			case ' ':
+				add_char_to_whatis (c);
+			default:
+				break;
+			}
+		}
+		return;
+	}
+	have_separator = 1;
 	if (p_name != newname && *(p_name - 1) != ' ')
 		add_char_to_whatis (' ');
 	add_str_to_whatis ("- ", 2);
 }
 
-static void newline_found (void)
+static __inline__ void newline_found (void)
 {
 	/* If we are mid p_name and the last added char was not a space,
 	 * best add one.
@@ -457,6 +503,7 @@ int find_name_decompressed (pipeline *p,
 
 	fill_mode = 1;
 	waiting_for_quote = 0;
+	have_separator = 0;
 
 	if (p_lg->type)
 		BEGIN (CAT_FILE);
--- src/man.c
+++ src/man.c	2008-08-12 16:59:18.640462210 +0200
@@ -66,6 +66,7 @@ static char *cwd;
 #include <utime.h>
 #include <sys/types.h>
 #include <sys/stat.h>
+#include <sys/time.h>
 
 #include "argp.h"
 #include "dirname.h"
@@ -104,6 +105,8 @@ static char *cwd;
 #ifdef SECURE_MAN_UID
 extern uid_t ruid;
 extern uid_t euid;
+extern gid_t rgid;
+extern gid_t egid;
 #endif /* SECURE_MAN_UID */
 
 /* the default preprocessor sequence */
@@ -134,6 +137,10 @@ const char *lang;
 
 static int global_manpath = -1;	/* global or user manual page hierarchy? */
 static int skip;		/* page exists but has been skipped */
+static struct termios tms;	/* To save terminal settings in */
+static int tms_set = 0;		/* Do we have saved terminal settings? */
+
+static void set_term(void) { if (tms_set) tcsetattr(fileno(stdin), TCSANOW, &tms); }
 
 #if defined _AIX || defined __sgi
 char **global_argv;
@@ -224,12 +231,12 @@ static char *tmp_cat_file;	/* for open_c
 static int tmp_cat_fd;
 static int created_tmp_cat;			/* dto. */
 static int man_modtime;		/* modtime of man page, for commit_tmp_cat() */
-#endif
+#endif /* MAN_CATS */
 
 # ifdef TROFF_IS_GROFF
-static int ditroff;
+static int ditroff = 0;
 static const char *gxditview;
-static int htmlout;
+static int htmlout = 0;
 static const char *html_pager;
 # endif /* TROFF_IS_GROFF */
 
@@ -537,25 +544,6 @@ static void gripe_no_name (const char *s
 	exit (FAIL);
 }
 
-static struct termios tms;
-static int tms_set = 0;
-
-static void set_term (void)
-{
-	if (tms_set)
-		tcsetattr (STDIN_FILENO, TCSANOW, &tms);
-}
-
-static void get_term (void)
-{
-	if (isatty (STDOUT_FILENO)) {
-		debug ("is a tty\n");
-		tcgetattr (STDIN_FILENO, &tms);
-		if (!tms_set++)
-			atexit (set_term);
-	}
-}
-
 static int get_roff_line_length (void)
 {
 	int line_length = get_line_length ();
@@ -640,11 +628,11 @@ static inline char **manopt_to_env (int 
 {
 	char *manopt, *opt_start, **argv;
 
-	manopt = getenv ("MANOPT");
+	opt_start = manopt = getenv ("MANOPT");
 	if (manopt == NULL || *manopt == '\0')
 		return NULL;
 
-	opt_start = manopt = xstrdup (manopt);
+	manopt = xstrdup (manopt);
 
 	/* allocate space for the program name */
 	*argc = 0;
@@ -760,30 +748,43 @@ static int local_man_loop (const char *a
 		display (NULL, "", NULL, "(stdin)", NULL);
 	else {
 		struct stat st;
+		char *pwd = cwd;
+		char *file = basename((char*)argv);
 
-		if (cwd[0]) {
-			debug ("chdir %s\n", cwd);
-			if (chdir (cwd)) {
-				error (0, errno, _("can't chdir to %s"), cwd);
+		if (strcmp(argv, file)) {
+			char *dlm;
+			pwd = strdupa(argv);
+   
+			if ((dlm = strrchr(pwd, '/')))
+				*dlm = '\0';
+		}
+ 
+		if (pwd[0]) {
+			debug ("chdir %s\n", pwd);
+			if (chdir (pwd)) {
+				error (0, errno, _("can't chdir to %s"), pwd);
 				regain_effective_privs ();
 				return 0;
 			}
 		}
 
 		/* Check that the file exists and isn't e.g. a directory */
-		if (stat (argv, &st)) {
+		if (stat (file, &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;
 		}
 
@@ -801,8 +802,10 @@ static int local_man_loop (const char *a
 					argv_abs = xstrdup (argv);
 			}
 			lang = lang_dir (argv_abs);
+			if (!lang || !*lang)
+				lang = internal_locale;
 			free (argv_abs);
-			if (!display (NULL, argv, NULL, argv_base, NULL)) {
+			if (!display (NULL, file, NULL, argv_base, NULL)) {
 				if (local_mf)
 					error (0, errno, "%s", argv);
 				exit_status = NOT_FOUND;
@@ -834,7 +837,16 @@ int main (int argc, char *argv[])
 	bindtextdomain (PACKAGE "-gnulib", LOCALEDIR);
 	textdomain (PACKAGE);
 
-	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") &&
@@ -904,9 +916,13 @@ int main (int argc, char *argv[])
 	if (external)
 		do_extern (argc, argv);
 
-	get_term (); /* stores terminal settings */
 #ifdef SECURE_MAN_UID
 	debug ("real user = %d; effective user = %d\n", ruid, euid);
+	if (isatty(fileno(stdin)) && isatty(fileno(stdout))) {
+		tcgetattr(fileno(stdin), &tms);
+		if (!tms_set++)
+			atexit(set_term);
+	}
 #endif /* SECURE_MAN_UID */
 
 	/* close this locale and reinitialise if a new locale was 
@@ -924,6 +940,7 @@ int main (int argc, char *argv[])
 			setenv ("LANGUAGE", internal_locale, 1);
 			++_nl_msg_cat_cntr;
 			multiple_locale = NULL;
+#define MULTIPLE_LOCALE_IS_NULL	1
 		}
 	}
 
@@ -978,6 +995,22 @@ int main (int argc, char *argv[])
 	}
 
 	if (manp == NULL) {
+#if MULTIPLE_LOCALE_IS_NULL
+		char * tmp_locale = xstrdup(internal_locale);
+		char * ptr;
+
+		manp = get_manpath (alt_system_name);
+
+		/*
+		 * Use strsep () to not intermix with strtok ()
+		 */
+		for (ptr = strsep (&tmp_locale, ":"); ptr; ptr = strsep (&tmp_locale, ":")) {
+			if (debug_level)
+				fprintf (stderr, "checking for locale %s\n", ptr);
+			manp = add_nls_manpath (manp, ptr);
+		}
+		free(tmp_locale);
+#else
 		char tmp_locale[3];
 		int idx;
 
@@ -999,6 +1032,7 @@ int main (int argc, char *argv[])
 			debug ("checking for locale %s\n", tmp_locale);
 			manp = add_nls_manpath (manp, tmp_locale);
 		}
+#endif
 	} else
 		free (get_manpath (NULL));
 
@@ -1155,7 +1189,7 @@ static inline const char *is_section (co
 }
 
 /* Snarf pre-processors from file, return (static) string or NULL on failure */
-static const char *get_preprocessors_from_file (pipeline *decomp)
+static const char *get_preprocessors_from_file (pipeline *decomp, char * pp_encoding)
 {
 	static char *directive = NULL;
 
@@ -1174,7 +1208,8 @@ static const char *get_preprocessors_fro
 	if (!line)
 		return NULL;
 
-	if (!strncmp (line, PP_COOKIE, 4)) {
+	if (!strncmp (line, PP_COOKIE, 4) ||
+	    (strlen(line) == 6 && !strncmp(line, ".\\\" ", 4))) {
 		const char *newline = strchr (line, '\n');
 		if (newline)
 			directive = xstrndup (line + 4, newline - (line + 4));
@@ -1182,6 +1217,25 @@ static const char *get_preprocessors_fro
 			directive = xstrdup (line + 4);
 	}
 
+	if (directive && strstr (directive, "-*-")) {
+		const char *pp_search = strstr (directive, "-*-") + 3;
+		while (*pp_search == ' ')
+			++pp_search;
+		if (STRNEQ (pp_search, "coding:", 7)) {
+			const char *pp_encoding_end;
+			pp_search += 7;
+			while (*pp_search == ' ')
+				++pp_search;
+			pp_encoding_end = strchr (pp_search, ' ');
+			if (pp_encoding_end) {
+				size_t len = pp_encoding_end - pp_search;
+				pp_encoding = xstrndup (pp_search, len);
+			} else
+				pp_encoding = xstrdup (pp_search);
+			debug ("preprocessor encoding: %s\n", pp_encoding);
+		}
+	}
+
 	/* if we didn't find PP_COOKIE, then directive == NULL */
 #endif
 	return directive;
@@ -1190,7 +1244,7 @@ static const char *get_preprocessors_fro
 
 /* Determine pre-processors, set save_cat and return
    (static) string */
-static const char *get_preprocessors (pipeline *decomp, const char *dbfilters)
+static const char *get_preprocessors (pipeline *decomp, const char *dbfilters, char * pp_encoding)
 {
 	const char *pp_string;
 	const char *pp_source;
@@ -1204,7 +1258,7 @@ static const char *get_preprocessors (pi
 	} else if ((pp_string = preprocessors)) {
 		pp_source = "command line";
 		save_cat = 0;
-	} else if ((pp_string = get_preprocessors_from_file (decomp))) {
+	} else if ((pp_string = get_preprocessors_from_file (decomp, pp_encoding))) {
 		pp_source = "file";
 		save_cat = 1;
 	} else if ((pp_string = getenv ("MANROFFSEQ"))) {
@@ -1230,6 +1284,7 @@ static pipeline *make_roff_command (cons
 {
 	const char *pp_string;
 	const char *roff_opt;
+	const char *pp_encoding;
 	char *fmt_prog;
 	pipeline *p = pipeline_new ();
 	command *cmd;
@@ -1239,8 +1294,8 @@ static pipeline *make_roff_command (cons
 #ifndef ALT_EXT_FORMAT
 	dir = dir; /* not used unless looking for formatters in catdir */
 #endif
-
-	pp_string = get_preprocessors (decomp, dbfilters);
+	pp_encoding = (char*)0;
+	pp_string = get_preprocessors (decomp, dbfilters, pp_encoding);
 
 	roff_opt = getenv ("MANROFFOPT");
 	if (!roff_opt)
@@ -1295,8 +1350,10 @@ static pipeline *make_roff_command (cons
 		if (!recode)
 			pipeline_command_argstr (p, get_def ("soelim",
 							     SOELIM));
-
-		page_encoding = get_page_encoding (lang);
+		if (pp_encoding)
+			page_encoding = pp_encoding;
+		else
+			page_encoding = get_page_encoding (lang);
 		source_encoding = get_source_encoding (lang);
 		debug ("page_encoding = %s\n", page_encoding);
 		debug ("source_encoding = %s\n", source_encoding);
@@ -1652,6 +1709,18 @@ static void setenv_less (const char *tit
 	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
+	}
+}
+
 /* Return pipeline to display file. NULL means stdin.
  *
  * TODO: htmlout case is pretty weird now. I'd like the intelligence to be
@@ -1664,6 +1733,9 @@ static pipeline *make_display_command (c
 
 	setenv_less (title);
 
+	if (!htmlout)
+		disable_x();
+
 	if (file) {
 		if (ascii) {
 			p = pipeline_new ();
@@ -1706,7 +1778,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)
 {
@@ -1809,8 +1881,6 @@ static int commit_tmp_cat (const char *c
 	return status;
 }
 
-#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)
 {
@@ -1884,6 +1954,7 @@ static int close_cat_stream (pipeline *c
 	free (tmp_cat_file);
 	return status;
 }
+#endif /* MAN_CATS */
 
 /* TODO: This should all be refactored after work on the decompression
  * library is complete.
@@ -1896,6 +1967,7 @@ void discard_stderr (pipeline *p)
 		p->commands[i]->discard_err = 1;
 }
 
+#ifdef MAN_CATS
 /*
  * format a manual page with format_cmd, display it with disp_cmd, and
  * save it to cat_file
@@ -2057,6 +2129,7 @@ static void format_display (pipeline *de
 	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, pipeline *decomp,
@@ -2095,6 +2168,7 @@ static void display_catman (const char *
 	pop_cleanup();
 	free (tmpcat);
 }
+#endif /* MAN_CATS */
 
 /*
  * optionally chdir to dir, if necessary update cat_file from man_file
@@ -2117,10 +2191,18 @@ static int display (const char *dir, con
 	if (dir) {
 		debug ("chdir %s\n", dir);
 
+		if (global_manpath)
+			drop_effective_privs();
+
 		if (chdir (dir)) {
 			error (0, errno, _("can't chdir to %s"), dir);
+			if (global_manpath)
+				regain_effective_privs();
 			return 0;
 		}
+
+		if (global_manpath)
+			regain_effective_privs();
 	}
 
 	/* define format_cmd */
@@ -2133,11 +2215,10 @@ static int display (const char *dir, con
 
 	if (decomp) {
 		pipeline_start (decomp);
-		format_cmd = make_roff_command (dir, man_file, decomp,
-						dbfilters);
+		format_cmd = make_roff_command (dir, man_file, decomp, dbfilters);
 	} else
 		format_cmd = NULL;
-
+#ifdef MAN_CATS
 	/* Get modification time, for commit_tmp_cat(). */
 	if (man_file && *man_file) {
 		struct stat stb;
@@ -2146,7 +2227,7 @@ static int display (const char *dir, con
 		else
 			man_modtime = stb.st_mtime;
 	}
-
+#endif /* MAN_CATS */
 	display_to_stdout = troff;
 #ifdef TROFF_IS_GROFF
 	if (htmlout)
@@ -2263,6 +2344,7 @@ static int display (const char *dir, con
 			}
 			if (printed)
 				putchar ('\n');
+#ifdef MAN_CATS
 		} else if (catman) {
 			if (format) {
 				if (!save_cat)
@@ -2274,6 +2356,7 @@ static int display (const char *dir, con
 					display_catman (cat_file, decomp,
 							format_cmd);
 			}
+#endif /* MAN_CATS */
 		} else if (format) {
 			/* no cat or out of date */
 			pipeline *disp_cmd;
@@ -2324,8 +2407,10 @@ static int display (const char *dir, con
 		}
 	}
 
-	pipeline_free (format_cmd);
-	pipeline_free (decomp);
+	if (format_cmd)
+		pipeline_free (format_cmd);
+	if (decomp)
+		pipeline_free (decomp);
 
 	if (!prompt)
 		prompt = found;
@@ -2923,7 +3008,7 @@ static int display_database_check (struc
 #ifdef MAN_DB_UPDATES
 	if (!exists && !skip) {
 		debug ("dbdelete_wrapper (%s, %p)\n",
-		       candp->req_name, candp->source);
+		       candp->req_name, candp->source->addr);
 		dbdelete_wrapper (candp->req_name, candp->source);
 	}
 #endif /* MAN_DB_UPDATES */
--- src/man_db.conf.in
+++ src/man_db.conf.in	2008-08-12 15:35:48.000000000 +0200
@@ -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
@@ -63,12 +73,133 @@ MANPATH_MAP	/opt/sbin		/opt/man
 #
 #		*MANPATH*     ->	*CATPATH*
 #
-MANDB_MAP	/usr/man		/var/cache/man/fsstnd
+MANDB_MAP	/usr/share/man/ca	/var/cache/man/ca
+MANDB_MAP	/usr/share/man/cs	/var/cache/man/cs
+MANDB_MAP	/usr/share/man/cs_CZ	/var/cache/man/cs
+MANDB_MAP	/usr/share/man/da	/var/cache/man/da
+MANDB_MAP	/usr/share/man/de	/var/cache/man/de
+MANDB_MAP	/usr/share/man/de_AT	/var/cache/man/de
+MANDB_MAP	/usr/share/man/de_DE	/var/cache/man/de
+MANDB_MAP	/usr/share/man/en	/var/cache/man/en
+MANDB_MAP	/usr/share/man/es	/var/cache/man/es
+MANDB_MAP	/usr/share/man/es_ES	/var/cache/man/es
+MANDB_MAP	/usr/share/man/et	/var/cache/man/et
+MANDB_MAP	/usr/share/man/fi	/var/cache/man/fi
+MANDB_MAP	/usr/share/man/fr_FR	/var/cache/man/fr
+MANDB_MAP	/usr/share/man/ga	/var/cache/man/ga
+MANDB_MAP	/usr/share/man/is	/var/cache/man/is
+MANDB_MAP	/usr/share/man/it	/var/cache/man/it
+MANDB_MAP	/usr/share/man/ja	/var/cache/man/ja
+MANDB_MAP	/usr/share/man/ja_JP	/var/cache/man/ja
+MANDB_MAP	/usr/share/man/ja_JP.eucJP /var/cache/man/ja
+MANDB_MAP	/usr/share/man/ko	/var/cache/man/ko
+MANDB_MAP	/usr/share/man/nl	/var/cache/man/nl
+MANDB_MAP	/usr/share/man/no	/var/cache/man/no
+MANDB_MAP	/usr/share/man/pl	/var/cache/man/pl
+MANDB_MAP	/usr/share/man/pt	/var/cache/man/pt
+MANDB_MAP	/usr/share/man/pt_BR	/var/cache/man/pt
+MANDB_MAP	/usr/share/man/ru	/var/cache/man/ru
+MANDB_MAP	/usr/share/man/sk	/var/cache/man/sk
+MANDB_MAP	/usr/share/man/sr	/var/cache/man/sr
+MANDB_MAP	/usr/share/man/sv	/var/cache/man/sv
+MANDB_MAP	/usr/share/man/uk	/var/cache/man/uk
 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	/usr/local/man/ca	/var/cache/man/local/ca
+MANDB_MAP	/usr/local/man/cs	/var/cache/man/local/cs
+MANDB_MAP	/usr/local/man/cs_CZ	/var/cache/man/local/cs
+MANDB_MAP	/usr/local/man/da	/var/cache/man/local/da
+MANDB_MAP	/usr/local/man/de	/var/cache/man/local/de
+MANDB_MAP	/usr/local/man/de_AT	/var/cache/man/local/de
+MANDB_MAP	/usr/local/man/de_DE	/var/cache/man/local/de
+MANDB_MAP	/usr/local/man/en	/var/cache/man/local/en
+MANDB_MAP	/usr/local/man/es	/var/cache/man/local/es
+MANDB_MAP	/usr/local/man/es_ES	/var/cache/man/local/es
+MANDB_MAP	/usr/local/man/et	/var/cache/man/local/et
+MANDB_MAP	/usr/local/man/fi	/var/cache/man/local/fi
+MANDB_MAP	/usr/local/man/fr_FR	/var/cache/man/local/fr
+MANDB_MAP	/usr/local/man/ga	/var/cache/man/local/ga
+MANDB_MAP	/usr/local/man/is	/var/cache/man/local/is
+MANDB_MAP	/usr/local/man/it	/var/cache/man/local/it
+MANDB_MAP	/usr/local/man/ja	/var/cache/man/local/ja
+MANDB_MAP	/usr/local/man/ja_JP	/var/cache/man/local/ja
+MANDB_MAP	/usr/local/man/ja_JP.eucJP /var/cache/man/local/ja
+MANDB_MAP	/usr/local/man/ko	/var/cache/man/local/ko
+MANDB_MAP	/usr/local/man/nl	/var/cache/man/local/nl
+MANDB_MAP	/usr/local/man/no	/var/cache/man/local/no
+MANDB_MAP	/usr/local/man/pl	/var/cache/man/local/pl
+MANDB_MAP	/usr/local/man/pt	/var/cache/man/local/pt
+MANDB_MAP	/usr/local/man/pt_BR	/var/cache/man/local/pt
+MANDB_MAP	/usr/local/man/ru	/var/cache/man/local/ru
+MANDB_MAP	/usr/local/man/sk	/var/cache/man/local/sk
+MANDB_MAP	/usr/local/man/sr	/var/cache/man/local/sr
+MANDB_MAP	/usr/local/man/sv	/var/cache/man/local/sv
+MANDB_MAP	/usr/local/man/uk	/var/cache/man/local/uk
+MANDB_MAP	/usr/local/man		/var/cache/man/local
+#
+MANDB_MAP	/usr/local/share/man/ca		/var/cache/man/local/ca
+MANDB_MAP	/usr/local/share/man/cs		/var/cache/man/local/cs
+MANDB_MAP	/usr/local/share/man/cs_CZ	/var/cache/man/local/cs
+MANDB_MAP	/usr/local/share/man/da		/var/cache/man/local/da
+MANDB_MAP	/usr/local/share/man/de		/var/cache/man/local/de
+MANDB_MAP	/usr/local/share/man/de_AT	/var/cache/man/local/de
+MANDB_MAP	/usr/local/share/man/de_DE	/var/cache/man/local/de
+MANDB_MAP	/usr/local/share/man/en		/var/cache/man/local/en
+MANDB_MAP	/usr/local/share/man/es		/var/cache/man/local/es
+MANDB_MAP	/usr/local/share/man/es_ES	/var/cache/man/local/es
+MANDB_MAP	/usr/local/share/man/et		/var/cache/man/local/et
+MANDB_MAP	/usr/local/share/man/fi		/var/cache/man/local/fi
+MANDB_MAP	/usr/local/share/man/fr_FR	/var/cache/man/local/fr
+MANDB_MAP	/usr/local/share/man/ga		/var/cache/man/local/ga
+MANDB_MAP	/usr/local/share/man/is		/var/cache/man/local/is
+MANDB_MAP	/usr/local/share/man/it		/var/cache/man/local/it
+MANDB_MAP	/usr/local/share/man/ja		/var/cache/man/local/ja
+MANDB_MAP	/usr/local/share/man/ja_JP	/var/cache/man/local/ja
+MANDB_MAP	/usr/local/share/man/ja_JP.eucJP /var/cache/man/local/ja
+MANDB_MAP	/usr/local/share/man/ko		/var/cache/man/local/ko
+MANDB_MAP	/usr/local/share/man/nl		/var/cache/man/local/nl
+MANDB_MAP	/usr/local/share/man/no		/var/cache/man/local/no
+MANDB_MAP	/usr/local/share/man/pl		/var/cache/man/local/pl
+MANDB_MAP	/usr/local/share/man/pt		/var/cache/man/local/pt
+MANDB_MAP	/usr/local/share/man/pt_BR	/var/cache/man/local/pt
+MANDB_MAP	/usr/local/share/man/ru		/var/cache/man/local/ru
+MANDB_MAP	/usr/local/share/man/sk		/var/cache/man/local/sk
+MANDB_MAP	/usr/local/share/man/sr		/var/cache/man/local/sr
+MANDB_MAP	/usr/local/share/man/sv		/var/cache/man/local/sv
+MANDB_MAP	/usr/local/share/man/uk		/var/cache/man/local/uk
+MANDB_MAP	/usr/local/share/man		/var/cache/man/local
+#
+MANDB_MAP	/opt/share/man/ca	/var/cache/man/opt/ca
+MANDB_MAP	/opt/share/man/cs	/var/cache/man/opt/cs
+MANDB_MAP	/opt/share/man/cs_CZ	/var/cache/man/opt/cs
+MANDB_MAP	/opt/share/man/da	/var/cache/man/opt/da
+MANDB_MAP	/opt/share/man/de	/var/cache/man/opt/de
+MANDB_MAP	/opt/share/man/de_AT	/var/cache/man/opt/de
+MANDB_MAP	/opt/share/man/de_DE	/var/cache/man/opt/de
+MANDB_MAP	/opt/share/man/en	/var/cache/man/opt/en
+MANDB_MAP	/opt/share/man/es	/var/cache/man/opt/es
+MANDB_MAP	/opt/share/man/es	/var/cache/man/opt/es
+MANDB_MAP	/opt/share/man/et	/var/cache/man/opt/et
+MANDB_MAP	/opt/share/man/fi	/var/cache/man/opt/fi
+MANDB_MAP	/opt/share/man/fr_FR	/var/cache/man/opt/fr
+MANDB_MAP	/opt/share/man/ga	/var/cache/man/opt/ga
+MANDB_MAP	/opt/share/man/is	/var/cache/man/opt/is
+MANDB_MAP	/opt/share/man/it	/var/cache/man/opt/it
+MANDB_MAP	/opt/share/man/ja	/var/cache/man/opt/ja
+MANDB_MAP	/opt/share/man/ja_JP	/var/cache/man/opt/ja
+MANDB_MAP	/opt/share/man/ja_JP.eucJP /var/cache/man/opt/ja
+MANDB_MAP	/opt/share/man/ko	/var/cache/man/opt/ko
+MANDB_MAP	/opt/share/man/nl	/var/cache/man/opt/nl
+MANDB_MAP	/opt/share/man/no	/var/cache/man/opt/no
+MANDB_MAP	/opt/share/man/pl	/var/cache/man/opt/pl
+MANDB_MAP	/opt/share/man/pt	/var/cache/man/opt/pt
+MANDB_MAP	/opt/share/man/pt_BR	/var/cache/man/opt/pt
+MANDB_MAP	/opt/share/man/ru	/var/cache/man/opt/ru
+MANDB_MAP	/opt/share/man/sk	/var/cache/man/opt/sk
+MANDB_MAP	/opt/share/man/sr	/var/cache/man/opt/sr
+MANDB_MAP	/opt/share/man/sv	/var/cache/man/opt/sv
+MANDB_MAP	/opt/share/man/uk	/var/cache/man/opt/uk
+MANDB_MAP	/opt/share/man		/var/cache/man/opt
 #
 #---------------------------------------------------------
 # Program definitions.  These are commented out by default as the value
--- src/mandb.c
+++ src/mandb.c	2008-08-12 16:59:18.688466727 +0200
@@ -185,6 +185,8 @@ static const char *xtmpfile;
 #ifdef SECURE_MAN_UID
 extern uid_t ruid;
 extern uid_t euid;
+extern gid_t rgid;
+extern gid_t egid;
 #endif /* SECURE_MAN_UID */
 
 static char *manpathlist[MAXDIRS];
@@ -518,7 +520,7 @@ static short process_manpath (const char
 	if (!opt_test && amount) {
 		finish_up ();
 #ifdef SECURE_MAN_UID
-		if (global_manpath && euid == 0)
+		if (global_manpath && (euid == 0 || ruid == 0))
 			do_chown (man_owner->pw_uid);
 #endif /* SECURE_MAN_UID */
 	}
@@ -586,8 +588,14 @@ int main (int argc, char *argv[])
 		error (FAIL, 0,
 		       _("the setuid man user \"%s\" does not exist"),
 		       MAN_OWNER);
-	if (!user && euid != 0 && euid != man_owner->pw_uid)
-		user = 1;
+	if (!user) {
+		if (!ruid && euid != man_owner->pw_uid) {
+			seteuid(man_owner->pw_uid);
+			euid = geteuid();
+		}
+		if (euid != man_owner->pw_uid)
+			user = 1;
+	}
 #endif /* SECURE_MAN_UID */
 
 
--- src/manp.c
+++ src/manp.c	2008-08-12 16:59:18.712468986 +0200
@@ -70,6 +70,7 @@
 #include "security.h"
 #include "encodings.h"
 #include "manp.h"
+#include "security.h"
 
 struct list {
 	char *key;
@@ -673,6 +674,8 @@ char *get_manpath (const char *systems)
 #ifdef SECURE_MAN_UID
 extern uid_t ruid;			/* initial real user id */
 extern uid_t euid;			/* initial effective user id */
+extern gid_t rgid;			/* initial real group id */
+extern gid_t egid;			/* initial effective group id */
 #endif /* SECURE_MAN_UID */
 
 /* create the catman hierarchy if it doesn't exist */
@@ -701,6 +704,8 @@ mkcatdirs (const char *mandir, const cha
 #ifdef SECURE_MAN_UID
 			if (ruid == 0)
 				chown (catdir, man_owner->pw_uid, 0);
+			if (rgid == 0)
+				chown (catdir, -1, man_owner->pw_gid);
 #endif /* SECURE_MAN_UID */
 			drop_effective_privs ();
 		}
@@ -711,9 +716,14 @@ mkcatdirs (const char *mandir, const cha
 			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++) {
+				unsigned int 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,
@@ -722,11 +732,12 @@ mkcatdirs (const char *mandir, const cha
 							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);
 #ifdef SECURE_MAN_UID
 					if (ruid == 0)
-						chown (catname,
-						       man_owner->pw_uid, 0);
+						chown (catname, man_owner->pw_uid, 0);
+					if (rgid == 0)
+						chown (catname, -1, man_owner->pw_gid);
 #endif /* SECURE_MAN_UID */
 				}
 			}
@@ -865,7 +876,7 @@ static char *def_path (int flag)
 
 	/* If we have complete config file failure... */
 	if (!manpath)
-		return xstrdup ("/usr/man");
+		return xstrdup ("/usr/share/man");
 
 	return manpath;
 }
--- src/security.c
+++ src/security.c	2007-12-10 14:24:24.000000000 +0100
@@ -76,10 +76,13 @@
 #  ifdef POSIX_SAVED_IDS
 #    if defined (HAVE_SETEUID)
 #      define SET_EUID(euid)		seteuid(euid)
+#      define SET_EGID(egid)		setegid(egid)
 #    elif defined (HAVE_SETREUID)
 #      define SET_EUID(euid)		setreuid(-1, euid)
+#      define SET_EGID(egid)		setregid(-1, egid)
 #    elif defined (HAVE_SETRESUID)
 #      define SET_EUID(euid)		setresuid(-1, euid, -1)
+#      define SET_EGID(egid)		setresgid(-1, egid, -1)
 #    endif /* HAVE_SETEUID */
 
 /* Sort out the function to use to swap ruid with euid.  Used if no suid. */
@@ -87,8 +90,10 @@
 #  else /* !POSIX_SAVED_IDS */
 #    if defined (HAVE_SETREUID)
 #      define SWAP_UIDS(ida, idb)	setreuid(idb, ida)
+#      define SWAP_GIDS(ida, idb)	setregid(idb, ida)
 #    elif defined (HAVE_SETRESUID)
 #      define SWAP_UIDS(ida, idb)	setresuid(idb, ida, -1)
+#      define SWAP_GIDS(ida, idb)	setresgid(idb, ida, -1)
 #      warning Using setresuid() whithout _POSIX_SAVED_IDS!
 #    endif /* HAVE_SETREUID */
 #  endif /* POSIX_SAVED_IDS */
@@ -100,7 +105,10 @@
 
 uid_t ruid;				/* initial real user id */
 uid_t euid;				/* initial effective user id */
+gid_t rgid;				/* initial real group id */
+gid_t egid;				/* initial effective group id */
 uid_t uid;				/* current euid */
+gid_t gid;				/* current egid */
 
 static struct passwd *man_owner;
 
@@ -114,10 +122,17 @@ static inline void gripe_set_euid (void)
 	error (FATAL, errno, _("can't set effective uid"));
 }
 
+static __inline__ void gripe_set_egid ()
+{
+	error (FATAL, errno, _( "can't set effective gid"));
+}
+
 void init_security (void)
 {
 	ruid = getuid ();
+	rgid = getgid ();
 	uid = euid = geteuid ();
+	gid = egid = getegid ();
 	debug ("ruid=%d, euid=%d\n", (int) ruid, (int) euid);
 	priv_drop_count = 0;
 	drop_effective_privs ();
@@ -191,6 +206,28 @@ void regain_effective_privs (void)
 
 		uid = euid;
 	}
+
+	if (gid != rgid) {
+#  ifdef POSIX_SAVED_IDS
+		if (SET_EGID (rgid))
+#  else
+		if (SWAP_GIDS (egid, rgid))
+#  endif 
+			gripe_set_egid();
+
+		gid = rgid;
+	}
+
+	if (gid != egid) {
+#  ifdef POSIX_SAVED_IDS
+		if (SET_EGID (egid))
+#  else
+		if (SWAP_GIDS (rgid, egid))
+#  endif
+			gripe_set_egid();
+
+		gid = egid;
+	}
 #endif /* SECURE_MAN_UID */
 }
 
--- src/security.h
+++ src/security.h	2008-04-21 15:19:19.000000000 +0200
@@ -25,8 +25,8 @@
 #include <pwd.h>
 
 /* security.c */
-extern inline void drop_effective_privs (void);
-extern inline void regain_effective_privs (void);
+extern void drop_effective_privs (void);
+extern void regain_effective_privs (void);
 extern int do_system_drop_privs (struct pipeline *p);
 extern int remove_with_dropped_privs (const char *filename);
 extern void init_security (void);
--- src/straycats.c
+++ src/straycats.c	2008-08-12 16:59:18.780475384 +0200
@@ -35,6 +35,7 @@
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <unistd.h>
+#include <fcntl.h>
 
 #ifdef HAVE_DIRENT_H
 #  include <dirent.h>
@@ -268,13 +269,17 @@ static int check_for_stray (void)
 
 			if (lg.whatis)
 				free (lg.whatis);
-			pipeline_free (decomp);
+			if (decomp)
+				pipeline_free (decomp);
 next_exists:
-			free_mandata_struct (exists);
-			free (mandir_base);
+			if (exists)
+				free_mandata_struct (exists);
+			if (mandir_base)
+				free (mandir_base);
 		}
 next_section:
-		free (section);
+		if (section)
+			free (section);
 	}
 	closedir (cdir);
 	return strays;
--- src/ult_src.c
+++ src/ult_src.c	2007-12-10 14:34:00.000000000 +0100
@@ -289,12 +289,17 @@ const char *ult_src (const char *name, c
 		}
 		pipeline_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 = pipeline_readline (decomp);
-		} while (buffer && STRNEQ (buffer, ".\\\"", 3));
+		} while (buffer && *buffer &&
+			 (STRNEQ (buffer, ".\\\"", 3) ||
+			  STRNEQ (buffer, "'\\\"", 3)));
 
-		if (buffer) {
+		if (buffer && *buffer) {
 			char *include = test_for_include (buffer);
 			if (include) {
 				const char *ult;
--- src/ult_src.h
+++ src/ult_src.h	2007-12-10 13:24:30.000000000 +0100
@@ -21,9 +21,10 @@
  * Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  */
 
-#define SO_LINK		0001
-#define SOFT_LINK	0002
-#define HARD_LINK	0004
+#define SO_LINK		0x0001
+#define SOFT_LINK	0x0002
+#define HARD_LINK	0x0004
+#define WHATISBUF	0x0008
 
 extern const char *ult_src (const char *name, const char *path,
 			    struct stat *buf, int flags);
--- src/util.c
+++ src/util.c	2007-12-10 13:24:30.000000000 +0100
@@ -43,6 +43,9 @@
 #include <dirent.h>
 #include <unistd.h>
 
+#include <libintl.h>
+#define _(String) gettext (String)
+
 #include "manconfig.h"
 
 #include "pipeline.h"
--- src/wrapper.c
+++ src/wrapper.c	2008-01-07 13:06:02.000000000 +0100
@@ -29,6 +29,7 @@
 #include <stdio.h>
 #include <unistd.h>
 #include <errno.h>
+#include <grp.h>
 #include <pwd.h>
 #include <grp.h>
 #include <sys/types.h>
@@ -48,7 +49,7 @@
  * it is fixed at compile time to avoid a full class of 
  * dangers ...
  */
-struct	{
+static struct {
 	const char *prog;
 	const char *run;
 	const char *user;
@@ -64,10 +65,11 @@ struct	{
 
 char *program_name;
 
-int main (int argc, char **argv)
+int main (int argc, char **argv, char *envp[])
 {
-	uid_t ruid;
-	char *fakeroot;
+	uid_t ruid, euid;
+	gid_t rgid;
+//	char *fakeroot;
 	struct passwd *pwd;
 
 	argc = argc; /* not used */
@@ -84,57 +86,56 @@ int main (int argc, char **argv)
 	program_name = base_name (argv[0]);
 
 	ruid = getuid ();
-	fakeroot = getenv ("FAKEROOTKEY");
+	euid = geteuid();
+	rgid = getgid ();
+//	fakeroot = getenv ("FAKEROOTKEY");
 
 #ifdef DEBUG
 	printf ("%s:\n", program_name);
-	printf ("real = %d, = %d, fakeroot = %d\n",
-		(int) ruid, (fakeroot != 0));
+//	printf ("real = %d, = %d, fakeroot = %d\n", (int) ruid, (fakeroot != 0));
 #endif
 
-	for (wlp = wrapped_list; wlp->prog && strcmp (program_name, wlp->prog);
-	     ++wlp)
-		;
+	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;
 	}
-
-	if (!fakeroot && ruid == 0) {
+#ifdef DEBUG
+	printf ("%s\n", wlp->run);
+#endif
+	if (/* !fakeroot && */ (ruid == 0 || euid == 0)) {
 		pwd = getpwnam (wlp->user);
-		/*
-		if (!pwd
-		 || setgid (pwd->pw_gid)
-		 || initgroups (wlp->user, pwd->pw_gid)
-		 || setuid (pwd->pw_uid)) {
-			fprintf (stderr, _("%s: Failed su to user %s\n"),
-				 wlp->prog, wlp->user);
-			return -EACCES;
-		}
-		*/
 		if (!pwd) {
-			fprintf (stderr, _("%s: Failed su to user %s\n"),
-				 wlp->prog, wlp->user);
+			fprintf (stderr, _("%s: Failed su to user %s\n"), wlp->prog, wlp->user);
 			return -EACCES;
 		}
-		if (setgid (pwd->pw_gid)) {
-			fprintf (stderr, _("%s: Failed su to user %s\n"),
-				 wlp->prog, wlp->user);
+		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/chache/man */
+			pwd->pw_uid = ruid;
+			pwd->pw_gid = rgid;
+#endif
+		}
+		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, pwd->pw_gid)) {
-			fprintf (stderr, _("%s: Failed su to user %s\n"),
-				 wlp->prog, wlp->user);
+		if (initgroups (wlp->user, rgid)) {
+			fprintf (stderr, _("%s: Failed su to user %s\n"), wlp->prog, wlp->user);
 			return -EACCES;
 		}
-		if (setuid (pwd->pw_uid)) {
-			fprintf (stderr, _("%s: Failed su to user %s\n"),
-				 wlp->prog, wlp->user);
+		if (setreuid (ruid, pwd->pw_uid)) {
+			fprintf (stderr, _("%s: Failed su to user %s\n"), wlp->prog, wlp->user);
 			return -EACCES;
 		}
 	}
-	execv (wlp->run, argv);
-	perror ("execv");
+	execve (wlp->run, argv, envp);
+	perror ("execve");
 	return -errno;
 }
openSUSE Build Service is sponsored by