From 5f9b76752f5213b26c47be57a6733ead09cfdff3 Mon Sep 17 00:00:00 2001 From: ian Date: Sat, 20 May 2000 20:04:03 +0000 Subject: [PATCH] @@ -1,3 +1,9 @@ +userv (0.2) unstable; urgency=low + + * Embryonic new finger program. + + -- + userv (0.1) experimental; urgency=low * Initial release. --- changelog | 6 + debian/changelog | 6 + finger/.cvsignore | 6 + finger/Makefile | 64 ++++++++++ finger/config.in | 40 ++++++ finger/finger-finger.in | 10 ++ finger/finger-getprefs.in | 13 ++ finger/finger-notmyself.in | 10 ++ finger/finger-setprefs.in | 11 ++ finger/in.fingerd | 256 +++++++++++++++++++++++++++++++++++++ finger/install-confs | 11 ++ finger/services.in | 18 +++ finger/setprefs | 29 +++++ 13 files changed, 480 insertions(+) create mode 100644 finger/.cvsignore create mode 100644 finger/Makefile create mode 100644 finger/config.in create mode 100644 finger/finger-finger.in create mode 100644 finger/finger-getprefs.in create mode 100644 finger/finger-notmyself.in create mode 100644 finger/finger-setprefs.in create mode 100755 finger/in.fingerd create mode 100755 finger/install-confs create mode 100644 finger/services.in create mode 100755 finger/setprefs diff --git a/changelog b/changelog index c0f6a31..80a0170 100644 --- a/changelog +++ b/changelog @@ -1,3 +1,9 @@ +userv (0.2) unstable; urgency=low + + * Embryonic new finger program. + + -- + userv (0.1) experimental; urgency=low * Initial release. diff --git a/debian/changelog b/debian/changelog index c0f6a31..80a0170 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +userv (0.2) unstable; urgency=low + + * Embryonic new finger program. + + -- + userv (0.1) experimental; urgency=low * Initial release. diff --git a/finger/.cvsignore b/finger/.cvsignore new file mode 100644 index 0000000..157bb59 --- /dev/null +++ b/finger/.cvsignore @@ -0,0 +1,6 @@ +config +services +finger-finger +finger-notmyself +finger-getprefs +finger-setprefs diff --git a/finger/Makefile b/finger/Makefile new file mode 100644 index 0000000..f818c7e --- /dev/null +++ b/finger/Makefile @@ -0,0 +1,64 @@ +# Copyright (C) 2000 Ian Jackson +# +# This is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with userv-utils; if not, write to the Free Software +# Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# $Id$ + +etcdir= /etc +var= /var +varlib= $(var)/lib +prefix= /usr/local +bindir= $(prefix)/bin +sbindir= $(prefix)/sbin + +libdir= $(prefix)/lib +libuserv= $(libdir)/userv +libfinger= $(libuserv)/finger + +varuserv= $(varlib)/userv +varfinger= $(varuserv)/finger + +etcuserv= $(etcdir)/userv +etcfinger= $(etcuserv)/finger +uservicesd= $(etcuserv)/services.d + +user= daemon + +ROOTMKDIRS= $(etcfinger) $(uservicesd) $(libfinger) $(varuserv) +USERVICES= finger-notmyself finger-finger finger-getprefs finger-setprefs +FINGERCONFS= config services +TARGETS= $(FINGERCONFS) $(USERVICES) + +SUBSTVARS= user etcfinger varfinger libfinger +SEDSCRIPT= '$(foreach f, $(SUBSTVARS), s,@$f@,$($f),g; )' + +all: $(TARGETS) + +%: %.in + sed -e $(SEDSCRIPT) <$< >$@.new && mv -f $@.new $@ + +install: all + install -d -m 755 -o root $(ROOTMKDIRS) + install -d -m 700 -o $(user) $(varfinger) + install -m 755 in.fingerd $(sbindir) + install -m 755 setprefs $(libfinger) + ./install-confs $(etcfinger) $(FINGERCONFS) + ./install-confs $(uservicesd) $(USERVICES) + +fresh-install: erase-configs install + +erase-configs: + cd $(etcfinger); rm -f $(FINGERCONFS) + cd $(uservicesd); rm -f $(USERVICES) diff --git a/finger/config.in b/finger/config.in new file mode 100644 index 0000000..db21cd3 --- /dev/null +++ b/finger/config.in @@ -0,0 +1,40 @@ +# This configuration file controls the userv finger daemon +# The possible directives in it are: +# default-pref +# hostname +# prefs-file +# services-file +# Blank lines and #-comments are allowed. +# +# The per-user prefs file has a list of +# +# and may NOT contain blank lines or comments. It is supposed +# to be edited only by the finger-pref userv service. +# +# The logged-on-list preference controls how, if at all, a user +# appears in the list of logged on users. It may be is either `-', or +# `+' followed by a possibly-empty list of fields to show. `-' means +# that the user will not appear, whether they are logged on or not. +# `+' means that they will appear. It may be followed by one or more +# of the following letters: +# i Show the idle time +# m Show whether the session is accepting messages (`mesg') +# t Show why tty the session is on +# l Show when the session started (ie, when the user logged on) +# f Show where the user is logged on from +# n Show the user's name (from the passwd file GCOS field) +# +# The search-preference controls how, if at all, a user's details will +# be used and their information returned, in response to a search request. +# n The user will never be returned for a search request +# u Only matches against their username will count, and only their +# username will be displayed. +# y Matching is performed against username or full name and both +# are displayed. +# +# The extended services file is usually the file `services' in +# this directory. + +default-pref +m y +services-file @etcfinger@/services +prefs-file @varfinger@/prefs diff --git a/finger/finger-finger.in b/finger/finger-finger.in new file mode 100644 index 0000000..4e09226 --- /dev/null +++ b/finger/finger-finger.in @@ -0,0 +1,10 @@ +# +if ( glob calling-user @user@ + & grep service-user-shell /etc/shells + ) + reset + no-set-environment + suppress-args + disconnect-hup + execute userv @user@ finger-notmyself +fi diff --git a/finger/finger-getprefs.in b/finger/finger-getprefs.in new file mode 100644 index 0000000..2f91f47 --- /dev/null +++ b/finger/finger-getprefs.in @@ -0,0 +1,13 @@ +# +if ( grep calling-user-shell /etc/shells + & glob service-user daemon + ) + reset + no-set-environment + suppress-args + disconnect-hup + execute sh -c " \ + if test -f @varfinger@/prefs; then \ + grep '^$USERV_USER ' @varfinger/prefs || test $? = 1; fi \ + " +fi diff --git a/finger/finger-notmyself.in b/finger/finger-notmyself.in new file mode 100644 index 0000000..33353e6 --- /dev/null +++ b/finger/finger-notmyself.in @@ -0,0 +1,10 @@ +# +if ( grep calling-user-shell /etc/shells + & glob service-user @user@ + ) + reset + no-set-environment + suppress-args + disconnect-hup + execute sh -c "finger -m $USERV_USER" +fi diff --git a/finger/finger-setprefs.in b/finger/finger-setprefs.in new file mode 100644 index 0000000..6602fce --- /dev/null +++ b/finger/finger-setprefs.in @@ -0,0 +1,11 @@ +# +if ( grep calling-user-shell /etc/shells + & glob service-user daemon + ) + reset + no-set-environment + no-suppress-args + no-disconnect-hup + execute with-lock-ex -w @varfinger@/lock \ + @libfinger@/setprefs @varfinger@/prefs +fi diff --git a/finger/in.fingerd b/finger/in.fingerd new file mode 100755 index 0000000..58d4c93 --- /dev/null +++ b/finger/in.fingerd @@ -0,0 +1,256 @@ +#!/usr/bin/perl -- + +use POSIX; + +setup(); +read_config(); +read_services(); +parse_query(); +process_query(); + +sub process_query () { + if (exists $services{$query}) { + + exec ($verbose && length $services{$query}->{'verbose'} ? + $services{$query}->{'verbose'} : + $services{$query}->{'command'}); + die $!; + + } + + if ($query eq '/') { + + print ("userv fingerd on $hostname\r\n". + "queries supported:\r\n". + "\r\n". + " list of logged on users and available services\r\n". + " / this help text\r\n". + " separately advertised special finger service\r\n". + " user (logged in or otherwise)\r\n". + " + user-provided extended/special finger service\r\n". + " / search for user matching substring\r\n") + or die $!; + + return; + + } + + if (!length $query) { + + read_per_user(); + + if ($verbose) { + print "Username Idle Msg,tty Login at From\r\n" or die $!; + } + + open W,"who -iw|" or die $!; + while () { + + m/^(\w+) +(\S) +(\S+) +(\w+ +\d+ \d\d\:\d\d) +(\S+) +(.*)$/ or die; + ($user, $mesg, $tty, $login, $idle, $from) = ($1,$2,$3,$4,$5,$6); + $mesg = $mesg =~ m/[-+]/ ? $& : '?'; + + if ($tty =~ m/\./) { + $from =~ s/.$/$& /; + $from.= $tty; + $tty= ''; + } + + $pref= exists $user_pref_list{$user} + ? $user_pref_list{$user} : $def_pref_list; + next unless $pref =~ m/^\+/; + + $idle= '' unless $pref =~ m/i/; + $mesg= ' ' unless $pref =~ m/m/; + $tty= '' unless $pref =~ m/t/; + $login= '' unless $pref =~ m/l/; + $from= '' unless $pref =~ m/t/; + + if ($verbose) { + + printf "%-8s %-5s %s%-8s %-12s %s\r\n", + $user, $idle, $mesg, $tty, $login, $from + or die $!; + } else { + $users{$user}->{'pref'} = $pref; + $users{$user}->{'mesg'}->{$mesg} = 1; + $users{$user}->{'idle'} = min_idle($users{$user}->{'idle'}, $idle); + } + + } + $!=0; close W; $? and die "$! $?"; + + if (!$verbose) { + print "Username Idle Msg Name\r\n" or die $!; + + for $user (sort keys %users) { + $pref= $users{$user}->{'pref'}; + $name= $pref =~ m/n/ ? (getpwnam($user))[6] : ''; + $name =~ s/,.*//; + $mesg= join('', sort keys %{ $users{$user}->{'mesg'} }); + $mesg= '+' if $mesg =~ m,\+,; + printf "%-8s %-5s %s %s\r\n", + $user, $users{$user}->{'idle'}, $mesg, $name + or die $!; + } + } + + foreach $service (sort keys %services) { + $desc= $services{$service}->{'desc'}; + next unless length $desc; + + if (!$anyservice) { + print "\r\nService Description\r\n" or die $!; + $anyservice= 1; + } + + printf "%-12s %s\r\n", $service, $desc or die $!; + } + + print "\r\nFor help, finger /\@$hostname\r\n"; + return; + + } + + if ($query =~ s,^/,,) { + $query =~ s/\W/\\$&/g; + read_per_user(); + + while (($user,$passwd,$uid,$gid,$quota,$comment,$name) = getpwent) { + $name =~ s/,.*//; + + $pref= exists $user_pref_search{$user} + ? $user_pref_search{$user} + : $def_pref_search; + next unless $pref =~ m/[uy]/; + $name= '' unless $pref =~ m/y/; + next unless query_match($user) || query_match($name); + + if (!$found) { + print "Username Name\r\n" or die $!; + $found= 1; + } + printf "%-9s %s\r\n", $user,$name or die $!; + + } + + if (!$found) { + print "No matches. finger /\@$hostname for help.\r\n" or die $!; + } + + return; + } + + if ($query =~ s/\+.*$//) { $qsuffix= $&; } + + if (!(($user)= getpwnam($query))) { + print "No user named \`$query'. finger /\@$hostname for help.\r\n" or die $!; + return; + } + + @servcmd= length $qsuffix + ? ('finger-finger') + : ('finger-extended',$qsuffix); + exec 'userv','-t',300,$user,@list; + die $!; + +} + +sub query_match ($) { + my ($data) = @_; + return $data =~ m/\b$query\b/io; +} + +sub setup () { + $progname= $0; $progname =~ s,.*/,,; + alarm(300); + + $config= '/etc/finger-userv/config'; + + if (@ARGV) { @ARGV == 1 or die; $config= $ARGV[1]; } + $services= '/etc/userv/finger/services'; + $peruser= '/var/lib/userv/finger/prefs'; + $def_pref_list= '+m'; $list_fields= 'imtlfn'; + $def_pref_search= 'y'; $search_opts= 'nuy'; +} + +sub parse_query () { + $query= ; + $query =~ s/\r?\n$// or die "$0: no query\n"; + + $verbose = $query =~ s,^/[wW],,; + $query =~ s/^ *//; +} + +sub min_idle ($$) { + my ($a,$b) = @_; + return '.' if $a eq '.' || $b eq '.'; + return $b if $a eq 'old' || $a eq ''; + return $a if $b eq 'old' || $b eq '';; + return $a le $b ? $a : $b; +} + +sub read_config () { + if (open C, "$config") { + while () { + chomp; s/\s+$//; s/^\s+//; + if (m/^default\-pref\s+([-+][$list_fields]+)\s+([$search_opts])$/) { + $def_pref_list= $1; + $def_pref_search= $2; + } elsif (m/^hostname\s+(\S+)$/) { + $hostname= $1; + } elsif (m/^prefs\-file\s+(\S.*)$/) { + $peruser= $1; + } elsif (m/^services\-file\s+(\S.*)$/) { + $services= $1; + } elsif (m/\S/ && !m/^\#/) { + die; + } + } + close C or die $!; + } elsif ($! != &ENOENT) { + die $!; + } + + if (!defined $hostname) { + chomp($hostname= `hostname -f`); + length $hostname or die $?; + } +} + +sub read_services () { + if (open C, "$services") { + while () { + chomp; s/\s+$//; s/^\s+//; + next if m/^\#/ || !m/\S/; + if (m/^service\s+(\S.*)$/) { + $sname= $1; + die if exists $services{$sname}; + } elsif (m/^(desc|command|verbose)\s+(\S.*)$/) { + die if exists $services{$sname}->{$1}; + $services{$sname}->{$1}= $2; + } else { + die; + } + } + close C; + foreach $sname (keys %services) { + die unless exists $services{$sname}->{'command'}; + } + } elsif ($! != &ENOENT) { + die $!; + } +} + +sub read_per_user () { + if (open DL, "$peruser") { + while (
) { + m/^(\w+) ([-+][$list_fields]+) ([$search_opts])$/ or die; + $user_pref_list{$1}= $2; + $user_pref_search{$1}= $3; + } + close DL; + } elsif ($! != &ENOENT) { + die $!; + } +} diff --git a/finger/install-confs b/finger/install-confs new file mode 100755 index 0000000..68044a9 --- /dev/null +++ b/finger/install-confs @@ -0,0 +1,11 @@ +#!/bin/sh +set -e +destdir="$1"; shift +for f in "$@"; do install -m 644 -o root "$f" "$destdir/$f:new"; done +cd "$destdir" +for f in "$@"; do + if ! test -f "$f"; then + echo installing new "$destdir/$f" + mv -f "$f:new" "$f" + fi +done diff --git a/finger/services.in b/finger/services.in new file mode 100644 index 0000000..4bc7cfd --- /dev/null +++ b/finger/services.in @@ -0,0 +1,18 @@ +# This file contains the special advertised or unadvertised services +# The result is that finger @ will run some +# command. +# +# Each service is listed like this: +# service +# command +# [ verbose ] +# [ desc ] +# Blank lines and #-comments are allowed. +# +# If a description is provided it will be printed in the normal +# finger @host output. If the verbose command is provided it +# will be run instead of the usual command if a verbose request +# (from `finger -l' on UN*X) is made; otherwise verbose requests +# will run the normal command. +# +# You can override anything usually displayed by this fingerd here. diff --git a/finger/setprefs b/finger/setprefs new file mode 100755 index 0000000..53de506 --- /dev/null +++ b/finger/setprefs @@ -0,0 +1,29 @@ +#!/usr/bin/perl + +use POSIX; + +@ARGV==3 or die; +($prefs_file, $new_list, $new_search) = @ARGV; + +$new_list =~ m/^(\-|\+[imtlfn]+)$/ or die; $new_list= $1; +$new_search =~ m/^([nuy])$/ or die; $new_search= $1; + +$user= $ENV{'USERV_USER'}; length $user or die; + +open N, ">$prefs_file.new" or die $!; + +if (open P, $prefs_file) { + while (

) { + die unless m/^(\w+) /; + next if $1 eq $user; + print N or die $!; + } + close P or die $!; +} elsif ($! != &ENOENT) { + die $!; +} + +print N "$user $new_list $new_search\n" or die $!; +close N or die $!; + +rename "$prefs_file.new", $prefs_file or die $!; -- 2.30.2