GC;      !"#$%&'()*+,-./0123456789:None9just a newtype to distinguish address from other strings.P... actually, any string at all is considered a valid "time" string we can use.get the unix time is this a ; field? Is this a < field? make up the " Received:G" header, given a time, a possible "from" address, and a "to" address. $strip whitespace from right-hand end add minimal headers: a " Received: " header, a "Date:4" header if we haven't already been given one, a "From:-" field if we haven't already been given one. =     = None *Data structure for command-line arguments.Possible envelope address.Possible sender full nameRecipients. (Ignored.)>,A hidden "helper" option which always fails.?Addr option reader@name option readerAjcombinator thing for the mode of something (e.g. "-bm".) Tell user we only accept one permissible mode.BParser for command-line args.TODO:!add more (ignored) options. see 3http://www.sendmail.org/~ca/email/man/sendmail.htmlCprogram versionDjust here for testingElocal E" function, can be used for testingFjust used for testing G>?@ABCDEF   G>?@ABCDEFSafe6Location of the config file, baked in at compile time.Safe- $wrapper around our implementation - H.Wrapper around I.validate "foo@gmail.com"Right "foo@gmail.com"import Data.Either (isLeft)(isLeft $ validate "not an email address"TrueWrapper around J. Similar to , but returns K& if the email address fails to parse.emailAddress "foo@gmail.com"Just "foo@gmail.com"#emailAddress "not an email address"Nothing Create an  from a L value. See . Create an  from a L value. See . Create an  from a M value. See . Create an  from a M value. See .Wrapper around N.Unsafely create an z from a local part and a domain part. The first argument is the local part, and the second argument is the domain part."For example, in the email address  foo@gmail.com, the local part is foo and the domain part is  gmail.com.$unsafeEmailAddress "foo" "gmail.com""foo@gmail.com" ,import qualified Data.ByteString.Char8 as BS:set -XOverloadedStrings+show $ unsafeEmailAddress "foo" "gmail.com""\"foo@gmail.com\""!*(read "\"foo@gmail.com\"") :: EmailAddress"foo@gmail.com"  Local part Domain part !    ! unportableNone:$,Configuration, as read from the config file.) unistd funcs:  #include  unistd.ht int setresuid(uid_t ruid, uid_t euid, uid_t suid); int setresgid(gid_t rgid, gid_t egid, gid_t sgid); *wrapper around C func  setresgid.+wrapper around C func  setresuid.,-opens w/ mode 0644, but gives error if existsi.e.  -rw-r--r---_opens and closes a file created with openIfNExist, and executes the action f on it in between.."get the uid and gid for a username/bReturn an allegedly unique filename; useful to add new mail files in a maildir. Name is of format  time  randomnum  hostname.from 0https://hackage.haskell.org/package/imm-0.5.1.0/0 force either1emit warning to stderr2for use with Either3getConfig filename reads the config file at filename.4the I type is simply something that _might_ be an address, this validates it.5wrapper around validateAddr. Pass in a func that takes in a (presumably bad) address and an error message, and spits out a stringAnd then, the Maybe/Either result of validation will get turned into an appropriate MonadError action we can just execute in IO.6bdeliver mail to the maildir directory mailDir, owned by userName, with command-line args cmdArgs.Creates a unique file name w/ getUniqueName. If something creates the file in between generating the name and delivering mail, an IOError will get thrown. )AttCmdArgs should never have 0 recipients7process args as for sendmail.  sendmail [flags] [receipients] < message -f = envelop sender address -F = full name of sender -bm = read mail from stdin (default) -bp, -bs = we ignore these 8here for testing purposes $%&'()*+,-./012345678$%'&()*+,-./012345678)(*+,-./012$%&'345678$%&'()*+,-./012345678O      !"#$%&&'()*+,-./0123456789:;<=;<>?@ABCDEFGHIHJHJKLMNOPKLQHI!RmainDeliveryHeadersCmdArgsConfigLocation EmailAddressMainAddrunAddrMailTimetoStr getMailTimeisDateisFrom makeReceivedrstrip addHeaders $fShowAddr$fEqAddr AttCmdArgssenderEnvelopeAddresssenderFullName recipients withCmdArgs$fEqAttCmdArgs$fShowAttCmdArgsconfigFileLocnunEmailAddressvalidate emailAddressvalidateFromTextemailAddressFromTextvalidateFromStringemailAddressFromStringunsafeEmailAddress$fShowEmailAddress$fReadEmailAddress$fEqEmailAddress$fOrdEmailAddressConfigmailDiruserName setresuid_c setresgid_c setResGid setResUid openIfNExist withMailFile getUserIDs getUniqueNameforceEitherMsgwarningmkError getConfig validateAddr handleAddr deliverMailtest $fShowConfig $fEqConfig'hsemail-ns-1.7.7-8qup0FGKjGaE3HDW64rXcY'Text.ParserCombinators.Parsec.Rfc2822NSDateFromhelperaddrnamemode attCmdArgsversiontestMaindoStuff strOption+email-validate-2.2.0-KIZNKyGrO33JvE2ajJguVLText.Email.ParserText.Email.ValidatebaseGHC.BaseNothing#text-1.2.2.2-FIorhdfEwKc4H3v6Mihn0yData.Text.InternalTextString