CGI/Perl Guide | Learning Center | Forums | Advertise | Login
Site Search: in

  Main Index MAIN
INDEX
Search Posts SEARCH
POSTS
Who's Online WHO'S
ONLINE
Log in LOG
IN

Home: Perl Programming Help: Beginner:
Seeking a few pointers in basic FIFO script

 



IlovePERL!
Novice

Oct 18, 2012, 10:18 AM

Post #1 of 14 (2013 views)
Seeking a few pointers in basic FIFO script Can't Post

Hello all!! I'm new to these forums, and I love perl. After reading a few posts I decided this site was the one to use to learn / contribute to perl in anyway. I'm seeking a few pointers on a fifo script. This FIFO is used for proftpd logs, I want to simply open the logs, read line by line, and do an action by comparing. I have the openlog syntax,

"penlog($program, 'pid', $syslog_facility);
syslog($syslog_level, $_) while (<FIFO>); {
$line=$_;"

Which I thought should read it line by line, then if statements to compare the lines to elements in an array (upload locations), and simply print the output to the screen ( which another perl script will then handle, but that script works fine, since it handles output from many other utilities).

How would I assign a variable to lines opened one by one, and compare them to the array variable?

"if ($line=$_ == $uploadfolders[0])" ? ( the array was predeclared already).

Any assistance is welcome,

thank you almighty gurus!

In Reply To


Laurent_R
Veteran / Moderator

Oct 18, 2012, 10:46 AM

Post #2 of 14 (2010 views)
Re: [IlovePERL!] Seeking a few pointers in basic FIFO script [In reply to] Can't Post

You may want to try something like this:


Code
while (my $line = <$INPUT>) { 
chomp $line;
if ($line eq $something[0]) { # whetever



IlovePERL!
Novice

Oct 18, 2012, 11:09 AM

Post #3 of 14 (2008 views)
Re: [Laurent_R] Seeking a few pointers in basic FIFO script [In reply to] Can't Post

I will try out this syntax, thank you very much!


IlovePERL!
Novice

Oct 18, 2012, 1:36 PM

Post #4 of 14 (1998 views)
Re: [IlovePERL!] Seeking a few pointers in basic FIFO script [In reply to] Can't Post

Hello, I was trying this out but sort of had an issue;

because I need to use the while syntax to read from the fifo, ie;

while (= <$fifo_fh>);

even if I add while while (my $line = <$fifo_fh>);

it won't parse anything. How can I open the fifo, but also assign a variable to the input, while also chomping it?
IE,


while (<$fifo_fh>) {
chomp;

^ my problem with that is I can't compare anything, since there's no variable. If I do,
while (my $line = <$fifo_fh>) {
chomp $line;

then compare the line, $line has no global bearing.
your recommendation should work, but I'm not sure how to read from the fifo, while also assigning a variable to the input to compare in an if / other statement fashion.

Kind regards,


FishMonger
Veteran / Moderator

Oct 18, 2012, 1:52 PM

Post #5 of 14 (1995 views)
Re: [IlovePERL!] Seeking a few pointers in basic FIFO script [In reply to] Can't Post

Please post your complete script and explain in clear terms how its output differs from what you expect. You should also post a short sample of your data file.


IlovePERL!
Novice

Oct 18, 2012, 2:02 PM

Post #6 of 14 (1993 views)
Re: [FishMonger] Seeking a few pointers in basic FIFO script [In reply to] Can't Post

Understood, sorry for that blooper I meant to attach. Here is my script;

#!/usr/bin/perl -w

use strict;
use warnings;
use File::Basename qw(basename);
use Sys::Syslog qw(:DEFAULT setlogsock);


my $fifo_file = "/var/log/xferlog.fifo";
my $syslog_facility = 'daemon';
my $syslog_level = 'info';
my $program = "proftpd";
my $httplivelog = "/var/log/proftpd/live-http.log";
my $livelog = "/var/log/proftpd/live.log";
my $jorgelog = "/var/log/proftpd/jorge.log";
my $jhome = "/home/liveupload/jorge";
my $hlhome = "/home/liveupload/http-live";
my $lhome = "/home/liveupload/live";

unless (-p $fifo_file)
{
unlink $fifo_file;
system('mknod', $fifo_file, 'p') && die "can't mknod $fifo_file: $!";
system('chmod', '666', $fifo_file) && die "can't chown $fifo_file: $!";
}

my $fifo_fh;
open($fifo_fh, "+< $fifo_file") or die "The FIFO file \"$fifo_file\" is missing, and this program can't run without it.:$!";


setlogsock 'unix';
openlog($program, 'pid', $syslog_facility);

while (my $line = <$fifo_fh>) {
chomp $line;
if ($line eq $hlhome) {
print "$line\n" >> $httplivelog; }
elsif ($line eq $lhome) {
print "$line\n" >> $livelog; }
elsif ($line eq $jhome) {
print "$line\n" >> $jorgelog; }
else { print "The destination folder is invalid\n"; }
syslog($syslog_level, $_);
}

closelog();

close $fifo_fh;
exit(0);


The default syntax I just scrounged around for, but some of it I changed for my system. Perhaps my if loops may do nothing in the fifo context, but I get no errors, just no data is being logged into the files. I also understand this may not be the best way, but I was tasked to do this a certain way so following a few guidelines. I want the log folders to capture the variables I listed from the fifo data, into the other log folders.


Laurent_R
Veteran / Moderator

Oct 18, 2012, 2:33 PM

Post #7 of 14 (1989 views)
Re: [IlovePERL!] Seeking a few pointers in basic FIFO script [In reply to] Can't Post

Not sure to fuly understand what you are trying to do, but:


Code
if ($line eq $hlhome) { 
print "$line\n" >> $httplivelog; }


is not the Perl syntax to write to a file whose name is stored in the $httplivelog variable.

You need to open the output files with the open command and then write to the filehandler used to open these files with an instruction similar to this:


Code
print $OUT_FILE_FH  "$line\n";



IlovePERL!
Novice

Oct 18, 2012, 3:16 PM

Post #8 of 14 (1982 views)
Re: [Laurent_R] Seeking a few pointers in basic FIFO script [In reply to] Can't Post

Thank you for that miss!!! I see you're quite correct. I have updated my script with that in mind and will retest it.

Kind regards


IlovePERL!
Novice

Oct 18, 2012, 4:32 PM

Post #9 of 14 (1976 views)
Re: [IlovePERL!] Seeking a few pointers in basic FIFO script [In reply to] Can't Post

Hello, does this like the correct syntax using fh's?

#!/usr/bin/perl -w

use strict;
use warnings;
use File::Basename qw(basename);
use Sys::Syslog qw(:DEFAULT setlogsock);

my $fifo_file= "/var/log/xferlog.fifo";
my $syslog_facility = 'daemon';
my $syslog_level ='info';
my $program= "proftpd";
my $hlhome= "/home/liveupload/http-live";
my $lhome= "/home/liveupload/live";
my $jhome= "/home/liveupload/jorge";
my $httpdlivelog = "/var/log/proftpd/live-http.log";
my $jorgelog = "/var/log/proftpd/jorge.log";
my $livelog = "/var/log/proftpd/live.log";

my $httpdlivelog_fh;
open($httpdlivelog_fh, ">+ $httpdlivelog");

my $livelog_fh;
open($livelog_fh, ">+ $livelog");

my $jorgelog_fh;
open($jorgelog_fh, ">+ $jorgelog");

unless (-p $fifo_file)
{
unlink $fifo_file;
system('mknod', $fifo_file, 'p') && die "can't mknod $fifo_file: $!";
system('chmod', '666', $fifo_file) && die "can't chown $fifo_file: $!";
}

my $fifo_fh;
open($fifo_fh, "+< $fifo_file") or die "The FIFO file \"$fifo_file\" is missing, and this program can't run without it.:$!";


setlogsock 'unix';
openlog($program, 'pid', $syslog_facility);

while (my $lines = <$fifo_fh>) {
chomp $lines;
if ($lines eq $hlhome) {
print $httpdlivelog_fh "$lines\n"; }
elsif ($lines eq $lhome) {
print $livelog_fh "$lines\n"}
elsif ($lines eq $jhome) {
print $jorgelog_fh "$lines\n";}
else { print "The destination folder is invalid\n"; }
}

closelog();

close $fifo_fh;

As of now the script shows no perl errors, and seems to run. However, it only displays the else option, saying invalid folders. The folder uploaded is correct, so I'm guessing it's actually the
"chomp $lines;" and parsing of the $lines syntax. Still have not gotten it to run correctly.


FishMonger
Veteran / Moderator

Oct 18, 2012, 5:01 PM

Post #10 of 14 (1971 views)
Re: [IlovePERL!] Seeking a few pointers in basic FIFO script [In reply to] Can't Post

Please use the code tags when posing your code so that its formatting is retained.

Is it your intention to overwrite those 3 logfiles each time you run this script? I ask because that's what you're doing. I suspect that you really want to append to those files, not overwrite them.

You should use the 3 arg form of open and ALWAYS check the return code to verify that it was successful and take action if it wasn't.


Code
open my $httpdlivelog_fh, '>', $httpdlivelog or die "failed to open '$httpdlivelog' <$!>";


What version of perl are you using?


FishMonger
Veteran / Moderator

Oct 18, 2012, 5:04 PM

Post #11 of 14 (1970 views)
Re: [IlovePERL!] Seeking a few pointers in basic FIFO script [In reply to] Can't Post

You should dump/output $lines to see if it holds what you expect, which it most likely doesn't.


Laurent_R
Veteran / Moderator

Oct 19, 2012, 5:23 AM

Post #12 of 14 (1963 views)
Re: [FishMonger] Seeking a few pointers in basic FIFO script [In reply to] Can't Post

Yes, judging from the original shell-like syntax of the print instructions, it seems the intention is to append new text to the file rather than over-riding the previous content. In this case, the file-open mode should be append ('>>') rather than '>'.


IlovePERL!
Novice

Oct 23, 2012, 2:49 PM

Post #13 of 14 (1941 views)
Re: [Laurent_R] Seeking a few pointers in basic FIFO script [In reply to] Can't Post

Hi, sorry I was in the hospital for medical issues. I'd like to say thank you very much for all the help!! My script indeed worked fine once I used the proper fh syntax. Much thanks to fishmonger / laurenT!! Very nice and helpful individuals, I'll post the code just in case someone has similar issues. I ended up using a bash cut command as well;

#!/usr/bin/perl -w

use strict;
use File::Basename qw(basename);
use Sys::Syslog qw(:DEFAULT setlogsock);

$|=1;
my $fifo_file = "/var/log/proftpd/xferlog.fifo";
my $program = "xfer_ftp";

my $jhome = "/jorge";
my $livehome = "/live";
my $httphome = "/http-live";

my @logs = qw(/home/jorge.log /home/live.log /home/http.log);

my $jorge_fh;
open($jorge_fh, ">> $logs[0]") or die "The file \"$logs[0]\" is not accessible.:$!";

my $livelog_fh;
open($livelog_fh, ">> $logs[1]") or die "The file \"$logs[1]\" is not accessible.:$!";

my $http_fh;
open($http_fh, ">> $logs[2]") or die "The file \"$logs[0]\" is not accessible.:$!";

my $fifo_fh;
open($fifo_fh, "+< $fifo_file") or die "The FIFO file \"$fifo_file\" is missing, and this program can't run without it.:$!";

setlogsock 'unix';

while (my $lines = <$fifo_fh>) {
chomp($lines);
my @values = split(/ +/, $lines);
my $folders = `printf "$values[8]" | cut -d/ -f1,4`;
chomp($folders);
if ($folders eq $jhome) {
print $jorge_fh "@values\n"; }
elsif ($folders eq $livehome) {
print $livelog_fh "@values\n"; }
elsif ($folders eq $httphome) {
print $http_fh "@values\n"; }
else { print "The folder specified for upload is invalid, contact the system administrator, possible security breach.\n"; }
}

close $fifo_fh;
close $jorge_fh;
close $livelog_fh;
close $http_fh;

exit(0);


Laurent_R
Veteran / Moderator

Oct 24, 2012, 1:14 AM

Post #14 of 14 (1934 views)
Re: [IlovePERL!] Seeking a few pointers in basic FIFO script [In reply to] Can't Post

As a matter of personal taste, I would not do this:


Code
my $folders = `printf "$values[8]" | cut -d/ -f1,4`;


but use the perl split function to get the relevant fields with something like this:


Code
my ($part1, $part4); 
($part1,, undef, undef, $part4) = split '/', $value[8];
print "$part1 $part4";


or, if you really insist on keeping it concise, this somewhat less readable syntax using an anonymous array:


Code
print @{[split '/', $value[8]]}[qw (0 3)];


 
 


Search for (options) Powered by Gossamer Forum v.1.2.0

Web Applications & Managed Hosting Powered by Gossamer Threads
Visit our Mailing List Archives