diff src/scanner.cpp @ 6:cea50d98a6cf

start work on content url scanner
author carl
date Wed, 21 Apr 2004 22:39:46 -0700
parents
children 93ff6d1ef647
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/scanner.cpp	Wed Apr 21 22:39:46 2004 -0700
@@ -0,0 +1,1036 @@
+// normal stuff
+#include <stdio.h>
+#include <stdlib.h>
+
+// needed for std c++ collections
+#include <set>
+#include <map>
+#include <list>
+
+// for the dns resolver
+#include <netinet/in.h>
+#include <arpa/nameser.h>
+#include <resolv.h>
+
+// misc stuff needed here
+#include <ctype.h>
+#include <fstream>
+
+static char* version="$Id$";
+
+using namespace std;
+
+enum status {oksofar,   // not rejected yet
+             white,     // whitelisted by envelope from
+             black,     // blacklisted by envelope from or to
+             reject};   // rejected by a dns list
+
+enum state {//u_init,         // url  decoder states
+
+            m_init,         // mime decoder states
+            m_eq,
+            m_1,
+
+            e_init,         // html entity decoder states
+            e_amp,
+            e_num,
+
+            b_init,         // base64 decoder states
+            b_lf,
+            b_lf2,
+            b_64,
+
+            end_state,      // counter for number of columns in the table
+
+            m_2,            // temporary mime states
+            m_cr,
+            m_nl,
+            e_semi,
+            b_cr,
+           };
+
+typedef state PARSE[end_state];
+
+static PARSE parse_table[256] = {
+  // m_init,    m_eq,   m_1,    e_init, e_amp,  e_num,  b_init, b_lf,   b_lf2,  b_64
+
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0x00
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0x01
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0x02
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0x03
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0x04
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0x05
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0x06
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0x07
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0x08
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0x09
+    {m_init,    m_nl,   m_init, e_init, e_init, e_init, b_lf,   b_init, b_lf2,  b_init,  },  // 0x0a <lf>
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0x0b
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0x0c
+    {m_init,    m_cr,   m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_cr,    },  // 0x0d <cr>
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0x0e
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0x0f
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0x10
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0x11 xon char
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0x12
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0x13 xoff char
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0x14
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0x15
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0x16
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0x17
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0x18
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0x19
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0x1a
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0x1b
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0x1c
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0x1d
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0x1e
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0x1f
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0x20 space
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0x21 !
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0x22 ""
+    {m_init,    m_init, m_init, e_init, e_num,  e_init, b_init, b_init, b_init, b_init,  },  // 0x23 #
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0x24 $
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0x25 %
+    {m_init,    m_init, m_init, e_amp,  e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0x26 &
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0x27 '
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0x28 (
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0x29 )
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0x2A *
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_64,   b_64,   b_64,    },  // 0x2B +
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0x2C ,
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0x2D -
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0x2E .
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_64,   b_64,   b_64,    },  // 0x2F /
+    {m_init,    m_1,    m_2,    e_init, e_init, e_num,  b_init, b_64,   b_64,   b_64,    },  // 0x30 0
+    {m_init,    m_1,    m_2,    e_init, e_init, e_num,  b_init, b_64,   b_64,   b_64,    },  // 0x31 1
+    {m_init,    m_1,    m_2,    e_init, e_init, e_num,  b_init, b_64,   b_64,   b_64,    },  // 0x32 2
+    {m_init,    m_1,    m_2,    e_init, e_init, e_num,  b_init, b_64,   b_64,   b_64,    },  // 0x33 3
+    {m_init,    m_1,    m_2,    e_init, e_init, e_num,  b_init, b_64,   b_64,   b_64,    },  // 0x34 4
+    {m_init,    m_1,    m_2,    e_init, e_init, e_num,  b_init, b_64,   b_64,   b_64,    },  // 0x35 5
+    {m_init,    m_1,    m_2,    e_init, e_init, e_num,  b_init, b_64,   b_64,   b_64,    },  // 0x36 6
+    {m_init,    m_1,    m_2,    e_init, e_init, e_num,  b_init, b_64,   b_64,   b_64,    },  // 0x37 7
+    {m_init,    m_1,    m_2,    e_init, e_init, e_num,  b_init, b_64,   b_64,   b_64,    },  // 0x38 8
+    {m_init,    m_1,    m_2,    e_init, e_init, e_num,  b_init, b_64,   b_64,   b_64,    },  // 0x39 9
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0x3A :
+    {m_init,    m_init, m_init, e_init, e_init, e_semi, b_init, b_init, b_init, b_init,  },  // 0x3B ;
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0x3C <
+    {m_eq,      m_init, m_init, e_init, e_init, e_init, b_init, b_64,   b_64,   b_64,    },  // 0x3D =
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0x3E >
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0x3F ?
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0x40 @
+    {m_init,    m_1,    m_2,    e_init, e_init, e_init, b_init, b_64,   b_64,   b_64,    },  // 0x41 A
+    {m_init,    m_1,    m_2,    e_init, e_init, e_init, b_init, b_64,   b_64,   b_64,    },  // 0x42 B
+    {m_init,    m_1,    m_2,    e_init, e_init, e_init, b_init, b_64,   b_64,   b_64,    },  // 0x43 C
+    {m_init,    m_1,    m_2,    e_init, e_init, e_init, b_init, b_64,   b_64,   b_64,    },  // 0x44 D
+    {m_init,    m_1,    m_2,    e_init, e_init, e_init, b_init, b_64,   b_64,   b_64,    },  // 0x45 E
+    {m_init,    m_1,    m_2,    e_init, e_init, e_init, b_init, b_64,   b_64,   b_64,    },  // 0x46 F
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_64,   b_64,   b_64,    },  // 0x47 G
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_64,   b_64,   b_64,    },  // 0x48 H
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_64,   b_64,   b_64,    },  // 0x49 I
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_64,   b_64,   b_64,    },  // 0x4A J
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_64,   b_64,   b_64,    },  // 0x4B K
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_64,   b_64,   b_64,    },  // 0x4C L
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_64,   b_64,   b_64,    },  // 0x4D M
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_64,   b_64,   b_64,    },  // 0x4E N
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_64,   b_64,   b_64,    },  // 0x4F O
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_64,   b_64,   b_64,    },  // 0x50 P
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_64,   b_64,   b_64,    },  // 0x51 Q
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_64,   b_64,   b_64,    },  // 0x52 R
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_64,   b_64,   b_64,    },  // 0x53 S
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_64,   b_64,   b_64,    },  // 0x54 T
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_64,   b_64,   b_64,    },  // 0x55 U
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_64,   b_64,   b_64,    },  // 0x56 V
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_64,   b_64,   b_64,    },  // 0x57 W
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_64,   b_64,   b_64,    },  // 0x58 X
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_64,   b_64,   b_64,    },  // 0x59 Y
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_64,   b_64,   b_64,    },  // 0x5A Z
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0x5B [
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0x5C brace
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0x5D ]
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0x5E ^
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0x5F _
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0x60 `
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_64,   b_64,   b_64,    },  // 0x61 a
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_64,   b_64,   b_64,    },  // 0x62 b
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_64,   b_64,   b_64,    },  // 0x63 c
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_64,   b_64,   b_64,    },  // 0x64 d
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_64,   b_64,   b_64,    },  // 0x65 e
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_64,   b_64,   b_64,    },  // 0x66 f
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_64,   b_64,   b_64,    },  // 0x67 g
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_64,   b_64,   b_64,    },  // 0x68 h
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_64,   b_64,   b_64,    },  // 0x69 i
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_64,   b_64,   b_64,    },  // 0x6A j
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_64,   b_64,   b_64,    },  // 0x6B k
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_64,   b_64,   b_64,    },  // 0x6C l
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_64,   b_64,   b_64,    },  // 0x6D m
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_64,   b_64,   b_64,    },  // 0x6E n
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_64,   b_64,   b_64,    },  // 0x6F o
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_64,   b_64,   b_64,    },  // 0x70 p
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_64,   b_64,   b_64,    },  // 0x71 q
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_64,   b_64,   b_64,    },  // 0x72 r
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_64,   b_64,   b_64,    },  // 0x73 s
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_64,   b_64,   b_64,    },  // 0x74 t
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_64,   b_64,   b_64,    },  // 0x75 u
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_64,   b_64,   b_64,    },  // 0x76 v
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_64,   b_64,   b_64,    },  // 0x77 w
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_64,   b_64,   b_64,    },  // 0x78 x
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_64,   b_64,   b_64,    },  // 0x79 y
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_64,   b_64,   b_64,    },  // 0x7A z
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0x7B {
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0x7C |
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0x7D }
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0x7E ~
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0x7f
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0x80
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0x81
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0x82
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0x83
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0x84
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0x85
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0x86
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0x87
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0x88
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0x89
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0x8a
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0x8b
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0x8c
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0x8d
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0x8e
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0x8f
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0x90
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0x91
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0x92
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0x93
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0x94
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0x95
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0x96
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0x97
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0x98
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0x99
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0x9a
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0x9b
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0x9c
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0x9d
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0x9e
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0x9f
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0xa0
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0xa1
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0xa2
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0xa3
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0xa4
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0xa5
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0xa6
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0xa7
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0xa8
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0xa9
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0xaa
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0xab
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0xac
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0xad
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0xae
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0xaf
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0xb0
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0xb1
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0xb2
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0xb3
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0xb4
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0xb5
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0xb6
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0xb7
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0xb8
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0xb9
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0xba
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0xbb
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0xbc
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0xbd
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0xbe
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0xbf
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0xc0
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0xc1
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0xc2
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0xc3
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0xc4
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0xc5
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0xc6
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0xc7
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0xc8
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0xc9
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0xca
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0xcb
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0xcc
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0xcd
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0xce
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0xcf
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0xd0
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0xd1
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0xd2
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0xd3
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0xd4
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0xd5
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0xd6
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0xd7
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0xd8
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0xd9
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0xda
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0xdb
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0xdc
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0xdd
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0xde
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0xdf
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0xe0
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0xe1
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0xe2
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0xe3
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0xe4
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0xe5
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0xe6
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0xe7
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0xe8
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0xe9
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0xea
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0xeb
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0xec
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0xed
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0xee
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0xef
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0xf0
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0xf1
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0xf2
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0xf3
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0xf4
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0xf5
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0xf6
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0xf7
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0xf8
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0xf9
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0xfa
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0xfb
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0xfc
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0xfd
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0xfe
+    {m_init,    m_init, m_init, e_init, e_init, e_init, b_init, b_init, b_init, b_init,  },  // 0xff
+};
+
+
+u_char hex_decode[256] = {
+    0,  // 0x00
+    0,  // 0x01
+    0,  // 0x02
+    0,  // 0x03
+    0,  // 0x04
+    0,  // 0x05
+    0,  // 0x06
+    0,  // 0x07
+    0,  // 0x08
+    0,  // 0x09
+    0,  // 0x0a
+    0,  // 0x0b
+    0,  // 0x0c
+    0,  // 0x0d
+    0,  // 0x0e
+    0,  // 0x0f
+    0,  // 0x10
+    0,  // 0x11 xon char
+    0,  // 0x12
+    0,  // 0x13 xoff char
+    0,  // 0x14
+    0,  // 0x15
+    0,  // 0x16
+    0,  // 0x17
+    0,  // 0x18
+    0,  // 0x19
+    0,  // 0x1a
+    0,  // 0x1b
+    0,  // 0x1c
+    0,  // 0x1d
+    0,  // 0x1e
+    0,  // 0x1f
+    0,  // 0x20 space
+    0,  // 0x21 !
+    0,  // 0x22 ""
+    0,  // 0x23 #
+    0,  // 0x24 $
+    0,  // 0x25 %
+    0,  // 0x26 &
+    0,  // 0x27 '
+    0,  // 0x28 (
+    0,  // 0x29 )
+    0,  // 0x2A *
+    0,  // 0x2B +
+    0,  // 0x2C ,
+    0,  // 0x2D -
+    0,  // 0x2E .
+    0,  // 0x2F /
+    0,  // 0x30 0
+    1,  // 0x31 1
+    2,  // 0x32 2
+    3,  // 0x33 3
+    4,  // 0x34 4
+    5,  // 0x35 5
+    6,  // 0x36 6
+    7,  // 0x37 7
+    8,  // 0x38 8
+    9,  // 0x39 9
+    0,  // 0x3A :
+    0,  // 0x3B ;
+    0,  // 0x3C <
+    0,  // 0x3D =
+    0,  // 0x3E >
+    0,  // 0x3F ?
+    0,  // 0x40 @
+    10, // 0x41 A
+    11, // 0x42 B
+    12, // 0x43 C
+    13, // 0x44 D
+    14, // 0x45 E
+    15, // 0x46 F
+    0,  // 0x47 G
+    0,  // 0x48 H
+    0,  // 0x49 I
+    0,  // 0x4A J
+    0,  // 0x4B K
+    0,  // 0x4C L
+    0,  // 0x4D M
+    0,  // 0x4E N
+    0,  // 0x4F O
+    0,  // 0x50 P
+    0,  // 0x51 Q
+    0,  // 0x52 R
+    0,  // 0x53 S
+    0,  // 0x54 T
+    0,  // 0x55 U
+    0,  // 0x56 V
+    0,  // 0x57 W
+    0,  // 0x58 X
+    0,  // 0x59 Y
+    0,  // 0x5A Z
+    0,  // 0x5B [
+    0,  // 0x5C brace
+    0,  // 0x5D ]
+    0,  // 0x5E ^
+    0,  // 0x5F _
+    0,  // 0x60 `
+    10, // 0x61 a
+    11, // 0x62 b
+    12, // 0x63 c
+    13, // 0x64 d
+    14, // 0x65 e
+    15, // 0x66 f
+    0,  // 0x67 g
+    0,  // 0x68 h
+    0,  // 0x69 i
+    0,  // 0x6A j
+    0,  // 0x6B k
+    0,  // 0x6C l
+    0,  // 0x6D m
+    0,  // 0x6E n
+    0,  // 0x6F o
+    0,  // 0x70 p
+    0,  // 0x71 q
+    0,  // 0x72 r
+    0,  // 0x73 s
+    0,  // 0x74 t
+    0,  // 0x75 u
+    0,  // 0x76 v
+    0,  // 0x77 w
+    0,  // 0x78 x
+    0,  // 0x79 y
+    0,  // 0x7A z
+    0,  // 0x7B {
+    0,  // 0x7C |
+    0,  // 0x7D }
+    0,  // 0x7E ~
+    0,  // 0x7f
+    0,  // 0x80
+    0,  // 0x81
+    0,  // 0x82
+    0,  // 0x83
+    0,  // 0x84
+    0,  // 0x85
+    0,  // 0x86
+    0,  // 0x87
+    0,  // 0x88
+    0,  // 0x89
+    0,  // 0x8a
+    0,  // 0x8b
+    0,  // 0x8c
+    0,  // 0x8d
+    0,  // 0x8e
+    0,  // 0x8f
+    0,  // 0x90
+    0,  // 0x91
+    0,  // 0x92
+    0,  // 0x93
+    0,  // 0x94
+    0,  // 0x95
+    0,  // 0x96
+    0,  // 0x97
+    0,  // 0x98
+    0,  // 0x99
+    0,  // 0x9a
+    0,  // 0x9b
+    0,  // 0x9c
+    0,  // 0x9d
+    0,  // 0x9e
+    0,  // 0x9f
+    0,  // 0xa0
+    0,  // 0xa1
+    0,  // 0xa2
+    0,  // 0xa3
+    0,  // 0xa4
+    0,  // 0xa5
+    0,  // 0xa6
+    0,  // 0xa7
+    0,  // 0xa8
+    0,  // 0xa9
+    0,  // 0xaa
+    0,  // 0xab
+    0,  // 0xac
+    0,  // 0xad
+    0,  // 0xae
+    0,  // 0xaf
+    0,  // 0xb0
+    0,  // 0xb1
+    0,  // 0xb2
+    0,  // 0xb3
+    0,  // 0xb4
+    0,  // 0xb5
+    0,  // 0xb6
+    0,  // 0xb7
+    0,  // 0xb8
+    0,  // 0xb9
+    0,  // 0xba
+    0,  // 0xbb
+    0,  // 0xbc
+    0,  // 0xbd
+    0,  // 0xbe
+    0,  // 0xbf
+    0,  // 0xc0
+    0,  // 0xc1
+    0,  // 0xc2
+    0,  // 0xc3
+    0,  // 0xc4
+    0,  // 0xc5
+    0,  // 0xc6
+    0,  // 0xc7
+    0,  // 0xc8
+    0,  // 0xc9
+    0,  // 0xca
+    0,  // 0xcb
+    0,  // 0xcc
+    0,  // 0xcd
+    0,  // 0xce
+    0,  // 0xcf
+    0,  // 0xd0
+    0,  // 0xd1
+    0,  // 0xd2
+    0,  // 0xd3
+    0,  // 0xd4
+    0,  // 0xd5
+    0,  // 0xd6
+    0,  // 0xd7
+    0,  // 0xd8
+    0,  // 0xd9
+    0,  // 0xda
+    0,  // 0xdb
+    0,  // 0xdc
+    0,  // 0xdd
+    0,  // 0xde
+    0,  // 0xdf
+    0,  // 0xe0
+    0,  // 0xe1
+    0,  // 0xe2
+    0,  // 0xe3
+    0,  // 0xe4
+    0,  // 0xe5
+    0,  // 0xe6
+    0,  // 0xe7
+    0,  // 0xe8
+    0,  // 0xe9
+    0,  // 0xea
+    0,  // 0xeb
+    0,  // 0xec
+    0,  // 0xed
+    0,  // 0xee
+    0,  // 0xef
+    0,  // 0xf0
+    0,  // 0xf1
+    0,  // 0xf2
+    0,  // 0xf3
+    0,  // 0xf4
+    0,  // 0xf5
+    0,  // 0xf6
+    0,  // 0xf7
+    0,  // 0xf8
+    0,  // 0xf9
+    0,  // 0xfa
+    0,  // 0xfb
+    0,  // 0xfc
+    0,  // 0xfd
+    0,  // 0xfe
+    0,  // 0xff
+};
+u_char b64_decode[256] = {
+    0,  // 0x00
+    0,  // 0x01
+    0,  // 0x02
+    0,  // 0x03
+    0,  // 0x04
+    0,  // 0x05
+    0,  // 0x06
+    0,  // 0x07
+    0,  // 0x08
+    0,  // 0x09
+    0,  // 0x0a
+    0,  // 0x0b
+    0,  // 0x0c
+    0,  // 0x0d
+    0,  // 0x0e
+    0,  // 0x0f
+    0,  // 0x10
+    0,  // 0x11 xon char
+    0,  // 0x12
+    0,  // 0x13 xoff char
+    0,  // 0x14
+    0,  // 0x15
+    0,  // 0x16
+    0,  // 0x17
+    0,  // 0x18
+    0,  // 0x19
+    0,  // 0x1a
+    0,  // 0x1b
+    0,  // 0x1c
+    0,  // 0x1d
+    0,  // 0x1e
+    0,  // 0x1f
+    0,  // 0x20 space
+    0,  // 0x21 !
+    0,  // 0x22 ""
+    0,  // 0x23 #
+    0,  // 0x24 $
+    0,  // 0x25 %
+    0,  // 0x26 &
+    0,  // 0x27 '
+    0,  // 0x28 (
+    0,  // 0x29 )
+    0,  // 0x2A *
+    62, // 0x2B +
+    0,  // 0x2C ,
+    0,  // 0x2D -
+    0,  // 0x2E .
+    63, // 0x2F /
+    52, // 0x30 0
+    53, // 0x31 1
+    54, // 0x32 2
+    55, // 0x33 3
+    56, // 0x34 4
+    57, // 0x35 5
+    58, // 0x36 6
+    59, // 0x37 7
+    60, // 0x38 8
+    61, // 0x39 9
+    0,  // 0x3A :
+    0,  // 0x3B ;
+    0,  // 0x3C <
+    0,  // 0x3D =
+    0,  // 0x3E >
+    0,  // 0x3F ?
+    0,  // 0x40 @
+     0, // 0x41 A
+     1, // 0x42 B
+     2, // 0x43 C
+     3, // 0x44 D
+     4, // 0x45 E
+     5, // 0x46 F
+     6, // 0x47 G
+     7, // 0x48 H
+     8, // 0x49 I
+     9, // 0x4A J
+    10, // 0x4B K
+    11, // 0x4C L
+    12, // 0x4D M
+    13, // 0x4E N
+    14, // 0x4F O
+    15, // 0x50 P
+    16, // 0x51 Q
+    17, // 0x52 R
+    18, // 0x53 S
+    19, // 0x54 T
+    20, // 0x55 U
+    21, // 0x56 V
+    22, // 0x57 W
+    23, // 0x58 X
+    24, // 0x59 Y
+    25, // 0x5A Z
+    0,  // 0x5B [
+    0,  // 0x5C brace
+    0,  // 0x5D ]
+    0,  // 0x5E ^
+    0,  // 0x5F _
+    0,  // 0x60 `
+    26, // 0x61 a
+    27, // 0x62 b
+    28, // 0x63 c
+    29, // 0x64 d
+    30, // 0x65 e
+    31, // 0x66 f
+    32, // 0x67 g
+    33, // 0x68 h
+    34, // 0x69 i
+    35, // 0x6A j
+    36, // 0x6B k
+    37, // 0x6C l
+    38, // 0x6D m
+    39, // 0x6E n
+    40, // 0x6F o
+    41, // 0x70 p
+    42, // 0x71 q
+    43, // 0x72 r
+    44, // 0x73 s
+    45, // 0x74 t
+    46, // 0x75 u
+    47, // 0x76 v
+    48, // 0x77 w
+    49, // 0x78 x
+    50, // 0x79 y
+    51, // 0x7A z
+    0,  // 0x7B {
+    0,  // 0x7C |
+    0,  // 0x7D }
+    0,  // 0x7E ~
+    0,  // 0x7f
+    0,  // 0x80
+    0,  // 0x81
+    0,  // 0x82
+    0,  // 0x83
+    0,  // 0x84
+    0,  // 0x85
+    0,  // 0x86
+    0,  // 0x87
+    0,  // 0x88
+    0,  // 0x89
+    0,  // 0x8a
+    0,  // 0x8b
+    0,  // 0x8c
+    0,  // 0x8d
+    0,  // 0x8e
+    0,  // 0x8f
+    0,  // 0x90
+    0,  // 0x91
+    0,  // 0x92
+    0,  // 0x93
+    0,  // 0x94
+    0,  // 0x95
+    0,  // 0x96
+    0,  // 0x97
+    0,  // 0x98
+    0,  // 0x99
+    0,  // 0x9a
+    0,  // 0x9b
+    0,  // 0x9c
+    0,  // 0x9d
+    0,  // 0x9e
+    0,  // 0x9f
+    0,  // 0xa0
+    0,  // 0xa1
+    0,  // 0xa2
+    0,  // 0xa3
+    0,  // 0xa4
+    0,  // 0xa5
+    0,  // 0xa6
+    0,  // 0xa7
+    0,  // 0xa8
+    0,  // 0xa9
+    0,  // 0xaa
+    0,  // 0xab
+    0,  // 0xac
+    0,  // 0xad
+    0,  // 0xae
+    0,  // 0xaf
+    0,  // 0xb0
+    0,  // 0xb1
+    0,  // 0xb2
+    0,  // 0xb3
+    0,  // 0xb4
+    0,  // 0xb5
+    0,  // 0xb6
+    0,  // 0xb7
+    0,  // 0xb8
+    0,  // 0xb9
+    0,  // 0xba
+    0,  // 0xbb
+    0,  // 0xbc
+    0,  // 0xbd
+    0,  // 0xbe
+    0,  // 0xbf
+    0,  // 0xc0
+    0,  // 0xc1
+    0,  // 0xc2
+    0,  // 0xc3
+    0,  // 0xc4
+    0,  // 0xc5
+    0,  // 0xc6
+    0,  // 0xc7
+    0,  // 0xc8
+    0,  // 0xc9
+    0,  // 0xca
+    0,  // 0xcb
+    0,  // 0xcc
+    0,  // 0xcd
+    0,  // 0xce
+    0,  // 0xcf
+    0,  // 0xd0
+    0,  // 0xd1
+    0,  // 0xd2
+    0,  // 0xd3
+    0,  // 0xd4
+    0,  // 0xd5
+    0,  // 0xd6
+    0,  // 0xd7
+    0,  // 0xd8
+    0,  // 0xd9
+    0,  // 0xda
+    0,  // 0xdb
+    0,  // 0xdc
+    0,  // 0xdd
+    0,  // 0xde
+    0,  // 0xdf
+    0,  // 0xe0
+    0,  // 0xe1
+    0,  // 0xe2
+    0,  // 0xe3
+    0,  // 0xe4
+    0,  // 0xe5
+    0,  // 0xe6
+    0,  // 0xe7
+    0,  // 0xe8
+    0,  // 0xe9
+    0,  // 0xea
+    0,  // 0xeb
+    0,  // 0xec
+    0,  // 0xed
+    0,  // 0xee
+    0,  // 0xef
+    0,  // 0xf0
+    0,  // 0xf1
+    0,  // 0xf2
+    0,  // 0xf3
+    0,  // 0xf4
+    0,  // 0xf5
+    0,  // 0xf6
+    0,  // 0xf7
+    0,  // 0xf8
+    0,  // 0xf9
+    0,  // 0xfa
+    0,  // 0xfb
+    0,  // 0xfc
+    0,  // 0xfd
+    0,  // 0xfe
+    0,  // 0xff
+};
+
+#define PENDING_LIMIT 1000
+struct fsa {
+    u_char  pending[PENDING_LIMIT];
+    int     count;
+    state   st;
+    state   init;
+    fsa*    next;
+
+    fsa(state init, fsa* next_);
+    void push(u_char *buf, int len);
+};
+
+fsa::fsa(state init_, fsa* next_) {
+    count = 0;
+    st    = init_;
+    init  = init_;
+    next  = next_;
+}
+
+void fsa::push(u_char *buf, int len) {
+    for (int i=0; i<len; i++) {
+        u_char c = buf[i];
+        // guard against buffer overflow
+        if (count == PENDING_LIMIT-1) {
+            if (next) next->push(pending, count);
+            else {
+                pending[count] = 0;
+                fprintf(stdout, "%s", (char*)pending);
+            }
+            count = 0;
+            st    = init;
+        }
+        pending[count++] = c;
+        st = parse_table[c][st];
+        switch (st) {
+
+            //////////////////////////////
+            //  mime decoder
+            case m_2: {
+                pending[0] = hex_decode[pending[1]] * 16 + hex_decode[pending[2]];
+                count = 1;
+                st    = m_init;
+                } // fall thru
+
+            case m_init: {
+                if (next) next->push(pending, count);
+                else {
+                    pending[count] = 0;
+                    fprintf(stdout, "%s", (char*)pending);
+                }
+                count = 0;
+                } break;
+
+            case m_cr: {
+                count = 1;
+                st    = m_eq;
+                } break;
+
+            case m_nl: {
+                count = 0;
+                st    = m_init;
+                } break;
+
+            //////////////////////////////
+            //  html entity decoder
+            case e_semi: {
+                pending[--count] = '\0';  // null terminate the digit string by overwriting the semicolon
+                pending[0] = atoi((const char *)pending+2);
+                count = 1;
+                st    = e_init;
+                } // fall thru
+
+            case e_init: {
+                if (next) next->push(pending, count);
+                else {
+                    pending[count] = 0;
+                    fprintf(stdout, "%s", (char*)pending);
+                }
+                count = 0;
+                } break;
+
+            //////////////////////////////
+            //  base64 decoder
+            case b_lf2: {
+                count--;
+                } break;
+
+            case b_cr: {
+                int cnt = 0;
+                if ((count % 4) == 1) {
+                    count--;
+                    // might have proper b64 data
+                    for (int i=0; i<count; i+=4) {
+                        unsigned long a1 = b64_decode[pending[i]];
+                        unsigned long a2 = b64_decode[pending[i+1]];
+                        unsigned long a3 = b64_decode[pending[i+2]];
+                        unsigned long a4 = b64_decode[pending[i+3]];
+                        unsigned long a = (a1 << 18) | (a2 << 12) | (a3 << 6) | a4;
+                        pending[cnt++] = (a & 0x00ff0000) >> 16;
+                        pending[cnt++] = (a & 0x0000ff00) >>  8;
+                        pending[cnt++] = (a & 0x000000ff);
+                        if ((char)pending[i+3] == '=') cnt--;
+                        if ((char)pending[i+2] == '=') cnt--;
+                    }
+                    count = cnt;
+                    st    = b_lf2;
+                }
+                else st = b_init;
+                } // fall thru
+
+            case b_lf:
+            case b_init: {
+                if (next) next->push(pending, count);
+                else {
+                    pending[count] = 0;
+                    fprintf(stdout, "%s", (char*)pending);
+                }
+                count = 0;
+                } break;
+
+            //////////////////////////////
+            //  states that just accumulate characters in the pending buffer
+            case e_amp:
+            case e_num:
+            case b_64:
+            case m_eq:
+            case m_1:
+            default: {
+                } break;
+        }
+    }
+}
+
+
+
+////////////////////////////////////////////////
+//  ask a dns question and get an A record answer
+//
+static unsigned long dns_interface(char *question);
+static unsigned long dns_interface(char *question) {
+    u_char answer[NS_PACKETSZ];
+    int length = res_search(question, ns_c_in, ns_t_a, answer, sizeof(answer));
+    if (length < 0) return oksofar;     // error in getting answer
+    // parse the answer
+    ns_msg handle;
+    ns_rr  rr;
+    if (ns_initparse(answer, length, &handle) != 0) return oksofar;
+    int rrnum = 0;
+    while (ns_parserr(&handle, ns_s_an, rrnum++, &rr) == 0) {
+        if (ns_rr_type(rr) == ns_t_a) {
+            unsigned long address;
+            memcpy(&address, ns_rr_rdata(rr), sizeof(address));
+            return reject;
+        }
+    }
+    return 0;
+}
+
+////////////////////////////////////////////////
+//  check a single dnsbl - we don't try very hard, just
+//  using the default resolver retry settings. If we cannot
+//  get an answer, we just accept the mail. The caller
+//  must ensure thread safety.
+//
+static status check_single(int ip, char *suffix);
+static status check_single(int ip, char *suffix) {
+    // make a dns question
+    const u_char *src = (const u_char *)&ip;
+    if (src[0] == 127) return oksofar;  // don't do dns lookups on localhost
+    char question[NS_MAXDNAME];
+    snprintf(question, sizeof(question), "%u.%u.%u.%u.%s.", src[3], src[2], src[1], src[0], suffix);
+    // ask the question, if we get an A record it implies a blacklisted ip address
+    unsigned long ans = dns_interface(question);
+    return (ans) ? reject : oksofar;
+}
+
+
+////////////////////////////////////////////////
+//  scan a file for URLs
+//
+static void scan_file(char *fn, fsa& parser);
+static void scan_file(char *fn, fsa& parser) {
+    const int LINE_SIZE = 2000;
+    char line[LINE_SIZE];
+    ifstream is(fn);
+    while (!is.eof()) {
+        is.getline(line, LINE_SIZE-1);
+        int n = strlen(line);
+        line[n++] = '\n';
+        parser.push((u_char*)line, n);
+    }
+    is.close();
+}
+
+
+int main(int argc, char**argv)
+{
+    char *fn = argv[1];
+    fsa *html_parser = new fsa(e_init, NULL);
+    fsa *mime_parser = new fsa(m_init, html_parser);
+    fsa *b64_parser  = new fsa(b_init, mime_parser);
+    if (fn) scan_file(fn, *b64_parser);
+    return 0;
+}