+{-# LANGUAGE DoAndIfThenElse #-}
+
+module Main
+where
+
+import Control.Monad (filterM)
+import qualified Data.ByteString.UTF8 as BS
+import Network.DNS (
+ Domain,
+ Resolver,
+ ResolvConf(..),
+ defaultResolvConf,
+ makeResolvSeed,
+ withResolver)
+import Network.DNS.Lookup (lookupMX)
+import System.IO (hGetContents, hFlush, hPutStrLn, stdin, stdout)
+
+
+type Address = BS.ByteString
+
+resolv_conf :: ResolvConf
+resolv_conf = defaultResolvConf { resolvTimeout = 5 * 1000 * 1000 }
+
+validate_mx :: Resolver -> Domain -> IO Bool
+validate_mx resolver domain = do
+ result <- lookupMX resolver domain
+ case result of
+ Nothing -> return False
+ _ -> return True
+
+validate_syntax :: Address -> IO Bool
+validate_syntax address = do
+ return True
+
+utf8_split = undefined
+
+validate :: Resolver -> Address -> IO Bool
+validate resolver address = do
+ valid_syntax <- validate_syntax address
+ if valid_syntax then do
+ let domain = utf8_split address (BS.fromString "@")
+ validate_mx resolver domain
+ else do
+ return False
+
+empty_string :: BS.ByteString
+empty_string = BS.fromString ""
+
+main :: IO ()
+main = do
+ input <- hGetContents stdin
+
+ let addresses = BS.lines $ BS.fromString input
+ let nonempty_addresses = filter (/= empty_string) addresses
+
+ rs <- makeResolvSeed resolv_conf
+ withResolver rs $ \resolver -> do
+ good_addresses <- filterM (validate resolver) nonempty_addresses
+ let good_address_strings = map BS.toString good_addresses
+ mapM_ (hPutStrLn stdout) good_address_strings
+
+ hFlush stdout