Difference between revisions of "Recipe language"

From Messaging Server Technical Reference Wiki
Jump to: navigation, search
m (Bulk update)
m (Bulk update)
 
Line 686: Line 686:
 
| | '''<tt>[[Recipe language#recipe_option_operations|get_option]](</tt>'''''<tt>s</tt>'''''<tt>)</tt>'''
 
| | '''<tt>[[Recipe language#recipe_option_operations|get_option]](</tt>'''''<tt>s</tt>'''''<tt>)</tt>'''
 
| |        Returns the value of the [[Option value syntax#Option_value_syntax|option]]      named ''<tt>s</tt>'' as a      string. An error will occur if the specified option name is invalid or      matches multiple options.      An empty string is returned in two cases: if the specified option is a      valid no-value option that is set, or if the specified      option is valid but not set.     
 
| |        Returns the value of the [[Option value syntax#Option_value_syntax|option]]      named ''<tt>s</tt>'' as a      string. An error will occur if the specified option name is invalid or      matches multiple options.      An empty string is returned in two cases: if the specified option is a      valid no-value option that is set, or if the specified      option is valid but not set.     
 +
|-
 +
| | [[Recipe language#recipe_environment_access|'''<tt>get_option_modification_locations</tt>''']]
 +
| |        (New in 8.1.0.6) Returns a list of locations in the current recipe where a configuration modification occurred.   
 
|-
 
|-
 
| | '''<tt>[[Recipe language#recipe_option_operations|get_options]](</tt>'''''<tt>s</tt>'''''<tt>)</tt>'''
 
| | '''<tt>[[Recipe language#recipe_option_operations|get_options]](</tt>'''''<tt>s</tt>'''''<tt>)</tt>'''
Line 1,184: Line 1,187:
  
 
The  '''<code>make_path(</code>'''''<code>s</code>'''''<code>)</code>''' function will return a file path specification by converting any environment variable or  [[Special symbolic names#Special_symbolic_names|special symbolic name]] in the string argument <code>s</code> into its path equivalent.   
 
The  '''<code>make_path(</code>'''''<code>s</code>'''''<code>)</code>''' function will return a file path specification by converting any environment variable or  [[Special symbolic names#Special_symbolic_names|special symbolic name]] in the string argument <code>s</code> into its path equivalent.   
 +
 +
The  '''<code>get_option_modification_locations</code>''' function will return a list of locations in the current recipe where a configuration modification occurred. This action also clears the internal list, so subsequent calls will only return any additional modifications that have occurred. An empty list is returned if the configuration has not been changed by the current recipe.
  
 
==== <code>msconfig</code> information operations ====
 
==== <code>msconfig</code> information operations ====

Latest revision as of 16:25, 20 May 2020

Recipe files are used to automate configuration management tasks within the msconfig utility. Recipe files are expressed using a domain specific language. Since recipe files are intended to manipulate configuration information, many parts of which most naturally appear as names and string values or lists of strings, the recipe language is rather string oriented. The primary inspirations for the recipe language is the Icon programming language designed by Ralph Griswald as well as the IETF's Sieve mail filtering language.

Recipe file syntax includes C-like expressions, operators, and assignments, Sieve-like conditionals, and loops. The available data types are integers, strings, and lists.

Like msconfig itself recipes can only be used with a unified configuration.

Note that imsimta test -expression -xc can be used to test the syntax of recipe operations.

Recipes are typically written to operate in several phases:

  1. Checks are done to make sure the right conditions exist for the recipe to be effective. If the desired conditions aren't met the recipe can either issue a warning or exit with an error.
  2. The recipe asks a number of questions to determine exactly what changes should be made.
  3. The recipe optionally uses the continue function to make sure the user wishes to proceed if any warnings were issued.
  4. Finally, the recipe implements the requested changes.

Note that while this is the typical ordering, recipes are not constrained to use it and may use other approaches if appropriate.

Comments

The # character indicates that the remainder of a line is a comment.

Integer values

Integers are expressed as decimal values with an optional sign. An optional base specification prefix can be used to write values in other bases:


    2%10 == 2
    16%ff == 255
    2%-1010 == -10

All integers are represented internally as signed 32 bit values.

String values and list values

As recipe files are intended for manipulating configuration files and parameters, which are generally thought of most naturally as strings or lists of strings, the recipe language is rather string oriented.

A string value is written simply as characters within double quotes, e.g.,


    "a sample string"
    "strings may
    include line breaks"

Backslashes have special meaning in string values:


    "\""     - quote
    "\t"     - tab
    "\r"     - carriage return
    "\n"     - line feed
    "\\"     - backslash
    "\uNNNN" - Unicode character, must specify exactly 4 hex digits
               (new in MS 8.0.2.3)

A list value is written as a comma-separated list of elements, delimited by brackets, e.g.,


    ["e1", "e2", "e3", "e4"]

As of MS 8.1.0.1 trailing commas are allowed in lists, making them easier to maintain:


    ["c1", "c2", ]

Note that the elements of a list are always strings.

Optlists

Optlists are regular lists with an even number of elements. The elements are processed in pairs: the first element in a pair is the "name" element while the second element is the "value" element. A number of the built-in functions are designed to work with optlists. The special case of empty string as the first element in a pair is used to represent annotations; in this case the second element of the pair contains the annotation text.

Variables

Variables may have integer, string, or list values. Variables are created by assigning them a value; no type declarations are necessary. Variable names are case-insensitive.


    v = 1;
    w = "this is a test";
    x = ["a", "b", "c"];

Variables may be used in most places where a string, integer, or list value is expected, including in list constructs. Given:


    s = "string";
    l = ["list"];

the following expressions are true:


    [s] == ["string"]
    [s,s] == ["string", "string"]
    [s,l] == ["string", "list"]
    [l,l] == ["list", "list"]

Variable indices

Substrings and sublists may be referenced through the use of indices. Indices into strings and lists point not at characters, but between characters, as for strings in the Icon programming language. That is, 1 points just before the first character, 2 between the first and second character, etc., and 0 points just after the last character, -1 points between the penultimate and last characters, -2 between the antepenultimate and penultimate characters, etc. The expression s[i] returns the character immediately following the interstice pointed to by the index.

For instance, if


    s = "abcdef";

then the following expressions are true:


    s[1] == "a" 
    s[3] == "c" 
    s[6] == "f" 
    s[-1] == "f" 
    s[-4] == "c" 
    s[-6] == "a" 

whereas s[0] is illegal as it is trying to return the character after the last one in the string.

When a range is specified, then the substring between the two indices is returned. There is no question about whether this is inclusive or exclusive as the indices point at interstices. Thus again taking as a sample string:


    s = "abcdef";

the following expressions are true:


    s[1,0] == s
    s[1,0] == "abcdef"
    s[1,2] == "a"
    s[2,0] == "bcdef"
    s[2,-1] == "bcde"
    s[-3, -1] == "de"
    s[i,i] == ""  # when 1 <= i <= length(s)+1
                  # or -length(s) <= i <= 0
    s[1,i+1] == left(s,i)
    s[-i,0] == right(s,i)

Indices can be used on the left hand side of assignment statements. For example, after the assignment


    s[1] = "z";

swill have the value "zbcdef".

List indices operate in a similar fashion, except that indices refer to list elements rather than characters. Single value list indices return a string while two-valued indices return a sublist. So if l is given a value


    l = ["a","b","c",d","e","f"];

the following expressions are all true:


    l[1] == "a"
    l[3] == "c"
    l[6] == "f"
    l[-1] == "f"
    l[-4] == "c"
    l[-6] == "a"
    l[1,0] == ["a", "b", "c", "d", "e", "f"]
    l[1,2] == ["a"]
    l[2,0] == ["b", "c", "d", "e", "f"]
    l[2,-1] == ["b", "c", "d", "e"]
    l[3,-1] == ["c", "d", "e"]
    l[-3,-1] == ["d", "e"]

Note that parentheses may be used in place of square brackets for indexing.

Statements

The if...then...else... statements in the recipe language are akin to those of the Sieve email filtering language:


    if expression { ... }

    if expression { ... }
    else { ... }

    if expression { ... }
    elsif { ... }

    if expression { ... }
    elsif { ... }
    else { ... }

A general loop construct is also provided, with the syntax:


    loop { 
          ...
          exitif (expression); 
          ... 
          nextif (expression); 
          ... 
         } 

A loop may contain zero or more exitif and/or nextif statements. The loop terminates if the argument to exitif evaluates to true. New in 8.0.2.3, nextif can be used to cause the loop to restart if the associated condition evaluates to true.

Loops may be nested:


    loop { 
          ...
          loop {
                ...
                exitif (expression-1); # Exit from inner loop #1
          }
          ...
          exitif (expression-2); # Exit from outer loop
          ...
          loop {
                ...
                exitif (expression-3); # Exit from inner loop #2
          }
         } 

Assignment statements are akin to those of the C programming language.


    a = "string";
    b = 2;
    c = d = ["list"];

Operators

The recipe language provides a variety of prefix, postfix, and infix operators. The following table lists the available operators in order of decreasing precedence.

Operators in Order of Precedence
Operator Description Precedence
?v Force interpretation of v as a variable, rather than as a pre-defined function 19
f(...) Function call 18
Index
sl[i] Return the ith character of string/list sl+ 17
sl[i,j] Return the ith through jth characters of string/list sl+ 17
sl(i) Return the ith character of string/list sl 17
sl(i,j) Return the ith through jth characters of string/list sl 17
Increment/decrement
v++ Return v and then increment its value (v must be a variable with an integer value) 16
v-- Return v and then decrement its value (v must be a variable with an integer value) 16
++v Increment the value of v and then return it (v must be a variable with an integer value) 16
--v Decrement the value of v and then return it (v must be a variable with an integer value) 16
Unary bitwise and logical
~n Bitwise not 15
!n Logical not 15
Arithmetic and concatenation
-n Integer negation 14
+n Integer plus 14
n * m Integer multiplication, string/list cross product 13
n / m Integer division 13
n % m Integer modulus 13
n + m Integer addition, string/list element by element concatenation 12
n - m Integer subtraction 12
n . m String/list concatenation 12
n << m Left shift 11
n >> m Right shift 11
Comparisons
n < m Less than 10
n <= m Less than or equal to 10
n >= m Greater than or equal to 10
n > m Greater than 10
n == m Equal to 9
n != m Not equal to 9
Infix bitwise
n & m Bitwise and 8
n ^ m Bitwise xor 7
n | m Bitwise or 6
n contains m String/list n contains string m. The position of the first match in the string is returned if n is a string; the position of the first matching string in the list is returned if n is a list. 5
n matches m String/list n is matched by the glob patternm true/false is returned if n is a string, the position of the first matching string in the list is returned if n is a list. 5
Infix logical
n && m Logical and 4
n ^^ m Logical xor 3
n || m Logical or 2
Conditional
p ? n : z n if p is nonzero, z otherwise 1
p ? : z (New in MS 8.1.0.3) p if p is nonzero, z otherwise 1
p ? n (New in MS 8.1.0.3) n if p is nonzero, p (0) otherwise 1
Assignment
v = e Assign v the value of e (v must be a variable) 0
v += e Add/concatenate the value of e to v (v must be a variable) 0
v -= e Subtract the value of e from v (v must be a variable with an integer value) 0
v *= e Multiply/cross product v by the value of e (v must be a variable) 0
v /= e Divide v by the value of e (v must be a variable with an integer value) 0
v &= e Bitwise and e into v (v must be a variable with an integer value) 0
v |= e Bitwise or e into v (v must be a variable with an integer value) 0
v ^= e Bitwise xor e into v (v must be a variable with an integer value) 0
v <<= e Left shift v by e (v must be a variable with an integer value) 0
v >>= e Right shift v by e (v must be a variable with an integer value) 0
v .= e Concatenate the value of e onto v (v must be a variable) 0
v1 :=: v2 Exchange the values in v1 and v2 (v1 and v2 must both be variables) 0

+Most operators are available for use in Sieve filters, as well as in recipes, except for use of square brackets, [...], for indexing into strings or lists. Sieve filter syntax uses square brackets to indicate Sieve lists, so in Sieve filters the alternate syntax for substring indexing of (...) must be used.

Functions

The recipe language provides a large number of built-in functions. The following table lists all of the built-in functions in alphabetical order; subsequent subsections describe all recipe-specific functions in groups. For general string/list/integer functions, see Symbol table functions.

Alphabetical List of Built-in Functions
Function Description
abs(i) Return the absolute value of the numeric value i.
add_alias(s,c[,e]) New in 8.0.1.2. Adds an alias named  s containing the optlist  c and, optionally, additional alias entries from the list e. An error will be returned if the alias already exists. Each element of the optlist specifies an alias option and its corresponding value. An empty string must be specified for alias options that do not accept a value.
add_channel(s,c) Adds a channel named  s containing the optlist  c. An error will be returned if the channel already exists. Each element of the optlist specifies a channel option and its corresponding value. An empty string must be specified for channel options that do not accept a value.
add_group(g,c) Adds a group named g containing the optlist  c. An error will be returned if the group already exists. Each element of the optlist specifies a group element and its corresponding value.
add_mapping(s,c) Adds a mapping named s containing the optlist  c. The mapping must not already exist. Each element of the optlist specifies either a mapping rule or an annotation. The name part of an optlist element specifies the rule pattern while the value part specifies the rule template.
allof(i1[,i2...]) Returns a nonzero (true) value if all of i1, i2, ... are nonzero; returns 0 otherwise.
any(s1,s2) Return 2 if any character in s1 appears as the first character of s2; return 0 otherwise.
anyof(i1[,i2...]) Returns a nonzero (true) value if any of i1, i2, ... are nonzero, returns 0 if all are zero.
append_alias(s,c[,e]) New in 8.0.1.2. Append the alias options specified in the optlist optlist  c and, optionally, the alias entries specified by the list e to the alias named by s. The alias will be created if it doesn't already exist.
append_group(s,c) Appends the contents of optlist  c to the group named s. The group will be created if it doesn't already exist. Each element of the optlist specifies a group element and its corresponding value.
append_mapping(s,c) Appends the contents of optlist  c to the mapping named s. The mapping will be created if it doesn't already exist. Each element of the optlist specifies either a mapping rule or an annotation. The name part of an optlist element specifies the rule pattern while the value part specifies the rule template.
append_rewrites(c) Appends the contents of optlist  c to the current set of rewrite rules. Each element of the optlist specifies either a rewrite rule or an annotation. The name part of an optlist element specifies the rule pattern while the value part specifies the rule template.
argc (New in 8.0) Returns the number of additional arguments given to the msconfig run command.
argv(n) (New in 8.0) Returns the nth argument given to the the msconfig run command as a string. The value n must be between 1 and argc inclusive.
bal(c1,c2,c3,s) Scan s looking for an occurrence of a character in c1 that is balanced with respect to c2 and c3. Returns the position of the first balanced c3 character in s if one is found, length(s)+1 if no c3 character is found but the string as a whole is balanced, or 0 if the string isn't balanced.
call_user(s1,s2,e[,e2...]) Call the routine named s2 in the external library image s1, passing the argument e (and optionally additional, comma-separated arguments).
chr(i1[,i2...]) Returns a string containing successive characters with decimal values i1, i2, ...
continue( [s1[,s2]]) The continue function does nothing if no warnings have been issued during the execution of the recipe. If one or more warnings have been issued by the recipe, the administrator is prompted with the string s1. An empty response or a response beginning with "Y" (yes) or "T" (true) will cause the script to continue running; any other response will cause the script to abort. A default prompt of "Some warnings have occurred. Do you want to continue [N]? " will be used if no value for s1 is specified. An optional argument s2 may be supplied as a default response to continue; for instance, continue("Continue [y]? ","Y") will mean that a user empty (carriage return) response will mean to continue.
continue The continue function does nothing if no warnings have been issued during the execution of the recipe. If one or more warnings have been issued by the recipe, and continue was not provided with a prompt string, then the administrator is prompted with the default prompt "Some warnings have occurred. Do you want to continue [N]? ". An empty response or a response beginning with "Y" (yes) or "T" (true) will cause the script to continue running; any other response will cause the script to abort.
decode [:e] s Decodes the string s from the specified encoding :e. The :e nonpositional parameter must be one of :base64, :base85, :hex, :idn, or :quotedprintable. The default is :hex.
default Undoes the effect of instance or role: options are interpreted as being of their preferred flavor.
defined(s) Returns 1 if s is defined as a variable; return 0 otherwise.
delete_alias(s) New in 8.0.1.2. Delete the alias named s. No operation is performed if the alias does not exist.
delete_channel(s) Delete the channel named  s. No operation is performed if the channel does not exist.
delete_file(s) New in 8.0.1.2. Delete the file named s. Returns 1 if the delete operation succeeded, and 1 if not.
delete_group(s) Delete the group named s. No operation is performed if the group does not exist.
delete_mapping(s) Delete the mapping named s. No operation is performed if the mapping does not exist.
delete_options(l) Deletes all values associated with the options specified in the list  l.
delete_optlist(o,n...) Delete option n from optlist  o and return the resulting modified list. The original optlist is returned if the specified option does not appear in the optlist. Additional option names can be specified to delete multiple options from the optlist. As of MS 8.0.1.3, n can be a two element list specifying a name/value pair to be removed from the list.
delete_rewrites(l) Delete the rewrite rules specified in list  l. No operation is performed if such rewrite rules do not exist.
delete_statefile(v) Delete the specified statefile variable v. The function returns true if the delete operation was successful; false if statefile support is not enabled.
deploymap ... (New in MS 8.0.1.1.0) Perform various operations on and obtain data from the deployment map.
deploymap :add [:deployment d] :host h [:role r] (New in MS 8.0.1.1.0) Add host(s) h with role r to deployment d in the deployment map. h may be either a string or list. An error occurs if any of the hosts already exist. The current deployment is used if d is not specified; if there is no current deployment, then the first deployment in the deployment map is selected; a deployment with the default name "site-01" will be created if no deployment exists in the deployment map. No role with be associated with the host(s) if r is not specified. Returns the number of modifications that were made to the deployment map.
deploymap :add [:deployment d] :host h :property p (New in MS 8.0.1.1.0) Add property/properties p to host h in deployment d. Host h will be created if it does not already exist. The current deployment is used if d is not specified; if there is no current deployment, then the first deployment in the deployment map is selected; a deployment with the default name "site-01" will be created if no deployment exists in the deployment map. Returns the number of modifications that were made to the deployment map.
deploymap :add [:deployment d] :host h :property p :role r (New in MS 8.0.1.1.0) The host h is created in deployment d with role r and properties p. The host must not already exists. The current deployment is used if d is not specified; if there is no current deployment, then the first deployment in the deployment map is selected; a deployment with the default name "site-01" will be created if no deployment exists in the deployment map. Returns the number of modifications that were made to the deployment map.
deploymap :create (New in MS 8.0.1.1.0) Create a new, empty deployment map. Note that if you write this out using msconfig's DEPLOYMAP WRITE command you will delete all your existing entries!
deploymap :delete​ :deployment d (New in MS 8.0.1.1.0) Delete the deployment named by string d from the deployment map. Deleting a nonexistent deployment is a no-op. Returns the number of modifications that were made to the deployment.
deploymap :delete[:deployment d] :host h (New in MS 8.0.1.1.0) Delete host(s) h from deployment d. h can be either a string or list. Deleting a nonexistent host is a no-op. The current deployment is used if d is not specified; if there is no current deployment, the first deployment in the deployment map is selected. Returns the number of modifications that were made to the deployment map.
deploymap :delete[:deployment d] :host h :role r (New in MS 8.0.1.1.0) Delete any role associated with host(s) h in deployment d. Deleting a nonexistent role is a no-op. An error occurs if host h does not exist. The current deployment is used if d is not specified; if there is no current deployment, the first deployment in the deployment map is selected. Returns the number of modifications that were made to the deployment map.
deploymap :delete[:deployment d] :host h :property p (New in MS 8.0.1.1.0) Delete any properties for host(s) h (which may be a string or list) in deployment d that match the glob-wildcarded values in string or listp. The current deployment is used if d is not specified; if there is no current deployment, the first deployment in the deployment map is selected. Returns the number of modifications that were made to the deployment map.
deploymap :dump (New in MS 8.0.1.1.0) Returns a string containing an outline of the entire deployment map.
deploymap :list... (New in MS 8.0.1.1.0)
deploymap :read s (New in MS 8.0.1.1.0) Reads a JSON-format deployment map from string s.
deploymap :rename s :deployment d (New in MS 8.0.1.1.0) Renames deployment d to s. d must specify an existing deployment; s must be a nonempty utf-8 string. Returns the mumber of modifications that were made to the deployment map.
deploymap :rename[:deployment d]' s :host h (New in MS 8.0.1.1.0) Renames host h in deployment d to s. The current deployment is used if d is not specified; if there is no current deployment, then the first deployment in the deployment map is selected. Host h must already exist and s must be a valid domain name. Returns the mumber of modifications that were made to the deployment map.
deploymap :set[:deployment d] :host h :role r (New in MS 8.0.1.1.0) Sets the role for host(s) h in deployment d to r. h can be either a string or list. The specified host(s) h must already exist in the deployment. The current deployment is used if d is not specified; if there is no current deployment, then the first deployment in the deployment map is selected. Returns the mumber of modifications that were made to the deployment map.
deploymap :write (New in MS 8.0.1.1.0) Returns the contents of the current deployment map as a JSON-formatted string. Note that no mechanism is provided in the recipe language to update the active deployment map; this can only be done at the msconfig level.
description(d) The description function is used to provide a description of the function of a recipe. The value of the string argument d is displayed when the recipe is processed by the msconfig directory command. Note that d must be a literal string enclosed in quotes; it cannot be an expression. When the recipe is executed the description function does nothing other than return the value of its argument d.
edit(s) Place the value of the string s in a temporary file and invoke the external editor specified by the EDITOR environment variable on the file. When the editor returns the edit function returns the (possibly modified) file content.
encode [:e] s Encodes the string s into the specified encoding :e. The :e nonpositional parameter must be one of :base64, :base85, :hex, :idn, :param, :quotedprintable, or :url. The default is :hex.
error(s) Issue error string s back to administrator executing the recipe.
exists_alias(s) New in 8.0.1.2. Returns a nonzero integer (specifically, the number of entries in the alias group) if the alias named s exists, zero if it does not.
exists_channel(s) Returns a nonzero integer (specifically, the number of channel options set on the channel) if the channel named  s exists, zero if it does not.
exists_file(s) Returns 1 if the file named by s exists, 0 if it doesn't. If only a file name is specified with no path, msconfig looks in the MTA configuration directory, IMTA_TABLE:.
exists_group(s) Returns a nonzero integer if the group named s exists, zero if it does not.
exists_mapping(s) Returns a nonzero integer if the mapping named s exists, zero if it does not.
exists_option(s) Returns the number of values currently set for the option s. A value of 0 is returned if the option isn't set.
exists_optlist(o,s) Returns 1 value if the the optlist  o contains an option named s, 0 otherwise.
exists_statefile(v) Returns 1 if the statefile variable named v is defined, 0 if it is not, and -1 if statefile support has not been enabled with the --statefile switch.
find(s1,s2[,i,j'']) Returns the position of the first occurrence of s1 in s2[i:j]. The entire string is searched if i and j are omitted.
find(s,l[,i,j']) Returns the position of the first list element from l[i:j] that matches s. The entire list is searched if i and j are omitted.
get_alias(s) New in 8.0.1.2. Returns the definition (alias options) of the alias named s as an optlist. An empty list is returned if the alias does not exist.
get_channel(s) Returns the definition (channel options) of the channel named  s as an optlist. An empty list is returned if the channel does not exist.
get_default(s) Returns the built-in default for the specified option s as a string. An empty string is returned if the option has no default. A error occurs if the option does not exist. New in MS 8.0.2.1.
get_group(s) Returns the content of the group named s as an optlist. An empty list is returned if the group does not exist.
get_mapping(s1[,s2[,s3]]) Returns the content of the mapping named s1 as an optlist. An empty list is returned if the mapping does not exist. Optionally, strings s2 (string with wildcards to match patterns) and s3 (string with wildcards to match templates) may be specified, to restrict which entries of the named mapping to return. If not specified, s2 and s3 each default to "*", meaning that all of the entries of the named mapping will be returned.
get_msconfig_info(s) New in MS 8.0.2.3. Return the value of the msconfig information item s. An error occurs if an unknown item is specified. Note that s is not case sensitive.
get_option(s) Returns the value of the option named s as a string. An error will occur if the specified option name is invalid or matches multiple options. An empty string is returned in two cases: if the specified option is a valid no-value option that is set, or if the specified option is valid but not set.
get_option_modification_locations (New in 8.1.0.6) Returns a list of locations in the current recipe where a configuration modification occurred.
get_options(s) Returns the names and values of the options named s as an optlist. (Note that when an option is set in both role and instance flavors, only the instance is returned.) An empty list is returned if the specified option is valid but not set.
get_optlist(o,s) Returns the value of the option named s from the optlist  o as a string. An empty string is returned if the specified option is not in the optlist.
get_path(r) (New in 8.0) Returns a path to a directory in the server instance. The argument r can be one of "server", "data", or "config", which will return the path to the server root, the data root, or configuration root directories, respectively.
get_rewrites[(p[,t])] Returns the selected set of rewrite rules as an optlist. p specifies a glob-style pattern to apply to the pattern part of each rewrite rule; only rules that match the pattern will be returned. Similarly, t specifies a glob-style pattern to apply to the template part of each rewrite rule; only the rules whose templates match the pattern will be returned. Both arguments are optional; if neither is specified then all rewrite rules are returned.
get_statefile(v) Returns the value of the statefile variable named v. An empty string is returned if the specified variable is not in the statefile or statefile support has not been enabled with the --statefile switch.
get_system_info(s) New in 8.0.1.2. Return the value of the system information item s. An error occurs if an unknown item is specified. Note that s is not case sensitive.
getenv(s) Return the value of the environment variable s. An empty string is returned if s is not defined. Note that s is case sensitive.
hash [:e] [:h] v Returns the hash of the value v. v may be either a string or a list; if a list is specified, a separate hash is computed for each element and returned as a new list. The hash :h may be any of :md2, :md4, :md5, :sha1, :sha256, :sha512, :ripemd128, or :ripemd160; the default is :sha1. (Support for :sha256 and :sha512 is new in MS 8.0.2.3.) An encoding may optionally be applied; :e may be any of :hex, :quotedprintable, :base64, :base85, or :binary. :binary, or no encoding, is the default.
hash_hmac [:e] [:h] k v Returns the hmac of the value v using key k. v may be either a string or a list; if a list is specified, a separate hmac is computed for each element and returned as a new list. The underlying hash function :h may be any of :md2, :md4, :md5, :sha1, :sha256, :sha512, :ripemd128, or :ripemd160; the default is :sha1. (Support for :sha256 and :sha512 is new in MS 8.0.2.3.) An encoding may optionally be applied; :e may be any of :hex, :quotedprintable, :base64, :base85, or :binary. :binary, or no encoding, is the default.
instance Operate on instance options.
integer(e) Converts e to an integer. If e is already an integer, it is returned unchanged; if e is a string, it is read as a sequence of ASCII digits. If e is a list, it must contain one element and that element is treated in the same way a string would be.
keywords(l) The keywords function is used to provide a list of keywords associated with a recipe. The value of the list argument l is displayed when the recipe is processed by the msconfig directory command.
lcase(e) Converts any upper case characters in e to lower case. If e is a number, it is converted to a string.
ldap_init(o) (New in MS 8.0.1) Initializes the built in LDAP client. This call must be performed prior to using any of the other ldap_* functions. The client uses the current settings of the configuration options ugldaphost, ugldapbinddn, ugldapbindcred, ugldapport, and ugldapusessl when it initializes. The single argument o is an optlist specifying override values for any or all of these options. The optlist may be empty. Repeated calls will shut down and reinitialize the LDAP client with new settings. The LDAP client is shut down automatically when the recipe terminates.
ldap_ldif(s[,f]) (New in MS 8.0.1) Apply the LDIF specified in the string s to the LDAP directory. Any LDAP error that occurs will be treated as a recipe warning (but see the bit 12 in the flag argument). The optional argument f is a bit-encoded integer specifying a number of flags. The currently defined flag bits are:
  • Bit 0 (value 1) - if set, continue processing after any error,
  • Bit 1 (value 2) - if set, treat "entry exists" on add as success,
  • Bit 2 (value 4) - if set, allow no-such-object if hint present, and
  • Bit 12 (value 4096) - if set, treat any LDAP error that occurs as a recipe error.

An integer count of the number of successful modifications performed is returned. ldap_init must be called before calling ldap_ldif.

ldap_search(o[,n]) (New in MS 8.0.1.1.0) The ldap_search function takes an optlist argument specifying at least the basedn for the search, and optionally also the attribute to return (attrs), the scope of the search, and a filter (filter) for the search. Valid values for the "scope" are: base, onelevel (or one), subtree (or sub). An optional second integer argument specifies the number of entries to return, and defaults to -1 (return all entries) if omitted. The function returns an optlist containing the attribute-value pairs matching the search.
left(s1,i[,s2]) Returns the leftmost i characters of s1. If i is greater than length(s1) the result is padded with s2. As much of s2 as is necessary will be used; if s2 is too short it will be used multiple times. s2 defaults to a space if it is omitted.
left(l1,i[,l2]) Returns the leftmost i elements of l1. If i is greater than length(l1) the result is padded with l2. As much of l2 as is necessary will be used; if l2 is too short it will be used multiple times. l2 defaults to one empty list element if it is omitted.
length(s) Returns the number of 8-bit characters in the string s.
length(l) Returns the number of elements in the list  l.
list(s,n) Returns a list  n elements long with each element equal to s.
list(l,n) Returns a list consisting of n copies of l.
list_names(s[,n]) Returns the options whose name begins with the specified string s as an optlist. The optional integer second argument specifies whether or not to retain backslash characters in the options' values; the default is 0 (false).
make_path(p) Converts a path p using IMTA_TABLE: and similar MTA-specific constructs into a proper file path. Note that the path that's constructed may only be valid on the system where msconfig is running.
match(r,s) Returns 1 (true) if the regular expression r matches a substring of string s, 0 (false) otherwise. Note that the pattern r may be prefixed with "^" (match beginning of line) and suffixed with "$" (match end of line) to require a full string match. The regular expression vocabulary is compatible with that of the TCL/TK scripting language.
map(s1,s2,s3) Returns a string obtained by mapping characters of s1 that occur in s2 into corresponding characters in s3. Characters that don't appear in s2 are unchanged.
max(i,j[,...]) Returns the largest element in a set of integers.
max(s1,s2[,...]) Returns the largest element in a set of strings.
min(i,j[,...]) Returns the smallest element in a set of integers.
min(s1,s2[,...]) Returns the smallest element in a set of strings.
ord(s) Returns the ordinal value of the first character of s, which must contain at least one character.
pop(l) Returns the first element of list  l. The element is deleted from the list. l must be a variable with a list value.
prepend_alias(s,c[,e]) New in 8.0.1.2. Prepends the contents of optlist  c, and, optionally, the alias entries from the list e, to the alias named s. The alias will be created if it doesn't already exist.
prepend_group(s,c) Prepends the contents of optlist  c to the group named s. The group will be created if it doesn't already exist.
prepend_mapping(s,c) Prepends the contents of optlist  c to the mapping named s. The mapping will be created if it doesn't already exist.
prepend_rewrites(c) Prepends the contents of optlist  c to the rewrite rules.
print(s) Print the string s on the administrator's terminal.
push(l,s) Adds the string s to the beginning of list l. The list l is updated as well as being returned. l must be a variable with a list value.
put_optlist(o,s,v...) Put the option s with the value v in optlist  o and return the resulting modified list. The option's value is replaced if the option is already present. Additional name-value pairs can be specified in the call to put multiple options on the optlist.
random(n) Returns a random integer value between 0 and n-1.
randomseed(n) Seeds the random number generater function random with the integer seed value n.
read(s1[,s2[,s3]]) Read and return a string from the administrator terminal, prompting with the string s1. The optional string argument s2 provides a default value for the function to return, if the administrator does not enter an explicit value (merely enters a null response). New in MS 8.0.2.3, the string argument s3 specifies the name of a statefile variable whose value is used if present or will be updated with whatever value is entered.
read_file(s) Reads and returns the content of the file named by s. msconfig looks in the MTA configuration directory, IMTA_TABLE:, if s specifies only a file name with no path. An error occurs if the file doesn't exist or cannot be read. Line feeds are used as line separators.
read_optlist(s) Converts a string s containing options into an optlist which is returned. The string s should be formatted with options expressed as name=value delimited by CR or LF. Leading space or horizontal tab characters prior to a name will be ignored (though space and horizontal tab are allowed and retained within a value). Comments, which start with exclamation point ! or hash character #, will be ignored.
read_password  [:minlength n1] [:maxlength n2] [:upper n3] [:lower n4] [:digit n5] [:symbol n6] [s1] [s2] Read a password from the administrator terminal, returning it as a string. Optional parameters may be used to specify requirements that the password must meet: :minlength default is -1 (no minimum), :maxlength default is -1 (no maximum), by default no requirements are placed on number of upper case characters, lower case characters, digits, or symbols (respectively, :upper, :lower, :digit, :symbol). The administrator is prompted with string s1 (default "Password: ") and optionally may be prompted to verify the password with string s2 (default "Verify ").
repl(s,j) Returns a string consisting of j concatenatations of s.
repl(l,j) Returns a list consisting of j concatenatations of l.
replace_alias(s,c[,e]) New in 8.0.1.2. Replaces the alias named s with the contents of optlist  c and, optionally, alias entries from the list e. The alias will be created if it doesn't already exist.
replace_channel(s,c) Replaces the channel named  s with the contents of optlist  c. The channel will be created if it doesn't already exist.
replace_group(s,c) For the group named by string s, replace its options with those in the optlist  c.
replace_mapping(s,c) Replaces the contents of the mapping named s with the contents of optlist  c. The mapping will be created if it doesn't already exist.
replace_rewrites(c) Replaces the current rewrite rules with the rewrite rules specified in the optlist  c.
resolve_option(o) The string value o is run through the option name resolution process and the resolution results are returned as a bit-encoded integer. The option need not exist in the current configuration and is not modified in any way. Currently four bits are defined: Bit 0 (value 1), if set, indicates the path specified was valid, bit 1 (value 2), if set, indicates the name specifies a valid option (as oppose to, say, the name of an option group), bit 2 (value 4), if set, indicates that the option has been deleted and is effectively a no-op, bit 3 (value 8), if set, indicates that the option is restricted, and bit bit 4 (value 16), indicates that this is an instance-only option.
restricted(p) The restricted function is used to control or check the recipe's ability to modify the values of restricted options. If the -restricted switch was given to the run command, the restricted function returns a value of 1 (true) unconditionally. If -restricted wasn't specified, the argument p will be evaluated to determine if the user should be prompted. A zero value will return a value of 0 (false). A nonzero value will prompt the user for permission to modify restricted options. A response beginning with "Y", "y", "T", "t", or "1" will enable modification access to restricted options and the function will return a value of 1 (true). A response beginning with "N", "n", "F", "f", or "0" will return a value of 0 (false). Any other response will cause the prompt to be repeated.
reverse(s) Reverses all the characters in string s and returns the result.
reverse(l) Reverses all the elements in list l and returns the result.
right(s1,i[,s2]) Returns rightmost i characters of s1. If i is greater than length(s1) the result is p added with s2. As much of s2 as is necessary will be used; if s2 is too short it will be used multiple times. s2 defaults to a space if it is omitted.
right(l1,i[,l2]) Returns rightmost i elements of l1. If i is greater than length(l1) the result is padded with l2. As much of l2 as is necessary will be used; if l2 is too short it will be used multiple times. l2 defaults to one empty list element if it is omitted.
role Operate on role options.
set_channel(s,c) Modify the channel named by s with the channel options specified by the optlist  c. The channel will be created if it doesn't already exist.
set_option(s[,v]) Set option  s (for options that take no value), or set option s to the string value v. An error will occur if the specified option name is invalid or matches multiple options.
set_options(o) Set zero or more options specified in optlist form. Option names and values are taken from optlist o in the obvious way. An error will occur if any of the specified option names are invalid or match multiple options.
set_statefile(v,s) Set the statefile variable v to the value s. The function returns true if the delete operation was succesful; false if statefile support is not enabled.
sign(i) Returns -1 if i < 0, 0 if i = 0, +1 if i > 0.
sort(l1[,i[,l2]]) Sorts the elements of l1 to be in ascending order if i <> 0 and descending order if i = 0. i defaults to 1 if it is omitted. If l2 is present, its elements are shifted in the same way as elements in l1 are shifted.
split(s[,c[,i]]) Produces a list of elements consisting of pieces of s delineated by characters in c. If omitted, c defaults to a comma. If i is 0 or 1, zero length elements are preserved; if i is 2, they are not. If omitted, i defaults to 1.
split(l[,c[,i]]) Produces a list of elements consisting of pieces of elements of l delineated by characters in c. If omitted, c defaults to a comma. If i is 0, boundaries between the original elements aren't preserved and zero length elements can be output; if i is 1, boundaries are preserved and zero length elements can be output; if i is 2, boundaries aren't preserved and zero length elements are omitted. If omitted, i defaults to 1.
string(e) Converts e to a string. If e is already a string, it is returned unchanged. If e is an integer, it is converted to a string. If e is a list, the string that results from concatenating the elements of e is returned.
string(l,s) Converts the list l to a string, inserting the string s between each pair of elements of l. So for instance string(["a","cd","e"],"01") would return the string "a01cd01e".
string(i[,j[,k]]) Converts the integer i to a string, optionally padding with zeros (on the left) so that the length of the string is j, and optionally outputting the result in the radix specified by k. So for instance string(15,8,2) returns 00001111.
strongrandom(n) Returns a string containing the specified number of bytes of random value.
translate(s1,s2,s3) Interprets the string s1 as being in the character set specified by s2 and returns a version translated into the character set specified by s3.
trim(s[,c]) Returns s with any trailing characters found in c removed. c defaults to space and tab if omitted.
trim(l[,c]) Returns list  l with any trailing characters found in c removed from each element. c defaults to space and tab if omitted.
type(e) Returns "integer" if e evaluates to an integer, "string" if e evaluates to a string, and "list" if e evaluates to a list.
ucase(e) Converts any lower case characters in e to upper case. If e is a number it is converted to a string.
unset_alias(s,v) New in 8.0.1.2. Remove the option or options specified in the string or list  v from the alias named s. Note that this function is unsuitable for use on alias entries.
unset_channel(s,v) Remove the option or options specified in the string or list  v from the channel named s.
unset_option(s) Removes option s from the configuration. An error will occur if the specified option name is invalid or matches multiple options.
validate_option(s1​[,s2]) Validate the option named s1: that the option name is valid and, if the optional value s2 is supplied, that the value is a valid value. Unlike set_option, validate_option does not set the option to the specified value: it merely checks validity.
warn(s) Print warning text s to the administrator's terminal, and update the internal setting (which may be tested via continue) that a (an additional) warning has occurred.
write_file(s1,s2) Writes the contents of string  s2 into the file named by s1. msconfig writes to the MTA configuration directory, IMTA_TABLE:, if s1 is merely a file name with no patch. An error occurs if the file cannot be opened or written. Line feeds should be used as line separators in the string.
write_file(s1,l[,s2]) Writes the contents of the list  l into the file named by s1. Each list element written is terminated by the value of s2; line feed is the default terminator if s2 isn't supplied. An error occurs if the file cannot be opened or written.
write_optlist(o) Convert the optlist o to a series of "name=value" lines and return the resulting string containing those lines. The string is in a format suitable for writing to a file with write_file.
yesno(s1[,m[,s2]]) Prompt at the recipe administrator's terminal with prompt string s1. A response of "y", "Y", "t", "T", or "1" will be accepted as meaning yes; a response of "n", "N", "f", "F", or "0" will be accepted as meaning no; these are the valid responses. m is an integer value to use as the default if the administrator merely returns (NULL response). s2 is a warning string to output if the administrator's input was not in the valid set of responses.

Configuration option access

The primary purpose of the recipe language is to manipulate the various option settings in a Messaging Server configuration. This functionality is provided by a number of separate functions. These functions all accept either an option name or optlist containing option name/value pairs as arguments. Some functions allow incomplete option names and/or wildcards while others do not.

The existence of an option setting can be determined with the exists_option function. This function accepts an option name string as an argument and returns a count of the number of options set in the configuration that match the name. 0 (false) is returned if no options are set that match the name. For example:


   exists_option("os_debug")      -> 0  (os_debug is not currently set)
   exists_option("channel:tcp_*") -> 42 (42 options are set on tcp_ channels)

As of MS 8.0.2.1, the default value for an option setting can be determined with the get_default function. It returns the built-in default for the option. An empty string is returned if the option has no built-in default value. An error occurs if the specified option does not exist.

The list_names(s[,n]) function returns, as an optlist, a list of the options (and their values) whose names begin with the specified string s. The optional integer second argument, n, specifies whether or not to retain backslash characters (for quoting special characters) in the options' values; the default is 0 (false).

The get_option function returns the value of a single option. An error will occur if the name given matches multiple options or does not exist. An empty string will be returned in either or two cases: if the specified option name is valid and the option is a no-value option which is set, or if the specified option name is valid for a valued option which is not set. (So note that get_option is not sufficient for checking whether a no-value option is set; instead use exists_option to check on a whether or not a no-value option is set.)


  get_option("mm_debug")       -> 0       (mm_debug is set to 0)
  get_option("os_debug")       -> ""      (os_debug, valued option, is not set)
  get_option("slave_debug")    -> ""      (slave_debug, no-value, may be set)
  exists_option("slave_debug") -> 0       (slave_debug not set)
  get_option("*_debug")        -> <error> (multiple *_debug options)

The function get_options(s) returns an optlist containing the names and values of the options with name s. (So note that unlike get_option, the result returned by get_options has no ambiguity and differentiates between set no-value options vs. unset valued options.) Note that when both role and instance flavors of an option are set get_options returns only the instance flavor of the option.

The function set_option(s[,v]) sets the option named s for options that take no value, or sets the option names s to the value v for options that do take a value. The function set_options(o) sets the option-value pairs in the optlist  o.

The unset_option(s) unsets (deletes) the option named by the string s. The delete_options(l) function deletes (unsets) the options named in the list l.

New in MS 8.0.2, recipes support a resolve_option function. This function accepts a single string argument which then undergoes the option resolution process. The result of that process is then returned as a bit-encoded integer. The bits are:

resolve_option return bits
Bit Value Meaning
0 1 Set if name resolved, clear if name invalid
1 2 Set if the string specified a valid option name, clear otherwise (Note that an option string can specify the name of a group, in which case this bit will be clear but bit 0 will be set.)
2 4 Set if option has been deleted and no longer has any effect
3 8 Set if option is restricted
4 16 Set if option is targeted for use in instances only

The validate_option(s1[,s2]) function validates that the specified option name is valid, and that the specified value is valid. It does not actually set the option to the specified value. For instance:


validate_option("service:SMTP.enable","test")     -> 0
validate_option("service:SMTP.enable","0")        -> 1

The instance and role functions tell the recipe to set the specified flavor of option. The default function tells the recipe to set options according to the option's own preferred flavor (which note is role for all but a few options).

For enabling modification of restricted options, see also the -restricted switch to the run command, or the restricted operation.

Configuration group access

In Unified Configuration, some options may be set under a named group. So there are function to access/set/delete/etc. an entire such named group of options.

The add_group(g,c) function adds the group named (by the string value of) g with options specified by the optlist  c; the function returns 1 if this operation was successful, or 0 if there was an error (such as in the case where the specified group name already existed). For example, the call:


add_group("dispatcher.service:SMTP_SPECIAL",
          ["enable", "1",
           "tcp_ports", "28225",
           "image", "IMTA_BIN:tcp_smtp_server",
           "parameter", "CHANNEL=tcp_special"
           "logfilename", "IMTA_LOG:tcp_special_server.log"])

adds a Dispatcher service named SMTP_SPECIAL, which will be a "special" SMTP server listening on port 28225 running the channel tcp_special.

The append_group(s,c) function appends to the group named (by the string value of) s the options specified by the optlistc; the function returns 1 if this operation was successful, or 0 if an error occurred. (The group will be created if it does not already exist; that is, append_group on a previously non-existent group is not an error.)

The delete_group(s) function deletes the group named (by the string value of) s.

The exists_group(s) function returns 0 if the group named (by the string value of) s exists, or the number of options set in the group if the group does exist.

The get_group(s) function returns the content of the group (the option names and values) as an optlist.

The prepend_group(s,c) function prepends to the group named (by the string value of) s the options specified by the optlistc; the function returns 1 if this operation was successful, or 0 if an error occurred. (The group will be created if it does not already exist; that is, prepend_group on a previously non-existent group is not an error.)

The replace_group(s,c) function replaces the group named (by the string value of) s with options specified by the optlistc; the function returns 1 if this operation was successful, or 0 if there was an error (such as in the case where the specified group name does not already exist).

System information

New in 8.0.1.2. The get_system_info function provides access to various pieces of static information about the system msconfig is running on. The function accepts a single case-insensitive string as its only argument specifying the piece of information to return.

In the following table, the Messaging Server version is taken to be "a.b.c.d" and the product build date is "yyyymmdd".

get_system_info information items
Item Return Type Example Value Description
ms_build_date string "yyyymmdd" The date the current system was built from source.
ms_build_date_int integer yyyymmdd The date the current system was built from source.
ms_version string "a.b.c.d" Messaging Server version
ms_version_int integer aabbccddd Messaging Server version, expressed as a single integer computed by the formula ((a * 100 + b) * 100 + c) * 1000 + d. This form is intended to be used in comparison operations.
ms_version_major string "a" Messaging Server major version.
ms_version_major_int integer a Messaging Server major version.
ms_version_minor string "b" Messaging Server minor version.
ms_version_minor_int integer b Messaging Server minor version.
ms_version_update string "c" Messaging Server update version.
ms_version_update_int integer c Messaging Server update version
ms_version_patch string "d" Messaging Server patch number.
ms_version_patch_int integer d Messaging Server patch number.
ms_version_build string "" Messaging Server build number.
ms_version_build_int integer Messaging Server build number.

msconfig information

New in 8.0.1.2. The get_msconfig_info function provides access to various pieces of information about how msconfig was invoked and its current status.

The following information items are currently supported:

get_msconfig_info information items
Item Return Type Example Value Description
noprompt boolean false Returns true if msconfig was invoked with the -noprompt switch.
statefile_name string file.state The name of the statefile specified with the -statefile switch.

Environment access

The recipe language can find out the values of environment variables, or find file path specifications using Messaging Server's basic environment variable values or (for the MTA) special symbolic names.

The getenv(s) function returns the value of the environment variable named s, or the empty string if no such environment variable is defined.

The get_path(s) function takes a string "server", "data", or "config" as argument, returning the file path specification of the SERVERROOT, DATAROOT, or CONFIGROOT, respectively.

The make_path(s) function will return a file path specification by converting any environment variable or special symbolic name in the string argument s into its path equivalent.

The get_option_modification_locations function will return a list of locations in the current recipe where a configuration modification occurred. This action also clears the internal list, so subsequent calls will only return any additional modifications that have occurred. An empty list is returned if the configuration has not been changed by the current recipe.

msconfig information operations

The argc function returns the number of additional arguments given to the msconfig RUN command.

The argv(n) function returns, as a string, the nth argument given to the msconfig RUN command. The value n must be between 1 and argc inclusive.

The description(d) function sets a string to display when the recipe is listed by the msconfig DIRECTORY command. Note that dmust be a literal string enclosed in quotes; it cannot be an expression. When the recipe itself is executed, the description function does nothing other than return the value of its argument d.

The keywords(l) function specifies keywords to display when the recipe is listed by the msconfig DIRECTORY command.

File operations

Although recipes primarily operate directly on Messaging Server configuration data without any need for explicit file operations, situations may arise where additional files need to be read or written. Accordingly, a set of file manipulation functions is provided in the recipe language.

If no explicit path is given in the file name, the file location defaults to the config root directory. Explicit paths may be specified or any of the following special prefixes may be used:


    IMTA_ROOT:    -> <serverroot> "/"
    IMTA_LIB:     -> <serverroot> "/lib/"
    IMTA_TABLE:   -> <configroot> "/"
    IMTA_PROGRAM: -> <dataroot> "/site-programs/"
    IMTA_LOG:     -> <dataroot> "/log/"
    IMTA_QUEUE:   -> <dataroot> "/queue/"
    IMTA_HTTP:    -> <dataroot> "/www/"

For manipulating paths in file names, see also the get_path and make_path functions.

The exists_file(s) function returns 1 if the file named by s exists, 0 if it doesn't.

Files may be read with read_file(s). The contents of the file named by s are returned as a string. Line feeds are used as line delimiters in the string. For example:


    split(trim(read_file("a.a"),"\n"),"\n")

returns the contents of the file with each line as a list element and any trailing blank lines removed.

There are two ways to write files. write_file(s1,s2) writes the contents of string s2 to the file named by string s1. write_file(s1,l[,s2]) writes the contents of the list l into the file named by s1. Each list element written is terminated by the value of s2; line feed is the default terminator if s2 isn't supplied. In either form an error occurs if the file cannot be opened or written.

(New in MS 8.0.1.2) The delete_file(s) function deletes the file named by the string s, returning 1 if the delete operation was successful, or 0 if not.

Unless -trusted was specified for the msconfig invocation, the utility will check whether to perform a requested delete_file operation:


Allow recipe to delete file [Y, N, A]? 

and if such prompting is disallowed (-noprompt specified), will not execute the delete operaiton and instead issue an error:


Delete_file not allowed to prompt for permission in -noprompt mode

Terminal I/O operations

The recipe language has a few terminal I/O primitives.

The print(s) operation prints a string to the terminal of the administrator executing the recipe.

The warn(s) operation prints a warning string to the terminal of the administrator executing the recipe, and updates the internal setting (which may be tested via continue) that a warning (an additional warning) has occurred.

New in MS 8.0.2.3, warn without any arguments returns the number of warnings that have been issued during the current run.

The error(s) operation issues a specified error string back to the administrator.

The continue([s1[,s2]) operation asks the administrator whether to continue after a warning. (Note that the prompt string argument s1 and default response string argument s2 are optional, with a default prompt string and empty response string, interpreted as false, used they are omitted. So merely continue is also valid syntax.)

The yesno(s1[,m[,s2]]) operation asks the administrator to respond with a yes or no response.

The read(s1[,s2[,s3]]) operation reads a string input from the terminal of the administrator executing the recipe. s1 specifies the prompt to print on the terminal, s2 specifies a default to return if no value is entered or --noprompt was specified when msconfig was invoked, and (new in 8.0.2.3) s2 specifies the name of a statefile variable whose value is used as a default and updated with any value that's entered. The --statefile switch must be specified on the msconfig command line for s2 to have any effect.

The read_password operation obtains a password string from the administrator executing the recipe.

If the -restricted switch was specified on a run command, the restricted operation merely returns a 1 unconditionally. But otherwise, the restricted operation prompts the administrator for whether or not to enable modification access to restricted options.

Statefile operations

The functions exists_statefile, get_statefile, set_statefile, and delete_statefile can be used to check the existence of, get, set, and delete statefile variables, respectively. Note that exists_statefile returns -1 and the other functions are no-ops if statefile suport is not enabled by specifying the --statefile switch on the msconfig command line.

Alias creation and manipulation operations

Messaging Server 8.0.1.2 now provides a set of recipe functions to create and manipulate aliases.

An MTA alias consists of a named set of option-value pairs, always containing one ore more alias_entry options which specify the alias expansion addresses. A single alias is represented in the recipe language using an optlist, and a number of functions are provided to access and manipulate aliases. All of these functions accept the unquoted name of the alias as the first argument. This name may be specified in any case and is converted to lower case.

Alias existence can be checked with exists_alias. A nonzero value is returned if the named alias is already part of the configuration; zero if it isn't.

The contents of an alias definition can be retrieved as an optlist using the get_alias function. For example, if the configuration has a users-prefix@example.com alias:


user-prefix@example.com: [prefix_text] Prefix text, user1@example.com, user2@example.com

The call get_alias("user-prefix@exmaple.com") will return an optlist:


["alias_prefix_text", "Prefix text",
 "alias_entry", "user1@example.com",
 "alias_entry", "user2@example.com"]

Note that alias options that do not accept a value will appear with a zero length string as the value.

The add_alias function is used to add a new alias to the configuration. A second argument is required specifying the various alias options as an optlist. An optional third parameter can also be specified containing a list of alias entries; these are converted to alias_entry alias options. An error is returned if the alias already exists. For example, the call:


  add_alias("list@example.com",
            ["envelope_from", "list-error@example.com"],
            ["list1@example.com, "list2@example.com])

adds this alias to the configuration:


list@example.com: [envelope_from] list-error@example.com, list1@example.com, list2@example.com

The replace_alias function is the same as add_alias, except that any alias with that name that already exists will be removed prior to the addition.

The append_alias function is also the same as add_alias, except that specified alias options and entries will be appended to any existing alias definition.

The preend_alias function is also the same as add_alias, except that specified alias options and entries will be preended to any existing alias definition.

The delete_alias function deletes the named channel from the configuration. No operation is performed if the alias doesn't exist.

The unset_alias function takes two arguments: The name of an existing alias and a list of alias options to delete from it. Note that unset_alias is not designed to work on alias entries.

Channel creation and manipulation operations

An MTA channel consists of a named set of option-value pairs, usually containing an official_host_name option. A single channel is represented in the recipe language using an optlist, and a number of functions are provided to access and manipulate channels. All of these functions accept the name of the channel as the first argument. This name may be specified in any case and is converted to lower case.

Channel existence can be checked with exists_channel. A nonzero value is returned if the named channel is already part of the configuration; zero if it isn't.

The contents of a channel definition can be retrieved as an optlist using the get_channel function. For example, if the configuration has a tcp_tas channel:


tcp_tas deliveryflags 2 mustsaslserver smtp allowswitchchannel maytlsserver
tcp_tas-daemon

The call get_channel("tcp_tas") will return an optlist:


["official_host_name", "tcp_tas-daemon",
 "deliveryflags", "2",
 "mustsaslserver", "",
 "smtp", "",
 "allowswitchchannel", "",
 "maytlsserver", ""]

Note that channel options that do not accept a value appear with a zero length string as the value.

The add_channel function is used to add a new channel to the configuration. A second argument is required specifying the various channel options as an optlist. An error is returned if the channel already exists. For example, the call:


  add_channel("tcp_aol", ["official_host_name", "tcp-aol",
                          "single_sys", "",
                          "randonmx", "",
                          "noswitchchannel", "",
                          "pool", "SMTP_POOL",
                          "smtp", ""]);

adds this channel to the configuration:


tcp_aol single_sys randommx noswitchchannel pool SMTP_POOL smtp
tcp-aol

The fact that a channel is represented as an optlist makes it easy to add a channel based on an existing one:


  add_channel("tcp_new",
              put_optlist(get_channel("tcp_local"),
                          "official_host_name", "tcp-new"));

The replace_channel function is the same as add_channel, except that any channel with that name that already exists will be removed prior to the addition.

The delete_channel function deletes the named channel from the configuration. No operation is performed if the channel doesn't exist.

Finally, the set_channel function changes an existing channel. The second argument to set_channel must be an optlist containing the channel options to set. Existing options will be overridden; new options will be added. For example, given the channel:


tcp_intranet loopcheck maysaslserver mx pool SMTP_POOL \
 saslswitchchannel tcp_auth single_sys smtp \
 allowswitchchannel maytlsserver
tcp_intranet-daemon

The call:


  set_channel("tcp_intranet", ["master_debug", "",
                               "nomx", "",
                               "daemon", "router.example.com",
                               "multiple", ""]);

will modify the channel to be:


tcp_intranet daemon router.example.com loopcheck master_debug \
 maysaslserver multiple nomx pool SMTP_POOL \
 saslswitchchannel tcp_auth single_sys smtp \
 allowswitchchannel maytlsserver
tcp_intranet-daemon

Rewrite rule creation and manipulation operations

MTA rewrite rules are represented in Unified Configuration a list of rule values under the rewrite group. Each such rule value has a pattern and a template, separated by white space. The recipe language supports a number of functions which operate on rewrite rules; for rewrite rule values, such functions use an optlist specifying pattern-template pairs. For instance, the call:


append_rewrites([".lmtp", "$E$F$U%$H.lmtp@lmtpcs-daemon",
                 ".lmtp", "$B$F$U%$H@$H@lmtpcs-daemon"])


adds rewrite rules:


msconfig> show rewrite * .lmtp*
role.rewrite.rule = .lmtp $E$F$U%$H.lmtp@lmtpcs-daemon
role.rewrite.rule = .lmtp $B$F$U%$H@$H@lmtpcs-daemon

Note how, in contrast to many other recipe language function uses of optlists, when it comes to the rewrite rule creation and manipulation functions, the optlist arguments used are not specifying option-value pairs, but rather are specifying (an ordered rule list of) pattern-template pairs.

The recipe language functions available specifically for creating or manipulating rewrite rules are:

  • append_rewrites(c)
  • delete_rewrites(l)
  • get_rewrites[(p[,t])]
  • prepend_rewrites(c)
  • replace_rewrites(c)

Mapping creation and manipulation operations

An MTA mapping consists of a named and possibly annotated set of pattern-template pairs. A single mapping is represented in the recipe language using an optlist, and a number of functions are provided to access and manipulate mappings. All of these functions accept the name of a mapping as the first argument. This name may be specified in any case and is converted to upper case.

Mapping existence can be checked with exists_mapping. A nonzero value is returned if the named mapping is already part of the configuration; zero if it isn't.

The contents of a mapping can be retrieved as an optlist using the get_mapping function. For example, if the configuration has a PORT_ACCESS mapping:


PORT_ACCESS

! Handle internal IP addresse
  *|*|*|*|*                    $C$|INTERNAL_IP;$3|$Y$E
  *                            $NEXTERNAL

The call get_mapping("PORT_ACCESS") will return an optlist:


["", " Handle internal IP addresses\n",
 "*|*|*|*|*", "$C$|INTERNAL_IP;$3|$Y$E",
 "*", "$NEXTERNAL"]

Note that the comment appears as name-value pair with an empty string as the name.

The add_mapping function is used to add a new mapping to the configuration. A second argument is required specifying the content of the mapping as an optlist. An error is returned if the mapping already exists. For example, the call:


  add_mapping("test_mapping", ["a","b","c","d","","Last","e","f"]);

adds this mapping to the configuration:


TEST_MAPPING

  a b
  c d
! Last
  e f

The replace_mapping function is the same as add_mapping, except that if the mapping already exists its contents will be replaced.

The delete_mapping function deletes the named mapping from the configuration. No operation is performed if the mapping doesn't already exist.

Finally, the append_mapping and prepend_mapping functions add entries to an existing mapping. The second argument to these functions must be an optlist containing the entries to add. Both functions are equivalent to add_mapping if the specified mapping doesn't already exist. For example, given the mapping:


TEST_MAPPING

  c d

then the calls:


  prepend_mapping("Test_Mapping", ["a","b"]);
  append_mapping("test_mapping", ["e","f"]);

will modify the mapping to be:


TEST_MAPPING

  a b
  c d
  e f

Deployment map operations

The deploymap recipe language function's semantics closely follow those of the DEPLOYMAP msconfig command.

All of the deploymap recipe and msconfig support was added in the 8.0.1.1.0 release of Messaging Server.

Add operations
  deploymap :add :deployment d

Adds deployment d to the deployment. Adding a deployment that already exists is a no-op.


  deploymap :add [:deployment d] :host h [:role r]

Adds host(s) h with role r to deployment d in the deployment map. h can be either a string or a list. An error occurs if any of the hosts already exist. The current deployment is used if d is not specified; if there is no current deployment the first deployment in the deployment map is selected. A deployment with the default name of "site-01" will be created if no deployment exists in the deployment map. No role will be associated with the hosts if r is not specified.


  deploymap :add [:deployment d] :host h :property p

Add property/properties p to host h in deployment d. Host h will be created if it does not already exist. The current deployment is used if d is not specified; if there is no current deployment the first deployment in the deployment map is selected. A deployment with the default name of "site-01" will be created if no deployment exists in the deployment map.


  deploymap :add [:deployment d] :host h :property p :role r

The host h is created in deployment d with role r and properties p. The host must not already exist. The current deployment is used if d is not specified; if there is no current deployment the first deployment in the deployment map is selected. A deployment with the default name of "site-01" will be created if no deployment exists in the deployment map.

All add operations return the number of modifications that were made to the deployment map.

Create operations
  deploymap :create

Create a new, empty deployment map. Note that if you write this out using msconfig's deploymap write command you will delete all your existing entries!

Delete operations
  deploymap :delete :deployment d

Deletes deployment d from the deployment map. Deleting a nonexistent deployment is a no-op.


  deploymap :delete [:deployment d] :host h

Deletes host(s) h from deployment d. h can be either a string or a list. Deleting a nonexistent host is a no-op. The current deployment is used if d is not specified; if there is no current deployment the first deployment in the deployment map is selected.


  deploymap :delete [:deployment d] :host h :role

Delete any role associated with host(s) h in deployment d. Deleting a nonexistent role is a no-op. An error occurs if host h does not exist. The current deployment is used if d is not specified; if there is no current deployment the first deployment in the deployment map is selected.


  deploymap :delete [:deployment d] :host h :property p

Delete any properties for host h in deployment d that match any of the glob-style wildcard(s) p. Both p and h can be a string or a list. The current deployment is used if d is not specified; if there is no current deployment the first deployment in the deployment map is selected.

All delete operations return the number of modifications that were made to the deployment map.

Dump operation
  deploymap :dump

Returns a string containing an outline of the entire deployment map.

List operations
  deploymap :list :deployment [d]

Returns a list of all the deployments in the deployment map that match the pattern d. All deployments are returned if d is omitted.


  deploymap :list [:deployment d] :host [h] [:online | :offline]

Returns a list of all of the hosts in deployment d which match the pattern glob-style pattern h. The current deployment is used if d is not specified; if there is no current deployment the first deployment in the deployment map is selected. All hosts are returned if h is not specified.


deploymap :list [:deployment d] [:host h] :role [r] [:online | :offline]

Returns a list of all the unique roles of the hosts in deployment d matching the glob-style pattern h. The current deployment is used if d is not specified; if there is no current deployment the first deployment in the deployment map is selected. r is an optional glob-style pattern used to filter the roles that are returned. A list of all the roles associated with all of the hosts is returned if :host h is not specified. Note that the expression:


    string(deploymap :list :host h :role)

can be used to obtain the role of host h as a string.


  deploymap :list [:deployment d] :host :role [r] [:online | :offline]

Returns an optlist containing a list of all the hosts in deployment d and their associated roles. Hosts that do not have roles are not returned. The current deployment is used if d is not specified; if there is no current deployment the first deployment in the deployment map is selected. r is an optional glob-style pattern containing one or more wildcards or two or more non-wildcard strings used to filter the roles that are returned.

Note that a sublist l of the first elements in an optlist t is easily extracted with a loop of the form:


       l = []; loop {exitif t == []; l = pop(t); pop(t);}
 

  deploymap :list [:deployment d] :host :role r [:online | :offline]

Returns a list of all the hosts in deployment d with role r. r must not contain more than one element or any glob-style wildcard characters; if it does an optlist is returned as described above. The current deployment is used if d is not specified; if there is no current deployment the first deployment in the deployment map is selected.


deploymap :list [:deployment d] [:host h] [:role r]
          :property [p] [:online | :offline]

Returns a list of property values for hosts matching h in deployment d and with a role matching r. The current deployment is used if d is not specified; if there is no current deployment the first deployment in the deployment map is selected. If :host h is not specified the properties of all hosts are returned. No role check is performed if r is not specified. p is an optional glob-style pattern used to filter the properties that are returned.


  deploymap :list [:deployment d] :host [:role r] :property p [:online | :offline]

Returns a list of hosts in deployment d which have properties matching p, and optionally, a role matching r. The current deployment is used if d is not specified; if there is no current deployment the first deployment in the deployment map is selected. p must be a string or list of glob-style patterns.

In all of these operations the :online and :offline parameters will limit hosts to those known to be online or offline, respectively.

Read operations
  deploymap :read s

Reads a JSON-format deployment map from string s.

Rename operations
  deploymap :rename n :deployment d

Renames deployment d to n. d must specify an existing deployment; n must be a nonempty utf-8 string.


  deploymap [:deployment d] :rename n :host h

Renamed host h in deployment d to n. The current deployment is used if d is not specified; if there is no current deployment the first deployment in the deployment map is selected. Host h must already exist and n must be a valid domain name.

All rename operations return the number of modifications that were made to the deployment map.

Set operations
  deploymap :set [:deployment d] :host h :role r

Sets the role for host(s) h in deployment d to r. h can be either a string or list. The specified hosts must already exist in the deployment. The current deployment is used if d is not specified; if there is no current deployment the first deployment in the deployment map is selected.

All set operations return the number of modifications that were made to the deployment map.

Write operations

  deploymap :write

Returns the contents of the current deployment map as a JSON-formatted string. Note that no mechanism is provided in the recipe language to update the active deployment map; this can only be done at the msconfig level.

Optlist manipulation operations

As previously described, an optlist is a list containing an even number of strings which are interpreted as name-value pairs. A number of functions are provided to manipulate these sorts of lists.

An optlist can be created and populated just like any other list. Alternately, the put_optlist function can be used to add elements to an empty optlist. Optlists can also be read from files in name=value format. For example:


  o = []; # Empty optlist
  o = ["A","B"]; # Optlist containing a single option A with value B
  o = ["A","C", "B", "D"]; Optlist containing two options A and B with values C and D
  o = put_optlist([], "A","C", "B", "D"); # Same as previous optlist
  o = read_optlist(read_file("optlist.txt"); # Read optlist from file optlist.txt

You can get option values from an optlist or check if a given option exists. For example, given an optlist o = ["A", "C", "B", "D"], the following results would be returned:


  get_optlist(o, "A") -> "C"
  get_optlist(o, "B") -> "D"
  get_optlist(o, "E") -> ""
  exists_optlist(o, "A") -> 1
  exists_optlist(o, "N") -> 0

Options can be set or deleted from an optlist. Note that it is common to assign the results of these functions back to the same optlist.


  o = put_optlist(o, "E", "F"); # Add option E with value F to optlist o
  o = delete_optlist(o, "A"); # Delete option A from optlist o  

And in MS 8.0.1.3 or later:


  o = delete_optlist(o, ["A","B"]); # Delete option A with value B from optlist o  

Optlists can be written out as name=value format files:


  write_file("optlist.txt", write_optlist(o));

LDAP operations

(New in MS 8.0.1) The recipe language can access LDAP. Several functions exist for such operations.

The ldap_init(o) function initializes the built in LDAP client. It must be called prior to using any of the other recipe language ldap_* functions.

By default, the LDAP client uses the current settings of the ugldaphost, ugldapbinddn, ugldapbindcred, ugldapport, and ugldapusessl base options when it initializes. The single argument o is an optlist specifying override values for any or all of these options. The optlist may be empty. Repeated calls will shut down and reinitialize the LDAP client with new settings. The LDAP client is shut down automatically when the recipe terminates.

The ldap_ldif(s[,f]) function applies the LDIF contained in the string s to an LDAP directory. (Details of which LDAP directory -- and how to connect to it -- must previously be established via an ldap_init call; attempting to call ldap_ldif before ldap_init will result in an error.)

By default, any LDAP errors that occur attempting to perform the operation of applying the LDAP will be treated as a recipe warning, but see bit 4096 of the optional flags argument f. The optional flag argument f is a bit-encoded integer specifying flags; the currently defined flag bits are:

ldap_ldif optional flag argument bits
Bit Value Usage
0 1 If set, continute processing after any error.
1 2 If set, treat "entry exists" on add as success.
2 4 If set, allow no-such-object if hint present.
12 4096 If set, treat any LDAP error that occurs as a recipe error.

The ldap_ldif function returns an integer count of the number of successful modifications performed.

(New in MS 8.0.1.1.0) The ldap_search function takes an optlist argument specifying at least the basedn for the search, and optionally also the attribute to return (attrs), the scope of the search, and a filter (filter) for the search. Valid values for the "scope" are: base, onelevel (or one), subtree (or sub). An optional second integer argument specifies the number of entries to return, and defaults to -1 (return all entries) if omitted. The function returns an optlist containing the matching attribute-value pairs.

Random value generation

The strongrandom(n) function returns the specified number of bytes of random value. This is a cryptographically strong generator.

The random(n) function returns a uniformly distributed random number between 0 and n-1. The linear congruential generator described in "Random Number Generators: Good Ones Are Hard To Find", S. Park and K. Miller, CACM 31 No. 10, pp. 1192-1201, October 1988 is used to generate these numbers. The sequence is initially seeded with the sytem time.

An explicit 32 bit integer seed for the random function can be specified by calling the randomseed(n) function. This may be useful for debugging purposes. A value of 0 will cause the sequence to be reinitialized from the system clock.

Call-out to routine in external library

The call_user(s1,s2,e[,e2...]) function lets recipes call out to routines in external libraries. The argument s1 specifies the path to the external library (assumed to be in IMTA_LIB if a full path is not provided); the argument s2 specifies the routine name; and argument(s) e, e2, e3, etc., specify the arguments to provide to routine s2. The result of the routine call is returned as the result of call_user.

call_userperforms a call of the routine named s2 of the form:

s2(int argc, struct argv, char *reason, int *rlength);

This feature is intended for calling out to site-supplied external routines.

User-defined routines

As of the 8.0 release, the recipe language supports user-defined routines:


    sub routine(p1, ...) {
        ...
        return expression-1;
    }
    ...
    variable = routine(expression-1, ...);

Up to 20 parameters are allowed. Parameters are passed by value and evaluation is lazy: An unused parameter is never evaluated. Parameters are only evaluated once, so it is easy to force evaluation to occur at the beginning of the routine:


    sub f(x, y, z) {
        x; y; z;
        ...
    }

The entire parameter list can be omitted if the routine requires no parameters.

Routines may call themselves recursively, e.g.,


    sub factorial(n) {if n <= 1 {return 1;} else {return n * factorial(n-1);}}

Note, however, that since there is currently no mechanism for forward declarations of routines, two or more routines cannot call each other recursively.

Routines can reference and modify global variables. Local variables can also be defined by placing the my control command immediately prior to the first use of the variable:


    sub fib(n) {
        my s = [1, 1];
        my a = 1;
        my b = 1;
        loop {
            exitif --n < 2;
            my c = a + b;
            s .= c;
            a = b;
            b = c;
        }
        return s;
    }

Autoincrement, autodecrement, and the various augmented assignment operators (+=, .=, and so on) are all allowed on parameters and local variables. So is the exchange operator :=:; however, exchange cannot be used with a global variable on the right hand side and a local variable or parameter on the left hand side.

Preprocessing Directives

The recipe language provides a very limited preprocessor facility as of the 8.0.1 release. The following preprocessing directives are supported:

Preprocessor Directives
Directive Description
%define name [value] Define the preprocessor symbol name. A optional value can be specified but nothing presently makes use of such values.
%elifdef name Combines %else and %ifdef.
%elifndef name Combines %else and %ifndef.
%else Invert the processing state of the preceding %ifdef or %ifndef
%endif Terminates the innermost %ifdef or %ifndef processing block. The processing state reverts to that of the enclosing block if there is one.
%ifdef name Only process subsequent material up to a matching %else or %endif if name is defined.
%ifndef name Only process subsequent material up to a matching %else or %endif if name is not defined.
%include filename Include the content of the file filename in the recipe at the point where the %include directive appears. If a path is not provided in the file specification a series of paths will be checked: (1) The paths to any nested include files, innermost first, (3) The path to the recipe file specified in the RUN command, (4) CONFIGROOT/recipes/, and SERVERROOT/lib/recipes/. Checking (4) and (5) is new in MS 8.0.1.2.0.
%undef name Remove a previous definition of name.

Preprocessing directives must appear in column 1 to be recognized. Note that preprocessor directives have lower precedence than quoted strings, so directives won't be recognized inside of multiline quoted strings.


See also: