Initial Camotes to Cebu ferry commit
authorJan Kratochvil <jan@jankratochvil.net>
Wed, 9 Aug 2023 00:39:16 +0000 (08:39 +0800)
committerJan Kratochvil <jan@jankratochvil.net>
Wed, 9 Aug 2023 00:39:16 +0000 (08:39 +0800)
mailsize [new file with mode: 0755]

diff --git a/mailsize b/mailsize
new file mode 100755 (executable)
index 0000000..d8064da
--- /dev/null
+++ b/mailsize
@@ -0,0 +1,133 @@
+#! /usr/bin/perl
+use strict;
+use warnings;
+require Net::DNS;
+require Net::SMTP;
+use HTML::Entities;
+require URI::Query;
+use POSIX;
+
+die "arg required" if @ARGV!=!$ENV{"GATEWAY_INTERFACE"};
+my $arg=$ARGV[0];
+
+my $nl="\n";
+my $html;
+if ($ENV{"GATEWAY_INTERFACE"}) {
+  $nl="<br />$nl";
+  $html=1;
+  print <<"EOH";
+Content-type: text/html
+
+<html><head><title>Maximum Mail Size Query</title></head><body>
+EOH
+  my %q=URI::Query->new($ENV{"QUERY_STRING"})->hash();
+  my $domain=$q{"domain"};
+  if ($domain) {
+    if ($domain=~/([^-_a-zA-Z0-9.])/) {
+      print "<p><b>Error: Invalid character '".encode_entities($1)."' in specified domain name: ".encode_entities($domain)."</b></p>\n";
+    } else {
+      $arg=$domain;
+    }
+  }
+}
+sub query($) {
+  my($domain)=@_;
+  my $dns=Net::DNS::Resolver->new();
+  #my $dns=Net::DNS::Resolver->new("nameservers"=>["255.255.255.255"]);
+  my $reply=$dns->search($domain,"MX");
+  my $type="MX";
+  do { $type="AAAA"; $reply=$dns->search($domain,"AAAA") } if !$reply&&$dns->errorstring() eq "NOERROR";
+  do { $type="A"   ; $reply=$dns->search($domain,"A"   ) } if !$reply&&$dns->errorstring() eq "NOERROR";
+  if (!$reply) {
+    print $dns->errorstring().$nl if !$reply;
+    return;
+  }
+  print "Found $type$nl";
+  my @retval;
+  foreach my $rr ($reply->answer()) {
+    my $addr;
+    $addr=$rr->exchange() if $rr->type eq "MX";
+    $addr=$rr->address() if $rr->type=~/^(?:A|AAAA)$/;
+    do { print "Invalid RR: ".$rr->string()."$nl"; next; } if !defined $addr;
+    print "$addr...$nl";
+    my $smtp=Net::SMTP->new($addr,"Timeout"=>10);
+    do { print "Cannot connect to SMTP server $addr: $@$nl"; next; } if !$smtp;
+    my $size=($smtp->message()=~/^SIZE\s*(\d+)\s*$/mi)[0];
+    push @retval,[$addr,$size];
+  }
+  return @retval;
+}
+if ($arg) {
+  print "<pre>\n";
+  my @r=query $arg;
+  print "</pre>\n";
+  if (!@r) {
+    print "<p>Error: Unable to determine anything about domain ".encode_entities($arg)."</p>\n";
+  } else {
+    my $size=$r[0][1];
+    for my $r (@r) {
+      $size=undef if !$size||!$r->[1]||$size!=$r->[1];
+    }
+    sub sizecalc($) {
+      my($input_size)=@_;
+      # https://stackoverflow.com/a/1533248/2995591
+      my $code_size    = ceil(($input_size * 4) / 3);
+      my $padding_size = ($input_size % 3) ? (3 - ($input_size % 3)) : 0;
+      my $crlfs_size   = 2 + ceil(2 * ($code_size + $padding_size) / 72);
+      my $total_size   = $code_size + $padding_size + $crlfs_size;
+      return $total_size;
+    }
+    sub rev($) {
+      my($size)=@_;
+      my $l=0;
+      my $r=$size;
+      while ($l+1<$r) {
+       my $m=int(($l+$r)/2);
+       my $x=sizecalc($m);
+       if ($x<$size) {
+         $l=$m;
+       } else {
+         $r=$m;
+       }
+      }
+      return $l;
+    }
+    sub human($) {
+      my($b)=@_;
+      my $kb=int($b/1000);
+      return "$b bytes" if !$kb;
+      my $mb=int($kb/1000);
+      return "$kb KB" if !$mb;
+      my $gb=int($kb/1000);
+      return "$mb MB" if !$gb;
+      return "$gb GB";
+    }
+    sub size($) {
+      my($size)=@_;
+      return "unknown" if !$size;
+      my $rev=rev($size);
+      return human($rev)." ($rev bytes; raw text mail size $size)";
+    }
+    if ($size) {
+      print "<p>Domain ".encode_entities($arg)." has maximum attachment size ".size($size)."</p>\n";
+    } else {
+      print "<p>Domain ".encode_entities($arg)." maximum attachment size depends on which server is contacted:</p>";
+      print "<table border=\"1\">\n";
+      for my $r (@r) {
+       print "<tr><td>".encode_entities($r->[0])."</td><td>".size($r->[1])."</td></tr>\n";
+      }
+      print "</table>\n";
+    }
+  }
+}
+if ($ENV{"GATEWAY_INTERFACE"}) {
+  print <<"EOH";
+<p>
+  <form action="/cgi-bin/smtpsize" method="get">
+    <input type="text" name="domain" size="32" value="@{[ encode_entities($arg||"") ]}" autofocus="autofocus" />
+    <input type="submit">
+  </form>
+</p>
+</body></html>
+EOH
+}