Question

Im working on an assignment where i have to have a user log in (check their username/password against a file) if they log in successfully i then need to print their paycheck data which is stored in another file named IN-accounting.data. ive managed to get the user log in part working but i am having trouble print the "paycheck" part as it stands now it will print for every one in the accounting file i could use some help figuring out how to only print the data for the user logged in any suggestions? All ssn, phone numbers, addresses and people in these files and code are fake, they're just data provided to do the assignment


11-6-12 updated to reflect the suggested changes, it now runs the way I originally wanted it to


#!/usr/bin/perl
use warnings;
use strict;
use Digest::MD5 'md5_hex';

open (PSWD, '<', 'password.passwd');
#getting username and password
#converting username to lowercase if username is entered in CAPS
print "Please enter your username: ";
chomp(my $userN = <STDIN>);
my $username = lc($userN);
############################################
print "Please enter your password: ";
chomp(my $password = <STDIN>);
my $passwd=md5_hex($password);
###############################################
my $matchCount = 0;#used later to make sure username and password match file
#reading password.passwd and assigning values
while (my $lines = <PSWD>){
my($user,$pswd,$userID,$groupID,$info,$home,$shell) = split ':', $lines;

#checking username entered vs that in the passwd file
if ($username eq $user){
print "Checking username... MATCH\n";
$username=$info;
#keeps track if username matches or not
$matchCount+=1;

#checking password entered vs that in the passwd file
if ($passwd eq $pswd){
    print "Checking password... MATCH\n";
        my ($first,$last)=split(" ", $info);
        accounting($first,$last);
}
else{
        print "Password does not match!\n";
    }
    last;


}
}

# if matchcount did not change, username did not match killing the program
if ($matchCount == 0){
    die ("\"$username\" does not match any users in our database!\n");
}





sub accounting{
   my $first_name=shift;
   my $last_name=shift;
   open(my $fh, '<', 'IN-accounting.data') or die "cannot open accounting file $!";
    while (my $lines = <$fh>){
    chomp $lines;
        my @fields = split(/\|/, $lines);

        push @data2, \@fields;



    my($Lname,$Fname,$ssn,$address)=($fields[0],$fields[1],$fields[2],$fields[3]);
        my($city,$state,$zip,$payDate)=($fields[4],$fields[5],$fields[6],$fields[7]);
        my($hours,$rate,$taxes,$deductions,$notes)= ($fields[8],$fields[9],$fields[10],$fields[11],$fields[12]);

        next if $Lname ne $last_name and $Fname ne $first_name;

    my ($Gpay)= eval($hours)*eval($rate);#gross pay
    my ($Tpay)=$Gpay-($taxes+$deductions);#total pay
    my $Essn=substr($ssn,+-4);#edited ssn
    print "$Fname $Lname\n";
    print "$address\n";
    print "$city $state $zip\n";
    print "SSN: xxx-xx-$Essn\n";
    print"\n";
    print "Pay Date: $payDate";
    print"\n";
    print"You had $hours hours at \$$rate/hour\n";
    print"Gross Pay: $Gpay\n";
    print"Taxes:\$-$taxes\n";
    print"Deductions:\$-$deductions\n";
    print"Total Pay: $Tpay\n";
    print"\n";
    print"Notes:$notes\n\n";



}
print"press enter to quit: ";
       my $quit=<>;     
       if ($quit){ exit;}
}

password.passwd

amon9640:4cb9c8a8048fd02294477fcb1a41191a:500:25:Alexander Monday:/home/payroll:/bin/payroll iart1373:4cb9c8a8048fd02294477fcb1a41191a:501:25:Inigo Arterbury:/home/payroll:/bin/payroll wher0210:4cb9c8a8048fd02294477fcb1a41191a:502:25:Wardell Herman:/home/payroll:/bin/payroll

accounting file

Monday|Alexander|815-19-9640|4662 Dewy Subdivision|Owltown|Oregon|97434-8480|1/18/1998|19|21.68|60.28|2.24|Payroll is auditing the account and a report will be due soon.

Arterbury|Inigo|037-30-1373|987 Rocky Island Byway|Christmas City|New Mexico|88023-3889|4/1/1993|9|7.02|17.75|12.71|Audit complete. Deficencies found.

Herman|Wardell|114-29-0210|5555 Cinder Forest Wynd|White Eyes Town|Washington|98707-5628|10/0/2003|37|3.07|41.90|20.89|Audit complete. Deficencies found.

Was it helpful?

Solution

I'll skip over the security issues. Let's look at a few things:

What's your accounting sub-routine suppose to do? Print the paycheck for the user? You're not passing any data to the subroutine. How does the subroutine know which user's paycheck to print?

Why not do something like this?

 accounting($Fname, $Lname); 

sub accounting {
   my $first_name = shift;
   my $last_name = shift;

   if (not $first_name or not $last_name) {
      die "You need a first name and a last name...)
   }

Now, you can loop through your accounting file line by line, looking for lines where the $first_name and $last_name match.

while (my $lines = <$fh>){
    chomp $lines;

    my ( $Lname, $Fname, $ssn,  $address,
        $city,  $state, $zip,  $payDatek,
        $hours, $rate,  $taxes,$deductions, $notes) = split /\|/, $lines;

        #Skip over non matching lines
        next if $Lname ne $last_name and $Fname ne $first_name;

You've got some bogus errors in your code. A few quick ones I noticed:

  • push @data2, \@fields; You're pushing a reference of an array into an array.
  • my ( $Lname, $Fname, ... $notes) = %fields; Field is an array, not a hash.

I'm surprised your program compiled with these issues.

And, please use spaces in your code. It makes it much easier to read and follow.

OTHER TIPS

Wow, there are some serious security issues with your approach here. I'll try and point a few out in the comments.

To focus on your specific question, you need some way to link the user to the accounting data and then filter by user. Ideally you would ingest the raw data into a database with relational contraints to make this easier. But for the current approach you could do something like:

next unless "$Fname $Lname" eq $username;

Place this after the mapping of variable names to the returned regex fields.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top