146acc370SDag-Erling Smørgrav#!/usr/bin/perl -w 246acc370SDag-Erling Smørgrav#- 331c521e9SDag-Erling Smørgrav# Copyright (c) 2002-2003 Networks Associates Technology, Inc. 449e56509SDag-Erling Smørgrav# Copyright (c) 2004-2017 Dag-Erling Smørgrav 546acc370SDag-Erling Smørgrav# All rights reserved. 646acc370SDag-Erling Smørgrav# 746acc370SDag-Erling Smørgrav# This software was developed for the FreeBSD Project by ThinkSec AS and 8ee02aaa9SDag-Erling Smørgrav# Network Associates Laboratories, the Security Research Division of 9ee02aaa9SDag-Erling Smørgrav# Network Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 10ee02aaa9SDag-Erling Smørgrav# ("CBOSS"), as part of the DARPA CHATS research program. 1146acc370SDag-Erling Smørgrav# 1246acc370SDag-Erling Smørgrav# Redistribution and use in source and binary forms, with or without 1346acc370SDag-Erling Smørgrav# modification, are permitted provided that the following conditions 1446acc370SDag-Erling Smørgrav# are met: 1546acc370SDag-Erling Smørgrav# 1. Redistributions of source code must retain the above copyright 1646acc370SDag-Erling Smørgrav# notice, this list of conditions and the following disclaimer. 1746acc370SDag-Erling Smørgrav# 2. Redistributions in binary form must reproduce the above copyright 1846acc370SDag-Erling Smørgrav# notice, this list of conditions and the following disclaimer in the 1946acc370SDag-Erling Smørgrav# documentation and/or other materials provided with the distribution. 2046acc370SDag-Erling Smørgrav# 3. The name of the author may not be used to endorse or promote 2146acc370SDag-Erling Smørgrav# products derived from this software without specific prior written 2246acc370SDag-Erling Smørgrav# permission. 2346acc370SDag-Erling Smørgrav# 2446acc370SDag-Erling Smørgrav# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 2546acc370SDag-Erling Smørgrav# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2646acc370SDag-Erling Smørgrav# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2746acc370SDag-Erling Smørgrav# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 2846acc370SDag-Erling Smørgrav# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2946acc370SDag-Erling Smørgrav# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 3046acc370SDag-Erling Smørgrav# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 3146acc370SDag-Erling Smørgrav# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 3246acc370SDag-Erling Smørgrav# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3346acc370SDag-Erling Smørgrav# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3446acc370SDag-Erling Smørgrav# SUCH DAMAGE. 3546acc370SDag-Erling Smørgrav# 3646acc370SDag-Erling Smørgrav 3746acc370SDag-Erling Smørgravuse strict; 38ce77a8d6SDag-Erling Smørgravuse warnings; 39ce77a8d6SDag-Erling Smørgravuse open qw(:utf8); 40ce77a8d6SDag-Erling Smørgravuse utf8; 4146acc370SDag-Erling Smørgravuse Fcntl; 42ee02aaa9SDag-Erling Smørgravuse Getopt::Std; 43ce77a8d6SDag-Erling Smørgravuse POSIX qw(strftime); 44ce77a8d6SDag-Erling Smørgravuse vars qw(%AUTHORS $TODAY %FUNCTIONS %PAMERR); 45ee02aaa9SDag-Erling Smørgrav 467f106882SDag-Erling Smørgrav%AUTHORS = ( 472f3ed619SDag-Erling Smørgrav THINKSEC => "developed for the 482f3ed619SDag-Erling Smørgrav.Fx 492f3ed619SDag-Erling SmørgravProject by ThinkSec AS and Network Associates Laboratories, the 507f106882SDag-Erling SmørgravSecurity Research Division of Network Associates, Inc.\\& under 517f106882SDag-Erling SmørgravDARPA/SPAWAR contract N66001-01-C-8035 527f106882SDag-Erling Smørgrav.Pq Dq CBOSS , 53ce77a8d6SDag-Erling Smørgravas part of the DARPA CHATS research program. 54ce77a8d6SDag-Erling Smørgrav.Pp 55ce77a8d6SDag-Erling SmørgravThe OpenPAM library is maintained by 56f3b0ac34SDag-Erling Smørgrav.An Dag-Erling Sm\\(/orgrav Aq Mt des\@des.no .", 57ce77a8d6SDag-Erling Smørgrav UIO => "developed for the University of Oslo by 58f3b0ac34SDag-Erling Smørgrav.An Dag-Erling Sm\\(/orgrav Aq Mt des\@des.no .", 592f3ed619SDag-Erling Smørgrav DES => "developed by 60f3b0ac34SDag-Erling Smørgrav.An Dag-Erling Sm\\(/orgrav Aq Mt des\@des.no .", 617f106882SDag-Erling Smørgrav); 627f106882SDag-Erling Smørgrav 6346acc370SDag-Erling Smørgrav%PAMERR = ( 6446acc370SDag-Erling Smørgrav PAM_SUCCESS => "Success", 6546acc370SDag-Erling Smørgrav PAM_OPEN_ERR => "Failed to load module", 6646acc370SDag-Erling Smørgrav PAM_SYMBOL_ERR => "Invalid symbol", 6746acc370SDag-Erling Smørgrav PAM_SERVICE_ERR => "Error in service module", 6846acc370SDag-Erling Smørgrav PAM_SYSTEM_ERR => "System error", 6946acc370SDag-Erling Smørgrav PAM_BUF_ERR => "Memory buffer error", 7046acc370SDag-Erling Smørgrav PAM_CONV_ERR => "Conversation failure", 7146acc370SDag-Erling Smørgrav PAM_PERM_DENIED => "Permission denied", 7246acc370SDag-Erling Smørgrav PAM_MAXTRIES => "Maximum number of tries exceeded", 7346acc370SDag-Erling Smørgrav PAM_AUTH_ERR => "Authentication error", 7446acc370SDag-Erling Smørgrav PAM_NEW_AUTHTOK_REQD => "New authentication token required", 7546acc370SDag-Erling Smørgrav PAM_CRED_INSUFFICIENT => "Insufficient credentials", 7646acc370SDag-Erling Smørgrav PAM_AUTHINFO_UNAVAIL => "Authentication information is unavailable", 7746acc370SDag-Erling Smørgrav PAM_USER_UNKNOWN => "Unknown user", 7846acc370SDag-Erling Smørgrav PAM_CRED_UNAVAIL => "Failed to retrieve user credentials", 7946acc370SDag-Erling Smørgrav PAM_CRED_EXPIRED => "User credentials have expired", 8046acc370SDag-Erling Smørgrav PAM_CRED_ERR => "Failed to set user credentials", 81b33ab329SDag-Erling Smørgrav PAM_ACCT_EXPIRED => "User account has expired", 8246acc370SDag-Erling Smørgrav PAM_AUTHTOK_EXPIRED => "Password has expired", 8346acc370SDag-Erling Smørgrav PAM_SESSION_ERR => "Session failure", 8446acc370SDag-Erling Smørgrav PAM_AUTHTOK_ERR => "Authentication token failure", 8546acc370SDag-Erling Smørgrav PAM_AUTHTOK_RECOVERY_ERR => "Failed to recover old authentication token", 8646acc370SDag-Erling Smørgrav PAM_AUTHTOK_LOCK_BUSY => "Authentication token lock busy", 8746acc370SDag-Erling Smørgrav PAM_AUTHTOK_DISABLE_AGING => "Authentication token aging disabled", 8846acc370SDag-Erling Smørgrav PAM_NO_MODULE_DATA => "Module data not found", 8946acc370SDag-Erling Smørgrav PAM_IGNORE => "Ignore this module", 9046acc370SDag-Erling Smørgrav PAM_ABORT => "General failure", 9146acc370SDag-Erling Smørgrav PAM_TRY_AGAIN => "Try again", 9246acc370SDag-Erling Smørgrav PAM_MODULE_UNKNOWN => "Unknown module type", 9346acc370SDag-Erling Smørgrav PAM_DOMAIN_UNKNOWN => "Unknown authentication domain", 9449e56509SDag-Erling Smørgrav PAM_BAD_HANDLE => "Invalid PAM handle", 9549e56509SDag-Erling Smørgrav PAM_BAD_ITEM => "Unrecognized or restricted item", 9649e56509SDag-Erling Smørgrav PAM_BAD_FEATURE => "Unrecognized or restricted feature", 9749e56509SDag-Erling Smørgrav PAM_BAD_CONSTANT => "Bad constant", 9846acc370SDag-Erling Smørgrav); 9946acc370SDag-Erling Smørgrav 10046acc370SDag-Erling Smørgravsub parse_source($) { 10146acc370SDag-Erling Smørgrav my $fn = shift; 10246acc370SDag-Erling Smørgrav 10346acc370SDag-Erling Smørgrav local *FILE; 10446acc370SDag-Erling Smørgrav my $source; 10546acc370SDag-Erling Smørgrav my $func; 10646acc370SDag-Erling Smørgrav my $descr; 10746acc370SDag-Erling Smørgrav my $type; 10846acc370SDag-Erling Smørgrav my $args; 10946acc370SDag-Erling Smørgrav my $argnames; 11046acc370SDag-Erling Smørgrav my $man; 11146acc370SDag-Erling Smørgrav my $inlist; 1127f106882SDag-Erling Smørgrav my $intaglist; 11346acc370SDag-Erling Smørgrav my $inliteral; 1142f3ed619SDag-Erling Smørgrav my $customrv; 1152f3ed619SDag-Erling Smørgrav my $deprecated; 1162f3ed619SDag-Erling Smørgrav my $experimental; 117ce77a8d6SDag-Erling Smørgrav my $version; 11846acc370SDag-Erling Smørgrav my %xref; 11949e56509SDag-Erling Smørgrav my %errors; 1207f106882SDag-Erling Smørgrav my $author; 12146acc370SDag-Erling Smørgrav 12246acc370SDag-Erling Smørgrav if ($fn !~ m,\.c$,) { 12346acc370SDag-Erling Smørgrav warn("$fn: not C source, ignoring\n"); 124ee02aaa9SDag-Erling Smørgrav return undef; 12546acc370SDag-Erling Smørgrav } 12646acc370SDag-Erling Smørgrav 1277f106882SDag-Erling Smørgrav open(FILE, "<", "$fn") 12846acc370SDag-Erling Smørgrav or die("$fn: open(): $!\n"); 12946acc370SDag-Erling Smørgrav $source = join('', <FILE>); 13046acc370SDag-Erling Smørgrav close(FILE); 13146acc370SDag-Erling Smørgrav 132ee02aaa9SDag-Erling Smørgrav return undef 133ee02aaa9SDag-Erling Smørgrav if ($source =~ m/^ \* NOPARSE\s*$/m); 13446acc370SDag-Erling Smørgrav 13549e56509SDag-Erling Smørgrav if ($source =~ m/(\$OpenPAM:[^\$]+\$)/) { 136ce77a8d6SDag-Erling Smørgrav $version = $1; 137ce77a8d6SDag-Erling Smørgrav } 138ce77a8d6SDag-Erling Smørgrav 1397f106882SDag-Erling Smørgrav $author = 'THINKSEC'; 1402f3ed619SDag-Erling Smørgrav if ($source =~ s/^ \* AUTHOR\s+(\w*)\s*$//m) { 1417f106882SDag-Erling Smørgrav $author = $1; 1427f106882SDag-Erling Smørgrav } 1437f106882SDag-Erling Smørgrav 1442f3ed619SDag-Erling Smørgrav if ($source =~ s/^ \* DEPRECATED\s*(\w*)\s*$//m) { 1452f3ed619SDag-Erling Smørgrav $deprecated = $1 // 0; 1462f3ed619SDag-Erling Smørgrav } 1472f3ed619SDag-Erling Smørgrav 1482f3ed619SDag-Erling Smørgrav if ($source =~ s/^ \* EXPERIMENTAL\s*$//m) { 1492f3ed619SDag-Erling Smørgrav $experimental = 1; 1502f3ed619SDag-Erling Smørgrav } 1512f3ed619SDag-Erling Smørgrav 15246acc370SDag-Erling Smørgrav $func = $fn; 15346acc370SDag-Erling Smørgrav $func =~ s,^(?:.*/)?([^/]+)\.c$,$1,; 15446acc370SDag-Erling Smørgrav if ($source !~ m,\n \* ([\S ]+)\n \*/\n\n([\S ]+)\n$func\((.*?)\)\n\{,s) { 15546acc370SDag-Erling Smørgrav warn("$fn: can't find $func\n"); 156ee02aaa9SDag-Erling Smørgrav return undef; 15746acc370SDag-Erling Smørgrav } 15846acc370SDag-Erling Smørgrav ($descr, $type, $args) = ($1, $2, $3); 15946acc370SDag-Erling Smørgrav $descr =~ s,^([A-Z][a-z]),lc($1),e; 16046acc370SDag-Erling Smørgrav $descr =~ s,[\.\s]*$,,; 16146acc370SDag-Erling Smørgrav while ($args =~ s/^((?:[^\(]|\([^\)]*\))*),\s*/$1\" \"/g) { 16246acc370SDag-Erling Smørgrav # nothing 16346acc370SDag-Erling Smørgrav } 16446acc370SDag-Erling Smørgrav $args =~ s/,\s+/, /gs; 16546acc370SDag-Erling Smørgrav $args = "\"$args\""; 16646acc370SDag-Erling Smørgrav 16746acc370SDag-Erling Smørgrav %xref = ( 168b33ab329SDag-Erling Smørgrav 3 => { 'pam' => 1 }, 16946acc370SDag-Erling Smørgrav ); 17046acc370SDag-Erling Smørgrav 17146acc370SDag-Erling Smørgrav if ($type eq "int") { 17246acc370SDag-Erling Smørgrav foreach (split("\n", $source)) { 17349e56509SDag-Erling Smørgrav next unless (m/^ \*\t(!?PAM_[A-Z_]+|=[a-z_]+)\s*(.*?)\s*$/); 17449e56509SDag-Erling Smørgrav $errors{$1} = $2; 17546acc370SDag-Erling Smørgrav } 176ce77a8d6SDag-Erling Smørgrav ++$xref{3}->{pam_strerror}; 17746acc370SDag-Erling Smørgrav } 17846acc370SDag-Erling Smørgrav 17946acc370SDag-Erling Smørgrav $argnames = $args; 180b33ab329SDag-Erling Smørgrav # extract names of regular arguments 18146acc370SDag-Erling Smørgrav $argnames =~ s/\"[^\"]+\*?\b(\w+)\"/\"$1\"/g; 182b33ab329SDag-Erling Smørgrav # extract names of function pointer arguments 183b33ab329SDag-Erling Smørgrav $argnames =~ s/\"([\w\s\*]+)\(\*?(\w+)\)\([^\)]+\)\"/\"$2\"/g; 184b33ab329SDag-Erling Smørgrav # escape metacharacters (there shouldn't be any, but...) 18546acc370SDag-Erling Smørgrav $argnames =~ s/([\|\[\]\(\)\.\*\+\?])/\\$1/g; 186b33ab329SDag-Erling Smørgrav # separate argument names with | 18746acc370SDag-Erling Smørgrav $argnames =~ s/\" \"/|/g; 188b33ab329SDag-Erling Smørgrav # and surround with () 1892f3ed619SDag-Erling Smørgrav $argnames =~ s/^\"(.*)\"$/$1/; 190b33ab329SDag-Erling Smørgrav # $argnames is now a regexp that matches argument names 1917f106882SDag-Erling Smørgrav $inliteral = $inlist = $intaglist = 0; 19246acc370SDag-Erling Smørgrav foreach (split("\n", $source)) { 19346acc370SDag-Erling Smørgrav s/\s*$//; 19446acc370SDag-Erling Smørgrav if (!defined($man)) { 19546acc370SDag-Erling Smørgrav if (m/^\/\*\*$/) { 19646acc370SDag-Erling Smørgrav $man = ""; 19746acc370SDag-Erling Smørgrav } 19846acc370SDag-Erling Smørgrav next; 19946acc370SDag-Erling Smørgrav } 20046acc370SDag-Erling Smørgrav last if (m/^ \*\/$/); 20146acc370SDag-Erling Smørgrav s/^ \* ?//; 20246acc370SDag-Erling Smørgrav s/\\(.)/$1/gs; 20346acc370SDag-Erling Smørgrav if (m/^$/) { 2047f106882SDag-Erling Smørgrav # paragraph separator 2052f3ed619SDag-Erling Smørgrav if ($inlist || $intaglist) { 2062f3ed619SDag-Erling Smørgrav # either a blank line between list items, or a blank 2072f3ed619SDag-Erling Smørgrav # line after the final list item. The latter case 2082f3ed619SDag-Erling Smørgrav # will be handled further down. 2092f3ed619SDag-Erling Smørgrav next; 2102f3ed619SDag-Erling Smørgrav } 2112f3ed619SDag-Erling Smørgrav if ($man =~ m/\n\.Sh [^\n]+\n$/s) { 2122f3ed619SDag-Erling Smørgrav # a blank line after a section header 2132f3ed619SDag-Erling Smørgrav next; 2142f3ed619SDag-Erling Smørgrav } 21546acc370SDag-Erling Smørgrav if ($man ne "" && $man !~ m/\.Pp\n$/s) { 21646acc370SDag-Erling Smørgrav if ($inliteral) { 21746acc370SDag-Erling Smørgrav $man .= "\0\n"; 21846acc370SDag-Erling Smørgrav } else { 21946acc370SDag-Erling Smørgrav $man .= ".Pp\n"; 22046acc370SDag-Erling Smørgrav } 22146acc370SDag-Erling Smørgrav } 22246acc370SDag-Erling Smørgrav next; 22346acc370SDag-Erling Smørgrav } 224b33ab329SDag-Erling Smørgrav if (m/^>(\w+)(\s+\d)?$/) { 2257f106882SDag-Erling Smørgrav # "see also" cross-reference 226b33ab329SDag-Erling Smørgrav my ($page, $sect) = ($1, $2 ? int($2) : 3); 227b33ab329SDag-Erling Smørgrav ++$xref{$sect}->{$page}; 22846acc370SDag-Erling Smørgrav next; 22946acc370SDag-Erling Smørgrav } 2302f3ed619SDag-Erling Smørgrav if (s/^([A-Z][0-9A-Z -]+)$/.Sh $1/) { 2312f3ed619SDag-Erling Smørgrav if ($1 eq "RETURN VALUES") { 2322f3ed619SDag-Erling Smørgrav $customrv = $1; 2332f3ed619SDag-Erling Smørgrav } 2342f3ed619SDag-Erling Smørgrav $man =~ s/\n\.Pp$/\n/s; 2352f3ed619SDag-Erling Smørgrav $man .= "$_\n"; 2362f3ed619SDag-Erling Smørgrav next; 2372f3ed619SDag-Erling Smørgrav } 2387f106882SDag-Erling Smørgrav if (s/^\s+-\s+//) { 2397f106882SDag-Erling Smørgrav # item in bullet list 24046acc370SDag-Erling Smørgrav if ($inliteral) { 24146acc370SDag-Erling Smørgrav $man .= ".Ed\n"; 24246acc370SDag-Erling Smørgrav $inliteral = 0; 24346acc370SDag-Erling Smørgrav } 2447f106882SDag-Erling Smørgrav if ($intaglist) { 2457f106882SDag-Erling Smørgrav $man .= ".El\n.Pp\n"; 2467f106882SDag-Erling Smørgrav $intaglist = 0; 2477f106882SDag-Erling Smørgrav } 24846acc370SDag-Erling Smørgrav if (!$inlist) { 24946acc370SDag-Erling Smørgrav $man =~ s/\.Pp\n$//s; 2507f106882SDag-Erling Smørgrav $man .= ".Bl -bullet\n"; 25146acc370SDag-Erling Smørgrav $inlist = 1; 25246acc370SDag-Erling Smørgrav } 2537f106882SDag-Erling Smørgrav $man .= ".It\n"; 2547f106882SDag-Erling Smørgrav # fall through 2557f106882SDag-Erling Smørgrav } elsif (s/^\s+(\S+):\s*/.It $1/) { 2567f106882SDag-Erling Smørgrav # item in tag list 2577f106882SDag-Erling Smørgrav if ($inliteral) { 2587f106882SDag-Erling Smørgrav $man .= ".Ed\n"; 2597f106882SDag-Erling Smørgrav $inliteral = 0; 2607f106882SDag-Erling Smørgrav } 2617f106882SDag-Erling Smørgrav if ($inlist) { 2627f106882SDag-Erling Smørgrav $man .= ".El\n.Pp\n"; 2637f106882SDag-Erling Smørgrav $inlist = 0; 2647f106882SDag-Erling Smørgrav } 2657f106882SDag-Erling Smørgrav if (!$intaglist) { 2667f106882SDag-Erling Smørgrav $man =~ s/\.Pp\n$//s; 2677f106882SDag-Erling Smørgrav $man .= ".Bl -tag -width 18n\n"; 2687f106882SDag-Erling Smørgrav $intaglist = 1; 2697f106882SDag-Erling Smørgrav } 270ce77a8d6SDag-Erling Smørgrav s/^\.It [=;]([A-Za-z][0-9A-Za-z_]+)$/.It Dv $1/gs; 27146acc370SDag-Erling Smørgrav $man .= "$_\n"; 27246acc370SDag-Erling Smørgrav next; 2737f106882SDag-Erling Smørgrav } elsif (($inlist || $intaglist) && m/^\S/) { 2747f106882SDag-Erling Smørgrav # regular text after list 275ee02aaa9SDag-Erling Smørgrav $man .= ".El\n.Pp\n"; 2767f106882SDag-Erling Smørgrav $inlist = $intaglist = 0; 27746acc370SDag-Erling Smørgrav } elsif ($inliteral && m/^\S/) { 2787f106882SDag-Erling Smørgrav # regular text after literal section 27946acc370SDag-Erling Smørgrav $man .= ".Ed\n"; 280ac7e3b9dSDag-Erling Smørgrav $inliteral = 0; 28146acc370SDag-Erling Smørgrav } elsif ($inliteral) { 2827f106882SDag-Erling Smørgrav # additional text within literal section 28346acc370SDag-Erling Smørgrav $man .= "$_\n"; 28446acc370SDag-Erling Smørgrav next; 2857f106882SDag-Erling Smørgrav } elsif ($inlist || $intaglist) { 2867f106882SDag-Erling Smørgrav # additional text within list 28746acc370SDag-Erling Smørgrav s/^\s+//; 28846acc370SDag-Erling Smørgrav } elsif (m/^\s+/) { 2897f106882SDag-Erling Smørgrav # new literal section 29046acc370SDag-Erling Smørgrav $man .= ".Bd -literal\n"; 29146acc370SDag-Erling Smørgrav $inliteral = 1; 29246acc370SDag-Erling Smørgrav $man .= "$_\n"; 29346acc370SDag-Erling Smørgrav next; 29446acc370SDag-Erling Smørgrav } 2952f3ed619SDag-Erling Smørgrav s/\s*=($func)\b\s*/\n.Fn $1\n/gs; 2962f3ed619SDag-Erling Smørgrav s/\s*=($argnames)\b\s*/\n.Fa $1\n/gs; 297f3b0ac34SDag-Erling Smørgrav s/\s*=((?:enum|struct|union) \w+(?: \*)?)\b\s*/\n.Vt $1\n/gs; 298ce77a8d6SDag-Erling Smørgrav s/\s*:([a-z][0-9a-z_]+)\b\s*/\n.Va $1\n/gs; 299ce77a8d6SDag-Erling Smørgrav s/\s*;([a-z][0-9a-z_]+)\b\s*/\n.Dv $1\n/gs; 300ce77a8d6SDag-Erling Smørgrav s/\s*=!([a-z][0-9a-z_]+)\b\s*/\n.Xr $1 3\n/gs; 301ce77a8d6SDag-Erling Smørgrav while (s/\s*=([a-z][0-9a-z_]+)\b\s*/\n.Xr $1 3\n/s) { 302b33ab329SDag-Erling Smørgrav ++$xref{3}->{$1}; 30346acc370SDag-Erling Smørgrav } 30446acc370SDag-Erling Smørgrav s/\s*\"(?=\w)/\n.Do\n/gs; 30546acc370SDag-Erling Smørgrav s/\"(?!\w)\s*/\n.Dc\n/gs; 306ce77a8d6SDag-Erling Smørgrav s/\s*=([A-Z][0-9A-Z_]+)\b\s*(?![\.,:;])/\n.Dv $1\n/gs; 307ce77a8d6SDag-Erling Smørgrav s/\s*=([A-Z][0-9A-Z_]+)\b([\.,:;]+)\s*/\n.Dv $1 $2\n/gs; 30846acc370SDag-Erling Smørgrav s/\s*{([A-Z][a-z] .*?)}\s*/\n.$1\n/gs; 30946acc370SDag-Erling Smørgrav $man .= "$_\n"; 31046acc370SDag-Erling Smørgrav } 31146acc370SDag-Erling Smørgrav if (defined($man)) { 3127f106882SDag-Erling Smørgrav if ($inlist || $intaglist) { 313ac7e3b9dSDag-Erling Smørgrav $man .= ".El\n"; 3147f106882SDag-Erling Smørgrav $inlist = $intaglist = 0; 315ac7e3b9dSDag-Erling Smørgrav } 316ac7e3b9dSDag-Erling Smørgrav if ($inliteral) { 317ac7e3b9dSDag-Erling Smørgrav $man .= ".Ed\n"; 3187f106882SDag-Erling Smørgrav $inliteral = 0; 319ac7e3b9dSDag-Erling Smørgrav } 3207f106882SDag-Erling Smørgrav $man =~ s/\%/\\&\%/gs; 3212f3ed619SDag-Erling Smørgrav $man =~ s/(\n\.[A-Z][a-z] [\w ]+)\n([.,:;-])\s+/$1 $2\n/gs; 32246acc370SDag-Erling Smørgrav $man =~ s/\s*$/\n/gm; 32346acc370SDag-Erling Smørgrav $man =~ s/\n+/\n/gs; 32446acc370SDag-Erling Smørgrav $man =~ s/\0//gs; 325ac7e3b9dSDag-Erling Smørgrav $man =~ s/\n\n\./\n\./gs; 32646acc370SDag-Erling Smørgrav chomp($man); 32746acc370SDag-Erling Smørgrav } else { 32846acc370SDag-Erling Smørgrav $man = "No description available."; 32946acc370SDag-Erling Smørgrav } 33046acc370SDag-Erling Smørgrav 33146acc370SDag-Erling Smørgrav $FUNCTIONS{$func} = { 332ee02aaa9SDag-Erling Smørgrav 'source' => $fn, 333ce77a8d6SDag-Erling Smørgrav 'version' => $version, 33446acc370SDag-Erling Smørgrav 'name' => $func, 33546acc370SDag-Erling Smørgrav 'descr' => $descr, 33646acc370SDag-Erling Smørgrav 'type' => $type, 33746acc370SDag-Erling Smørgrav 'args' => $args, 33846acc370SDag-Erling Smørgrav 'man' => $man, 33946acc370SDag-Erling Smørgrav 'xref' => \%xref, 34049e56509SDag-Erling Smørgrav 'errors' => \%errors, 3417f106882SDag-Erling Smørgrav 'author' => $author, 3422f3ed619SDag-Erling Smørgrav 'customrv' => $customrv, 3432f3ed619SDag-Erling Smørgrav 'deprecated' => $deprecated, 3442f3ed619SDag-Erling Smørgrav 'experimental' => $experimental, 34546acc370SDag-Erling Smørgrav }; 34646acc370SDag-Erling Smørgrav if ($source =~ m/^ \* NODOC\s*$/m) { 347ce77a8d6SDag-Erling Smørgrav $FUNCTIONS{$func}->{nodoc} = 1; 34846acc370SDag-Erling Smørgrav } 34946acc370SDag-Erling Smørgrav if ($source !~ m/^ \* XSSO \d/m) { 350ce77a8d6SDag-Erling Smørgrav $FUNCTIONS{$func}->{openpam} = 1; 35146acc370SDag-Erling Smørgrav } 352ee02aaa9SDag-Erling Smørgrav expand_errors($FUNCTIONS{$func}); 353ee02aaa9SDag-Erling Smørgrav return $FUNCTIONS{$func}; 35446acc370SDag-Erling Smørgrav} 35546acc370SDag-Erling Smørgrav 35646acc370SDag-Erling Smørgravsub expand_errors($); 35746acc370SDag-Erling Smørgravsub expand_errors($) { 35846acc370SDag-Erling Smørgrav my $func = shift; # Ref to function hash 35946acc370SDag-Erling Smørgrav 36046acc370SDag-Erling Smørgrav my %errors; 361ee02aaa9SDag-Erling Smørgrav my $ref; 362ee02aaa9SDag-Erling Smørgrav my $fn; 36346acc370SDag-Erling Smørgrav 364ce77a8d6SDag-Erling Smørgrav if (defined($$func{recursed})) { 365ce77a8d6SDag-Erling Smørgrav warn("$$func{name}(): loop in error spec\n"); 36646acc370SDag-Erling Smørgrav return qw(); 36746acc370SDag-Erling Smørgrav } 368ce77a8d6SDag-Erling Smørgrav $$func{recursed} = 1; 36946acc370SDag-Erling Smørgrav 37049e56509SDag-Erling Smørgrav foreach (keys %{$$func{errors}}) { 37146acc370SDag-Erling Smørgrav if (m/^(PAM_[A-Z_]+)$/) { 37246acc370SDag-Erling Smørgrav if (!defined($PAMERR{$1})) { 373ce77a8d6SDag-Erling Smørgrav warn("$$func{name}(): unrecognized error: $1\n"); 37446acc370SDag-Erling Smørgrav next; 37546acc370SDag-Erling Smørgrav } 37649e56509SDag-Erling Smørgrav $errors{$1} = $$func{errors}->{$_}; 37746acc370SDag-Erling Smørgrav } elsif (m/^!(PAM_[A-Z_]+)$/) { 37846acc370SDag-Erling Smørgrav # treat negations separately 37946acc370SDag-Erling Smørgrav } elsif (m/^=([a-z_]+)$/) { 380ee02aaa9SDag-Erling Smørgrav $ref = $1; 381ee02aaa9SDag-Erling Smørgrav if (!defined($FUNCTIONS{$ref})) { 382ce77a8d6SDag-Erling Smørgrav $fn = $$func{source}; 383ce77a8d6SDag-Erling Smørgrav $fn =~ s/$$func{name}/$ref/; 384ee02aaa9SDag-Erling Smørgrav parse_source($fn); 385ee02aaa9SDag-Erling Smørgrav } 386ee02aaa9SDag-Erling Smørgrav if (!defined($FUNCTIONS{$ref})) { 387ce77a8d6SDag-Erling Smørgrav warn("$$func{name}(): reference to unknown $ref()\n"); 38846acc370SDag-Erling Smørgrav next; 38946acc370SDag-Erling Smørgrav } 39049e56509SDag-Erling Smørgrav foreach (keys %{$FUNCTIONS{$ref}->{errors}}) { 39149e56509SDag-Erling Smørgrav $errors{$_} //= $FUNCTIONS{$ref}->{errors}->{$_}; 39246acc370SDag-Erling Smørgrav } 39346acc370SDag-Erling Smørgrav } else { 394ce77a8d6SDag-Erling Smørgrav warn("$$func{name}(): invalid error specification: $_\n"); 39546acc370SDag-Erling Smørgrav } 39646acc370SDag-Erling Smørgrav } 39749e56509SDag-Erling Smørgrav foreach (keys %{$$func{errors}}) { 39846acc370SDag-Erling Smørgrav if (m/^!(PAM_[A-Z_]+)$/) { 39946acc370SDag-Erling Smørgrav delete($errors{$1}); 40046acc370SDag-Erling Smørgrav } 40146acc370SDag-Erling Smørgrav } 402ce77a8d6SDag-Erling Smørgrav delete($$func{recursed}); 40349e56509SDag-Erling Smørgrav $$func{errors} = \%errors; 40446acc370SDag-Erling Smørgrav} 40546acc370SDag-Erling Smørgrav 406556dce83SDag-Erling Smørgravsub dictionary_order($$) { 407556dce83SDag-Erling Smørgrav my ($a, $b) = @_; 408556dce83SDag-Erling Smørgrav 409556dce83SDag-Erling Smørgrav $a =~ s/[^[:alpha:]]//g; 410556dce83SDag-Erling Smørgrav $b =~ s/[^[:alpha:]]//g; 411556dce83SDag-Erling Smørgrav $a cmp $b; 412556dce83SDag-Erling Smørgrav} 413556dce83SDag-Erling Smørgrav 414b33ab329SDag-Erling Smørgravsub genxref($) { 415b33ab329SDag-Erling Smørgrav my $xref = shift; # References 416b33ab329SDag-Erling Smørgrav 417b33ab329SDag-Erling Smørgrav my $mdoc = ''; 418b33ab329SDag-Erling Smørgrav my @refs = (); 419b33ab329SDag-Erling Smørgrav foreach my $sect (sort(keys(%{$xref}))) { 420556dce83SDag-Erling Smørgrav foreach my $page (sort(dictionary_order keys(%{$xref->{$sect}}))) { 421b33ab329SDag-Erling Smørgrav push(@refs, "$page $sect"); 422b33ab329SDag-Erling Smørgrav } 423b33ab329SDag-Erling Smørgrav } 424b33ab329SDag-Erling Smørgrav while ($_ = shift(@refs)) { 425b33ab329SDag-Erling Smørgrav $mdoc .= ".Xr $_" . 426b33ab329SDag-Erling Smørgrav (@refs ? " ,\n" : "\n"); 427b33ab329SDag-Erling Smørgrav } 428b33ab329SDag-Erling Smørgrav return $mdoc; 429b33ab329SDag-Erling Smørgrav} 430b33ab329SDag-Erling Smørgrav 43146acc370SDag-Erling Smørgravsub gendoc($) { 43246acc370SDag-Erling Smørgrav my $func = shift; # Ref to function hash 43346acc370SDag-Erling Smørgrav 43446acc370SDag-Erling Smørgrav local *FILE; 43549e56509SDag-Erling Smørgrav my %errors; 43646acc370SDag-Erling Smørgrav my $mdoc; 43746acc370SDag-Erling Smørgrav my $fn; 43846acc370SDag-Erling Smørgrav 439ce77a8d6SDag-Erling Smørgrav return if defined($$func{nodoc}); 44046acc370SDag-Erling Smørgrav 441ce77a8d6SDag-Erling Smørgrav $$func{source} =~ m/([^\/]+)$/; 442ce77a8d6SDag-Erling Smørgrav $mdoc = ".\\\" Generated from $1 by gendoc.pl\n"; 443ce77a8d6SDag-Erling Smørgrav if ($$func{version}) { 444ce77a8d6SDag-Erling Smørgrav $mdoc .= ".\\\" $$func{version}\n"; 445ce77a8d6SDag-Erling Smørgrav } 446ce77a8d6SDag-Erling Smørgrav $mdoc .= ".Dd $TODAY 447ce77a8d6SDag-Erling Smørgrav.Dt " . uc($$func{name}) . " 3 44846acc370SDag-Erling Smørgrav.Os 44946acc370SDag-Erling Smørgrav.Sh NAME 450ce77a8d6SDag-Erling Smørgrav.Nm $$func{name} 451ce77a8d6SDag-Erling Smørgrav.Nd $$func{descr} 452f3b0ac34SDag-Erling Smørgrav"; 453f3b0ac34SDag-Erling Smørgrav if ($func =~ m/^(?:open)?pam_/) { 454f3b0ac34SDag-Erling Smørgrav $mdoc .= ".Sh LIBRARY 45546acc370SDag-Erling Smørgrav.Lb libpam 456f3b0ac34SDag-Erling Smørgrav"; 457f3b0ac34SDag-Erling Smørgrav } 458f3b0ac34SDag-Erling Smørgrav $mdoc .= ".Sh SYNOPSIS 459644f2b7cSDag-Erling Smørgrav.In sys/types.h 4602f3ed619SDag-Erling Smørgrav"; 461ce77a8d6SDag-Erling Smørgrav if ($$func{args} =~ m/\bFILE \*\b/) { 4622f3ed619SDag-Erling Smørgrav $mdoc .= ".In stdio.h\n"; 4632f3ed619SDag-Erling Smørgrav } 464f3b0ac34SDag-Erling Smørgrav if ($$func{name} =~ m/^(?:open)?pam/) { 4652f3ed619SDag-Erling Smørgrav $mdoc .= ".In security/pam_appl.h 46646acc370SDag-Erling Smørgrav"; 467f3b0ac34SDag-Erling Smørgrav } 468ce77a8d6SDag-Erling Smørgrav if ($$func{name} =~ m/_sm_/) { 4692f3ed619SDag-Erling Smørgrav $mdoc .= ".In security/pam_modules.h\n"; 47046acc370SDag-Erling Smørgrav } 471ce77a8d6SDag-Erling Smørgrav if ($$func{name} =~ m/openpam/) { 4722f3ed619SDag-Erling Smørgrav $mdoc .= ".In security/openpam.h\n"; 473ac7e3b9dSDag-Erling Smørgrav } 474ce77a8d6SDag-Erling Smørgrav $mdoc .= ".Ft \"$$func{type}\" 475ce77a8d6SDag-Erling Smørgrav.Fn $$func{name} $$func{args} 47646acc370SDag-Erling Smørgrav.Sh DESCRIPTION 47746acc370SDag-Erling Smørgrav"; 478ce77a8d6SDag-Erling Smørgrav if (defined($$func{deprecated})) { 4792f3ed619SDag-Erling Smørgrav $mdoc .= ".Bf Sy\n" . 4802f3ed619SDag-Erling Smørgrav "This function is deprecated and may be removed " . 4812f3ed619SDag-Erling Smørgrav "in a future release without further warning.\n"; 482ce77a8d6SDag-Erling Smørgrav if ($$func{deprecated}) { 483ce77a8d6SDag-Erling Smørgrav $mdoc .= "The\n.Fn $$func{deprecated}\nfunction " . 4842f3ed619SDag-Erling Smørgrav "may be used to achieve similar results.\n"; 4852f3ed619SDag-Erling Smørgrav } 4862f3ed619SDag-Erling Smørgrav $mdoc .= ".Ef\n.Pp\n"; 4872f3ed619SDag-Erling Smørgrav } 488ce77a8d6SDag-Erling Smørgrav if ($$func{experimental}) { 4892f3ed619SDag-Erling Smørgrav $mdoc .= ".Bf Sy\n" . 4902f3ed619SDag-Erling Smørgrav "This function is experimental and may be modified or removed " . 491ce77a8d6SDag-Erling Smørgrav "in a future release without prior warning.\n"; 4922f3ed619SDag-Erling Smørgrav $mdoc .= ".Ef\n.Pp\n"; 4932f3ed619SDag-Erling Smørgrav } 494ce77a8d6SDag-Erling Smørgrav $mdoc .= "$$func{man}\n"; 49549e56509SDag-Erling Smørgrav %errors = %{$$func{errors}}; 496ce77a8d6SDag-Erling Smørgrav if ($$func{customrv}) { 4972f3ed619SDag-Erling Smørgrav # leave it 49849e56509SDag-Erling Smørgrav } elsif ($$func{type} eq "int" && %errors) { 49946acc370SDag-Erling Smørgrav $mdoc .= ".Sh RETURN VALUES 50046acc370SDag-Erling SmørgravThe 501ce77a8d6SDag-Erling Smørgrav.Fn $$func{name} 50246acc370SDag-Erling Smørgravfunction returns one of the following values: 50346acc370SDag-Erling Smørgrav.Bl -tag -width 18n 50446acc370SDag-Erling Smørgrav"; 50549e56509SDag-Erling Smørgrav delete($errors{PAM_SUCCESS}); 50649e56509SDag-Erling Smørgrav foreach ('PAM_SUCCESS', sort keys %errors) { 50749e56509SDag-Erling Smørgrav $mdoc .= ".It Bq Er $_\n" . 50849e56509SDag-Erling Smørgrav ($errors{$_} || $PAMERR{$_}) . 50949e56509SDag-Erling Smørgrav ".\n"; 51046acc370SDag-Erling Smørgrav } 51146acc370SDag-Erling Smørgrav $mdoc .= ".El\n"; 512ce77a8d6SDag-Erling Smørgrav } elsif ($$func{type} eq "int") { 51346acc370SDag-Erling Smørgrav $mdoc .= ".Sh RETURN VALUES 51446acc370SDag-Erling SmørgravThe 515ce77a8d6SDag-Erling Smørgrav.Fn $$func{name} 5162f3ed619SDag-Erling Smørgravfunction returns 0 on success and -1 on failure. 5172f3ed619SDag-Erling Smørgrav"; 518ce77a8d6SDag-Erling Smørgrav } elsif ($$func{type} =~ m/\*$/) { 5192f3ed619SDag-Erling Smørgrav $mdoc .= ".Sh RETURN VALUES 5202f3ed619SDag-Erling SmørgravThe 521ce77a8d6SDag-Erling Smørgrav.Fn $$func{name} 52246acc370SDag-Erling Smørgravfunction returns 52346acc370SDag-Erling Smørgrav.Dv NULL 52446acc370SDag-Erling Smørgravon failure. 52546acc370SDag-Erling Smørgrav"; 526ce77a8d6SDag-Erling Smørgrav } elsif ($$func{type} ne "void") { 527ce77a8d6SDag-Erling Smørgrav warn("$$func{name}(): no error specification\n"); 52846acc370SDag-Erling Smørgrav } 529ce77a8d6SDag-Erling Smørgrav $mdoc .= ".Sh SEE ALSO\n" . genxref($$func{xref}); 53046acc370SDag-Erling Smørgrav $mdoc .= ".Sh STANDARDS\n"; 531ce77a8d6SDag-Erling Smørgrav if ($$func{openpam}) { 53246acc370SDag-Erling Smørgrav $mdoc .= "The 533ce77a8d6SDag-Erling Smørgrav.Fn $$func{name} 53446acc370SDag-Erling Smørgravfunction is an OpenPAM extension. 53546acc370SDag-Erling Smørgrav"; 53646acc370SDag-Erling Smørgrav } else { 53746acc370SDag-Erling Smørgrav $mdoc .= ".Rs 53846acc370SDag-Erling Smørgrav.%T \"X/Open Single Sign-On Service (XSSO) - Pluggable Authentication Modules\" 53946acc370SDag-Erling Smørgrav.%D \"June 1997\" 54046acc370SDag-Erling Smørgrav.Re 54146acc370SDag-Erling Smørgrav"; 54246acc370SDag-Erling Smørgrav } 54346acc370SDag-Erling Smørgrav $mdoc .= ".Sh AUTHORS 54446acc370SDag-Erling SmørgravThe 545ce77a8d6SDag-Erling Smørgrav.Fn $$func{name} 5462f3ed619SDag-Erling Smørgravfunction and this manual page were\n"; 547ce77a8d6SDag-Erling Smørgrav $mdoc .= $AUTHORS{$$func{author} // 'THINKSEC_DARPA'} . "\n"; 548ce77a8d6SDag-Erling Smørgrav $fn = "$$func{name}.3"; 5497f106882SDag-Erling Smørgrav if (open(FILE, ">", $fn)) { 55046acc370SDag-Erling Smørgrav print(FILE $mdoc); 55146acc370SDag-Erling Smørgrav close(FILE); 552ac7e3b9dSDag-Erling Smørgrav } else { 553ac7e3b9dSDag-Erling Smørgrav warn("$fn: open(): $!\n"); 554ac7e3b9dSDag-Erling Smørgrav } 55546acc370SDag-Erling Smørgrav} 55646acc370SDag-Erling Smørgrav 557ee02aaa9SDag-Erling Smørgravsub readproto($) { 558ee02aaa9SDag-Erling Smørgrav my $fn = shift; # File name 55946acc370SDag-Erling Smørgrav 560ee02aaa9SDag-Erling Smørgrav local *FILE; 561ee02aaa9SDag-Erling Smørgrav my %func; 562ee02aaa9SDag-Erling Smørgrav 5637f106882SDag-Erling Smørgrav open(FILE, "<", "$fn") 564ee02aaa9SDag-Erling Smørgrav or die("$fn: open(): $!\n"); 565ee02aaa9SDag-Erling Smørgrav while (<FILE>) { 566f3b0ac34SDag-Erling Smørgrav if (m/^\.Nm ((?:(?:open)?pam)_.*?)\s*$/) { 567ce77a8d6SDag-Erling Smørgrav $func{Nm} = $func{Nm} || $1; 568ee02aaa9SDag-Erling Smørgrav } elsif (m/^\.Ft (\S.*?)\s*$/) { 569ce77a8d6SDag-Erling Smørgrav $func{Ft} = $func{Ft} || $1; 570ee02aaa9SDag-Erling Smørgrav } elsif (m/^\.Fn (\S.*?)\s*$/) { 571ce77a8d6SDag-Erling Smørgrav $func{Fn} = $func{Fn} || $1; 572ee02aaa9SDag-Erling Smørgrav } 573ee02aaa9SDag-Erling Smørgrav } 574ee02aaa9SDag-Erling Smørgrav close(FILE); 575ce77a8d6SDag-Erling Smørgrav if ($func{Nm}) { 576ce77a8d6SDag-Erling Smørgrav $FUNCTIONS{$func{Nm}} = \%func; 577ee02aaa9SDag-Erling Smørgrav } else { 578ee02aaa9SDag-Erling Smørgrav warn("No function found\n"); 579ee02aaa9SDag-Erling Smørgrav } 580ee02aaa9SDag-Erling Smørgrav} 581ee02aaa9SDag-Erling Smørgrav 582ee02aaa9SDag-Erling Smørgravsub gensummary($) { 583ee02aaa9SDag-Erling Smørgrav my $page = shift; # Which page to produce 584ee02aaa9SDag-Erling Smørgrav 585ee02aaa9SDag-Erling Smørgrav local *FILE; 586ee02aaa9SDag-Erling Smørgrav my $upage; 58746acc370SDag-Erling Smørgrav my $func; 588ee02aaa9SDag-Erling Smørgrav my %xref; 58946acc370SDag-Erling Smørgrav 5907f106882SDag-Erling Smørgrav open(FILE, ">", "$page.3") 591ee02aaa9SDag-Erling Smørgrav or die("$page.3: $!\n"); 592ee02aaa9SDag-Erling Smørgrav 5937f106882SDag-Erling Smørgrav $page =~ m/(\w+)$/; 5947f106882SDag-Erling Smørgrav $upage = uc($1); 595ce77a8d6SDag-Erling Smørgrav print FILE ".\\\" Generated by gendoc.pl 59646acc370SDag-Erling Smørgrav.Dd $TODAY 597ee02aaa9SDag-Erling Smørgrav.Dt $upage 3 59846acc370SDag-Erling Smørgrav.Os 59946acc370SDag-Erling Smørgrav.Sh NAME 60046acc370SDag-Erling Smørgrav"; 60146acc370SDag-Erling Smørgrav my @funcs = sort(keys(%FUNCTIONS)); 60246acc370SDag-Erling Smørgrav while ($func = shift(@funcs)) { 603ce77a8d6SDag-Erling Smørgrav print FILE ".Nm $FUNCTIONS{$func}->{Nm}"; 604ee02aaa9SDag-Erling Smørgrav print FILE " ," 605ee02aaa9SDag-Erling Smørgrav if (@funcs); 606ee02aaa9SDag-Erling Smørgrav print FILE "\n"; 60746acc370SDag-Erling Smørgrav } 608ee02aaa9SDag-Erling Smørgrav print FILE ".Nd Pluggable Authentication Modules Library 60946acc370SDag-Erling Smørgrav.Sh LIBRARY 61046acc370SDag-Erling Smørgrav.Lb libpam 611ee02aaa9SDag-Erling Smørgrav.Sh SYNOPSIS\n"; 612ee02aaa9SDag-Erling Smørgrav if ($page eq 'pam') { 613ee02aaa9SDag-Erling Smørgrav print FILE ".In security/pam_appl.h\n"; 614ee02aaa9SDag-Erling Smørgrav } else { 615ee02aaa9SDag-Erling Smørgrav print FILE ".In security/openpam.h\n"; 61646acc370SDag-Erling Smørgrav } 617ee02aaa9SDag-Erling Smørgrav foreach $func (sort(keys(%FUNCTIONS))) { 618ce77a8d6SDag-Erling Smørgrav print FILE ".Ft $FUNCTIONS{$func}->{Ft}\n"; 619ce77a8d6SDag-Erling Smørgrav print FILE ".Fn $FUNCTIONS{$func}->{Fn}\n"; 620ee02aaa9SDag-Erling Smørgrav } 621ee02aaa9SDag-Erling Smørgrav while (<STDIN>) { 622ee02aaa9SDag-Erling Smørgrav if (m/^\.Xr (\S+)\s*(\d)\s*$/) { 623b33ab329SDag-Erling Smørgrav ++$xref{int($2)}->{$1}; 624ee02aaa9SDag-Erling Smørgrav } 625ee02aaa9SDag-Erling Smørgrav print FILE $_; 626ee02aaa9SDag-Erling Smørgrav } 627ee02aaa9SDag-Erling Smørgrav 628ee02aaa9SDag-Erling Smørgrav if ($page eq 'pam') { 629ee02aaa9SDag-Erling Smørgrav print FILE ".Sh RETURN VALUES 630ee02aaa9SDag-Erling SmørgravThe following return codes are defined by 631b33ab329SDag-Erling Smørgrav.In security/pam_constants.h : 63246acc370SDag-Erling Smørgrav.Bl -tag -width 18n 63346acc370SDag-Erling Smørgrav"; 63446acc370SDag-Erling Smørgrav foreach (sort(keys(%PAMERR))) { 635ee02aaa9SDag-Erling Smørgrav print FILE ".It Bq Er $_\n$PAMERR{$_}.\n"; 63646acc370SDag-Erling Smørgrav } 637ee02aaa9SDag-Erling Smørgrav print FILE ".El\n"; 638ee02aaa9SDag-Erling Smørgrav } 639ee02aaa9SDag-Erling Smørgrav print FILE ".Sh SEE ALSO 64046acc370SDag-Erling Smørgrav"; 641b33ab329SDag-Erling Smørgrav if ($page eq 'pam') { 642ce77a8d6SDag-Erling Smørgrav ++$xref{3}->{openpam}; 643b33ab329SDag-Erling Smørgrav } 644ee02aaa9SDag-Erling Smørgrav foreach $func (keys(%FUNCTIONS)) { 645b33ab329SDag-Erling Smørgrav ++$xref{3}->{$func}; 64646acc370SDag-Erling Smørgrav } 647b33ab329SDag-Erling Smørgrav print FILE genxref(\%xref); 648ee02aaa9SDag-Erling Smørgrav print FILE ".Sh STANDARDS 64946acc370SDag-Erling Smørgrav.Rs 65046acc370SDag-Erling Smørgrav.%T \"X/Open Single Sign-On Service (XSSO) - Pluggable Authentication Modules\" 65146acc370SDag-Erling Smørgrav.%D \"June 1997\" 65246acc370SDag-Erling Smørgrav.Re 653f3b0ac34SDag-Erling Smørgrav"; 654f3b0ac34SDag-Erling Smørgrav print FILE ".Sh AUTHORS 655f3b0ac34SDag-Erling SmørgravThe OpenPAM library and this manual page were $AUTHORS{THINKSEC} 656ee02aaa9SDag-Erling Smørgrav"; 657ee02aaa9SDag-Erling Smørgrav close(FILE); 658ee02aaa9SDag-Erling Smørgrav} 659ee02aaa9SDag-Erling Smørgrav 660ee02aaa9SDag-Erling Smørgravsub usage() { 661ee02aaa9SDag-Erling Smørgrav 6627f106882SDag-Erling Smørgrav print(STDERR "usage: gendoc [-op] source [...]\n"); 663ee02aaa9SDag-Erling Smørgrav exit(1); 66446acc370SDag-Erling Smørgrav} 66546acc370SDag-Erling Smørgrav 66646acc370SDag-Erling SmørgravMAIN:{ 667ee02aaa9SDag-Erling Smørgrav my %opts; 668ee02aaa9SDag-Erling Smørgrav 669ee02aaa9SDag-Erling Smørgrav usage() 670ee02aaa9SDag-Erling Smørgrav unless (@ARGV && getopts("op", \%opts)); 67146acc370SDag-Erling Smørgrav $TODAY = strftime("%B %e, %Y", localtime(time())); 67246acc370SDag-Erling Smørgrav $TODAY =~ s,\s+, ,g; 673ce77a8d6SDag-Erling Smørgrav if ($opts{o} || $opts{p}) { 67446acc370SDag-Erling Smørgrav foreach my $fn (@ARGV) { 675ee02aaa9SDag-Erling Smørgrav readproto($fn); 67646acc370SDag-Erling Smørgrav } 677ee02aaa9SDag-Erling Smørgrav gensummary('openpam') 678ce77a8d6SDag-Erling Smørgrav if ($opts{o}); 679ee02aaa9SDag-Erling Smørgrav gensummary('pam') 680ce77a8d6SDag-Erling Smørgrav if ($opts{p}); 681ee02aaa9SDag-Erling Smørgrav } else { 682ee02aaa9SDag-Erling Smørgrav foreach my $fn (@ARGV) { 683ee02aaa9SDag-Erling Smørgrav my $func = parse_source($fn); 684ee02aaa9SDag-Erling Smørgrav gendoc($func) 685ee02aaa9SDag-Erling Smørgrav if (defined($func)); 68646acc370SDag-Erling Smørgrav } 687ee02aaa9SDag-Erling Smørgrav } 688ee02aaa9SDag-Erling Smørgrav exit(0); 68946acc370SDag-Erling Smørgrav} 690