#!/usr/bin/perl # # Name : Matthew Reeves # # This is a program to duplicate the finger cmd while allowing for misspelling # via the use of soundex # #use diagnostics; use warnings; use strict; use feature ":5.10"; #checks if cmd line argument provided, if not, print usage statement and exit if ($ARGV[0] ~~ undef) { print "\nUsage: $0 \n\n"; exit; } #stores command line argument in a more friendly named scalar my $input = $ARGV[0]; #saves soundex converted value to a scalar for easier comparisons later my $inputSDX = &soundex($input); #prints a statement echoing the input value, and its soundex converted value print "\nPoss match: $input\nConv value: $inputSDX\n\n"; #open /etc/passwd file to find userid's first names's and last name's to compare #against input value, stores contents in @wholeFile open (IN,"/etc/passwd"); my @wholeFile = ; #close /etc/passwd file close IN; #declare @args with default value, which will be used to call finger cmd via system() #also declares $check, which tracks if any sdx match was found in etc/passwd file my @args = ("finger", $input); my $check = 0; #for loop will process /etc/passwd data line by line foreach my $line (@wholeFile) { my @pmatches; #sends current line to &getnames subroutine to get username, first name #and last name, stores data in @pmatches @pmatches = &getNames($line); #converts each of the three names currently in @pmatches to soundex #value, compares against input's soundex, and if match found runs #finger using corresponding userid as arguement foreach (@pmatches) { if ($inputSDX ~~ &soundex($_)) { @args = ("finger", $pmatches[0]); system(@args); $check = 1; say ""; } } } #if no sdx matches were found in etc/passwd, calls finger with string #entered at command line so user will get finger error message system(@args) if $check~~0; sub getNames { #grabs the arguement passed to soundex my $parameter = shift; #initializes @results with default values my @results = ( "fakeuserid", "fake first name", "fake last name" ); #splits line with : delimiter my @tmp = split(/:/ , $parameter); #stores username in $results[0] $results[0] = $tmp[0]; #identifies first name and last name using regex $tmp[4] =~ /(\w*\s*.*?)\s*(\w*),/; #backreferencing stores first name and last name to @results $results[1] = $1; $results[2] = $2; #returns results return @results; } sub soundex { my $temp = shift; #grabs the argument passed to soundex $temp = uc $temp; #uppercase the name passed in to normalize it my $sdxValue = "*** $temp not processed ***"; #default response #removes all non-alphabetic characters $temp =~ s/[^A-Za-z]//g; #stores first letter's value my $letter = substr($temp, 0, 1); #uses transliteration to change letters, to numeric code $temp =~ tr/BFPVCGJKQSXZDTLMNR/111122222222334556/; #eliminates consecutive duplicate code values $temp =~ tr/0-9//s; #deletes letters AEHIOUWY $temp =~ tr/AEHIOUWY//d; #pads 0's to the end of temp $temp .= "0000"; #if/else block to check if first letter was AEHIOUWY, and reinserts #first letter onto temp as a letter as appropriate, either tacked on to #the front of temp, or overwriting the first value in temp to prevent #innaccuracies due to duplication of first character. Also serves to #fix final length of soundex code to 5 characters. if ($letter =~ /A|E|H|I|O|U|W|Y/) { $temp = $letter.substr($temp, 0, 4); } else { $temp = $letter.substr($temp, 1, 4); } #stores, then returns soundex value $sdxValue = $temp; return $sdxValue; }