]> gitweb.michael.orlitzky.com - email-validator.git/commitdiff
Use a hyphen instead of an underscore in the program name.
authorMichael Orlitzky <michael@orlitzky.com>
Sun, 9 Jun 2013 19:17:00 +0000 (15:17 -0400)
committerMichael Orlitzky <michael@orlitzky.com>
Sun, 9 Jun 2013 19:17:00 +0000 (15:17 -0400)
Add a new -a parameter, to accept an 'A' record in addition to the MX required by default.
Update the man page with the new option.

doc/man1/email-validator.1
email-validator.cabal
makefile
src/CommandLine.hs
src/Main.hs

index 3e56741dd694e2123ef826c7b603e01d4e16c6b5..5fd7d10c3a610f414ec0821dcc58458e24d4dac5 100644 (file)
@@ -5,7 +5,7 @@ email-validator \- Perform basic syntax and deliverability checks on email addre
 
 .SH SYNOPSIS
 
-\fBemail-validator\fR [\fB\-h\fR] [\fB-i \fIFILE\fR] [\fB-o \fIFILE\fR] \fI<input>\fR
+\fBemail-validator\fR [\fB\-ha\fR] [\fB-i \fIFILE\fR] [\fB-o \fIFILE\fR] \fI<input>\fR
 
 .SH INPUT
 
@@ -33,10 +33,20 @@ A regular expression is used to check for invalid characters and syntax.
 
 .IP \[bu]
 We confirm the existence of a MX record for the domain part of the
-address.
+address. This is not required; in fact many domains accept mail via
+an 'A' record for e.g. example.com which is used in lieu of an MX
+record. This behavior can be controlled via the \fR\-a\fR flag.
+
+.P
+These checks are performed in parallel using the number of available
+threads.
 
 .SH OPTIONS
 
+.IP \fB\-\-accept-a\fR,\ \fB\-a\fR
+Accept an 'A' record for the domain instead of requiring an MX record
+(the default).
+
 .IP \fB\-\-input\fR,\ \fB\-i\fR
 Specify the input file containing a list of email addresses, rather
 than using stdin (the default).
index 7ccf0f0dd14cc056b636861515eb05e1baa06718..e080aa17789fd00f5105d5b54e472550eae31087 100644 (file)
@@ -15,7 +15,7 @@ description:
   Perform basic syntax and deliverability checks on email addresses.
 
 
-executable email_validator
+executable email-validator
   build-depends:
     base                        == 4.*,
     bytestring                  == 0.10.*,
index 7dd4524eb067117ce184bbc070e9d23ea88358b3..2681fc3488b7f710fa07d98bcb5468e11aab0195 100644 (file)
--- a/makefile
+++ b/makefile
@@ -1,4 +1,4 @@
-BIN           = dist/build/email_validator/email_validator
+BIN           = dist/build/email-validator/email-validator
 TESTSUITE_BIN = dist/build/testsuite/testsuite
 
 .PHONY : test dist hlint
index 1088f2a906a2d2055143f1c0b2036f039fb0155c..a7507df6a381a5365e7328aa8c3333158fac4c6b 100644 (file)
@@ -17,7 +17,8 @@ import ExitCodes
 
 -- We optionally accept input/output files to use instead of
 -- stdin/stdout.
-data Args = Args { input_file :: Maybe FilePath,
+data Args = Args { accept_a :: Bool,
+                   input_file :: Maybe FilePath,
                    output_file :: Maybe FilePath }
   deriving   (Show, Data, Typeable)
 
@@ -30,6 +31,10 @@ program_name = "email-validator"
 my_summary :: String
 my_summary = program_name ++ "-" ++ (showVersion version)
 
+accept_a_help :: String
+accept_a_help =
+  "Accept an 'A' record for the domain instead of requiring an MX record."
+
 input_file_help :: String
 input_file_help =
   "Path to the input file (default: stdin), one email address per line"
@@ -41,7 +46,8 @@ output_file_help =
 arg_spec :: Mode (CmdArgs Args)
 arg_spec =
   cmdArgsMode $
-    Args { input_file  = def &= typFile &= help input_file_help,
+    Args { accept_a    = def &=            help accept_a_help,
+           input_file  = def &= typFile &= help input_file_help,
            output_file = def &= typFile &= help output_file_help }
       &= program program_name
       &= summary my_summary
index 9b22f5cfa20afe00ac3b82160a743781061ae754..fc1b1b18eba02c44d549de693cc8f3d65fd6ea1e 100644 (file)
@@ -15,7 +15,7 @@ import Network.DNS (
   defaultResolvConf,
   makeResolvSeed,
   withResolver)
-import Network.DNS.Lookup (lookupMX)
+import Network.DNS.Lookup (lookupA, lookupMX)
 import System.Directory (doesFileExist)
 import System.Exit (exitWith, ExitCode(..))
 import System.IO (
@@ -60,17 +60,35 @@ validate_mx resolver domain
         _       -> return True
 
 
+-- | Check whether the given domain has a valid A record.
+validate_a :: Resolver -> Domain -> IO Bool
+validate_a resolver domain
+  | domain `elem` common_domains = return True
+  | otherwise = do
+      result <- lookupA resolver domain
+      case result of
+        Nothing -> return False
+        _       -> return True
+
 
 -- | Validate an email address by doing some simple syntax checks and
 --   (if those fail) an MX lookup. We don't count an A record as a mail
 --   exchanger.
-validate :: Resolver -> Address -> IO (Address, Bool)
-validate resolver address = do
+validate :: Resolver -> Bool -> Address -> IO (Address, Bool)
+validate resolver accept_a address = do
   let valid_syntax = validate_syntax address
   if valid_syntax then do
     let (_,domain) = parts address
     mx_result <- validate_mx resolver domain
-    return (address, mx_result)
+    if mx_result
+    then return (address, True)
+    else
+      if accept_a
+      then do
+        a_result <- validate_a resolver domain
+        return (address, a_result)
+      else
+        return (address, False)
   else
     return (address, False)
 
@@ -112,7 +130,7 @@ main = do
   rs <- makeResolvSeed resolv_conf
   withResolver rs $ \resolver -> do
     -- Construst a list of [IO (Address, Bool)]
-    let actions = map (validate resolver) nonempty_addresses
+    let actions = map (validate resolver accept_a) nonempty_addresses
     -- And compute them in parallel.
     results <- parallel actions
     stopGlobalPool