{
    "mode": "info",
    "parameter": "maildropfilter",
    "section": "",
    "url": "https://www.chedong.com/phpMan.php/info/maildropfilter/json",
    "generated": "2026-07-06T02:03:22Z",
    "synopsis": "/etc/maildroprc, $HOME/.mailfilter, $HOME/.mailfilters/*, and\nfriends...",
    "sections": {
        "NAME": {
            "content": "maildropfilter - maildrop's filtering language\n",
            "subsections": []
        },
        "SYNOPSIS": {
            "content": "/etc/maildroprc, $HOME/.mailfilter, $HOME/.mailfilters/*, and\nfriends...\n",
            "subsections": []
        },
        "DESCRIPTION": {
            "content": "This manual page describes the language used by maildrop to filter\nE-mail messages. The mail filtering instructions are read from a file.\nThe language is loosely structured, it is based on pattern matching.\nThe language has a distinct lexical and syntactical structure, very\nsimilar to Perl's, but it is important to note that it is not Perl, and\nis very different from Perl, in certain cases.\n\nIf the filtering instructions do not exist, maildrop delivers the\nmessage to the default mailbox without doing any additional processing,\nmaking it indistinguishable from the usual mail delivery agent.\n\nIt is important to note that maildrop reads and parses the filter file\nbefore doing anything. If there are any errors maildrop prints an error\nmessage, and terminates with the exit code set to EXTEMPFAIL. A\ncompliant mail transport agent should re-queue the message for a later\ndelivery attempt. Hopefully, most simple syntax errors will not cause\nmail to be bounced back if the error is caught and fixed quickly.\n\nEnvironment\nmaildrop uses variables to access and manipulate messages. Variables\nare arbitrary text accessed by referring to the name of the variable,\nsuch as HOME, or DEFAULT. Text is placed into a variable by using an\nassignment statement, such as:\n\nFILE=\"IN.junk\"\n\nThis statement puts the text \"IN.junk\" (without the quotes) into a\nvariable whose name is FILE. Later, the contents of a variable are\naccessed by using the $ symbol and the name for the variable. For\nexample:\n\nto $FILE\n\nThis will deliver the current message to the mailbox file (or a maildir\ndirectory) named \"IN.junk\".\n\nmaildrop initially creates variables from the environment variables of\nthe operating system, UNLESS maildrop runs in delivery mode. Each\noperating system environment variable becomes a maildrop variable. When\nrunning in delivery mode, maildrop does not import the environment for\nsecurity reasons, except for the environment variables that define the\nprocess locale (LANG, LANGUAGE, and LC*), which are still imported.\n\nIn all cases maildrop resets the following variables to their default\nvalues: HOME, DEFAULT, SHELL, PATH, LOCKEXT, LOCKREFRESH, LOCKSLEEP,\nLOCKTIMEOUT, MAILDIRQUOTA, SENDMAIL and LOGNAME.\n\nThere's one exception to this rule which applies to the version of\nmaildrop that comes with the Courier mail server[1]. The following does\nnot apply to the standalone version of maildrop: when running in\ndelivery mode, if the -d flag was not used, or if it specifies the same\nuserid as the one that's running maildrop: the following variables are\nautomatically imported from the environment: HOME, SHELL, LOGNAME and\nMAILDIRQUOTA. These environment variables are initialized by the\nCourier mail server prior to running maildrop. Additionally, the\ninitial value for the DEFAULT maildrop variable is imported from the\nMAILDROPDEFAULT environment variable. This is because the Courier mail\nserver overloads the DEFAULT environment variable to store the\ndefaulted portion of the local mailbox address. See the\ndot-courier(5)[2] man page in the Courier mail server distribution. You\ncan get the Courier mail server's DEFAULT value by using the import\ncommand. Note, however, that this will clobber the old contents of\nDEFAULT, which is probably not what you want. The right way to do this\nwould be something like this:\n\nSAVEDEFAULT=$DEFAULT\nimport DEFAULT\nLOCALDEFAULT=$DEFAULT\nDEFAULT=$SAVEDEFAULT\n\nAll internal variables are exported back as environment variables when\nmaildrop runs an external command. Changes to internal variables, made\nby the filter file, are reflected in the exported environment.\n\nLexical structure\nMost whitespace is generally ignored. The # character introduces a\ncomment running to the end of the line, which is also ignored. Unlike\nother mail filters, maildrop parses the filter file before taking any\naction with the message. If there are syntax errors in the file,\nmaildrop displays an error message, and returns EXTEMPFAIL. That\nshould cause the mail message to remain in the queue, and, hopefully\nallow the problem to be corrected, without bouncing any mail.\n\nNote\nIn maildrop, the end of line is a lexical token. In order to\ncontinue a long statement on the next line, terminate the line with\na backslash character.\n\nLiteral text\nLiteral text in the maildrop filtering language is surrounded by either\nsingle or double quotes. In order to enter a single quote into a text\nliteral surrounded by single quotes, or a double quote into a literal\nsurrounded by double quotes, prefix it with a backslash character. Use\ntwo backslash characters characters to enter one backslash character in\nthe text literal.\n\nNote\nA backslash followed by either a backslash, or a matching quote, is\nthe only situation where the backslash character is actually\nremoved, leaving only the following character in the actual text\nliteral. If a backslash character is followed by any other\ncharacter, the backslash is NOT removed.\n\nMultiple text literals in a row are automatically concatenated, even if\nthey use different quotes. For example:\n\nFOOBAR=\"Foo\"'bar'\nSAVEDEFAULT=$DEFAULT\nimport DEFAULT\nLOCALDEFAULT=$DEFAULT\nDEFAULT=$SAVEDEFAULT\n\nThis sets the variable FOOBAR to the text \"Foobar\".\n\nVariable substitution\nVariable substitution is performed on text literals that's surrounded\nby double quotation marks. The \"$\" character, followed by a variable\nname, is replaced by that variable's contents.\n\nMAILBOX=\"$HOME/Mailbox\"\n\nThis sets the variable MAILBOX to the contents of the variable HOME\nfollowed by \"/Mailbox\". Variable names must begin with an uppercase\nletter, a lowercase letter, or an underscore. Following that, all\nletters, digits, and underscores are taken as a variable name, and its\ncontents replace the $ sign, and the variable name. It is possible to\naccess variables whose name includes other characters, by using braces\nas follows:\n\nMAILBOX=\"${HOME-WORD}/Mailbox\"\n\nInserts the contents of the HOME-WORD variable. If the variable does\nnot exist, the empty text literal is used to replace the variable name.\nIt is not possible to access variables whose names include the }\ncharacter.\n\nIf the $ character is not followed by a left brace, letter, or an\nunderscore, the $ character remains unmolested in the text literal. A\nbackslash followed by the $ character results in a $ character in the\ntext literal, without doing any variable substitution.\n\nVariable substitution is not done in text literals which are surrounded\nby single quotes (apostrophes).\n\nCommand line arguments\nmaildrop initializes special variables: $1, $2, and so on, with\nadditional parameters specified on the maildrop command line. A filter\nfile may use those variables just like any other variables.\n\nPredefined variables\nThe following variables are automatically defined by maildrop. The\ndefault values for the following variables may be changed by the system\nadministrator. For security reasons, the values of the following\nvariables are always reset to their default values, and are never\nimported from the environment:\n\nDEFAULT\nThe default mailbox to deliver the message to. If the filter file\ndoes not indicate a mailbox to deliver this message to, the message\nis delivered to this mailbox. The default mailbox is defined by the\nsystem administrator.\n\nFROM\nMessage envelope sender. This is usually the same address as what\nappears in the From: header, but may not be. This information may\nor may not be available to maildrop on your system. The message\nenvelope sender is usually specified with the -f option to\nmaildrop. If the -f option is not given, maildrop looks for the\nReturn-Path: header in the message. As the last resort, FROM\ndefaults to \"MAILER-DAEMON\". Note that FROM may be empty - the\nmessage envelope sender is empty for bounce messages.\n\nHOME\nHome directory of the user running maildrop.\n\nHOSTNAME\nNetwork name of the machine running maildrop. Obtained from\ngethostname(3).\n\nLOCKEXT\nExtension for dot-lock files (default: .lock).\n\nLOCKREFRESH\nRefresh interval, in seconds, for dot-locks (default: 15). When\nmaildrop dot-locks a mailbox, maildrop tries to refresh the lock\nperiodically in order to keep other programs from removing a stale\ndot-lock. This is only required if a dot-lock exists for a\nprolonged period of time, which should be discouraged anyway.\n\nLOCKSLEEP\nNumber of seconds to wait to try again to create a dot-lock file,\nif one already exists (default: 5).\n\nLOCKTIMEOUT\nNumber of seconds to wait before removing a stale dot-lock file\n(default: 60). If a dot-lock file still exists after LOCKTIMEOUT\nseconds, maildrop assumes that the process holding the lock no\nlonger exists, and the dot-lock file can be safely removed. After\nremoving the dot-lock file, maildrop waits LOCKSLEEP seconds before\ntrying to create its own dot-lock file, in order to avoid a race\ncondition with another process which is also trying to remove the\nsame stale dot-lock, at the same time.\n\nLOGNAME\nName of the user to who the message is being delivered.\n\nMAILDROPOLDREGEXP\nRevert to using the old legacy pattern matching engine. Versions of\nmaildrop prior to version 2.0 (included in the Courier mail server\n0.51, and earlier), used a built-in pattern matching engine,\ninstead of using the PCRE library (see the \"Patterns\" section).\nmaildrop 1.x used a different syntax for patterns, which is no\nlonger described in this manual page. The old pattern matching\nengine is still available, by setting MAILDROPOLDREGEXP to \"1\".\nSetting this variable will use the legacy pattern matching engine\nfor the rest of the maildrop recipe file.\n\nThe pattern matching engine will be removed completely in a future\nversion of maildrop. This setting provides for a transitional\nperiod of converting old recipes.  MAILDROPOLDREGEXP can be set\nto \"1\" in the global maildroprc file, then reset to \"0\" in each\nindividual maildrop recipe file, after it gets converted to the new\nsyntax.\n\nMAILFILTER\nThis is the name of the original filter file that was given to\nmaildrop on the command line. This is mostly useful to -default\nfilter files, it allows them to obtain the value of the -M\noption[3] specified on the command line.\n\nPATH\nCommand execution path.  maildrop resets PATH to the system default\n(usually /bin:/usr/bin:/usr/local/bin).\n\nSENDMAIL\nThe mail delivery agent. When maildrop is instructed to deliver the\nmessage to a mailbox whose name begins with the ! character, this\nis interpreted as a request to forward the message. The SENDMAIL\ncommand is executed to forward the message.\n\nSHELL\nThe login shell. The shell is used to execute all commands invoked\nby maildrop.\n\nVERBOSE\nCurrent Debug level (default: 0). Setting VERBOSE to progressive\nhigher values, between 1 and 9, produces debugging output on\nstandard error.  maildrop ignores the VERBOSE variable in delivery\nmode (in order not to confuse the mail transport agent).\n\nUMASK\nThe file creation mode mask, in octal. The default setting of 077\ncreates mailboxes that are readable and writable by the owner only.\nUse 007 to create mailboxes that are readable/writable by both\nowner and the group. Use 037 to create mailboxes that are readable\nby both owner and group, but writable by owner only. Permissions on\nexisting mailboxes are not changed, this setting affects only new\nmailboxes. When delivering to maildirs this setting sets the\npermissions on new messages only. Access permissions on messages in\nmaildirs are also affected by the permissions on the maildir\ndirectories.\n\nOther special variables\nThe following variables are automatically used by maildrop when the\nfilter file is being processed:\n\nEXITCODE\nReturn code for maildrop. When maildrop successfully delivers a\nmessage, it terminates with this exit code, which defaults to 0.\nWhen the to or the cc command is used to deliver the message to an\nexternal process, via a pipe, maildrop will set this variable to\nthe exit code of the external process. Since maildrop immediately\nterminates after completing the to command this means that\nmaildrop's exit code will be the exit code of the external process.\nIf the to command does not deliver the message to a process you\nmust set EXITCODE before the to command, since maildrop terminates\nimmediately after finishing the delivery.\n\nFLAGS\nThe FLAGS variable is used only when delivering a message to a\nmaildir, and may contain only the following letters: \"D\", \"F\", \"R\",\nand \"S\". They may appear in any order. When the message gets\ndelivered to the maildir, the message will be marked with a draft,\nflag, replied, or seen, attribute, correspondingly.\n\nFLAGS must be set before the message is delivered to a maildir. The\ncontents of FLAGS are ignored, when delivering on an mbox folder.\n\nKEYWORDS\nThe KEYWORDS variable is used only when delivering a message to a\nmaildir, and implements the optional IMAP keyword extension as\nimplemented in the Courier IMAP server[1]. It may be optionally\ninitialized to contain a comma-separate list of keywords. The to,\nor the cc command, delivers the message to the maildir normally,\nbut also associated the list of keywords in KEYWORDS with the newly\ndelivered message.\n\nKEYWORDS must be set before the message is delivered to a maildir.\nThe contents of KEYWORDS are ignored, when delivering on an mbox\nfolder.\n\nLINES\nNumber of lines in the current message. Note that this may be an\napproximation. It may or may not take into account the -A option.\nUse this as criteria for filtering, nothing more.\n\nMAILDIRQUOTA\nSet this variable in order to manually enforce a maximum size on\nANY maildir where the message is delivered. This is an optional\nfeature that must be enabled by the system administrator, see\nmaildirquota(8)[4] for more information.\n\nRETURNCODE\nThis variable is set when maildrop runs the system[5] command,\nxfilter[6] command, or a command that's specified within a pair of\nbacktick characters ( command substitution ). The RETURNCODE\nvariable will be set to the exit code of the command, after it\ncompletes.\n\nSIZE\nNumber of bytes in the message. This may or may not include the -A\noption. Use this as a criteria for filtering, nothing more.\n\nUnquoted text\nAll text strings in filter files should be in single, or double quotes.\nHowever, for convenience sake, quotes can be omitted under certain\ncircumstances.\n\nText that includes ONLY letters, digits, and the following characters:\n-.:/${}@ may appear without quotes. Note that this does not allow\nspaces, or backslashes to be entered, however the text is still\nvariable-substituted, and the substituted text may contain other\ncharacters.\n\nAlso, note that patterns (see below) begin with the slash character.\nNormally, anything that begins with the slash is interpreted as a\npattern. However, text immediately after \"VARIABLE=\" is interpreted as\na string even if it begins with a slash. This is why something like:\n\nMAILDIR=/var/mail\n\nworks as expected. Using quotes, though, is highly recommended. You\nmust use quotes to set a variable to a lone slash, because an unquoted\nslash is interpreted as a division sign.\n\nLong double or singly-quoted text can be broken across multiple lines\nby ending the line with a lone backslash character, like this:\n\nTEXT=\"This is a long \\\ntext string\"\n\nThe backslash, the newline, and all leading whitespace on the next line\nis removed, resulting in \"This is a long text string\".\n\nCommand substitution\nText enclosed in back-tick characters is interpreted as a shell\ncommand. The shell command is executed as a child process by maildrop.\nIts output is used in place of the command. For example:\n\nDIR=`ls`\n\nplaces the names of the files in the current directory into the DIR\nvariable.\n\nThe output of the command will have all newline characters replaced by\nspaces, and leading and trailing spaces will be stripped (multiple\nspaces are not removed, though). Also, the contents of the message\nbeing delivered is made available to the command on standard input.\n\nPatterns\nThe pattern syntax in maildrop is similar to the grep command's syntax,\nwith some minor differences. A pattern takes the following form in the\nfilter file:\n\n/pattern/:options\n\npattern specifies the text to look for in the message, in the UTF-8\ncodeset.  pattern must not begin with a space, otherwise the leading\nslash will then be interpreted as a division sign. If you must search\nfor text that starts with a space, use something like \"/[ ] ... /\".\n\nThe general syntax of maildrop's patterns is described in the\npcrepattern(3) manual page, with certain exceptions noted below.\nmaildrop uses the PCRE[7] library to implement pattern matching. Not\nall features in PCRE are available in maildrop, and the \"options\" part,\nwhich follows the pattern specification, changes the pattern matching\nfurther. Consult the pcrepattern(3) manual page for more information,\nbut note the following exceptions:\n\no   Internal options settings are not supported (but see the \"D\"\nmaildrop option, below). Do not include option settings in the\npattern, doing so will lead to undefined results.\n\no   Named subpatterns are not implemented. Numbered subpatterns are\nimplemented, see \"Pattern Match Results\", below.\n\no   The search pattern gets executed not against the raw message text,\nbut the message transcoded into a canonical UTF-8-based format.\nThis process involves transcoding any non-UTF-8 message content\ninto UTF-8. Additionally, message headers get converted into a\ncanonical format before the search pattern gets executed.\n\nFor structured headers with email addresses, the process involves\nremoving extraneous punctuation, or adding missing ones (in\nsituations where a missing punctuation character can be deduced).\nAdditionally certain pre-RFC822 obsolete header formats get\nconverted to canonical form.\n\nThis means that header search patterns that include punctuation\ncharacter may appear not to work against obviously-matching message\ntext. Use \"reformime -u <message.txt\", with message.txt containing\nthe sample message, to see exactly the actual text that gets\nsearched by patterns.\n\nPattern options\nFollowing /pattern/, there may be an optional colon, followed by one.\nor more options. The following options may be specified in any order:\n\nh\nMatch this pattern against the message header.\n\nb\nMatch this pattern against the message body.\n\nD\nThis is a case sensitive match. Normally the patterns match either\nuppercase or lowercase text.  /john/ will match \"John\", \"john\", or\n\"JOHN\". Specify the D option for a case-sensitive search: lowercase\nletters in the pattern must match lowercase letters in the message;\nditto for uppercase.\n\nIf neither 'h' or 'b' is specified, the pattern is matched against the\nheader only. Specifying the 'b' option causes the pattern to be matched\nagainst the message body. Specifying both causes the pattern to be\nmatched against the entire message.\n\nNormally, each line in the message gets matched against the pattern\nindividually. When applying patterns to a header, multi-line headers\n(headers split on several lines by beginning each continuation line\nwith whitespace) are silently combined into a single line, before the\npattern is applied.\n\nMIME encoding\nThe pattern must be a valid text string in the UTF-8 codeset, and\nmaildrop should handle messages that use MIME encodings in other known\ncharacter sets.  Options that specify a message header search result in\nmaildrop searching the initial message headers, and any headers of\nadditional MIME sections, in a multipart MIME message. Options that\nspecify a message body search will search through all \"text\" MIME\ncontent.\n\nFor a MIME search to succeed, the message must be a well-formed MIME\nmessage (with a Mime-Version: 1.0 header).\n\nWeighted scoring\nPatterns are evaluated by maildrop as any other numerical expression.\nIf a pattern is found, maildrop's filter interprets the results of the\npattern match as number 1, or true, for filtering purposes. If a\npattern is not found the results of the pattern search is zero. Once a\npattern is found, the search stops. Second, and subsequent occurrences\nof the same pattern are NOT searched for.\n\nmaildrop can also do weighted scoring. In weighted scoring, multiple\noccurrences of the same pattern are used to calculate a numerical\nscore.\n\nTo use a weighted search, specify the pattern as follows:\n\n/pattern/:options,xxx,yyy\n\nwhere xxx and yyy are two numbers.  yyy is optional -- it will default\nto 1, if missing.\n\nThe first occurrence of the pattern is evaluated as xxx. The second\noccurrence of the pattern is evaluated as xxx*yyy, the third as\nxxx*yyy*yyy, etc... All occurrences of the pattern are added up to\ncalculate the final score.\n\nNote\nmaildrop does not recognize multiple occurrences of the same\npattern in the same line. Multiple occurences of the same pattern\nin one line count as one occurence.\n\nPattern Match Results\nAfter a pattern is successfully matched, the actual text that is\nmatched is placed in the MATCH variable. For example:\n\n/^From:.*/\n\nmatches a line of the form:\n\nFrom: postmaster@localhost\n\nHere the variable MATCH will be set to \"From: postmaster@localhost\",\nwhich can be used in subsequent statements.\n\nIf the pattern contains subpatterns, the portions of the text that\nmatch the first subpattern is placed in the MATCH1 variable. The second\nsubpattern, if any, is placed in MATCH2, and so on:\n\n/^From:\\s+(.*)@(.*)/\n\nmatched against the same line will set MATCH to \"From:\npostmaster@localhost\", MATCH1 to \"postmaster\", and MATCH2 to\n\"localhost\". Of course, in real world the \"From:\" header is usually\nmuch more complicated, and can't be handled that easily. This is just\nan illustrative example.\n\nNote\nSubpatterns are not processed in the foreach statement.\n\nConversion of maildrop 1.x patterns to 2.0\nAlthough the new PCRE-based pattern matching code in maildrop is\ncompletely different from the built-in pattern matching code in\nmaildrop 1.x, very few changes will be required to convert recipes to\nthe new syntax. The only major differences are:\n\no   The subexpression format has changed. Any pattern that uses\nsubexpression needs to be converted. Additionally, references to\nMATCH2 must be replaced with MATCH1, MATCH3 to MATCH2, and so on.\nReferences to plain old MATCH will remain the same.\n\no   The \"w\" pattern option is no longer possible, with PCRE. The very\nfew recipes that use this option, if any actually exist, will have\nto be rewritten in some other fashion.\n\nExpressions\nAlthough maildrop evaluates expressions numerically, results of\nexpressions are stored as text literals. When necessary, text literals\nare converted to numbers, then the results of a mathematical operation\nis converted back into a text literal.\n\nOperators\nThe following operators carry their usual meaning, and are listed\nin order from lowest precedence, to the highest:\n\n||\n&&\n<  <=  >  >=  ==  !=  lt  le  gt  ge  eq  ne\n|\n&\n+  -\n*  /\n=~ /pattern/\n/pattern/  !  ~  function()\n\nVariable assignment\nVARIABLE=expression\n\nAssigns the result of the expression to VARIABLE (note no leading $\nin front of variable).\n\nNote\nIf VARIABLE is NOT surrounded by quotes, then it may contain\nonly letters, numbers, underscores, dashes, and a selected few\nother characters. In order to initialize a variable whose name\ncontains non-standard punctuation marks, surround the name of\nthe variable with quotes.\n\ncc - deliver a copy of the message\ncc expression\n\nThe cc statement is very similar to the to statement, except that\nafter delivering the message maildrop continues to process the\nfilter file, unlike the to statement which immediately terminates\nmaildrop after the delivery is complete. Essentially, the message\nis carbon copied to the given mailbox, and may be delivered again\nto another mailbox by another cc or to statement.\n\nSee the to statement[8] for more details. When cc is used to\ndeliver a message to a process maildrop will set the EXITCODE\nvariable to the process's exit code.\n\ndotlock - create a manual dot-lock\ndotlock expression {\n\n...\n\n}\n\nmaildrop automatically creates a lock when a message is delivered\nto a mailbox. Depending upon your system configuration, maildrop\nwill use either dot-locks, or the flock() system call.\n\nThe dotlock statement creates an explicit dot-lock file. Use the\nflock statement[9] to create an explicit flock() lock.\n\nThe expression is a filename that should be used as a lock file.\nmaildrop creates the indicated dot-lock, executes the filtering\ninstructions contained within the { ... } block, and removes the\nlock. The expression must be the name of the dot-lock file itself,\nNOT the name of the mailbox file you want to lock.\n\nNote\nWith manual locking, it is possible to deadlock multiple\nmaildrop processes (or any other processes that try to claim\nthe same locks).\n\nNo deadlock detection is possible with dot-locks, and since\nmaildrop automatically refreshes all of its dot-locks\nregularly, they will never go stale. You'll have maildrop\nprocesses hanging in limbo, until their watchdog timers go off,\naborting the mail delivery.\n\necho - output diagnostic information\necho expression\n\nmaildrop will print the given text. This is usually used when\nmaildrop runs in embedded mode, but can be used for debugging\npurposes. Normally, a newline is printed after the text. If text is\nterminated with a \\c, no newline will be printed.\n\nexception - trap fatal errors\nexception {\n\n...\n\n}\n\nThe exception statement traps errors that would normally cause\nmaildrop to terminate. If a fatal error is encountered anywhere\nwithin the block of statements enclosed by the exception clause,\nexecution will resume immediately following the exception clause.\n\nexit - terminate filtering unconditionally\nexit\n\nThe exit statement immediately terminates filtering.  maildrop's\nreturn code is set to the value of the EXITCODE variable. Normally,\nmaildrop terminates immediately after successfully delivering the\nmessage[8] to a mailbox. The exit statement causes maildrop to\nterminate without delivering the message anywhere.\n\nThe exit statement is usually used when maildrop runs in embedded\nmode[10], when message delivery instructions are not allowed.\n\nflock - create an manual flock() lock\nflock expression {\n\n...\n\n}\n\nmaildrop automatically creates a lock when a message is delivered\nto a mailbox. Depending upon your system configuration, maildrop\nwill use either dot-locks, or the flock() system call.\n\nThe flock statement creates a manual flock() lock. Use the dotlock\nstatement[11] to create a manual dot-lock file.\n\nThe expression is the name of the file that should be locked.\nmaildrop creates the lock on the indicated file, executes the\nfiltering instructions contained within the { ... } block, and\nremoves the lock.\n\nNote\nWith manual locking, it is possible to deadlock multiple\nmaildrop processes (or any other processes that try to claim\nthe same locks). The operating system will automatically break\nflock() deadlocks. When that happens, one of the maildrop\nprocesses will terminate immediately. Use the exception\nstatement in order to trap this exception condition, and\nexecute an alternative set of filtering instructions.\n\nforeach - iterate over text sections matched by a pattern\nforeach /pattern/:options\n{\n...\n}\n\nforeach (expression) =~ /pattern/:options\n{\n...\n}\n\nThe foreach statement executes a block of statements for each\noccurrence of the given pattern in the given message, or\nexpression. On every iteration MATCH variable will be set to the\nmatched string. All the usual options may be applied to the pattern\nmatch, EXCEPT the following:\n\n,xxx,yyy\nWeighted scoring is meaningless, in this context.\n\n( ... )\nSubpatterns are not processed. Only the MATCH variable will be\nset for each found pattern.\n\nif - conditional execution\nif (expression)\n{\n...\n}\nelse\n{\n...\n}\n\nConditional execution. If expression evaluates to a logical true\n(note - parenthesis are required) then the first set of statements\nis executed. The else keyword, and the subsequent statements, are\noptional. If present, and the expression evaluates to a logical\nfalse, the else part is executed.\n\nmaildrop evaluates all expression as text strings. In the context\nof a logical expression, an empty string, or the number 0\nconstitutes a logical false value, anything else is a logical true\nvalue.\n\nIf the if part, or the else part consists of only one statement,\nthe braces may be omitted.\n\nNote\nThe grammar of this if statement is stricter than usual. If you\nget baffling syntax errors from maildrop, make sure that the\nbraces, and the if statement, appear on separate lines.\nSpecifically: the closing parenthesis, the closing braces, and\nthe else statement, must be at the end of the line (comments\nare allowed), and there may not be any blank lines in between\n(not even ones containing comments only).\n\nIf the else part contains a single if, and nothing else, this may\nbe combined into an elsif:\n\nif (expression)\n{\n...\n}\nelsif (expression)\n{\n...\n}\n\nThe above example is logically identical to:\n\nif (expression)\n{\n...\n}\nelse\n{\nif (expression)\n{\n...\n}\n}\n\nConsecutive elsif sequences are allowed:\n\nif (expression)\n{\n...\n}\nelsif (expression)\n{\n...\n}\nelsif (expression)\n{\n...\n}\n\nConsecutive occurences of elsif commands eliminate a significant\namount of indentation, and the resulting code is more readable.\n\nimport - access original environment variable\nimport variable\n\nWhen maildrop starts, it normally imports the contents of the\nenvironment variables, and assigns them to internal maildrop\nvariables. For example, if there was an environment variable FOO,\nthe internal maildrop variable FOO will have the contents of the\nenvironment variable. From then on, FOO will be no different than\nany other variable, and when maildrop runs an external command, the\ncontents of maildrop's variables will be exported as the\nenvironment for the command.\n\nCertain variables, like HOME and PATH, are always reset to fixed\ndefaults, for security reasons. Also, in delivery and embedded\nmodes, the environment is not imported at all (with the exception\nof system locale environment variables), and maildrop starts with\nonly the fixed default variables.\n\nThe import statement initializes the specified variable with the\ncontents of the original environment variable when maildrop\nstarted. For example:\n\necho \"PATH is $PATH\"\nPATH=\"/bin\"\necho \"PATH is $PATH\"\nimport PATH\necho \"PATH is $PATH\"\nexit\n\nThis results in the following output:\n\nPATH is /bin:/usr/bin:/usr/local/bin\nPATH is /bin\nPATH is /home/root/bin:/sbin:/usr/sbin:/bin:/usr/bin:/usr/local/bin\n\nThis shows that when maildrop starts PATH is set to the fixed\ndefault of /bin:/usr/bin:/usr/local/bin. However, the original\ncontents of the PATH environment variable we different, and the\nimport statement shows what it was.\n\ninclude - execute filtering instructions from another file\ninclude expression\n\nThe include statement reads a file, and executes filtering\ninstructions contained in that file. Note that the include\nstatement is processed when the current filter file is being\nexecuted. When maildrop reads the initial filter file, any syntax\nerrors in the filtering instructions are immediately reported, and\nmaildrop will terminate with a return code of EXTEMPFAIL. Any\nerrors in files specified by include statements are NOT reported,\nbecause those files will not be read until the include statement is\nitself executed.\n\nIf the specified file does not exist, or if there are any syntax\nerrors in the file, maildrop reports the error, and terminates with\na return code of EXTEMPFAIL.\n\nlog, logfile - log message deliveries\nlogfile expression\n\nlog expression\n\nLogging in maildrop is normally turned off. The logfile statement\nspecifies the file where maildrop will log how the message has been\ndisposed of. The parameter is then name of the file. If the file\nexists maildrop appends to the file.\n\nFor each delivery (the to[8] and cc[12] statements, and default\ndeliveries) maildrop records the From: and the Subject: fields,\ntogether with the current time, in the log file.\n\nThe log statement adds additional logging text to the log file. The\nlog statement works exactly like the echo statement, except that\nthe text is written to the logfile, instead of standard output.\n\nsystem - execute a system command\nsystem expression\n\nexpression specifies an external program that maildrop runs as a\nsubprocess. The subprocess's standard input gets connected to\n/dev/null, and the subprocess inherits the standard output and\nerror from maildrop.\n\nto - deliver message to a mailbox\nto expression\n\nThe to statement delivers the message to a mailbox.  expression\nmust evaluate to a valid mailbox. A valid mailbox is either a\nmailbox file, a maildir, or an external program (which includes\nforwarding to another address).\n\nThe to statement is the final delivery statement.  maildrop\ndelivers message, then immediately terminates, with its return code\nset to the EXITCODE variable. If there was an error while\ndelivering the message, maildrop terminates with the EXTEMPFAIL\nexit code. A properly-written mail transport agent should re-queue\nthe message, and re-attempt delivery at some later time.\n\nAn expression that begins with the \"|\" character specifies an\nexternal program to run to handle the actual delivery. The SHELL\nvariable specifies the shell to execute the given command. The\nmessage is provided to the command on standard input.  maildrop's\nexit code will be the process's exit code.\n\nAn expression that begins with an exclamation mark, \"!\" specifies a\nwhitespace-delimited list of E-mail addresses to forward the\nmessage to. The program specified by the SENDMAIL variable is run\nas an external program, with the list of E-mail addresses provided\nas parameters to the program.\n\nOtherwise, expression names the mailbox where maildrop delivers the\nmessage. If expression is a directory, maildrop assumes that the\ndirectory is a maildir directory. Otherwise, maildrop will deliver\nthe message to a file, formatted in traditional mailbox format.\nmaildrop will use either dot-locking, or flock()-locking when\ndelivering the message to the file.\n\nwhile - repeatedly execute a block of statements\nwhile (expression)\n{\n...\n}\n\nThe expression is repeatedly evaluated. Each time it evaluates to a\nlogical true[13], the statements inside the braces are executed.\nWhen expression evaluates to a logical false, the while loop is\nover. Take care to avoid infinite loops.\n\nxfilter - filter message through another program\nxfilter expression\n\nexpression specifies an external program that maildrop runs to\nfilter the current message. The current message will be piped to\nthe filter program as standard input. The output of the filter\nprogram replaces the current message being delivered. The external\nprogram must terminate with an exit code of 0. If the external\nprogram does not terminate with an exit code of 0, or if it does\nnot read the message from the standard input, maildrop terminates\nwith an exit code of EXTEMPFAIL.\n\n|| - logical or\nexpression1 || expression2\n\nIf expression1 evaluates to a logical true, the result of the || is\nexpression1, otherwise it's expression2, which is evaluated.\n\nmaildrop uses the following concept of true/false: an empty text\nliteral, or a text literal that consists of the single character\n\"0\" is a logical false value. Anything else is a logical true\nvalue.\n\n&& - logical and\nexpression1 && expression2\n\nIf expression1 evaluates to a logical false, the result of the &&\nis expression1, otherwise it's expression2, which is evaluated.\n\nmaildrop uses the following concept of true/false: an empty text\nliteral, or a text literal that consists of the single character\n\"0\" is a logical false value. Anything else is a logical true\nvalue.\n\n<, <=, >, >=, ==, != - numerical comparison\nexpression1 < expression2\n\nexpression1 <= expression2\n\nexpression1 > expression2\n\nexpression1 >= expression2\n\nexpression1 == expression2\n\nexpression1 != expression2\n\nThese operators compare their left hand side expression against\ntheir right hand side. These operators compare the numerical values\nof each side, as floating point numbers. If the numbers compare as\nindicated, the result of the comparison is the text string \"1\",\notherwise it is the text string 0.\n\nNote\nCcomparisons are not associative: \"a < b < c\" is an error. If\nit is absolutely necessary, use \"(a < b) < c\".\n\nlt, le, gt, ge, eq, ne - text comparison\nexpression1 lt expression2\n\nexpression1 le expression2\n\nexpression1 gt expression2\n\nexpression1 ge expression2\n\nexpression1 eq expression2\n\nexpression1 ne expression2\n\nThese operators compare their left hand side expression against\ntheir right hand side. These operators compare each side as text\nstrings (alphabetically, although the text may include anything).\nIf the text strings compare as indicated, the result of the\ncomparison is the text string \"1\", otherwise it is the text string\n0.\n\nNote\nComparisons are not associative: \"a lt b lt c\" is an error. If\nit is absolutely necessary, use \"(a lt b) lt c\". (But why would\nyou?).\n\n| - bitwise or\nexpression1 | expression2\n\nThis is the bitwise or operator. Its result is a 32 bit integer,\nwhich is a bitwise-or combination of the left hand side and the\nright hand side.\n\n& - bitwise and\nexpression1 & expression2\n\nThis is the bitwise and operator. Its result is a 32 bit integer,\nwhich is a bitwise-and combination of the left hand side and the\nright hand side.\n\n+, -, *, / - numerical operations\nexpression1 + expression2\n\nexpression1 - expression2\n\nexpression1 * expression2\n\nexpression1 / expression2\n\nThese are numerical, floating point, operators.\n\n=~ /pattern/:options - pattern match against string\nexpression =~ /pattern/:option\n\nThe left hand side of the =~ operator can be any expression. The\nright hand side is always a pattern specification. The result of\nthe operator is the weighted match of the pattern against\nexpression (if the options do not specify weighted scoring, the\nresult is simply 1 if the pattern was found, 0 if not).\n\nSee \"Patterns[14]\" for more information.\n\n/pattern/:options - pattern match against message\n/pattern/:option\n\nThe result of this operator is the weighted match of the pattern\nagainst the current message (if the options do not specify weighted\nscoring, the result is simply 1 if the pattern was found, 0 if\nnot).\n\nSee \"Patterns[14]\" for more information.\n\n!, ~ - logical/bitwise not operator.\n! expression\n\n~ expression\n\nThe result of the !  operator is a logical opposite of its right\nhand side expression. If the right hand side expression evaluated\nto a logical true, the result is a logical false. If it evaluated\nto a logical false, the result is a logical true.\n\nmaildrop uses the following concept of true/false: an empty text\nliteral, or a text literal that consists of the single character\n\"0\" is a logical false value. Anything else is a logical true\nvalue.\n\nThe result of the ~ operator is a bitwise complement of its right\nhand side expression. The right hand side expression is evaluated\nas a 32 bit integer, and the result of this operator is a bitwise\ncomplement of the result.\n\nescape(string) - escape special characters in a string.\nescape(expression)\n\nThe escape function returns its sole argument with every occurrence\nof a special character prefixed by a backslash. A special character\nis any of the following characters:\n\n|!$()[]\\+*?.&;`'-~<>^{}\"\n\nThis can used when matching pattern sections[15], and then taking\none section and matching it again. For example:\n\nif ( /^From:\\s*(.*)/ )\n{\nMATCH1=escape($MATCH1)\nif ( /^Subject:.*$MATCH1/ )\n{\n...\n}\n}\n\nThis example checks if the contents of the From: header can also be\nfound in the Subject: header. If the escape function were not used,\nthen any special characters in the From: header that are also used\nin regular expressions, such as * or +, would introduce\nunpredictable behavior, most likely a syntax error.\n\nThe reason why this list of special characters also includes\ncharacters not used in maildrop's regular expressions is to allow\nmaildrop's variables to be used on the command line of a shell\ncommand executed by the xfilter command, backtick characters, or to\nor cc commands.\n\nAlthough using data from an external data source is dangerous, and\nit may result in inadvertent exploits, using the escape function\nshould hopefully result in fewer surprises.\n\ngdbmopen, gdbmclose, gdbmfetch, gdbmstore - GDBM support in maildrop\nThese functions provide support for GDBM database files. See\nmaildropgdbm(5)[16] for more information.\n\nNote\nThe system administrator can disable GDBM support in maildrop,\nso these commands may not be available to you.\n\ngetaddr(string) - extract RFC 2822 addresses from a header.\nif ( /^From:\\s*(.*)/ )\n{\nADDR=getaddr($MATCH1)\n}\n\nThis function is usually applied to a header that contains RFC\n2822[17] addresses. It extracts the actual addresses from the\nheader, without any comments or extraneous punctuation. Each\naddress is followed by a newline character. For example, if string\ncontains:\n\njoe@domain.com (Joe Brown), \"Alex Smith\" <alex@domain.com>, tom@domain.com\n\nThe result of the getaddr function is the following string:\n\njoe@domain.com<NL>alex@domain.com<NL>tom@domain.com<NL>\n\nNote\nBecause getaddr() interprets RFC 2822[18] loosely, it is not\nnecessary to strip off the \"To:\" or the \"Cc:\" header from the\nstring, before feeding it to getaddr(). For example, the\nfollowing snippet of code takes all addresses in the message,\nand concatenates them into a single string, separated by\nspaces:\n\nADDRLIST=\"\"\nforeach /^(To|Cc): .*/\n{\nforeach (getaddr $MATCH) =~ /.+/\n{\nADDRLIST=\"$ADDRLIST $MATCH\"\n}\n}\n\nNote\nIn certain rare situations, RFC 2822[18] allows spaces to be\nincluded in E-mail addresses, so this example is just\neducational.\n\nhasaddr(string) - Search for an address.\nif ( hasaddr(string) )\n{\n...\n}\n\n\"string\" is of the form user@domain. The hasaddr function returns 1\nif this address is included in any To:, Cc:,Resent-To:, or\nResent-Cc:, header in the message, otherwise this function returns\n0.\n\nThis is more than just a simple text search. Each header is parsed\naccording to RFC822. Addresses found in the header are extracted,\nignoring all comments and names. The remaining addresses are\nchecked, and if \"string\" is one of them, hasaddr returns 1,\notherwise it returns 0.\n\nThe comparison is case-insensitive. This actually violates RFC822\n(and several others) a little bit, because the user part of the\naddress may be (but is not required to be) case sensitive.\n\nlength (string) - length of a string\nif (length(string) > 80)\n{\n...\n}\n\nThe length function returns the number of characters in string.\n\nlookup (expr, 'filename', 'options') - read file for patterns\nif (lookup(expr, file, \"option\"))\n{\n...\n}\n\nexpr is any expression.  filename is a name of a file containing a\nlist of patterns. Note that filename is relative to the current\ndirectory, which is the home directory of the user when maildrop\nruns in delivery mode, or embedded mode.  maildrop then reads the\nfile. Blank lines will be ignored, as well as any lines that begin\nwith the # character (comments).\n\nLeading whitespace (but not trailing whitespace, take care) is\nremoved, and the remaining contents of each line are interpreted as\na pattern which is matched against expr. As soon as the match is\nfound, lookup returns \"1\". If no match is found after reading the\nentire file, lookup returns \"0\". For example:\n\nif ( /^To:\\s*(.*)/ && lookup( $MATCH1, \"badto.dat\" ))\n{\nexit\n}\n\nThe file badto.dat contains the following two lines:\n\nfriend@public\n^[^@]*$\n\nIf a message has a To: header that contains the text\n\"friend@public\", or does not contain at least one @ character, then\nthe message will be silently dropped on the floor ( maildrop will\nterminate without delivering the message anywhere).\n\noptions are the pattern matching options to use. The only supported\noption is \"D\" (the rest are meaningless, in this case).\n\nNote\nBe careful with discarding messages like that. Pattern matching\ncan be tricky, and a slight miscalculation can cause mail to be\nunintentionally discarded. It is much desirable to first\ndeliver message to a separate folder or mailbox, and once the\nfilter is verified to work correctly, change it so the messages\nare discarded completely.\n\nsubstr(string,start [,count]) - return substring\nfoo=substr($foo, 1, 10)\n\nThe substr function extracts characters from string beginning with\ncharacter #start. If count is specified, at most count characters\nstarting at position start are kept, any excess is trimmed.\n\ntime - return current time\nfoo=time\n\nThe time function returns the current time, in seconds, since\nJanuary 1, 1970. This function is useful when using GDBM files. See\nmaildropex(7)[19] for an example of using the time function.\n\ntolower(string) - Convert string to lowercase.\nfoo=tolower(string)\n\nThis function returns the string with all uppercase characters\nreplaced by lowercase characters.\n\ntoupper(string) - Convert string to uppercase.\nfoo=toupper(string)\n\nThis function returns the string with all lowercase characters\nreplaced by uppercase characters.\n\nStatements\nThe filter file is read by maildrop ($HOME/.mailfilter or another\nfile), and it contains filtering statements, one per line. The\nfiltering language used by maildrop has a loosely - defined grammatical\nstructure.\n\nStatements are listed one per line. Multiple statements may be listed\non the same line by separating them with semicolons. To continue a long\nstatement on the next line, terminate the line with a backslash\ncharacter.\n",
            "subsections": []
        },
        "BUGS": {
            "content": "If getaddr() or hasaddr() functions are used on broken headers, the\nresults are unpredictable.\n\nhasaddr() is completely case insensitive. This actually violates a few\nRFCs, because the userid portion of the address could be\ncase-sensitive, but it's not in too many cases, so there.\n",
            "subsections": []
        },
        "SEE ALSO": {
            "content": "lockmail(1)[20], maildrop(1)[21], maildropgdbm(5)[16],\nmaildirquota(8)[4], reformail(1)[22], egrep(1), sendmail(8).\n",
            "subsections": []
        },
        "AUTHOR": {
            "content": "Sam Varshavchik\nAuthor\n",
            "subsections": []
        },
        "NOTES": {
            "content": "1. Courier mail server\nhttp://www.courier-mta.org/\n\n2. dot-courier(5)\nhttp://www.courier-mta.org/maildrop/dot-courier.html\n\n3. value of the -M option\nhttp://www.courier-mta.org/maildrop/maildrop.html#moption\n\n4. maildirquota(8)\nhttp://www.courier-mta.org/maildrop/maildirquota.html\n\n5. system\nhttp://www.courier-mta.org/maildrop/#system\n\n6. xfilter\nhttp://www.courier-mta.org/maildrop/#xfilter\n\n7. PCRE\nhttp://www.pcre.org\n\n8. See the to statement\nhttp://www.courier-mta.org/maildrop/#to\n\n9. flock statement\nhttp://www.courier-mta.org/maildrop/#flock\n\n10. embedded mode\nhttp://www.courier-mta.org/maildrop/maildrop.html#embedded\n\n11. dotlock statement\nhttp://www.courier-mta.org/maildrop/#dotlock\n\n12. cc\nhttp://www.courier-mta.org/maildrop/#cc\n\n13. evaluates to a logical true\nhttp://www.courier-mta.org/maildrop/#if\n\n14. Patterns\nhttp://www.courier-mta.org/maildrop/#patterns\n\n15. matching pattern sections\nhttp://www.courier-mta.org/maildrop/#patmatch\n\n16. maildropgdbm(5)\nhttp://www.courier-mta.org/maildrop/maildropgdbm.html\n\n17. RFC 2822\nhttp://www.rfc-editor.org/rfc/rfc2822.txt\n\n18. RFC 2822\nhttp://www.rfc-editor.org/rfc/rfc822.txt\n\n19. maildropex(7)\nhttp://www.courier-mta.org/maildrop/maildropex.html\n\n20. lockmail(1)\nhttp://www.courier-mta.org/maildrop/lockmail.html\n\n21. maildrop(1)\nhttp://www.courier-mta.org/maildrop/maildrop.html\n\n22. reformail(1)\nhttp://www.courier-mta.org/maildrop/reformail.html\n\nCourier Mail Server               07/24/2017                 MAILDROPFILTER(7)",
            "subsections": []
        }
    },
    "summary": "maildropfilter - maildrop's filtering language",
    "flags": [],
    "examples": [],
    "see_also": [
        {
            "name": "lockmail",
            "section": "1",
            "url": "https://www.chedong.com/phpMan.php/man/lockmail/1/json"
        },
        {
            "name": "maildrop",
            "section": "1",
            "url": "https://www.chedong.com/phpMan.php/man/maildrop/1/json"
        },
        {
            "name": "maildropgdbm",
            "section": "5",
            "url": "https://www.chedong.com/phpMan.php/man/maildropgdbm/5/json"
        },
        {
            "name": "maildirquota",
            "section": "8",
            "url": "https://www.chedong.com/phpMan.php/man/maildirquota/8/json"
        },
        {
            "name": "reformail",
            "section": "1",
            "url": "https://www.chedong.com/phpMan.php/man/reformail/1/json"
        },
        {
            "name": "egrep",
            "section": "1",
            "url": "https://www.chedong.com/phpMan.php/man/egrep/1/json"
        },
        {
            "name": "sendmail",
            "section": "8",
            "url": "https://www.chedong.com/phpMan.php/man/sendmail/8/json"
        }
    ]
}