11 sub process_query
() {
12 if (exists $services{$query}) {
14 exec ($verbose && length $services{$query}->{'verbose'} ?
15 $services{$query}->{'verbose'} :
16 $services{$query}->{'command'});
23 print ("userv fingerd on $hostname\r\n".
24 "queries supported:\r\n".
26 " <nothing> list of logged on users and available services\r\n".
27 " / this help text\r\n".
28 " <service> separately advertised special finger service\r\n".
29 " <user> user (logged in or otherwise)\r\n".
30 " <user>+<xtra> user-provided extended/special finger service\r\n".
31 " /<substring> search for user matching substring\r\n")
43 print "Username Idle Msg,tty Login at From\r\n" or die $!;
46 open W
,"who -iw|" or die $!;
49 m/^(\w+) +(\S) +(\S+) +(\w+ +\d+ \d\d\:\d\d) +(\S+) +(.*)$/ or die;
50 ($user, $mesg, $tty, $login, $idle, $from) = ($1,$2,$3,$4,$5,$6);
51 $mesg = $mesg =~ m/[-+]/ ?
$& : '?';
59 $pref= exists $user_pref_list{$user}
60 ?
$user_pref_list{$user} : $def_pref_list;
61 next unless $pref =~ m/^\+/;
63 $idle= '' unless $pref =~ m/i/;
64 $mesg= ' ' unless $pref =~ m/m/;
65 $tty= '' unless $pref =~ m/t/;
66 $login= '' unless $pref =~ m/l/;
67 $from= '' unless $pref =~ m/t/;
71 printf "%-8s %-5s %s%-8s %-12s %s\r\n",
72 $user, $idle, $mesg, $tty, $login, $from
75 $users{$user}->{'pref'} = $pref;
76 $users{$user}->{'mesg'}->{$mesg} = 1;
77 $users{$user}->{'idle'} = min_idle
($users{$user}->{'idle'}, $idle);
81 $!=0; close W
; $?
and die "$! $?";
84 print "Username Idle Msg Name\r\n" or die $!;
86 for $user (sort keys %users) {
87 $pref= $users{$user}->{'pref'};
88 $name= $pref =~ m/n/ ?
(getpwnam($user))[6] : '';
90 $mesg= join('', sort keys %{ $users{$user}->{'mesg'} });
91 $mesg= '+' if $mesg =~ m
,\
+,;
92 printf "%-8s %-5s %s %s\r\n",
93 $user, $users{$user}->{'idle'}, $mesg, $name
98 foreach $service (sort keys %services) {
99 $desc= $services{$service}->{'desc'};
100 next unless length $desc;
103 print "\r\nService Description\r\n" or die $!;
107 printf "%-12s %s\r\n", $service, $desc or die $!;
110 print "\r\nFor help, finger /\@$hostname\r\n";
115 if ($query =~ s
,^/,,) {
116 $query =~ s/\W/\\$&/g;
119 while (($user,$passwd,$uid,$gid,$quota,$comment,$name) = getpwent) {
122 $pref= exists $user_pref_search{$user}
123 ?
$user_pref_search{$user}
125 next unless $pref =~ m/[uy]/;
126 $name= '' unless $pref =~ m/y/;
127 next unless query_match
($user) || query_match
($name);
130 print "Username Name\r\n" or die $!;
133 printf "%-9s %s\r\n", $user,$name or die $!;
138 print "No matches. finger /\@$hostname for help.\r\n" or die $!;
144 if ($query =~ s/\+.*$//) { $qsuffix= $&; }
146 if (!(($user)= getpwnam($query))) {
147 print "No user named \`$query'. finger /\@$hostname for help.\r\n" or die $!;
151 @servcmd= length $qsuffix
153 : ('finger-extended',$qsuffix);
154 exec 'userv','-t',300,$user,@list;
159 sub query_match
($) {
161 return $data =~ m/\b$query\b/io;
165 $progname= $0; $progname =~ s
,.*/,,;
168 $config= '/etc/finger-userv/config';
170 if (@ARGV) { @ARGV == 1 or die; $config= $ARGV[1]; }
171 $services= '/etc/userv/finger/services';
172 $peruser= '/var/lib/userv/finger/prefs';
173 $def_pref_list= '+m'; $list_fields= 'imtlfn';
174 $def_pref_search= 'y'; $search_opts= 'nuy';
179 $query =~ s/\r?\n$// or die "$0: no query\n";
181 $verbose = $query =~ s
,^/[wW
],,;
187 return '.' if $a eq '.' || $b eq '.';
188 return $b if $a eq 'old' || $a eq '';
189 return $a if $b eq 'old' || $b eq '';;
190 return $a le $b ?
$a : $b;
194 if (open C
, "$config") {
196 chomp; s/\s+$//; s/^\s+//;
197 if (m/^default\-pref\s+([-+][$list_fields]+)\s+([$search_opts])$/) {
199 $def_pref_search= $2;
200 } elsif (m/^hostname\s+(\S+)$/) {
202 } elsif (m/^prefs\-file\s+(\S.*)$/) {
204 } elsif (m/^services\-file\s+(\S.*)$/) {
206 } elsif (m/\S/ && !m/^\#/) {
211 } elsif ($! != &ENOENT
) {
215 if (!defined $hostname) {
216 chomp($hostname= `hostname -f`);
217 length $hostname or die $?
;
221 sub read_services
() {
222 if (open C
, "$services") {
224 chomp; s/\s+$//; s/^\s+//;
225 next if m/^\#/ || !m/\S/;
226 if (m/^service\s+(\S.*)$/) {
228 die if exists $services{$sname};
229 } elsif (m/^(desc|command|verbose)\s+(\S.*)$/) {
230 die if exists $services{$sname}->{$1};
231 $services{$sname}->{$1}= $2;
237 foreach $sname (keys %services) {
238 die unless exists $services{$sname}->{'command'};
240 } elsif ($! != &ENOENT
) {
245 sub read_per_user
() {
246 if (open DL
, "$peruser") {
248 m/^(\w+) ([-+][$list_fields]+) ([$search_opts])$/ or die;
249 $user_pref_list{$1}= $2;
250 $user_pref_search{$1}= $3;
253 } elsif ($! != &ENOENT
) {