fix log and sh/dx ordering issues.
[spider.git] / perl / DXLogPrint.pm
1 #
2 # Log Printing routines
3 #
4 # Copyright (c) - 1998 Dirk Koopman G1TLH
5 #
6 #
7 #
8
9 package DXLog;
10
11 use 5.10.1;
12
13 use IO::File;
14 use DXVars;
15 use DXDebug qw(dbg isdbg);
16 use DXUtil;
17 use DXLog;
18 use Julian;
19
20
21 our $readback = 1;
22 if ($readback) {
23         $readback = `which tac`;
24
25 chomp $readback;
26 #undef $readback;                               # yet another reason not to use the cloud!
27  
28
29 use strict;
30
31 use vars qw($maxmonths);
32 $maxmonths = 36;
33
34 #
35 # print some items from the log backwards in time
36 #
37 # This command outputs a list of n lines starting from time t with $pattern tags
38 #
39 sub print
40 {
41         my $fcb = $DXLog::log;
42         my $from = shift || 0;
43         my $to = shift || 10;
44         my $jdate = $fcb->unixtoj(shift);
45         my $pattern = shift;
46         my $who = shift;
47         my $search;
48         my @in;
49         my @out = ();
50         my $eval;
51         my $tot = $from + $to;
52         my $hint = "";
53             
54         $who = uc $who if defined $who;
55
56         if ($pattern) {
57                 $hint = q{m{\Q$pattern\E}i};
58         } else {
59                 $hint = q{!m{\^(?:ann|rcmd|talk|chat)\^}};
60         }
61         if ($who) {
62                 $hint .= ' && ' if $hint;
63                 $hint .= q{m{\Q$who\E}oi};
64         } 
65         $hint = "next unless $hint" if $hint;
66         $hint .= "; next unless m{^\\d+\\^$pattern\\^}" if $pattern;
67         $hint ||= "";
68         
69         $eval = qq(while (<\$fh>) {
70                                    $hint;
71                                    chomp;
72                    # say "line: \$_";
73                                    push \@in, \$_;
74                    last L1 if \@in >= $tot;
75                            } );
76         
77         if (isdbg('search')) {
78                 dbg("sh/log hint: $hint");
79                 dbg("sh/log eval: $eval");
80         }
81         
82         $fcb->close;                                      # close any open files
83
84         my $months;
85         my $fh;
86         if ($readback) {
87                 my $fn = $fcb->fn($jdate);
88                 $fh = IO::File->new("$readback $fn |");
89         } else {
90                 $fh = $fcb->open($jdate);       
91         }
92  L1: for ($months = 0; $fh && $months < $maxmonths && @in < $tot; $months++) {
93                 my $ref;
94
95                 if ($fh) {
96                         my @tmp;
97                         eval $eval;               # do the search on this file
98                         return ("Log search error", $@) if $@;
99                 }
100
101                 if ($readback) {
102                         my $fn = $fcb->fn($jdate->sub(1));
103                         $fh = IO::File->new("$readback $fn |");
104                 } else {
105                         $fh = $fcb->openprev();      # get the next file
106                 }
107         }
108
109         unless (@in) {
110                 my $name = $pattern ? $pattern : "log";
111                 my $s = "$who "|| '';
112                 return "show/$name: ${s}not found";
113         } 
114
115         for (sort {$a <=> $b } @in) {
116                 my @line = split /\^/ ;
117                 push @out, print_item(\@line);
118         
119         }
120         return @out;
121 }
122
123
124 #
125 # the standard log printing interpreting routine.
126 #
127 # every line that is printed should call this routine to be actually visualised
128 #
129 # Don't really know whether this is the correct place to put this stuff, but where
130 # else is correct?
131 #
132 # I get a reference to an array of items
133 #
134 sub print_item
135 {
136         my $r = shift;
137         my $d = atime($r->[0]);
138         my $s = 'undef';
139         
140         if ($r->[1] eq 'rcmd') {
141                 $r->[6] ||= 'Unknown';
142                 if ($r->[2] eq 'in') {
143                         $r->[5] ||= "";
144                         $s = "in: $r->[4] ($r->[6] priv: $r->[3]) rcmd: $r->[5]";
145                 } else {
146                         $r->[4] ||= "";
147                         $s = "$r->[3] $r->[6] reply: $r->[4]";
148                 }
149         } elsif ($r->[1] eq 'talk') {
150                 $r->[5] ||= "";
151                 $s = "$r->[3] -> $r->[2] ($r->[4]) $r->[5]";
152         } elsif ($r->[1] eq 'ann' || $r->[1] eq 'chat') {
153                 $r->[4] ||= "";
154                 $r->[4] =~ s/^\#\d+ //;
155                 $s = "$r->[3] -> $r->[2] $r->[4]";
156         } else {
157                 $r->[2] ||= "";
158                 $s = "$r->[2]";
159         }
160         return "$d $s";
161 }
162
163 1;