# Local defines sub msgdb { return "c:\\fido\\hpt\\dupebase\\plduper.db"; } sub pktdb { return "c:\\fido\\hpt\\dupebase\\plduperpkt.db"; } sub nldb { return "c:\\fido\\nodelist\\nodelist.db"; } sub faq { return "c:\\fido\\itrack\\faq\\"; } sub route94 { return "c:\\user\\gul\\work\\routing\\route.94"; } sub sechubs { return "c:\\fido\\nodelist\\2nd_hubs.463"; } sub echol463 { return "c:\\user\\gul\\work\\echolist.463"; } sub listdir { return "c:\\fido\\hpt\\"; } sub listname { return "5020_238.avl" if $_[0] eq "2:5020/238"; return "5020_1381.avl" if $_[0] eq "2:5020/1381"; return "94.avl" if $_[0] eq "2:463/94"; return "58.avl" if $_[0] eq "2:463/58"; return ""; } sub maillists { return ( "Staff", "Postmaster", "Admin", "Noc", "Hostmaster", "Cert", "Bugtraq", "Mutt-dev", "Registry" ); } use DB_File; use Fcntl ":flock"; use POSIX; #use strict; # predefined variables #my($fromname, $toname, $fromaddr, $toaddr, $subject, $date, $text, $attr); #my($secure, $pktname, $rc, $res, $area, $pktfrom, $addr, $from); #my($kill, $change, $flavour); # My global variables my(%nodelist, $nltied); my(%pkt, $pkttied, %msg, $msgtied, $newnet, $newecho, @crc_32_tab); my($processpktname, $pktkey, $pktval, %msgpkt, $curnodelist, @areas); sub filter { # predefined variables: # $fromname, $fromaddr, $toname, # $toaddr (for netmail), # $area (for echomail), # $subject, $text, $pktfrom, $date, $attr # $secure (defined if message from secure link) # return "" or reason for moving to badArea # set $kill for kill the message (not move to badArea) # set $change to update $text, $subject, $fromaddr, $toaddr, $fromname, $toname my(@hf, @mypoints, @lines, $firstpath, $lastpath, @path, $origin); my(@lastpath, $net, @origin, $msgid, $msgidfrom, $approved, $path); my($key, $oldval, $fromboss, $toboss, $knownpoint, $fname, $time, @myaddr); my($oldtime, $oldpath, $oldpktfrom, $curtime, $dupetext, @roechoes); local(*F); @hf = qw( 2:5020/113 2:5020/32 2:5020/140 2:5020/50.40 2:5020/50.140 2:5020/140.1 2:5020/35 2:5020/35.1 2:5000/13 2:5000/44 2:5020/293 2:5020/1040 2:5020/443 2:5020/517 ); @mypoints = qw( 2:463/68 2:463/68.1 # Yutta 2:463/68.2 # son 2:463/68.3 # Bor Mal 2:463/68.4 # Voronov 2:463/68.5 # Ksyu 2:463/68.8 # Sergey Iovov (/8.2) 2:463/68.9 # Kussul 2:463/68.11 # Brun 2:463/68.12 2:463/68.13 # Maxim Obukhov 2:463/68.17 # Kalina 2:463/68.18 # Andrew Ilchenko 2:463/68.26 # Dmitry Rachkovsky 2:463/68.27 # Andrey Zinin 2:463/68.28 # Jean Kantoroff 2:463/68.32 # dk 2:463/68.36 # Valentin Klinduh 2:463/68.41 # Motus 2:463/68.45 # Artem Kulakov Sergei Shevyryov 2:463/68.47 # Parkhom 2:463/68.50 # Rozhko 2:463/68.62 # Victor Cheburkin /62 2:463/68.67 # Alexey Suhoy /67 2:463/68.92 # Andrey Ichtchenko 2:463/68.108 # Vitaliy Oleynik 2:463/68.114 # Валерий Дмитриевич и Людмила Сергеевна Кузнецовы 2:463/68.128 # gate 2:463/68.141 # Sergey Skorodinsky 2:463/68.163 # Den Dovgopoly 2:463/68.196 # Tverskaya flat 2:463/68.200 # Michael Bochkaryov 2:463/68.586 # eug@lucky.net 2:463/68.690 # Al Poduryan 2:463/68.702 # Miroslav Narosetsky ); @roechoes = qw( 1072.Compnews BOCHAROFF.MUST.DIE BOCHAROFF.UNPLUGGED DIG.LINUX JET.PHRASES HUMOR.FILTERED GUITAR.SONGS.FILTERED OBEC.FILTERED PVT.EXLER.FILTERED RU.ANEKDOT.FILTERED RU.ANEKDOT.THE.BEST RU.AUTOSTOP.INFO RU.SPACE.NEWS RU.UFO.THEORY RU.WINDOWS.NT.NEWS SPB.HUMOR SPB.SYSOP.FILTERED SU.CRISIS.SITUATION SU.FORMULA1.INFO SU.OS2.FAQ SU.WIN95.NEWS ); @myaddr = &myaddr; if (defined($area)) { unless ($pktfrom =~ /^(2:463\/94(\.0)?|2:5020\/238(\.0)?)$/) { # from downlink foreach(@roechoes) { if ($area eq $_) { putMsgInArea("UNSECURE", $fromname, $toname, $fromaddr, $toaddr, $subject, $date, "pvt sent read", "hpt> Posting to r/o echo $area\r" . $text, 0); $kill = 1; return "Posting to r/o echo $area"; } } } $text =~ s/\r\n/\r/gs; @lines = split('\r', $text); $firstpath = $lastpath = $origin = $msgidfrom = ""; @path = grep(/^\x01PATH: /, @lines); $firstpath = "2:$1" if $path[0] =~ /^\x01PATH: (\S+)/; $lastpath = pop(@path); $lastpath =~ s/^\x01PATH: //; @lastpath = split(/\s+/, $lastpath); foreach(@lastpath) { $net = $1 if m#^(\d+)/\d+$#; $_ = "$net/$_" if /^\d+$/; $lastpath = $_; } $lastpath = "2:$lastpath" if $lastpath; @lastpath = (); @origin = grep(/^ \* Origin: .*\(.*\)\s*$/, @lines); if (@origin) { $origin = pop(@origin); @origin = (); if ($origin =~ /\(([0-9:\/\.]+)(\@[A-Za-z0-9.\-]+)?\)\s*$/) { $origin = $1; } else { undef($origin); @origin = (); } } ($msgid) = grep(/^\x01MSGID:/, @lines); $msgidfrom = $1 if $msgid =~ /^\x01MSGID: ([0-9:\/\.])+(\@\S+)? /; if ($area eq "HUMOR.FILTERED") { $approved = 0; foreach (@hf) { $approved = 1 if $firstpath eq $_ || $origin eq $_ || $msgidfrom eq $_; } unless ($approved) { putMsgInArea("UNSECURE", $fromname, $toname, $fromaddr, $toaddr, $subject, $date, "pvt sent read", "hpt> Unapproved message in $area\r" . $text, 0); $kill = 1; return "Unapproved message in $area"; } } elsif ($area =~ /^PVT\.EXCH\./) { unless ($lastpath =~ m/^2:50/) { if ($origin =~ /^2:46/) { putMsgInArea("UNSECURE", $fromname, $toname, $fromaddr, $toaddr, $subject, $date, "pvt sent read", "hpt> R46 is r/o in PVT.EXCH.*\r" . $text, 0); $kill = 1; return "R46 is r/o in PVT.EXCH.*"; } } } elsif ($area eq "NET463.COORD") { if ($fromname eq "Routing Poster" && $fromaddr eq "2:463/94.0") { if (open(F, ">".route94)) { foreach(grep(!/^(\x01|SEEN-BY:)/, @lines)) { print F "$_\n"; } close(F); } } } elsif ($area eq "N463.SYSOP" && $fromname eq "N463EC" && $fromaddr eq "2:463/11.0") { $fname = ""; if ($subject eq "secondaries") { $fname = sechubs; } elsif ($subject eq "echolist") { $fname = echol463; } if ($fname && open(F, ">$fname")) { foreach(grep(!/^(\x01|SEEN-BY:)/, @lines)) { print F "$_\n"; } close(F); } } # Dupecheck unless ($msgtied) { if (tie(%msg, 'DB_File', msgdb, O_RDWR|O_CREAT, 0644)) { $msgtied = 1; } else { $newecho = 1; return ""; } } if ($msgid) { $msgid =~ s/^\x01MSGID:\s*//; $msgid =~ tr/A-Z/a-z/; } else { $msgid = sprintf("C%s %08x", $fromaddr, crc32($date . join(' ',grep(!/^(\x01PATH|SEEN-BY):/,@lines)))); } $key = "$area|$msgid|" . crc32($fromname . $toname . $subject); $path = ""; foreach(grep(/^\x01PATH: /, @lines)) { s/^\x01PATH:\s*//; $path .= " " if $path; $path .= $_; } $curtime = time(); if (defined($msg{$key}) || defined($msgpkt{$key})) { # Dupe if (defined($msg{$key})) { $oldval = $msg{$key}; } else { $oldval = $msgpkt{$key}; } ($oldtime, $oldpath, $oldpktfrom) = split(/\|/, $oldval); $dupetext = < FileAttach from unsecure link\r" . $text, 0); $kill = 1; return "FileAttach from unsecure link"; } if ($fromaddr =~ /^(2:463\/68|2:46\/128)(\.\d+)?$/) { putMsgInArea("UNSECURE", $fromname, $toname, $fromaddr, $toaddr, $subject, $date, "pvt sent read", "hpt> Unprotected message from my system\r" . $text, 0); $kill = 1; return "Unprotected message from my system"; } compileNL() unless $nltied; if ($nltied && !defined($nodelist{$fromboss})) { putMsgInArea("UNSECURE", $fromname, $toname, $fromaddr, $toaddr, $subject, $date, "pvt sent read", "hpt> Unprotected message from inlisted system\r" . $text, 0); $kill = 1; return "Unprotected message from unlisted system"; } unless ($toaddr =~ /^(2:463\/68(\.\d+)?|2:46\/128(\.\d+)?|2:463\/59\.4|17:.*)$/) { bounce($fromname, $fromaddr, $toname, $toaddr, $date, $subject, $text, "Unprotected outgoing message"); putMsgInArea("UNSECURE", $fromname, $toname, $fromaddr, $toaddr, $subject, $date, "pvt sent read", "hpt> Unprotected outgoing message\r" . $text, 0); $kill = 1; return "Unprotected outgoing message"; } } if ($toboss eq $myaddr[0]) { $knownpoint = 0; foreach(@mypoints) { $knownpoint = 1 if $_ eq $toaddr; } unless ($knownpoint) { bounce($fromname, $fromaddr, $toname, $toaddr, $date, $subject, $text, "Unknown point"); putMsgInArea("BADMAIL", $fromname, $toname, $fromaddr, $toaddr, $subject, $date, "pvt sent read", "hpt> Unknown point\r" . $text, 0); $kill = 1; return "Unknown point"; } } if ($toaddr eq $myaddr[0]) { # check maillists foreach (maillists) { if ($toname eq $_) { s/ //; tr/A-Z/a-z/; s/^(........).*$/$1/; putMsgInArea($_, $fromname, $toname, $fromaddr, $toaddr, $subject, $date, "pvt sent read", $text, 0); $kill = 1; return "Maillist $toname"; } } if ($toname =~ /^ping$/i) { if (isattr("cpt", $attr)) { putMsgInArea("BADMAIL", $fromname, $toname, $fromaddr, $toaddr, $subject, $date, "pvt sent read", "hpt> Ping request with RRC\r" . $text, 0); $kill = 1; return "Ping request with RRC"; } $text =~ s/\r\x01/\r\@/gs; $text =~ s/^\x01/\@/s; $time = localtime; $text = < FaqServer request with RRC\r" . $text, 0); $kill = 1; return "FaqServer request with RRC"; } faqserv($fromaddr, $fromname, $subject, $text); $newnet = 1; $kill = 1; return "Message to FaqServer"; } if (($fromname =~ /^(areafix|gecho|crashecho|areafix daemon|sqafix)$/i || $fromname =~ /echo manager/) && listname($fromaddr) ne "" && ($subject =~ /^(List request|List of areas available|List of available areas|AreaFix list of areas|AreaFix response|[Aa]reafix reply: (list request|available areas))/ || $subject =~ /^Your Areafix Request$/ && $text =~ /Areas available to|\001SPLITTED:/s && $text =~ /\r\n? \S+\r/s || $subject =~ /^Remote request operation report/ && $text =~ /areas available for|continued from the previous message/s || $subject =~ /Reply from Parma Tosser Echo Manager, part/)) { if ($subject eq "AreaFix response" && $text =~ /\r\n?%LIST.*\r\n?--- CrashEcho's AreaFix/s) { $kill = 1; return "CrashEcho's areafix response"; } if (@areas) { if ($areas[0] ne $fromaddr) { putlist(); @areas=($fromaddr); } } else { @areas=($fromaddr); } foreach (split(/\s*\r\n?/, $text)) { next if /^(\x01|SEEN-BY:)/; if ($subject =~ /^AreaFix list of areas/) # CrashEcho { if (/^ {15,}(\S(?:.*\S)?)\s+(?:\?|\d+)\s*$/ && $areas[1]) { $areas[@areas-1] .= " $1"; next; } } elsif (/^ {15,}(\S.*)$/ && $areas[1] && $subject =~ /Parma Tosser/) { $areas[@areas-1] .= " $1"; # or "$1", without space? next; } elsif (/^ {15,}(\S.*)$/ && $areas[1]) { $areas[@areas-1] .= " $1"; next; } if ($subject =~ /^List request/) { # FastEcho next unless /^[\* ] (\S+)(?:(?: \.*)? (\S.*))?\s*$/; push (@areas, "$1 $2"); next; } if ($subject =~ /^List of areas available/) { # FastEcho next unless /^([^() \*\'\-\[][^() *]*)(?: \.+ (\S.*))?\s*$/; push (@areas, "$1 $2"); next; } if ($subject =~ /^List of available areas/) { # GEcho next unless /^[+ ](\S+)(?: +(\S.*))?\s*$/; next if /^ '[+-]'/; push (@areas, "$1 $2"); next; } if ($subject =~ /^AreaFix list of areas/) { # CrashEcho next if /^ Group:/; next unless /^ (\S+)(?:\s+(\S(?:.*\S)?)?\s+(?:\?|\d+))?\s*$/; push (@areas, "$1 $2"); next; } if ($subject =~ /^Your Areafix Request/) { # Fidogate next unless /^[ *] [ R] (\S+)\s*$/; push (@areas, $1); next; } if ($subject =~ /^[Aa]reafix reply: list request/) { # hpt next unless /^[* ][R ]? (\S+)(?: \.* (\S.*))?\s*$/; push (@areas, "$1 $2"); next; } if ($subject =~ /^[Aa]reafix reply: available areas/) { # hpt next unless /^ (\S+)(?: \.* (\S.*))?\s*$/; push (@areas, "$1 $2"); next; } if ($subject =~ /^Remote request operation report/) { # SqaFix next unless /^(\S+) \.+ (?:Unlinked|Active ) \[\S\](?: (\S.*\S))?\s*$/; push (@areas, "$1 $2"); } if ($subject =~ /Parma Tosser/) { # Parma Tosser next if /^(Splitted by|--- |UpLink |Available areas|List of|Hello |Parma )/; if (/^([A-Za-z\.&\$0-9!'_\+\-]+)(?:(?: \.+)?\s+(\:Unlinked|Lined)\s+\[.\] (.*))?$/) { push(@areas, "$1 $2"); } } } $kill=1; return "List reply"; } if ($toname =~ /^(areafix|allfix|filefix)$/i) { if (isattr("cpt", $attr)) { putMsgInArea("BADMAIL", $fromname, $toname, $fromaddr, $toaddr, $subject, $date, "pvt sent read", "hpt> $toname request with RRC\r" . $text, 0) || ($kill = 1); return "$toname request with RRC"; } } else { if (isattr("rrq", $attr) || isattr("arq", $attr)) { receipt($fromaddr, $toaddr, $fromname, $toname, $subject, $date); } putMsgInArea("GUL", $fromname, $toname, $fromaddr, $toaddr, $subject, $date, "pvt sent read", $subject, $text, 0) || ($kill = 1); return "Message to gul"; } } else { # Transit message # Dupe- and loop- check opendupe(); if ($msgtied) { ($msgid) = grep(/^\x01MSGID:/, @lines); if ($msgid) { $msgid =~ s/^\x01MSGID:\s*//; $msgid =~ tr/A-Z/a-z/; } else { $msgid = sprintf("C%s %08x", $fromaddr, crc32($date . join(' ',grep(!/^(\x01(Via|Recd|Forwarded))(:|\s)/,@lines)))); } $key = sprintf("NETMAIL|%s|%s|%08x", $msgid, $toaddr, crc32($fromname . $toname . $subject)); $path = $lastpath = ""; foreach(grep(/^\x01(Via|Recd|Forwarded):?\s/, @lines)) { next unless m#(\d+:\d+/\d+(?:\.\d+)?)(\@|\s)#; next if $lastpath eq $1; $lastpath = $1; $path .= " " if $path; $path .= $1; } $curtime = time(); if ($oldval=checkdupe($key)) { # Dupe or Loop $dupetext = $text; $dupetext =~ s/\r\n?/\n/gs; ($oldtime, $oldpath, $oldpktfrom) = split(/\|/, $oldval); $oldtime = localtime($oldtime); if ($path eq $oldpath && $oldpktfrom eq $pktfrom) { # Dupe $dupetext = < loop\r" . $text, 0); $kill = 1; return "Loop"; } } adddupe($key, "$curtime|$path|$pktfrom"); } if (_route($toaddr, $attr, $text) eq $pktfrom) { # Route to pktfrom-addr -- ping-pong putMsgInArea("LOOPS", $fromname, $toname, $fromaddr, $toaddr, $subject, $date, "pvt sent read", "hpt> ping-pong with $pktfrom\r" . $text, 0); $kill = 1; return "Loop"; } if (isattr("arq", $attr)) { arqcpt($fromaddr, $toaddr, $fromname, $toname, $subject, $date, $attr, $text); } } $newnet = 1; return ""; } sub scan { # predefined variables: # $area, $fromname, $fromaddr, $toname, # $toaddr (for netmail), # $subject, $text, $date, $attr # return "" or reason for dont packing to downlinks # set $change to update $text, $subject, $fromaddr, $toaddr, $fromname, $toname my ($toboss, $addr, $msgid, $key); my ($oldtime, $oldpath, $oldpktfrom, $dupetext); if ($toaddr eq "") { # echomail unless ($msgtied) { tie(%msg, 'DB_File', msgdb, O_RDWR|O_CREAT, 0644) || return ""; $msgtied = 1; } ($msgid) = grep(/^\x01MSGID:/, split('\r', $text)); if ($msgid) { $msgid =~ s/^\x01MSGID:\s*//; $msgid =~ tr/A-Z/a-z/; } else { $msgid = sprintf("C%s %08x", $fromaddr, crc32($date . join(' ',grep(!/^(\x01PATH|SEEN-BY):/,split('\r', $text))))); } $key = "$area|$msgid|" . crc32($fromname . $toname . $subject); if (defined($msg{$key})) { # Dupe ($oldtime, $oldpath, $oldpktfrom) = split(/\|/, $msg{$key}); $dupetext = < " comments if ($text =~ /^((?:\x01[^\r]+\r)*)hpt> [^\r]+\r/) { $text = "$1$'"; $change = 1; } compileNL() unless $nltied; if ($nltied && !defined($nodelist{$toboss})) { bounce($fromname, $fromaddr, $toname, $toaddr, $date, $subject, $text, "Node $toboss mising in $curnodelist"); return "Node $toboss mising in $curnodelist"; } if ($fromaddr eq $myaddr[0] && !isattr("cpt", $attr) && $area =~ /^netmail$/i && $fromname !~ /areafix|crazy mail robot|allfix|ping|uucp/i) { putMsgInArea("I_SENT", $fromname, $toname, $fromaddr, $toaddr, $subject, $date, "pvt sent read", $text, 0); } if ($toaddr eq $myaddr[0]) { if ($toname =~ /^faqserver$/i) { faqserv($fromaddr, $fromname, $subject, $text); $newnet = 1; return "Message to FaqServer"; } unless ($toname =~ /^(areafix|allfix|filefix)$/i) { putMsgInArea("GUL", $fromname, $toname, $fromaddr, $toaddr, $subject, $date, "pvt sent read", $text, 0); return "Message to gul"; } } $addr = $area; $addr =~ tr/A-Z/a-z/; foreach(maillists) { s/ //g; tr/A-Z/a-z/; if ($addr eq $_) { $toaddr = "2:46/128"; $toname = "$_\@lucky.net"; $text =~ s#^((?:.*\r)?)\x01INTL\s+\S+\s+(\S+)\s*\r#$1\x01INTL 2:46/128 $2\r#s; $text =~ s/^((?:.*\r)?)\x01TOPT[^\r]+\r//s; $change = 1; return ""; } } return ""; } sub route { # $addr = dest addr # $from = orig addr # $text = message text # $attr = message attributes # set $flavour to hold|normal|crash|direct|immediate # return route addr or "" for default routing return _route($toaddr, $attr, $text); } sub _route { my ($toaddr, $attr, $text) = @_; my @routemail = ( "crash 17:1800/94 17:.*", "hold 2:46/128 (2:46/128|2:463/68.128)", "hold 2:999/999 2:46/128\.", "hold noroute 2:463/68(\.\d+)?", "hold 2:463/68.8 2:463/8\.2", "hold 2:463/68.17 2:463/62\.17", "crash 2:463/168 2:463/168(\.\d+)?", "normal 2:463/666 2:(463/666|46/200)(\.\d+)?", "crash 2:463/94 [123456]:.*", "hold 2:999/999 .*" ); my @routefile = ( "crash 2:463/94 2:(463/83|463/940(\.\d+)?|462/95|4653/10|4643/5", "crash 2:463/94 2:463/11(\.11)?", "normal 2:463/666 2:(463/666(\.\d+)?|2:46/200)", "crash 2:463/94 2:(46/0|465/50|465/70)", "hold noroute .*" ); my (@route, $dest, $patt, $boss, $host, $flags); compileNL() unless $nltied; if (isattr("att", $attr)) { @route = @routefile; } else { @route = @routemail; } $addr =~ s/\.0$//; $flags = $1 if $text =~ /^(.*\r\n?)?\x01FLAGS\s+(\S[^\r]*\S)\s*\r/; $flags =~ tr/A-Z/a-z/; foreach $flavour ("hld", "dir", "crash", "imm") { if (str2attr($flavour) != -1) { if ($attr & str2attr($flavour)) { $flavour = "hold" if $flavour eq "hld"; return $addr; } } else { if (index($flags, $flavour) >= 0) { $flavour = "immediate" if $flavour = "imm"; return $addr; } } } foreach (@route) { ($flavour, $dest, $patt) = split(/\s+/, $_); $boss = $addr; $boss =~ s/\..*//; $host = $boss; $host =~ s#/.*#/0#; if ($patt =~ /^hub(.*)/i) { $_ = $1; if ($nodelist{$boss} =~ /,(.*)/) { $patt = ".*" if $_ eq $1; } } elsif ($patt =~ /^reg(.*)/i) { $_ = $1; if ($nodelist{$host} =~ /^(.*),/) { $patt = ".*" if $_ eq $1; } } if ($addr =~ /^$patt$/) { if ($dest eq "noroute") { $dest = $addr; } elsif ($dest eq "boss") { $dest = $boss; } elsif ($dest eq "host") { $dest = $host; } elsif ($dest eq "hub") { $dest = $boss; if ($nodelist{$boss} =~ /,(.*)/) { $dest = $1; } else { $dest = $host; } } return $dest; } } return ""; } sub hpt_exit { my($flags); local(*F); untie %nodelist if $nltied; untie %pkt if $pkttied; untie %msg if $msgtied; if (@areas) { putlist(); @areas = (); } $nltied = $pkttied = $msgtied = 0; $flags = $ENV{"FLAGS"}; close(F) if $newnet && open(F, ">$flags/wasnet.now"); close(F) if $newecho && open(F, ">$flags/wasecho.now"); } sub process_pkt { # $pktname - name of pkt # $secure - defined for secure pkt # return non-empty string for rejecting pkt (don't process, rename to *.dup) my($crc, $a, $mtime, $size, $pktstart); local(*F); $processpktname = ""; %msgpkt = (); unless ($pkttied) { if (tie(%pkt, 'DB_File', pktdb, O_RDWR|O_CREAT, 0644)) { $pkttied = 1; } else { return ""; } } ($size,$mtime) = (stat($pktname))[7,9]; open(F, "<$pktname") || return; read(F, $pktstart, 58+178); # sizeof(pkthdr) + sizeof(msghdr) (max msghdr) close(F); $crc = crc32($pktstart); $pktname =~ s/^.*[\/\\]//; # basename $pktname =~ tr/A-Z/a-z/; $pktkey = sprintf("%s|%u|%08x|%08x", $pktname, $size, $mtime, $crc); $pktval = time(); $processpktname = $pktname; return "Duplicate $pktname" if defined($pkt{$pktkey}); return ""; } sub pkt_done { # $pktname - name of pkt # $rc - exit code (0 - OK) # $res - reason (text line) # 0 - OK ($res undefined) # 1 - Security violation # 2 - Can't open pkt # 3 - Bad pkt format # 4 - Not to us # 5 - Msg tossing problem my ($key, $val, $curtime, $sec, $min, $hour, $mday, $msgtime); return if defined($res) || !defined($pktkey) || !$pkttied; $pktname =~ s/^.*[\/\\]//; # basename $pktname =~ tr/A-Z/a-z/; return if $pktname ne $processpktname && $pktname ne ""; $pkt{$pktkey} = $pktval; ($sec,$min,$hour,$mday) = localtime(); if ($mday ne $pkt{"lastpurge"}) { print "Purging pkt dupebase..."; $curtime = time(); while (($key, $val) = each %pkt) { delete($pkt{$key}) if $curtime-$val>14*24*3600; } $pkt{"lastpurge"} = $mday; print " Done\n"; } $processpktname = ""; return if !$msgtied; while (($key, $val) = each %msgpkt) { $msg{$key} = $val; delete $msgpkt{$key}; } %msgpkt = (); if ($mday ne $msg{"lastpurge"}) { print "Purging msg dupebase..."; $curtime = time(); while (($key, $val) = each %msg) { ($msgtime) = split(/\|/, $val); delete($msg{$key}) if $curtime-$msgtime>14*24*3600; } $msg{"lastpurge"} = $mday; print " Done\n"; } } sub after_unpack { } sub before_pack { } # ======================================================================== # local functions # ======================================================================== sub compileNL { my(@nlfiles, $a, $mtime, $ctime, $curtime, $curmtime, $curctime); my($zone, $region, $net, $hub, $node, $flag); local(*F); opendir(F, nodelistDir()) || return; @nlfiles = grep(/^nodelist\.\d\d\d$/i, readdir(F)); closedir(F); return unless @nlfiles; $curnodelist = pop(@nlfiles); ($curmtime,$curctime) = (stat(nodelistDir . "/$curnodelist"))[9,10]; foreach(@nlfiles) { ($mtime,$ctime) = (stat(nodelistDir . "/$_"))[9,10]; if ($mtime > $curmtime) { $curmtime = $mtime; $curctime = $ctime; $curnodelist = $_; } } ($mtime,$ctime) = (stat($nldb))[9,10]; if (!defined($mtime) || $mtime < $curmtime) { unlink(nldb); tie(%nodelist, 'DB_File', nldb, O_RDWR|O_CREAT, 0644) || return; unless (open(F, "<".nodelistDir()."/$curnodelist")) { untie(%nodelist); return; } $zone = $region = $net = $hub = ""; print "Compiling nodelist..."; while () { chomp(); next if /^(;.*)?$/; ($flag,$node) = split(/,/); if ($flag eq "Zone") { $zone = $net = $node; $node = 0; $region = $hub = "$zone:$net/$node"; } elsif ($flag eq "Region") { $net = $node; $node = 0; $region = $hub = "$zone:$net/$node"; } elsif ($flag eq "Host") { $net = $node; $node = 0; $hub = "$zone:$net/$node"; } elsif ($flag eq "Hub") { $hub = "$zone:$net/$node"; } $nodelist{"$zone:$net/$node"}="$region,$hub"; } close(F); untie(%nodelist); print "Done.\n"; } tie(%nodelist, 'DB_File', nldb, O_RDONLY) && ($nltied=1); return; } sub bounce { my($fromname, $fromaddr, $toname, $toaddr, $date, $subject, $text, $reason) = @_; my($bouncetext); local(*F); $text =~ tr/\r/\n/; $text =~ s/\n\x01/\n\@/gs; $text =~ s/^\x01/\@/s; $bouncetext = < 102400) { $reply .= "Size limit riched, rest skipped\r"; $skip = 1; next; } if (open(F, "<" . faq . "$_.faq")) { read(F, $topic, $fsize); putMsgInArea("", "FaqServer", $fromname, "", $fromaddr, "Topic $_", "", "pvt loc k/s cpt", "Topic $_", $topic, 1); close(F); $correct = 1; } else { $reply .= "Topic $_ not found\r"; } } unless($correct) { $reply .= "No valid commands found, help sent\r"; if (open(F, "<" . faq . "help.faq")) { read(F, $topic, $fsize); putMsgInArea("", "FaqServer", $fromname, "", $fromaddr, "Help response", "", "pvt loc k/s cpt", $topic, 1); close(F); } } putMsgInArea("", "FaqServer", $fromname, "", $fromaddr, "FaqServer reply", "", "pvt loc k/s cpt", $reply, 1); } sub putlist { my(%areas, $fromaddr, $areaname, $desc); local(*F); %areas = (); $fromaddr = shift(@areas); while(@areas) { $_ = shift(@areas); next unless /^(\S+)(?:\s+(\S.*)|\s*)$/; ($areaname, $desc) = ($1, $2); $desc = "" if $desc =~ /autocreated|new\/unsorted|description missing/i; $desc = "" if $desc =~ /^(Regional|Gated) [Ee]choe?s$/; if (defined($areas{$areaname})) { next if $desc eq ""; $areas{$areaname} = $desc; } else { $areas{$areaname} = $desc; } } return if listname($fromaddr) eq ""; open(F, ">".listdir().listname($fromaddr)) || return; foreach (sort keys %areas) { print F "$_ " . $areas{$_} . "\n"; } close(F); return; } sub arqcpt { my($fromaddr, $toaddr, $fromname, $toname, $subject, $date, $attr, $origtext) = @_; my($text, $route); $route = _route($toaddr, $attr, $origtext); $route = "internet gate" if $route eq "2:46/128"; $text = <