]> git.treefish.org Git - fex.git/blob - bin/logwatch
Original release 20150120
[fex.git] / bin / logwatch
1 #!/usr/bin/perl -w
2
3 use Encode;
4 use File::Basename;
5 use Cwd 'abs_path';
6 use I18N::Langinfo qw'langinfo CODESET';
7
8 # add fex lib
9 unless ($FEXLIB = $ENV{FEXLIB}) {
10   if ($ENV{FEXHOME}) {
11     $FEXLIB = $ENV{FEXHOME}.'/lib';
12   } elsif (-f '/usr/share/fex/lib/fex.ph') {
13     $FEXLIB = '/usr/share/fex/lib';
14   } else {
15     $FEXLIB = dirname(dirname(abs_path($0))).'/lib';
16   }
17   $ENV{FEXLIB} = $FEXLIB;
18 }
19 die "$0: no $FEXLIB\n" unless -d $FEXLIB;
20
21 # import from fex.pp
22 our ($logdir,$spooldir,$debug);
23
24 # load common code, local config : $HOME/lib/fex.ph
25 require "$FEXLIB/fex.pp" or die "$0: cannot load $FEXLIB/fex.pp - $!\n";
26
27 $CTYPE = langinfo(CODESET());
28 binmode(STDOUT,":encoding($CTYPE)");
29
30 $log = shift || "$logdir/fexsrv.log";
31
32 $ignore = join('|',qw(
33   (CONNECT|CONTINUE).*(crawl|msnbot|obertux)
34   DISCONNECT:.no.HTTP.request
35   GET.*(favicon|robots\.txt)
36   GET./organization\.gif
37   GET./small_logo\.jpg
38   GET./logo\.jpg
39   GET./action-fex-camel\.gif
40   GET./fup\?showstatus
41   GET./FAQ/faq\.css
42   GET./FAQ/jquery\.js
43   GET./10+.B
44   GET.*Arrow\.gif
45   GET./apple-touch
46   User-Agent:.*(Webnote|FeedFetcher|\w+bot|bot/|Website.Watcher|crawler|spider|searchme|Yandex|Slurp|ScoutJet|findlinks|urlmon|nagios)
47   User-Agent:.fnb.*quak
48   From:.*(msnbot|yandex|googlebot|webcrawler)
49   Referer:.*sex.*stream
50   Referer:.*stream.*sex
51   X-.*prefetch
52   X-Purpose:.preview
53 ));
54
55 @weed = qw(
56   .*keep-alive
57   .*no-cache
58   Connection:
59   Cache-Control:
60   Content-Type:
61   Accept
62   TE:
63   UA-CPU:
64   Pragma:
65   DNT:
66   Via:
67   profile:
68   if-modified-since
69   Surrogate-Capability
70   Proxy-Authorization
71   http\.
72   NOKIA_
73   GPRS
74   X-Proxy-ID
75   X-Moz
76   X.Wap
77   X-FH
78   X-Nokia
79   X-UCBrowser
80   X-NSN
81   X-OperaMini
82   x-Device
83   x-source-id
84   x.up
85   X-Behavioral
86   X-Do-Not-Track
87   X-\S*Via
88   x-Mobile
89   X-Country
90   X-ClickOnceSupport
91   .*:\s*$
92 );
93
94 $/ = "\n\n"; 
95 $| = 1;
96
97 if (-t STDIN or $ENV{GATEWAY_INTERFACE}) {
98   open L,$log or die "$0: $log - $!\n";
99   seek L,0,2;
100 } else {
101   *L = *STDIN;
102 }
103 # binmode(L,":encoding(UTF-8)");
104
105 for (;;) {
106   while (<L>) {
107     next if /(^|\n)($ignore)/i;
108     s/[\x00-\x08\x0B-\x1F\x1F\x80-\x9F]/_/g;
109     s/^\n//;
110     foreach $weed (@weed) {
111       while (s/\n$weed.*\n/\n/i) {}
112     }
113     if (/^\n*(CONNECT|CONTINUE).*\s\[([\d_]+)\]/i) { $pid = $2 }
114     if (/\n(POST|GET)\s+\/(\w+)/i)                 { $cgi = $2 }
115     if (/Content-Length: (\d+)/i) {
116       $d = $1;
117       while ($d =~ s/(\d)(\d\d\d\b)/$1,$2/) {};
118       s/Content-Length: \d+/Content-Length: $d/i;
119     }
120     s/[\s\n]*$/\n\n/;
121     print or exit;
122     $from = '';
123     if (m:\nGET /fup/(\w{40,}):) {
124       $_ = decode_b64($1);
125       printf "  FROM=\"%s\"\n\n",$1 if /from=([\w\@.-]+)/;
126     } elsif (m:\nGET /fop/(\w+)/:) {
127       $dkey = $1;
128       my $ddir = "$spooldir/.dkeys/$dkey";
129       $_ = readlink $ddir or next;
130       (undef,$to,$from) = split('/');
131       printf "  FROM=\"%s\"\n",$from;
132       printf "  TO=\"%s\"\n",$to;
133       $cgi = '';
134       if ($comment = slurp("$ddir/comment")) {
135         printf "  COMMENT=\"%s\"\n",decode_utf8($comment,0)||'';
136       }
137       if (not -f "$ddir/data" and $_ = slurp("$ddir/error")) {
138         s/\n.*//s;
139         print "  ERROR=\"$_\"\n";
140       }
141       elsif ($size = -s "$ddir/data") {
142         printf "  SIZE=%s MB\n",int($size/1024/1024);
143       }
144       print "\n";
145     } elsif (m:\nGET /fup.*skey=(\w+):) {
146       read_skey($1);
147       print "\n";
148     }
149   }
150   sleep 1;
151   if ($debug and $pid and $cgi) {
152     &read_debug_log;
153     $pid = $cgi = '';
154   };
155 }
156
157
158 sub read_debug_log {
159   my (@log,$log);
160   local $/ = "\n";
161   local $_;
162   local $^W;
163   # no warnings "all";
164
165   for (1..2) {
166     sleep 1;
167     @log = `ls -rt $logdir/.debug/*_${pid}.$cgi 2>/dev/null`;
168     if ($log = $log[-1] and open $log,$log) {
169       # binmode($log,":encoding(UTF-8)");
170       while (<$log>) {
171         s/\r//;
172         if (/^Content-Disposition:.*name="FILE".*filename="(.+)"/i) {
173           print "  FILE=\"$1\"\n";
174         } elsif (/^Content-Disposition:.*name="(\w+)"/i) {
175           my $p = uc($1);
176           $_ = <$log>;
177           my $v = <$log>||'';
178           $v =~ s/[\r\n]+//;
179           printf "  %s=\"%s\"\n",$p,decode_utf8($v,0)||$v if $v;
180           read_akey($v) if $p eq 'AKEY';
181           read_skey($v) if $p eq 'SKEY';
182         } elsif (/^(Param|Exp): (\w+=".+")/) {
183           print "  $2\n";
184         }
185       }
186       close $log;
187       print "\n";
188       return;
189     }
190   }
191 }
192
193 sub read_akey {
194   my $akey = "$spooldir/.akeys/" . shift;
195   if (my $user = readlink($akey)) {
196     $user =~ s:../::;
197     printf "  USER=\"%s\"\n",$user;
198   }
199 }
200
201
202 sub read_skey {
203   my $skey = "$spooldir/.skeys/" . shift;
204   if (open $skey,$skey) {
205     while (<$skey>) {
206       printf "  FROM=\"%s\"\n",$1 if /from=(.+)/;
207       printf "  TO=\"%s\"\n",$1   if /to=(.+)/;
208     }
209     close $skey;
210   }
211 }