Processing a while within a while

R

Russell.Mottram

Hi,

I'm currently studying a relatively basic PERL course, and have an end
of semester assignment due very soon.
I've managed to get through everything so far, except I'm now stuck on
the very last bit, which is printing a comparison between two hashes.

Essentially, the problem is this:

The system log (system.evt) has been searched for Telnet entries, and
positive matches have been moved into %TelnetEntry.

Then the security log (security.evt) has been searched for users who
were logged on at the time, excluding Network Service, Local Service,
and one other random user. Users have been moved into %SecTime.

I now need to iterate through both to determine at the time the Telnet
service was started, who was logged on?

This is the code I'm working on:

while (($TelnetTime,$Telnetvalue)= each(%TelnetEntry))
{
while (($SecTime,$SecUser) = each(%SecTime))
{
if ($SecTime < $TelnetTime) # If the time the user logged on is less
than the time that Telnet was started, then do the following:
{
print "\n";
print "The Telnet Service was run by $SecTime{$SecTime}"; #
Prints the user logged on at that time.
print "\n";
print "The time was: ".scalar localtime $TelnetTime; # Prints the
time that Telnet was started. The key and value are the same in this
hash.
print "\n";
}
}
}

I'm pretty sure the problem lies in - if ($SecTime < $TelnetTime) - as
the current result of this code running is that all of the values in
both tables are printing out.

We haven't covered while loops inside while loops in much detail, and
I can't help but think that this problem is so easy that I'm going to
be quite annoyed when it is actually figured out. I know something is
missing!!

Please help... ASAP if possible :)

Cheers

Russ
 
P

Peter Wyzl

Hi,

I'm currently studying a relatively basic PERL course, and have an end
of semester assignment due very soon.
I've managed to get through everything so far, except I'm now stuck on
the very last bit, which is printing a comparison between two hashes.

Essentially, the problem is this:

The system log (system.evt) has been searched for Telnet entries, and
positive matches have been moved into %TelnetEntry.

Then the security log (security.evt) has been searched for users who
were logged on at the time, excluding Network Service, Local Service,
and one other random user. Users have been moved into %SecTime.

I now need to iterate through both to determine at the time the Telnet
service was started, who was logged on?

This is the code I'm working on:

while (($TelnetTime,$Telnetvalue)= each(%TelnetEntry))
{
while (($SecTime,$SecUser) = each(%SecTime))
{
if ($SecTime < $TelnetTime) # If the time the user logged on is less
than the time that Telnet was started, then do the following:
{
print "\n";
print "The Telnet Service was run by $SecTime{$SecTime}"; #
Prints the user logged on at that time.
print "\n";
print "The time was: ".scalar localtime $TelnetTime; # Prints the
time that Telnet was started. The key and value are the same in this
hash.
print "\n";
}
}
}

I'm pretty sure the problem lies in - if ($SecTime < $TelnetTime) - as
the current result of this code running is that all of the values in
both tables are printing out.

We haven't covered while loops inside while loops in much detail, and
I can't help but think that this problem is so easy that I'm going to
be quite annoyed when it is actually figured out. I know something is
missing!!

Please help... ASAP if possible :)

Do you have an example of what some of the data in those hashes actually
looks like? Without seeing that it is a bit hard to tell. One common
problem is forgetting to chomp entries into one of the hashes so you do a
numeric comparison on a string which isn't what you are really trying to
do... But it could be something else entirely.

P
 
R

Russell.Mottram

Thanks for replying! I was hoping someone would soon :)

Here is the contents of %TelnetEntry:

11929403381192940338
11917632661191763266
11905538451190553845
11929809061192980906
11924529191192452919
11917583541191758354
11924529301192452930
11905536661190553666
11929792871192979287
11917581701191758170
11905527891190552789
11929533691192953369
11924527891192452789
11929534021192953402
11917579801191757980
11929746761192974676
11930031091193003109
11924529091192452909
11924527951192452795

And here is the contents of %SecTime:

1192658788default
1192571374default
1192950646Sally
1192832626default
1193002890Geoff
1192510043default
1192953674default
1192784691default
1192708778default
1193002332default
1192865201default
1192921241default
1192744166default
1192950649Sally
1192708779default
1193003814default
1192949678default
1192679121default
1192744165default
1192510044default
1192953673default
1192865204default
1192489060default
1192658787default
1192953485Sally
1192950582default
1192950864default
1192397205default
1192888366default
 
S

sheinrich

On Nov 13, 1:54 pm, (e-mail address removed) wrote:
....
I'm pretty sure the problem lies in - if ($SecTime < $TelnetTime) - as
the current result of this code running is that all of the values in
both tables are printing out.
....

The timestamps from the logs which are usually a human readable
representation must be converted to either system ticks or, more easy,
to a comparable string representation like 'YYYYMMHHSS'.

Both can be taken for numerical comparison, but only the latter for a
string comparison (cmp) which is the default for the sort() function.

Cheers,
Steffen
 
R

Russell.Mottram

I used this to get the User ID out of the security log file:

$SecUser=substr($securitymessage,33,10);
$SecUser =~ s/\s*$//;
 
R

Russell.Mottram

Hey,

I've been working with the timestamps as whatever the format is called
when it's however many seconds have passed since January 1 1970.
 
P

Peter Wyzl

Thanks for replying! I was hoping someone would soon :)

Here is the contents of %TelnetEntry:

11929403381192940338
11917632661191763266
11905538451190553845
11929809061192980906
11924529191192452919
11917583541191758354
11924529301192452930
11905536661190553666
11929792871192979287
11917581701191758170
11905527891190552789
11929533691192953369
11924527891192452789
11929534021192953402
11917579801191757980
11929746761192974676
11930031091193003109
11924529091192452909
11924527951192452795

And here is the contents of %SecTime:

1192658788default
1192571374default
1192950646Sally
1192832626default
1193002890Geoff
1192510043default
1192953674default
1192784691default
1192708778default
1193002332default
1192865201default
1192921241default
1192744166default
1192950649Sally
1192708779default
1193003814default
1192949678default
1192679121default
1192744165default
1192510044default
1192953673default
1192865204default
1192489060default
1192658787default
1192953485Sally
1192950582default
1192950864default
1192397205default
1192888366default

Ok, so the problem here is not your code, its your algorithm. Basically
what is happening, is that for progressively greater values in %TelnetTime,
you are matching more and more entries in %SecTime, since you are only doing
a simple lessthan comparison. Think of it this way...

One list contains values from 1 to 3, and so does the other. If we loop
through the first list and for every value in that list loop through the
second list to see if it is a lower value, the output will be something
like:

1 < 1 False
1 < 2 False
1 < 3 False
2 < 1 True
2 < 2 False
2 < 3 False
3 < 1 True
3 < 2 True
3 < 3 False

So in that simple scenario we print 3 outputs (one for each True) so the
output would be 1, 2, 3...

You need to define a better algorithm for determining what is going on...
and probably something that showed all the people logged on for each time
might actually be more useful.

This might illustrate more clearly what is happening...and bear in mind this
doesn't sort the timestamps which would make sense...

while (($TelnetTime,$Telnetvalue)= each(%TelnetEntry)){
print "Telnet started at " .scalar localtime $TelnetTime;
while (($SecTime,$SecUser) = each(%SecTime)){
if ($SecTime < $TelnetTime) {
print "\n$SecTime{$SecTime} was logged on";
}
}
print "\n";
}


Hope that helps...

P
 
P

Peter Wyzl

<snip>

One list contains values from 1 to 3, and so does the other. If we loop
through the first list and for every value in that list loop through the
second list to see if it is a lower value, the output will be something
like:

1 < 1 False
1 < 2 False
1 < 3 False
2 < 1 True
2 < 2 False
2 < 3 False
3 < 1 True
3 < 2 True
3 < 3 False


Course for this illustration those should actually be > or the list is back
to front... gah!

P
 
R

Russell.Mottram

Thank you very much! My frustrations are over. It does make a lot more
sense!

Now I just have to clean it up a bit and that's it!

Have a great day!
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,482
Members
44,901
Latest member
Noble71S45

Latest Threads

Top