#!/usr/bin/perl
#
#	fingerize:
#	a filter (i.e. standard input to standard output)
#	for "massaging" data with a login-name as the first word of each line
#	into the style of finger.
#
#	For each complete (newline-terminated) line of standard input
#	with at least one word, fingerize tries to interpret
#	the first word as a login-name, and places the corresponding realname
#	from the passwd database just after it, in the style of finger.
#	A "???" realname is displayed if no actual realname can be found
#	(again, this is in the style of finger).
#	Login-names and realnames are truncated or padded to the same
#	field lengths as used by finger, or at least the finger at IC DoC.
#
#	The rest of each line (after the login-name and any whitespace)
#	is passed through unchanged. Lines which are not newline-terminated,
#	or which do not have at least one word,
#	are also passed through unchanged.
#
#	Used by fscan and lscan.
#

#
#	First build an associative array of login-names and realnames.
#
open(passwd_database, '/etc/passwd')
	|| die "$0: Can't open passwd database: $!\n";
while (<passwd_database>) {
	#
	#	Get latest entry from passwd database.
	#
	($login_name,$password,$uid,$gid,$realname) = split(/:/);

	#
	#	Strip away any extras in the realname such as room numbers,
	#	then turn a whitespace-only realname into "???".
	#
	$realname =~ s/,.*$//;
	$realname =~ s/^[ \t]*$/       ???/;

	#
	#	Truncate or pad the realname to the standard field length.
	#
	$truncated_or_padded_realname = $realname . '                   ';
	$truncated_or_padded_realname =~ s/^(....................).*$/$1/;

	#
	#	OK, now add to associative array!
	#
	$truncated_or_padded_realnames{$login_name} = $truncated_or_padded_realname;
}#endwhile
close(passwd_database)
	|| die "$0: Can't close passwd database: $!\n";


#
#	Now treat each line of standard input appropriately,
#	by looking up the relevant data in the associative array.
#
while (<STDIN>) {
	if (/^[ \t]*([^ \t][^ \t]*)[ \t]*(.*)\n/) {

		#
		#	We *do* have at least one word and a newline!
		#	So: capture $1 and $2 from the brackets above
		#	into named variables.
		#
		$login_name=$1; $rest_of_line=$2;

		#
		#	Truncate or pad the login-name to the standard
		#	field length.
		#
		$truncated_or_padded_login_name=$login_name . '       ';
		$truncated_or_padded_login_name =~ s/^(........).*$/$1/;

		#
		#	Try to find the realname in the associative array;
		#	but if it can't be found, take it as good old "???".
		#
		$truncated_or_padded_realname=$truncated_or_padded_realnames{$login_name};
		if ($truncated_or_padded_realname eq '') {
			$truncated_or_padded_realname='       ???          ';
		}#endif

		#
		#	OK, now print the massaged line!
		#
		print "$truncated_or_padded_login_name $truncated_or_padded_realname  $rest_of_line\n";

	}else{

		#
		#	We *don't* have at least one word and a newline!
		#	So: pass this line through unchanged.
		#
		print $_;

	}#endif
}#endwhile
