Index: head/etc/mtree/BSD.local.dist =================================================================== --- head/etc/mtree/BSD.local.dist (revision 89652) +++ head/etc/mtree/BSD.local.dist (revision 89653) @@ -1,400 +1,404 @@ # $FreeBSD$ # # Please see the file src/etc/mtree/README before making changes to this file. # /set type=dir uname=root gname=wheel mode=0755 . bin .. etc rc.d .. .. include .. info .. lib perl5 5.6.0 man man3 .. .. .. site_perl 5.6.0 auto .. mach auto .. .. .. .. .. .. libdata .. libexec .. man +/set uname=man cat1 .. cat2 .. cat3 .. cat4 .. cat5 .. cat6 .. cat7 .. cat8 .. cat9 .. catl .. catn .. - de.ISO8859-1 + de.ISO8859-1 uname=root cat1 .. cat2 .. cat3 .. cat4 .. cat5 .. cat6 .. cat7 .. cat8 .. cat9 .. catl .. catn .. +/set uname=root man1 .. man2 .. man3 .. man4 .. man5 .. man6 .. man7 .. man8 .. man9 .. manl .. mann .. .. en.ISO8859-1 +/set uname=man cat1 .. cat1aout .. cat2 .. cat3 .. cat4 alpha .. i386 .. .. cat5 .. cat6 .. cat7 .. cat8 alpha .. i386 .. .. cat9 i386 .. .. catn .. .. - ja + ja uname=root cat1 .. cat2 .. cat3 .. cat4 .. cat5 .. cat6 .. cat7 .. cat8 .. cat9 .. catl .. catn .. +/set uname=root man1 .. man2 .. man3 .. man4 .. man5 .. man6 .. man7 .. man8 .. man9 .. manl .. mann .. .. man1 .. man2 .. man3 .. man4 .. man5 .. man6 .. man7 .. man8 .. man9 .. manl .. mann .. .. sbin .. share aclocal .. dict .. doc ja .. .. emacs site-lisp .. .. examples .. misc .. nls C .. af_ZA.ISO8859-1 .. af_ZA.ISO8859-15 .. bg_BG.CP1251 .. cs_CZ.ISO8859-2 .. da_DK.ISO8859-1 .. da_DK.ISO8859-15 .. de_AT.ISO8859-1 .. de_AT.ISO8859-15 .. de_CH.ISO8859-1 .. de_CH.ISO8859-15 .. de_DE.ISO8859-1 .. de_DE.ISO8859-15 .. el_GR.ISO8859-7 .. en_AU.ISO8859-1 .. en_AU.ISO8859-15 .. en_AU.US-ASCII .. en_CA.ISO8859-1 .. en_CA.ISO8859-15 .. en_CA.US-ASCII .. en_GB.ISO8859-1 .. en_GB.ISO8859-15 .. en_GB.US-ASCII .. en_NZ.ISO8859-1 .. en_NZ.ISO8859-15 .. en_NZ.US-ASCII .. en_US.ISO8859-1 .. en_US.ISO8859-15 .. es_ES.ISO8859-1 .. es_ES.ISO8859-15 .. et_EE.ISO8859-15 .. fi_FI.ISO8859-1 .. fi_FI.ISO8859-15 .. fr_BE.ISO8859-1 .. fr_BE.ISO8859-15 .. fr_CA.ISO8859-1 .. fr_CA.ISO8859-15 .. fr_CH.ISO8859-1 .. fr_CH.ISO8859-15 .. fr_FR.ISO8859-1 .. fr_FR.ISO8859-15 .. hi_IN.ISCII-DEV .. hr_HR.ISO8859-2 .. hu_HU.ISO8859-2 .. is_IS.ISO8859-1 .. is_IS.ISO8859-15 .. it_CH.ISO8859-1 .. it_CH.ISO8859-15 .. it_IT.ISO8859-1 .. it_IT.ISO8859-15 .. ja_JP.SJIS .. ja_JP.eucJP .. ko_KR.eucKR .. la_LN.ISO8859-1 .. la_LN.ISO8859-15 .. la_LN.ISO8859-2 .. la_LN.ISO8859-4 .. la_LN.US-ASCII .. lt_LT.ISO8859-4 .. nl_BE.ISO8859-1 .. nl_BE.ISO8859-15 .. nl_NL.ISO8859-1 .. nl_NL.ISO8859-15 .. no_NO.ISO8859-1 .. no_NO.ISO8859-15 .. pl_PL.ISO8859-2 .. pt_PT.ISO8859-1 .. pt_PT.ISO8859-15 .. ro_RO.ISO8859-2 .. ru_RU.CP866 .. ru_RU.ISO8859-5 .. ru_RU.KOI8-R .. sk_SK.ISO8859-2 .. sl_SI.ISO8859-2 .. sv_SE.ISO8859-1 .. sv_SE.ISO8859-15 .. tr_TR.ISO8859-9 .. uk_UA.ISO8859-5 .. uk_UA.KOI8-U .. zh_CN.eucCN .. zh_TW.Big5 .. .. skel .. .. .. Index: head/etc/mtree/BSD.usr.dist =================================================================== --- head/etc/mtree/BSD.usr.dist (revision 89652) +++ head/etc/mtree/BSD.usr.dist (revision 89653) @@ -1,1040 +1,1042 @@ # $FreeBSD$ # # Please see the file src/etc/mtree/README before making changes to this file. # /set type=dir uname=root gname=wheel mode=0755 . bin .. games hide gname=games mode=0550 .. .. include .. lib aout .. compat aout .. .. .. libdata doscmd fonts .. .. gcc .. ldscripts .. lint .. msdosfs .. perl 5.6.0 B .. CGI .. CPAN .. Carp .. Class .. Data .. Devel .. Exporter .. ExtUtils .. File Spec .. .. Getopt .. I18N .. IO .. IPC .. Math .. Net .. Pod Text .. .. Search .. Sys .. Term .. Test .. Text .. Tie .. Time .. User .. auto DB_File .. File Glob .. .. GDBM_File .. Getopt Long .. .. POSIX .. .. mach B .. CORE .. Data .. IO Socket .. .. IPC .. arpa .. auto B .. DB_File .. Data Dumper .. .. DynaLoader .. Fcntl .. IO .. IPC SysV .. .. NDBM_File .. Opcode .. POSIX .. SDBM_File .. Socket .. attrs .. re .. sdbm .. .. .. pod .. unicode In .. Is .. To .. .. warnings .. .. BSDPAN BSDPAN .. ExtUtils .. .. .. stallion .. .. libexec aout .. elf .. lpr ru .. .. sendmail .. sm.bin .. .. local .. obj nochange .. sbin .. share calendar de_DE.ISO8859-1 .. hr_HR.ISO8859-2 .. ru_RU.KOI8-R .. .. dict .. doc IPv6 .. bind html .. misc .. .. ncurses .. ntp .. papers .. psd 05.sysman .. 12.make .. 13.rcs .. 18.gprof .. 20.ipctut .. 21.ipc .. 22.rpcgen .. 23.rpc .. 24.xdr .. 25.xdrrfc .. 26.rpcrfc .. 27.nfsrfc .. 28.cvs .. .. smm 01.setup .. 02.config .. 03.fsck .. 04.quotas .. 05.fastfs .. 06.nfs .. 07.lpd .. 08.sendmailop .. 10.named .. 11.timedop .. 12.timed .. 18.net .. .. usd 04.csh .. 07.mail .. 10.exref .. 11.edit .. 12.vi .. 13.viref .. 18.msdiffs .. 19.memacros .. 20.meref .. 30.rogue .. 31.trek .. .. .. examples BSD_daemon .. FreeBSD_version .. IPv6 .. atm .. bc .. bootforth .. cvs contrib .. .. cvsup .. dialog .. diskless 209.157.86.12 .. HT.DISKLESS .. HT.STD .. archive.backplane.com .. .. drivers .. etc defaults .. .. find_interface .. ibcs2 .. ipfilter .. ipfw .. isdn contrib .. i4brunppp .. v21 .. .. kld cdev module .. test .. .. dyn_sysctl module .. .. syscall module .. test .. .. .. libdialog .. libvgl .. mdoc .. meteor .. netgraph .. nwclient .. perfmon .. portal .. ppi .. ppp .. printing .. scsi_target .. ses getencstat .. sesd .. setencstat .. setobjstat .. srcs .. .. slattach .. sliplogin .. smbfs print .. .. startslip .. sunrpc dir .. msg .. sort .. .. worm .. .. games atc .. fortune .. larn .. quiz.db .. .. groff_font devX100 .. devX100-12 .. devX75 .. devX75-12 .. devascii .. devcp1047 .. devdvi .. devhtml .. devkoi8-r .. devlatin1 .. devlbp .. devlj4 .. devps .. devutf8 .. .. info .. isdn .. libg++ .. locale af_ZA.ISO8859-1 .. af_ZA.ISO8859-15 .. bg_BG.CP1251 .. cs_CZ.ISO8859-2 .. da_DK.ISO8859-1 .. da_DK.ISO8859-15 .. de_AT.ISO8859-1 .. de_AT.ISO8859-15 .. de_CH.ISO8859-1 .. de_CH.ISO8859-15 .. de_DE.ISO8859-1 .. de_DE.ISO8859-15 .. el_GR.ISO8859-7 .. en_AU.ISO8859-1 .. en_AU.ISO8859-15 .. en_AU.US-ASCII .. en_CA.ISO8859-1 .. en_CA.ISO8859-15 .. en_CA.US-ASCII .. en_GB.ISO8859-1 .. en_GB.ISO8859-15 .. en_GB.US-ASCII .. en_NZ.ISO8859-1 .. en_NZ.ISO8859-15 .. en_NZ.US-ASCII .. en_US.ISO8859-1 .. en_US.ISO8859-15 .. en_US.US-ASCII .. es_ES.ISO8859-1 .. es_ES.ISO8859-15 .. et_EE.ISO8859-15 .. fi_FI.ISO8859-1 .. fi_FI.ISO8859-15 .. fr_BE.ISO8859-1 .. fr_BE.ISO8859-15 .. fr_CA.ISO8859-1 .. fr_CA.ISO8859-15 .. fr_CH.ISO8859-1 .. fr_CH.ISO8859-15 .. fr_FR.ISO8859-1 .. fr_FR.ISO8859-15 .. hi_IN.ISCII-DEV .. hr_HR.ISO8859-2 .. hu_HU.ISO8859-2 .. is_IS.ISO8859-1 .. is_IS.ISO8859-15 .. it_CH.ISO8859-1 .. it_CH.ISO8859-15 .. it_IT.ISO8859-1 .. it_IT.ISO8859-15 .. ja_JP.SJIS .. ja_JP.eucJP .. ko_KR.eucKR .. la_LN.ISO8859-1 .. la_LN.ISO8859-15 .. la_LN.ISO8859-2 .. la_LN.ISO8859-4 .. la_LN.US-ASCII .. lt_LT.ISO8859-4 .. nl_BE.ISO8859-1 .. nl_BE.ISO8859-15 .. nl_NL.ISO8859-1 .. nl_NL.ISO8859-15 .. no_NO.ISO8859-1 .. no_NO.ISO8859-15 .. pl_PL.ISO8859-2 .. pt_PT.ISO8859-1 .. pt_PT.ISO8859-15 .. ro_RO.ISO8859-2 .. ru_RU.CP866 .. ru_RU.ISO8859-5 .. ru_RU.KOI8-R .. sk_SK.ISO8859-2 .. sl_SI.ISO8859-2 .. sv_SE.ISO8859-1 .. sv_SE.ISO8859-15 .. tr_TR.ISO8859-9 .. uk_UA.ISO8859-5 .. uk_UA.KOI8-U .. zh_CN.eucCN .. zh_TW.Big5 .. .. man +/set uname=man cat1 .. cat1aout .. cat2 .. cat3 .. cat4 alpha .. i386 .. .. cat5 .. cat6 .. cat7 .. cat8 alpha .. i386 .. .. cat9 i386 .. .. catn .. - en.ISO8859-1 + en.ISO8859-1 uname=root cat1 .. cat1aout .. cat2 .. cat3 .. cat4 alpha .. i386 .. .. cat5 .. cat6 .. cat7 .. cat8 alpha .. i386 .. .. cat9 i386 .. .. catn .. .. - ja + ja uname=root cat1 .. cat2 .. cat3 .. cat4 .. cat5 .. cat6 .. cat7 .. cat8 .. cat9 .. catn .. +/set uname=root man1 .. man2 .. man3 .. man4 .. man5 .. man6 .. man7 .. man8 .. man9 .. mann .. .. man1 .. man1aout .. man2 .. man3 .. man4 alpha .. i386 .. .. man5 .. man6 .. man7 .. man8 alpha .. i386 .. .. man9 i386 .. .. mann .. .. me .. misc fonts .. pcvtfonts .. .. mk .. nls C .. af_ZA.ISO8859-1 .. af_ZA.ISO8859-15 .. bg_BG.CP1251 .. cs_CZ.ISO8859-2 .. da_DK.ISO8859-1 .. da_DK.ISO8859-15 .. de_AT.ISO8859-1 .. de_AT.ISO8859-15 .. de_CH.ISO8859-1 .. de_CH.ISO8859-15 .. de_DE.ISO8859-1 .. de_DE.ISO8859-15 .. el_GR.ISO8859-7 .. en_AU.ISO8859-1 .. en_AU.ISO8859-15 .. en_AU.US-ASCII .. en_CA.ISO8859-1 .. en_CA.ISO8859-15 .. en_CA.US-ASCII .. en_GB.ISO8859-1 .. en_GB.ISO8859-15 .. en_GB.US-ASCII .. en_NZ.ISO8859-1 .. en_NZ.ISO8859-15 .. en_NZ.US-ASCII .. en_US.ISO8859-1 .. en_US.ISO8859-15 .. es_ES.ISO8859-1 .. es_ES.ISO8859-15 .. et_EE.ISO8859-15 .. fi_FI.ISO8859-1 .. fi_FI.ISO8859-15 .. fr_BE.ISO8859-1 .. fr_BE.ISO8859-15 .. fr_CA.ISO8859-1 .. fr_CA.ISO8859-15 .. fr_CH.ISO8859-1 .. fr_CH.ISO8859-15 .. fr_FR.ISO8859-1 .. fr_FR.ISO8859-15 .. hi_IN.ISCII-DEV .. hr_HR.ISO8859-2 .. hu_HU.ISO8859-2 .. is_IS.ISO8859-1 .. is_IS.ISO8859-15 .. it_CH.ISO8859-1 .. it_CH.ISO8859-15 .. it_IT.ISO8859-1 .. it_IT.ISO8859-15 .. ja_JP.SJIS .. ja_JP.eucJP .. ko_KR.eucKR .. la_LN.ISO8859-1 .. la_LN.ISO8859-15 .. la_LN.ISO8859-2 .. la_LN.ISO8859-4 .. la_LN.US-ASCII .. lt_LT.ISO8859-4 .. nl_BE.ISO8859-1 .. nl_BE.ISO8859-15 .. nl_NL.ISO8859-1 .. nl_NL.ISO8859-15 .. no_NO.ISO8859-1 .. no_NO.ISO8859-15 .. pl_PL.ISO8859-2 .. pt_PT.ISO8859-1 .. pt_PT.ISO8859-15 .. ro_RO.ISO8859-2 .. ru_RU.CP866 .. ru_RU.ISO8859-5 .. ru_RU.KOI8-R .. sk_SK.ISO8859-2 .. sl_SI.ISO8859-2 .. sv_SE.ISO8859-1 .. sv_SE.ISO8859-15 .. tr_TR.ISO8859-9 .. uk_UA.ISO8859-5 .. uk_UA.KOI8-U .. zh_CN.eucCN .. zh_TW.Big5 .. .. pcvt Doc .. Etc .. .. perl man - cat3 + cat3 uname=man .. man3 .. .. .. sendmail .. skel .. syscons fonts .. keymaps .. scrnmaps .. .. tabset .. tmac mdoc .. mm .. .. vi catalog .. perl .. tcl .. .. zoneinfo Africa .. America Indiana .. Kentucky .. North_Dakota .. .. Antarctica .. Arctic .. Asia .. Atlantic .. Australia .. Etc .. Europe .. Indian .. Pacific .. SystemV .. .. .. src nochange .. .. Index: head/etc/mtree/BSD.x11-4.dist =================================================================== --- head/etc/mtree/BSD.x11-4.dist (revision 89652) +++ head/etc/mtree/BSD.x11-4.dist (revision 89653) @@ -1,418 +1,420 @@ # $FreeBSD$ # # Please see the file src/etc/mtree/README before making changes to this file. # /set type=dir uname=root gname=wheel mode=0755 . bin .. etc rc.d .. .. include DPS .. GL .. X11 ICE .. PEX5 .. PM .. SM .. Xaw .. Xft .. Xmu .. bitmaps .. extensions .. fonts codeconv .. .. pixmaps .. .. bitmaps .. freetype2 freetype cache .. config .. internal .. .. .. .. info .. lib X11 XF86Setup pics .. scripts .. tcllib .. .. app-defaults .. config .. doc PostScript .. html .. .. etc .. fonts 100dpi .. 75dpi .. CID .. PEX .. Speedo .. Type1 .. cyrillic .. encodings large .. .. latin2 100dpi .. 75dpi .. .. local .. misc .. util .. .. fs .. lbxproxy .. locale C .. armscii-8 .. en_US.UTF-8 .. en_US.utf .. georgian-academy .. georgian-ps .. ibm-cp1133 .. iscii-dev .. isiri-3342 .. iso8859-1 .. iso8859-10 .. iso8859-13 .. iso8859-14 .. iso8859-15 .. iso8859-2 .. iso8859-3 .. iso8859-4 .. iso8859-5 .. iso8859-6 .. iso8859-7 .. iso8859-8 .. iso8859-9 .. iso8859-9e .. ja .. ja.JIS .. ja.SJIS .. ko .. koi8-c .. koi8-r .. koi8-u .. microsoft-cp1251 .. microsoft-cp1255 .. microsoft-cp1256 .. mk_MK.UTF-8 .. mulelao-1 .. nokhchi-1 .. tatar-cyr .. tbl_data .. th_TH .. th_TH.TACTIS .. tscii-0 .. vi_VN.tcvn .. vi_VN.viscii .. zh .. zh_CN.gbk .. zh_HK.big5hkscs .. zh_TW .. zh_TW.Big5 .. .. proxymngr .. rstart commands x11r6 .. .. contexts .. .. twm .. x11perfcomp .. xdm pixmaps .. .. xinit .. xkb compat .. compiled .. geometry digital .. sgi .. .. keycodes digital .. sgi .. .. keymap digital .. sgi .. sun .. .. rules .. semantics .. symbols digital .. fujitsu .. hp .. macintosh .. nec .. sgi .. sony .. sun .. xfree68 .. .. types .. .. xserver .. xsm .. .. aout .. modules codeconv .. dri .. drivers .. extensions .. fonts .. freebsd .. input .. .. .. libdata .. libexec .. man +/set uname=man cat1 .. cat2 .. cat3 .. cat4 .. cat5 .. cat6 .. cat7 .. cat8 .. cat9 .. catl .. catn .. - ja + ja uname=root cat1 .. cat2 .. cat3 .. cat4 .. cat5 .. cat6 .. cat7 .. cat8 .. cat9 .. catl .. catn .. +/set uname=root man1 .. man2 .. man3 .. man4 .. man5 .. man6 .. man7 .. man8 .. man9 .. manl .. mann .. .. man1 .. man2 .. man3 .. man4 .. man5 .. man6 .. man7 .. man8 .. man9 .. manl .. mann .. .. share aclocal .. doc ja .. .. examples .. .. .. Index: head/etc/mtree/BSD.x11.dist =================================================================== --- head/etc/mtree/BSD.x11.dist (revision 89652) +++ head/etc/mtree/BSD.x11.dist (revision 89653) @@ -1,300 +1,302 @@ # $FreeBSD$ # # Please see the file src/etc/mtree/README before making changes to this file. # /set type=dir uname=root gname=wheel mode=0755 . bin .. etc rc.d .. .. include X11 ICE .. PEX5 .. PM .. SM .. Xaw .. Xmu .. bitmaps .. extensions .. fonts .. pixmaps .. .. .. info .. lib X11 XF86Setup pics .. scripts .. tcllib .. .. app-defaults .. config .. doc .. etc .. fonts 100dpi .. 75dpi .. PEX .. Speedo .. Type1 .. cyrillic .. local .. misc .. .. fs .. lbxproxy .. locale C .. en_US.utf .. iso8859-1 .. iso8859-2 .. iso8859-3 .. iso8859-4 .. iso8859-5 .. iso8859-6 .. iso8859-7 .. iso8859-8 .. iso8859-9 .. ja .. ja.JIS .. ja.SJIS .. ko .. koi8-r .. tbl_data .. th_TH.TACTIS .. zh .. zh_TW .. zh_TW.Big5 .. .. proxymngr .. rstart commands x11r6 .. .. contexts .. .. twm .. x11perfcomp .. xdm .. xinit .. xkb compat .. compiled .. geometry digital .. sgi .. .. keycodes digital .. sgi .. .. keymap digital .. sgi .. sun .. .. rules .. semantics .. symbols digital .. fujitsu .. nec .. sony .. sun .. .. .. xserver .. xsm .. .. aout .. modules .. .. libdata .. libexec .. man +/set uname=man cat1 .. cat2 .. cat3 .. cat4 .. cat5 .. cat6 .. cat7 .. cat8 .. cat9 .. catl .. catn .. - ja + ja uname=root cat1 .. cat2 .. cat3 .. cat4 .. cat5 .. cat6 .. cat7 .. cat8 .. cat9 .. catl .. catn .. +/set uname=root man1 .. man2 .. man3 .. man4 .. man5 .. man6 .. man7 .. man8 .. man9 .. manl .. mann .. .. man1 .. man2 .. man3 .. man4 .. man5 .. man6 .. man7 .. man8 .. man9 .. manl .. mann .. .. share aclocal .. doc ja .. .. examples .. .. .. Index: head/gnu/usr.bin/man/man/man.c =================================================================== --- head/gnu/usr.bin/man/man/man.c (revision 89652) +++ head/gnu/usr.bin/man/man/man.c (revision 89653) @@ -1,1616 +1,1652 @@ /* * man.c * * Copyright (c) 1990, 1991, John W. Eaton. * * You may distribute under the terms of the GNU General Public * License as specified in the file COPYING that comes with the man * distribution. * * John W. Eaton * jwe@che.utexas.edu * Department of Chemical Engineering * The University of Texas at Austin * Austin, Texas 78712 * * $FreeBSD$ */ #define MAN_MAIN #include #include #include #include #include #ifdef __FreeBSD__ #include #include #endif #include #include #include #if HAVE_LIBZ > 0 #include #endif #include "config.h" #include "gripes.h" #include "version.h" #ifdef POSIX #include #else #ifndef R_OK #define R_OK 4 #endif #endif -#ifdef SECURE_MAN_UID -extern uid_t getuid (); -extern int setuid (); -#endif - #ifdef STDC_HEADERS #include #else extern char *malloc (); extern char *getenv (); extern void free (); extern int system (); extern int strcmp (); extern int strncmp (); extern int exit (); extern int fflush (); extern int printf (); extern int fprintf (); extern FILE *fopen (); extern int fclose (); extern char *sprintf (); #endif extern char **glob_filename (); extern int is_newer (); extern int is_directory (); extern int do_system_command (); char *prognam; static char *pager; static char *machine; static char *manp; static char *manpathlist[MAXDIRS]; static char *section; static char *colon_sep_section_list; static char **section_list; static char *roff_directive; static int apropos; static int whatis; static int findall; static int print_where; #ifdef __FreeBSD__ static char *locale, *locale_opts, *locale_nroff, *locale_codeset; static char locale_terr[3], locale_lang[3]; static int use_original; struct ltable { char *lcode; char *nroff; }; static struct ltable ltable[] = { {"KOI8-R", "koi8-r"}, {"ISO8859-1", "latin1"}, {"ISO8859-15", "latin1"}, {NULL} }; #endif static int troff = 0; int debug; #ifdef HAS_TROFF #ifdef __FreeBSD__ static char args[] = "M:P:S:adfhkm:op:tw?"; #else static char args[] = "M:P:S:adfhkm:p:tw?"; #endif #else #ifdef __FreeBSD__ static char args[] = "M:P:S:adfhkm:op:w?"; #else static char args[] = "M:P:S:adfhkm:p:w?"; #endif #endif +#ifdef SETUID +uid_t ruid; +uid_t euid; +#endif + int main (argc, argv) int argc; char **argv; { int status = 0; char *nextarg; char *tmp; extern char *mkprogname (); char *is_section (); char **get_section_list (); void man_getopt (); void do_apropos (); void do_whatis (); int man (); prognam = mkprogname (argv[0]); unsetenv("IFS"); #ifdef __FreeBSD__ (void) setlocale(LC_ALL, ""); #endif man_getopt (argc, argv); if (optind == argc) gripe_no_name ((char *)NULL); section_list = get_section_list (); if (optind == argc - 1) { tmp = is_section (argv[optind]); if (tmp != NULL) gripe_no_name (tmp); } +#ifdef SETUID + ruid = getuid(); + euid = geteuid(); + seteuid(ruid); +#endif + while (optind < argc) { nextarg = argv[optind++]; /* * See if this argument is a valid section name. If not, * is_section returns NULL. */ tmp = is_section (nextarg); if (tmp != NULL) { section = tmp; if (debug) fprintf (stderr, "\nsection: %s\n", section); continue; } if (apropos) { do_apropos (nextarg); status = (status ? 0 : 1); /* reverts status, see below */ } else if (whatis) { do_whatis (nextarg); status = (status ? 0 : 1); /* reverts status, see below */ } else { status = man (nextarg); if (status == 0) gripe_not_found (nextarg, section); } } return (status==0); /* status==1 --> exit(0), status==0 --> exit(1) */ } void usage () { static char usage_string[1024] = "%s, version %s\n\n"; #ifdef HAS_TROFF #ifdef __FreeBSD__ static char s1[] = "usage: %s [-adfhkotw] [section] [-M path] [-P pager] [-S list]\n\ [-m machine] [-p string] name ...\n\n"; #else static char s1[] = "usage: %s [-adfhktw] [section] [-M path] [-P pager] [-S list]\n\ [-m machine] [-p string] name ...\n\n"; #endif #else #ifdef __FreeBSD__ static char s1[] = "usage: %s [-adfhkow] [section] [-M path] [-P pager] [-S list]\n\ [-m machine] [-p string] name ...\n\n"; #else static char s1[] = "usage: %s [-adfhkw] [section] [-M path] [-P pager] [-S list]\n\ [-m machine] [-p string] name ...\n\n"; #endif #endif static char s2[] = " a : find all matching entries\n\ d : print gobs of debugging information\n\ f : same as whatis(1)\n\ h : print this help message\n\ k : same as apropos(1)\n"; #ifdef __FreeBSD__ static char s3[] = " o : use original, non-localized manpages\n"; #endif #ifdef HAS_TROFF static char s4[] = " t : use troff to format pages for printing\n"; #endif static char s5[] = " w : print location of man page(s) that would be displayed\n\n\ M path : set search path for manual pages to `path'\n\ P pager : use program `pager' to display pages\n\ S list : colon separated section list\n\ m machine : search for alternate architecture man pages\n"; static char s6[] = " p string : string tells which preprocessors to run\n\ e - [n]eqn(1) p - pic(1) t - tbl(1)\n\ g - grap(1) r - refer(1) v - vgrind(1)\n"; strcat (usage_string, s1); strcat (usage_string, s2); #ifdef __FreeBSD__ strcat (usage_string, s3); #endif #ifdef HAS_TROFF strcat (usage_string, s4); #endif strcat (usage_string, s5); strcat (usage_string, s6); fprintf (stderr, usage_string, prognam, version, prognam); exit(1); } char ** add_dir_to_mpath_list (mp, p) char **mp; char *p; { int status; status = is_directory (p); if (status < 0 && debug) { fprintf (stderr, "Warning: couldn't stat file %s!\n", p); } else if (status == 0 && debug) { fprintf (stderr, "Warning: %s isn't a directory!\n", p); } else if (status == 1) { if (debug) fprintf (stderr, "adding %s to manpathlist\n", p); *mp++ = strdup (p); } return mp; } /* * Get options from the command line and user environment. */ void man_getopt (argc, argv) register int argc; register char **argv; { register int c; register char *p; register char *end; register char **mp; extern void downcase (); extern char *manpath (); while ((c = getopt (argc, argv, args)) != EOF) { switch (c) { case 'M': manp = strdup (optarg); break; case 'P': pager = strdup (optarg); if (setenv("PAGER", pager, 1) != 0) (void)fprintf(stderr, "setenv PAGER=%s\n", pager); break; case 'S': colon_sep_section_list = strdup (optarg); break; case 'a': findall++; break; case 'd': debug++; break; case 'f': if (troff) gripe_incompatible ("-f and -t"); if (apropos) gripe_incompatible ("-f and -k"); if (print_where) gripe_incompatible ("-f and -w"); whatis++; break; case 'k': if (troff) gripe_incompatible ("-k and -t"); if (whatis) gripe_incompatible ("-k and -f"); if (print_where) gripe_incompatible ("-k and -w"); apropos++; break; case 'm': machine = optarg; break; case 'o': use_original++; break; case 'p': roff_directive = strdup (optarg); break; #ifdef HAS_TROFF case 't': if (apropos) gripe_incompatible ("-t and -k"); if (whatis) gripe_incompatible ("-t and -f"); if (print_where) gripe_incompatible ("-t and -w"); troff++; break; #endif case 'w': if (apropos) gripe_incompatible ("-w and -k"); if (whatis) gripe_incompatible ("-w and -f"); if (troff) gripe_incompatible ("-w and -t"); print_where++; break; case 'h': case '?': default: usage(); break; } } #ifdef __FreeBSD__ /* "" intentionally used to catch error */ if ((locale = setlocale(LC_CTYPE, "")) != NULL) locale_codeset = nl_langinfo(CODESET); if (!use_original && locale != NULL && *locale_codeset != '\0' && strcmp(locale_codeset, "US-ASCII") != 0 ) { char *tmp, *short_locale; struct ltable *pltable; *locale_lang = '\0'; *locale_terr = '\0'; if ((short_locale = strdup(locale)) == NULL) { perror ("ctype locale strdup"); exit (1); } if ((tmp = strchr(short_locale, '.')) != NULL) *tmp = '\0'; if (strlen(short_locale) == 2) strcpy(locale_lang, short_locale); else if ((tmp = strchr(short_locale, '_')) == NULL || tmp != short_locale + 2 || strlen(tmp + 1) != 2 ) { errno = EINVAL; perror ("ctype locale format"); locale = NULL; } else { strncpy(locale_terr, short_locale + 3, 2); locale_terr[2] = '\0'; strncpy(locale_lang, short_locale, 2); locale_lang[2] = '\0'; } free(short_locale); if (locale != NULL) { for (pltable = ltable; pltable->lcode != NULL; pltable++) { if (strcmp(pltable->lcode, locale_codeset) == 0) { locale_nroff = pltable->nroff; break; } } } } else { if (locale == NULL) { errno = EINVAL; perror ("ctype locale"); } else { locale = NULL; if (*locale_codeset == '\0') { errno = EINVAL; perror ("ctype codeset"); } } } #endif /* __FreeBSD__ */ if (pager == NULL || *pager == '\0') if ((pager = getenv ("PAGER")) == NULL) pager = strdup (PAGER); if (debug) fprintf (stderr, "\nusing %s as pager\n", pager); if (machine == NULL && (machine = getenv ("MACHINE")) == NULL) machine = MACHINE; if (debug) fprintf (stderr, "\nusing %s architecture\n", machine); if (manp == NULL) { if ((manp = manpath (0)) == NULL) gripe_manpath (); if (debug) fprintf (stderr, "\nsearch path for pages determined by manpath is\n%s\n\n", manp); } /* * Expand the manpath into a list for easier handling. */ mp = manpathlist; for (p = manp; ; p = end+1) { if (mp == manpathlist + MAXDIRS - 1) { fprintf (stderr, "Warning: too many directories in manpath, truncated!\n"); break; } if ((end = strchr (p, ':')) != NULL) *end = '\0'; mp = add_dir_to_mpath_list (mp, p); if (end == NULL) break; *end = ':'; } *mp = NULL; } /* * Check to see if the argument is a valid section number. If the * first character of name is a numeral, or the name matches one of * the sections listed in section_list, we'll assume that it's a section. * The list of sections in config.h simply allows us to specify oddly * named directories like .../man3f. Yuk. */ char * is_section (name) register char *name; { register char **vs; for (vs = section_list; *vs != NULL; vs++) if ((strcmp (*vs, name) == 0) || (isdigit ((unsigned char)name[0]) && strlen(name) == 1)) return strdup (name); return NULL; } /* * Handle the apropos option. Cheat by using another program. */ void do_apropos (name) register char *name; { register int len; register char *command; len = strlen (APROPOS) + strlen (name) + 4; if ((command = (char *) malloc(len)) == NULL) gripe_alloc (len, "command"); sprintf (command, "%s \"%s\"", APROPOS, name); (void) do_system_command (command); free (command); } /* * Handle the whatis option. Cheat by using another program. */ void do_whatis (name) register char *name; { register int len; register char *command; len = strlen (WHATIS) + strlen (name) + 4; if ((command = (char *) malloc(len)) == NULL) gripe_alloc (len, "command"); sprintf (command, "%s \"%s\"", WHATIS, name); (void) do_system_command (command); free (command); } /* * Change a name of the form ...man/man1/name.1 to ...man/cat1/name.1 * or a name of the form ...man/cat1/name.1 to ...man/man1/name.1 */ char * convert_name (name, to_cat) register char *name; register int to_cat; { register char *to_name; register char *t1; register char *t2 = NULL; #ifdef DO_COMPRESS if (to_cat) { int olen = strlen(name); int cextlen = strlen(COMPRESS_EXT); int len = olen + cextlen; to_name = malloc (len+1); if (to_name == NULL) gripe_alloc (len+1, "to_name"); strcpy (to_name, name); olen -= cextlen; /* Avoid tacking it on twice */ if (olen >= 1 && strcmp(name + olen, COMPRESS_EXT) != 0) strcat (to_name, COMPRESS_EXT); } else to_name = strdup (name); #else to_name = strdup (name); #endif t1 = strrchr (to_name, '/'); if (t1 != NULL) { *t1 = '\0'; t2 = strrchr (to_name, '/'); *t1 = '/'; /* Skip architecture part (if present). */ if (t2 != NULL && (t1 - t2 < 5 || *(t2 + 1) != 'm' || *(t2 + 3) != 'n')) { t1 = t2; *t1 = '\0'; t2 = strrchr (to_name, '/'); *t1 = '/'; } } if (t2 == NULL) gripe_converting_name (name, to_cat); if (to_cat) { *(++t2) = 'c'; *(t2+2) = 't'; } else { *(++t2) = 'm'; *(t2+2) = 'n'; } if (debug) fprintf (stderr, "to_name in convert_name () is: %s\n", to_name); return to_name; } /* * Try to find the man page corresponding to the given name. The * reason we do this with globbing is because some systems have man * page directories named man3 which contain files with names like * XtPopup.3Xt. Rather than requiring that this program know about * all those possible names, we simply try to match things like * .../man[sect]/name[sect]*. This is *much* easier. * * Note that globbing is only done when the section is unspecified. */ char ** glob_for_file (path, section, name, cat) register char *path; register char *section; register char *name; register int cat; { char pathname[FILENAME_MAX]; char **gf; if (cat) snprintf (pathname, sizeof(pathname), "%s/cat%s/%s.%s*", path, section, name, section); else snprintf (pathname, sizeof(pathname), "%s/man%s/%s.%s*", path, section, name, section); if (debug) fprintf (stderr, "globbing %s\n", pathname); gf = glob_filename (pathname); if ((gf == (char **) -1 || *gf == NULL) && isdigit ((unsigned char)*section)) { if (cat) snprintf (pathname, sizeof(pathname), "%s/cat%s/%s.%c*", path, section, name, *section); else snprintf (pathname, sizeof(pathname), "%s/man%s/%s.%c*", path, section, name, *section); gf = glob_filename (pathname); } if ((gf == (char **) -1 || *gf == NULL) && isdigit ((unsigned char)*section)) { if (cat) snprintf (pathname, sizeof(pathname), "%s/cat%s/%s.0*", path, section, name); else snprintf (pathname, sizeof(pathname), "%s/man%s/%s.0*", path, section, name); if (debug) fprintf (stderr, "globbing %s\n", pathname); gf = glob_filename (pathname); } return gf; } /* * Return an un-globbed name in the same form as if we were doing * globbing. */ char ** make_name (path, section, name, cat) register char *path; register char *section; register char *name; register int cat; { register int i = 0; static char *names[3]; char buf[FILENAME_MAX]; if (cat) snprintf (buf, sizeof(buf), "%s/cat%s/%s.%s", path, section, name, section); else snprintf (buf, sizeof(buf), "%s/man%s/%s.%s", path, section, name, section); if (access (buf, R_OK) == 0) names[i++] = strdup (buf); /* * If we're given a section that looks like `3f', we may want to try * file names like .../man3/foo.3f as well. This seems a bit * kludgey to me, but what the hey... */ if (section[1] != '\0') { if (cat) snprintf (buf, sizeof(buf), "%s/cat%c/%s.%s", path, section[0], name, section); else snprintf (buf, sizeof(buf), "%s/man%c/%s.%s", path, section[0], name, section); if (access (buf, R_OK) == 0) names[i++] = strdup (buf); } names[i] = NULL; return &names[0]; } char * get_expander (file) char *file; { char *end = file + (strlen (file) - 1); while (end > file && end[-1] != '.') --end; if (end == file) return NULL; #ifdef FCAT if (*end == 'F') return FCAT; #endif /* FCAT */ #ifdef YCAT if (*end == 'Y') return YCAT; #endif /* YCAT */ #ifdef ZCAT if (*end == 'Z' || !strcmp(end, "gz")) return ZCAT; #endif /* ZCAT */ return NULL; } /* * Simply display the preformatted page. */ int display_cat_file (file) register char *file; { register int found; char command[FILENAME_MAX]; found = 0; if (access (file, R_OK) == 0) { char *expander = get_expander (file); if (expander != NULL) snprintf (command, sizeof(command), "%s %s | %s", expander, file, pager); else snprintf (command, sizeof(command), "%s %s", pager, file); found = do_system_command (command); } return found; } /* * Try to find the ultimate source file. If the first line of the * current file is not of the form * * .so man3/printf.3s * * the input file name is returned. */ char * ultimate_source (name, path) char *name; char *path; { static char buf[BUFSIZ]; static char ult[FILENAME_MAX]; FILE *fp; char *beg; char *end; strncpy (ult, name, sizeof(ult)-1); ult[sizeof(ult)-1] = '\0'; strncpy (buf, name, sizeof(buf)-1); ult[sizeof(buf)-1] = '\0'; next: if ((fp = fopen (ult, "r")) == NULL) return ult; end = fgets (buf, BUFSIZ, fp); fclose(fp); if (!end || strlen (buf) < 5) return ult; beg = buf; if (*beg++ == '.' && *beg++ == 's' && *beg++ == 'o') { while ((*beg == ' ' || *beg == '\t') && *beg != '\0') beg++; end = beg; while (*end != ' ' && *end != '\t' && *end != '\n' && *end != '\0') end++; *end = '\0'; snprintf(ult, sizeof(ult), "%s/%s", path, beg); snprintf(buf, sizeof(buf), "%s", ult); goto next; } if (debug) fprintf (stderr, "found ultimate source file %s\n", ult); return ult; } void add_directive (first, d, file, buf, bufsize) int *first; char *d; char *file; char *buf; int bufsize; { if (strcmp (d, "") != 0) { if (*first) { *first = 0; snprintf(buf, bufsize, "%s %s", d, file); } else { strncat (buf, " | ", bufsize-strlen(buf)-1); strncat (buf, d, bufsize-strlen(buf)-1); } } } int parse_roff_directive (cp, file, buf, bufsize) char *cp; char *file; char *buf; int bufsize; { char c; char *exp; int first = 1; int preproc_found = 0; int use_col = 0; if ((exp = get_expander(file)) != NULL) add_directive (&first, exp, file, buf, bufsize); while ((c = *cp++) != '\0') { switch (c) { case 'e': if (debug) fprintf (stderr, "found eqn(1) directive\n"); preproc_found++; if (troff) add_directive (&first, EQN, file, buf, bufsize); else { #ifdef __FreeBSD__ char lbuf[FILENAME_MAX]; snprintf(lbuf, sizeof(lbuf), "%s -T%s", NEQN, locale_opts == NULL ? "ascii" : locale_opts); add_directive (&first, lbuf, file, buf, bufsize); #else add_directive (&first, NEQN, file, buf, bufsize); #endif } break; case 'g': if (debug) fprintf (stderr, "found grap(1) directive\n"); preproc_found++; add_directive (&first, GRAP, file, buf, bufsize); break; case 'p': if (debug) fprintf (stderr, "found pic(1) directive\n"); preproc_found++; add_directive (&first, PIC, file, buf, bufsize); break; case 't': if (debug) fprintf (stderr, "found tbl(1) directive\n"); preproc_found++; use_col++; add_directive (&first, TBL, file, buf, bufsize); break; case 'v': if (debug) fprintf (stderr, "found vgrind(1) directive\n"); add_directive (&first, VGRIND, file, buf, bufsize); break; case 'r': if (debug) fprintf (stderr, "found refer(1) directive\n"); add_directive (&first, REFER, file, buf, bufsize); break; case ' ': case '\t': case '\n': goto done; default: return -1; } } done: #ifdef HAS_TROFF if (troff) add_directive (&first, TROFF, file, buf, bufsize); else #endif { #ifdef __FreeBSD__ char lbuf[FILENAME_MAX]; snprintf(lbuf, sizeof(lbuf), "%s -T%s", NROFF, locale_opts == NULL ? "ascii" : locale_opts); add_directive (&first, lbuf, file, buf, bufsize); #else add_directive (&first, NROFF " -Tascii", file, buf, bufsize); #endif } if (use_col && !troff) add_directive (&first, COL, file, buf, bufsize); if (preproc_found) return 0; else return 1; } char * make_roff_command (file) char *file; { #if HAVE_LIBZ > 0 gzFile fp; #else FILE *fp; #endif char line [BUFSIZ]; static char buf [BUFSIZ]; int status; char *cp; if (roff_directive != NULL) { if (debug) fprintf (stderr, "parsing directive from command line\n"); status = parse_roff_directive (roff_directive, file, buf, sizeof(buf)); if (status == 0) return buf; if (status == -1) gripe_roff_command_from_command_line (file); } #if HAVE_LIBZ > 0 if ((fp = gzopen (file, "r")) != NULL) #else if ((fp = fopen (file, "r")) != NULL) #endif { cp = line; #if HAVE_LIBZ > 0 gzgets (fp, line, BUFSIZ); gzclose(fp); #else fgets (line, BUFSIZ, fp); fclose(fp); #endif if (*cp++ == '\'' && *cp++ == '\\' && *cp++ == '"' && *cp++ == ' ') { if (debug) fprintf (stderr, "parsing directive from file\n"); status = parse_roff_directive (cp, file, buf, sizeof(buf)); if (status == 0) return buf; if (status == -1) gripe_roff_command_from_file (file); } } else { /* * Is there really any point in continuing to look for * preprocessor options if we can't even read the man page source? */ gripe_reading_man_file (file); return NULL; } if ((cp = getenv ("MANROFFSEQ")) != NULL) { if (debug) fprintf (stderr, "parsing directive from environment\n"); status = parse_roff_directive (cp, file, buf, sizeof(buf)); if (status == 0) return buf; if (status == -1) gripe_roff_command_from_env (); } if (debug) fprintf (stderr, "using default preprocessor sequence\n"); status = parse_roff_directive ("t", file, buf, sizeof(buf)); if (status >= 0) return buf; else /* can't happen */ return NULL; } sig_t ohup, oint, oquit, oterm; static char temp[FILENAME_MAX]; void cleantmp() { unlink(temp); exit(1); } void set_sigs() { ohup = signal(SIGHUP, cleantmp); oint = signal(SIGINT, cleantmp); oquit = signal(SIGQUIT, cleantmp); oterm = signal(SIGTERM, cleantmp); } void restore_sigs() { signal(SIGHUP, ohup); signal(SIGINT, oint); signal(SIGQUIT, oquit); signal(SIGTERM, oterm); } /* * Try to format the man page and create a new formatted file. Return * 1 for success and 0 for failure. */ int -make_cat_file (path, man_file, cat_file) +make_cat_file (path, man_file, cat_file, manid) register char *path; register char *man_file; register char *cat_file; { int s, f; FILE *fp, *pp; char *roff_command; char command[FILENAME_MAX]; roff_command = make_roff_command (man_file); if (roff_command == NULL) return 0; snprintf(temp, sizeof(temp), "%s.tmpXXXXXX", cat_file); if ((f = mkstemp(temp)) >= 0 && (fp = fdopen(f, "w")) != NULL) { set_sigs(); if (fchmod (f, CATMODE) < 0) { perror("fchmod"); unlink(temp); restore_sigs(); fclose(fp); return 0; } else if (debug) fprintf (stderr, "mode of %s is now %o\n", temp, CATMODE); #ifdef DO_COMPRESS snprintf (command, sizeof(command), "(cd %s ; %s | %s)", path, roff_command, COMPRESSOR); #else snprintf (command, sizeof(command), "(cd %s ; %s)", path, roff_command); #endif fprintf (stderr, "Formatting page, please wait..."); fflush(stderr); if (debug) fprintf (stderr, "\ntrying command: %s\n", command); else { + +#ifdef SETUID + if (manid) + seteuid(ruid); +#endif if ((pp = popen(command, "r")) == NULL) { s = errno; fprintf(stderr, "Failed.\n"); errno = s; perror("popen"); +#ifdef SETUID + if (manid) + seteuid(euid); +#endif unlink(temp); restore_sigs(); fclose(fp); return 0; } +#ifdef SETUID + if (manid) + seteuid(euid); +#endif f = 0; while ((s = getc(pp)) != EOF) { putc(s, fp); f++; } if (!f || ((s = pclose(pp)) == -1)) { s = errno; fprintf(stderr, "Failed.\n"); errno = s; perror("pclose"); unlink(temp); restore_sigs(); fclose(fp); return 0; } if (s != 0) { fprintf(stderr, "Failed.\n"); gripe_system_command(s); unlink(temp); restore_sigs(); fclose(fp); return 0; } } if (debug) unlink(temp); else if (rename(temp, cat_file) == -1) { s = errno; fprintf(stderr, "\nHmm! Can't seem to rename %s to %s, check permissions on man dir!\n", temp, cat_file); errno = s; perror("rename"); unlink(temp); restore_sigs(); fclose(fp); return 0; } restore_sigs(); if (fclose(fp)) { s = errno; if (!debug) unlink(cat_file); fprintf(stderr, "Failed.\n"); errno = s; perror("fclose"); return 0; } if (debug) { fprintf(stderr, "No output, debug mode.\n"); return 0; } fprintf(stderr, "Done.\n"); return 1; } else { if (f >= 0) { s = errno; unlink(temp); errno = s; } if (debug) { s = errno; fprintf (stderr, "Couldn't open %s for writing.\n", temp); errno = s; } if (f >= 0) { perror("fdopen"); close(f); } return 0; } } /* * Try to format the man page source and save it, then display it. If * that's not possible, try to format the man page source and display * it directly. * * Note that we've already been handed the name of the ultimate source * file at this point. */ int format_and_display (path, man_file, cat_file) register char *path; register char *man_file; register char *cat_file; { int status; register int found; char *roff_command; char command[FILENAME_MAX]; found = 0; if (access (man_file, R_OK) != 0) return 0; if (troff) { roff_command = make_roff_command (man_file); if (roff_command == NULL) return 0; else snprintf (command, sizeof(command), "(cd %s ; %s)", path, roff_command); found = do_system_command (command); } else { status = is_newer (man_file, cat_file); if (debug) fprintf (stderr, "status from is_newer() = %d\n", status); if (status == 1 || status == -2) { /* * Cat file is out of date. Try to format and save it. */ if (print_where) { printf ("%s\n", man_file); found++; } else { - found = make_cat_file (path, man_file, cat_file); + +#ifdef SETUID + seteuid(euid); + found = make_cat_file (path, man_file, cat_file, 1); + seteuid(ruid); + + if (!found) + { + /* Try again as real user - see note below. + By running with + effective group (user) ID == real group (user) ID + except for the call above, I believe the problems + of reading private man pages is avoided. */ + found = make_cat_file (path, man_file, cat_file, 0); + } +#else + found = make_cat_file (path, man_file, cat_file, 0); +#endif if (found) { /* * Creating the cat file worked. Now just display it. */ (void) display_cat_file (cat_file); } else { /* * Couldn't create cat file. Just format it and * display it through the pager. */ roff_command = make_roff_command (man_file); if (roff_command == NULL) return 0; else snprintf (command, sizeof(command), "(cd %s ; %s | %s)", path, roff_command, pager); found = do_system_command (command); } } } else if (access (cat_file, R_OK) == 0) { /* * Formatting not necessary. Cat file is newer than source * file, or source file is not present but cat file is. */ if (print_where) { printf ("%s (source: %s)\n", cat_file, man_file); found++; } else { found = display_cat_file (cat_file); } } } return found; } /* * See if the preformatted man page or the source exists in the given * section. */ int try_section (path, section, name, glob) register char *path; register char *section; register char *name; register int glob; { register int found = 0; register int to_cat; register int cat; register char **names; register char **np; static int arch_search; char buf[FILENAME_MAX]; if (!arch_search) { snprintf(buf, sizeof(buf), "%s/man%s/%s", path, section, machine); if (is_directory (buf) == 1) { snprintf(buf, sizeof(buf), "%s/%s", machine, name); arch_search++; found = try_section (path, section, buf, glob); arch_search--; if (found && !findall) /* only do this architecture... */ return found; } } if (debug) { if (glob) fprintf (stderr, "trying section %s with globbing\n", section); else fprintf (stderr, "trying section %s without globbing\n", section); } #ifndef NROFF_MISSING /* * Look for man page source files. */ cat = 0; if (glob) names = glob_for_file (path, section, name, cat); else names = make_name (path, section, name, cat); if (names == (char **) -1 || *names == NULL) /* * No files match. See if there's a preformatted page around that * we can display. */ #endif /* NROFF_MISSING */ { if (!troff) { cat = 1; if (glob) names = glob_for_file (path, section, name, cat); else names = make_name (path, section, name, cat); if (names != (char **) -1 && *names != NULL) { for (np = names; *np != NULL; np++) { if (print_where) { printf ("%s\n", *np); found++; } else { found += display_cat_file (*np); } } } } } #ifndef NROFF_MISSING else { for (np = names; *np != NULL; np++) { register char *cat_file = NULL; register char *man_file; man_file = ultimate_source (*np, path); if (!troff) { to_cat = 1; cat_file = convert_name (man_file, to_cat); if (debug) fprintf (stderr, "will try to write %s if needed\n", cat_file); } found += format_and_display (path, man_file, cat_file); } } #endif /* NROFF_MISSING */ return found; } /* * Search for manual pages. * * If preformatted manual pages are supported, look for the formatted * file first, then the man page source file. If they both exist and * the man page source file is newer, or only the source file exists, * try to reformat it and write the results in the cat directory. If * it is not possible to write the cat file, simply format and display * the man file. * * If preformatted pages are not supported, or the troff option is * being used, only look for the man page source file. * */ int man (name) char *name; { register int found; register int glob; register char **mp; register char **sp; #ifdef __FreeBSD__ int l_found; char buf[FILENAME_MAX]; #endif found = 0; fflush (stdout); if (section != NULL) { for (mp = manpathlist; *mp != NULL; mp++) { if (debug) fprintf (stderr, "\nsearching in %s\n", *mp); glob = 1; #ifdef __FreeBSD__ l_found = 0; if (locale != NULL) { locale_opts = locale_nroff; if (*locale_lang != '\0' && *locale_terr != '\0') { snprintf(buf, sizeof(buf), "%s/%s_%s.%s", *mp, locale_lang, locale_terr, locale_codeset); if (is_directory (buf) == 1) l_found = try_section (buf, section, name, glob); } if (!l_found) { if (*locale_lang != '\0') { snprintf(buf, sizeof(buf), "%s/%s.%s", *mp, locale_lang, locale_codeset); if (is_directory (buf) == 1) l_found = try_section (buf, section, name, glob); } if (!l_found && strcmp(locale_lang, "en") != 0) { snprintf(buf, sizeof(buf), "%s/en.%s", *mp, locale_codeset); if (is_directory (buf) == 1) l_found = try_section (buf, section, name, glob); } } locale_opts = NULL; } if (!l_found) { #endif found += try_section (*mp, section, name, glob); #ifdef __FreeBSD__ } else found += l_found; #endif if (found && !findall) /* i.e. only do this section... */ return found; } } else { for (sp = section_list; *sp != NULL; sp++) { for (mp = manpathlist; *mp != NULL; mp++) { if (debug) fprintf (stderr, "\nsearching in %s\n", *mp); glob = 1; #ifdef __FreeBSD__ l_found = 0; if (locale != NULL) { locale_opts = locale_nroff; if (*locale_lang != '\0' && *locale_terr != '\0') { snprintf(buf, sizeof(buf), "%s/%s_%s.%s", *mp, locale_lang, locale_terr, locale_codeset); if (is_directory (buf) == 1) l_found = try_section (buf, *sp, name, glob); } if (!l_found) { if (*locale_lang != '\0') { snprintf(buf, sizeof(buf), "%s/%s.%s", *mp, locale_lang, locale_codeset); if (is_directory (buf) == 1) l_found = try_section (buf, *sp, name, glob); } if (!l_found && strcmp(locale_lang, "en") != 0) { snprintf(buf, sizeof(buf), "%s/en.%s", *mp, locale_codeset); if (is_directory (buf) == 1) l_found = try_section (buf, *sp, name, glob); } } locale_opts = NULL; } if (!l_found) { #endif found += try_section (*mp, *sp, name, glob); #ifdef __FreeBSD__ } else found += l_found; #endif if (found && !findall) /* i.e. only do this section... */ return found; } } } return found; } char ** get_section_list () { int i; char *p; char *end; #define TMP_SECTION_LIST_SIZE 100 static char *tmp_section_list[TMP_SECTION_LIST_SIZE]; if (colon_sep_section_list == NULL) { if ((p = getenv ("MANSECT")) == NULL) { return std_sections; } else { colon_sep_section_list = strdup (p); } } i = 0; for (p = colon_sep_section_list; i < TMP_SECTION_LIST_SIZE ; p = end+1) { if ((end = strchr (p, ':')) != NULL) *end = '\0'; tmp_section_list[i++] = strdup (p); if (end == NULL) break; } tmp_section_list [i] = NULL; return tmp_section_list; }