# Router

Reference

The `router` daemon makes all decisions affecting the processing of messages in ZMailer.

A mail message is submitted by placing it in a file in the `$`POSTOFFICE`/router/` directory. The `router` frequently scans this directory for new files and will lock and process them as it finds them. The result is a message control file that gets linked into the `$`POSTOFFICE`/scheduler/` and `$`POSTOFFICE`/transport/` directories for use by the `scheduler` in the next step of message processing. The original message file is then moved to the `$`POSTOFFICE`/queue/` directory.

The `router`'s behaviour is controlled by a configuration file read at startup. It is really a `zmsh`(1) script that uses facilities provided builtin to the `router`.

Usage:

- Invoking router without any arguments will do nothing (except make it read its configuration file and promptly exit). The normal startup method is to run the `zmailer`(1) script, as in "`zmailer router`". This will start the `router` as a daemon and kill the previous incarnation of the `router`.

        router
          -diksSV
          -f configfile
          -n #routers
          -o zmsh-options
          -t traceflag
          -L logfile
          -P postoffice

Parameters:

- `-d`

- Detach and run as a daemon.

`-f `configfile``

- Overrides the default configuration file `$`MAILSHARE`/router.cf`.

`-i`

- Run interactively, presenting a `zmsh` session with the configuration file preloaded.

`-k`

- Kill the currently running router by sending it a `SIGTERM` signal.

`-L `logfile``

- Overrides the default log file location `$`LOGDIR`/router`.

`-n `#routers``

- Starts the specified number of parallel router processes. The default is a single router process.

`-o `zmsh-options``

- Sets the option string passed on the internal `zmsh` invocation. The default is `-O`. Note that the leading "-" is mandatory. See `zmsh`(1) (at zref-zmsh-options) for the available options.

`-P `postoffice``

- Specifies an alternate `$`POSTOFFICE`/` directory.

`-S`

- Can be used to turn off non-serious syslogging.

`-s`

- Turns stability-flag off and on. Without this flag, the search of new jobs will be done with (sometimes) timeconsuming care of organizing the job files into time order.

`-t `traceflag``

- Sets trace options, one per `-t` switch, even before the configuration file is loaded. This is otherwise equivalent to the builtin `trace` command. The currently known options are: `assign, bind, compare, db, final, functions, matched, memory, on, regexp, resolv, rewrite, router, and sequencer`.

`-V`

- Print version message and run interactively.

To restart a `router` daemon:

       router -dk

To test an address, start up an interactive session:

      router -i

or if the ZMailer `sendmail`(8) is installed:

      sendmail -bt

Then just use the pre-defined functions.

## ZMSH Script Language

`zmsh` is an implementation of the Bourne shell suitable for use with the ZMailer `router`(8) as its configuration file language interpreter. It contains extensions that allow structured data (in the form of lists) to be manipulated.

The shell supports three basic kinds of functions: Unix commands, user-defined functions, and builtin commands. The latter comes in two variations: normal functions which take string arguments and return a status code (much as an embedded Unix command would work), and list-manipulation functions which understand list arguments and can return list arguments. The defined functions can take any form of argument and return any form of value (a status code, a string, or a list).

Shell operations (pipes, backquote evaluation and substitution) will work between combinations of builtin functions, defined functions, and Unix commands.

The shell precompiles its input to a (possibly optimized) byte-code form, which is then interpreted as required. This means that the original form of the input is not kept around in-core for future reference. If the input is an included file, the shell will try to save the byte-code form in a `.fc` file associated with the input file. For example, if input is from `file.cf`, the shell will try to create `fc/file.fc` and then `file.fc`. These files will in turn be searched for and loaded (after a consistency check) whenever a `.cf` file is included.

The effects of input and output redirections are predicted prior to the execution of a command and its I/O setup.

### ZMSH Usage:

      zmsh
        -CILOPRSYaefhinstuvx
        -c command
        script ...

### ZMSH Parameters:

`-c command`

- Run the given argument as a shell command script.

`-a`

- Automatically export new or changed shell variables.

`-e`

- Exit on non-zero status return of any command.

`-f`

- Disables filename generation.

`-h`

- Hash and cache the location of Unix commands. The option is set by default.

`-i`

- This shell is interactive, meaning prompts are printed when ready for more input, `SIGTERM` signal is ignored, and the shell does not exit easily. This flag is automatically set if `stdin` and `stderr` are both attached to a `/dev/tty`.

`-n`

- Read commands but do not execute them.

`-s`

- Read commands from `stdin`. If there are non-option arguments to the shell, the first of these will be interpreted as a shell script to open on `stdin`, and the rest as arguments to the script.

`-t`

- Exit after running one command.

`-u`

- Unset variables produce an error on substitution.

`-v`

- Print shell input as it is read.

`-x`

- Print commands as they are executed.

### ZMSH Debug options:

`-C`

- Print code generation output onto `stdout`. If this option is doubled, the non-optimized code is printed out instead.

`-I`

- Print runtime interpreter activity onto `/dev/tty`.

`-L`

- Print lexer output onto `stdout`.

`-O`

- Optimize the compiled script. If this option is doubled, the optimized code is also printed out.

`-P`

- Print parser output (S/SL trace output) onto `stdout`.

`-R`

- Print I/O actions onto `/dev/tty`.

`-S`

- Print scanner output (token assembly) onto `stdout`.

`-Y`

- Open `/dev/tty` for internal debugging use.

## Configuration Script Writing Rules

    Text to be inserted here.

## Script Security Issues

    Text to be inserted here.

## Router Script Well Known Entrypoints

This section describes the `router` internal functions used as entrypoints by various uses inside and outside the `router` program.

### The `process()` function

FIXME! WRITEME!

### The `router()` function

FIXME! WRITEME!

### The `crossbar()` function

FIXME! WRITEME!

### The `server()` function

FIXME! WRITEME!

## Script Language Internal Functions

This section describes the `router` internal functions.

FIXME! FIXME! some internal functions are missing from this listing!

### "`:`" (doublecolon)

Syntax:

-       :
          <SPC>
            anything else forming a command pipeline

Description:

- none

Return Values:

- 0

Options:

- none

Notes:

- none

### "`.`", "`include`"

Syntax:

-       .
          scriptfilename

Alternate syntax:

-       include
          scriptfilename

Return Values:

- Exit status of script evaluation, or specifically:

  1

- File not found, or not fstat:able.

2

- Internal loadeval() didn't yield same result as fstat:ed file size is.

64

- Usage: Not exactly one parameter, or it is a void string.

Options:

- none

Notes:

- This puts the running script to read more script from given filename.

### "`[`", "`test`"

Syntax:

-       [
          test parameters ]

Alternate syntax:

-       test
          test parameters

Return Values:

- 1

- True.

0

- False.

-1

- Error.

Options:

- - File testing unary prefix functions:

    `-b file`

  - True if file exists and is block special.

`-c file`

- True if file exists and is character special.

`-d file`

- True if file exists and is a directory.

`-f file`

- True if file exists and is a regular file.

`-g file`

- True if file exists and is set-group-id.

`-k file`

- True if file has its "sticky" bit set.

`-p file`

- True if file exists and is a named pipe.

`-r file`

- True if file exists and is readable.

`-s file`

- True if file exists and has a size greater than zero.

`-t [fd]`

- True if `fd` is opened on a terminal. If `fd` is omitted, it defaults to 1 (standard output).

`-u file`

- True if file exists and its set-user-id bit is set.

`-w file`

- True if file exists and is writable.

`-x file`

- True if file exists and is executable.

- String testing binary functions:

  `str1 = str2`

- True if the strings are equal.

  The "str1" must not begin with a hyphen "-" character! (Actually they must not be any of the magic prefix-, or infix keyword operators, nor "(", "!", or ")". )

  Suggested test setup:

        [ "x$varname" = "xliteral" ] ...

`str1 != str2`

- True if the strings are not equal.

  The "str1" must not begin with a hyphen "-" character! (Actually they must not be any of the magic prefix-, or infix keyword operators, nor "(", "!", or ")". )

  Suggested test setup:

        [ "x$varname" != "xliteral" ] ...

- Integer value testing binary functions:

  `iexpr -eq iexpr`

- True if integer values are equal.

  The iexpr intermediate products are strings for the purposes of this scanners input, but then they are internally treated as system local "integer" datatype.

  The second iexpr can be a pair of: "-l string-expr" which is evaluated as length of that string-expr.

`iexpr -ne iexpr`

- True if integer values are not equal.

  The second iexpr can be a pair of: "-l string-expr" which is evaluated as length of that string-expr.

`iexpr -gt iexpr`

- True if integer value1 is greater than integer value2.

  The second iexpr can be a pair of: "-l string-expr" which is evaluated as length of that string-expr.

`iexpr -ge iexpr`

- True if integer value1 is greater or equal than integer value2.

  The second iexpr can be a pair of: "-l string-expr" which is evaluated as length of that string-expr.

`iexpr -lt iexpr`

- True if integer value1 is less than integer value2.

  The second iexpr can be a pair of: "-l string-expr" which is evaluated as length of that string-expr.

`iexpr -le iexpr`

- True if integer value1 is less or equal than integer value2.

  The second iexpr can be a pair of: "-l string-expr" which is evaluated as length of that string-expr.

- File comparison binary functions:

  `file1 -nt file2`

- True if file1's mtime is newer than file2's.

  Filenames are best to be either absolute paths (begins with "/"), or dot-relative (begins with "./" pair). Unqualified names are hazardous, e.g. "-file-name-".

`file1 -ot file2`

- True if file1's mtime is older than file2's. (See comment above.)

`file1 -ef file2`

- True if both files have same inode, and device. (See comment above.)

- Logical functions:

  `! expr`

- Unary NOT

`expr -a expr`

- Binary AND

`expr -o expr`

- Binary OR

`( expr )`

- Parenthesis

Notes:

- This is basically the shell "`[`" a.k.a. "`test`" program.

  Do note that unlike more usual bourne-shells, this does not short-circuit logical evaluations, e.g. falseness of the left side of an AND does not eliminate evaluation of the right side!

  Usual "`test`" precautions with things like parameter data prefixing with some character so that it will not become treated as one of the control options.

      Not:
        [ "$(funcname ...)" ]
        [ "$varname" = "value" ]

      Ok:
        [ "z$(funcname ...)" ]
        [ "z$varname" = "zvalue" ]

### `attributes`

Syntax:

-       attributes
          object-reference

Return Values:

- The property list symbol (4th) component of an address quad.

Options:

- none

Notes:

- none

### `basename`

Syntax:

-       basename
          pathname
          suffix

Return Values:

- 0

- ok, result string to `stdout`.

1

- Error.

Options:

- If a suffix is given and matches the filename, the suffix too is stripped from the filename.

  There are no "-"-type options.

Notes:

- Prints the base filename of the pathname.

### `break`

Syntax:

-     while ...
      do
         ...
         break
         ...
      done

      case ...
         ...
         break
         ...
      esac

Return Values:

- 1

Options:

- none

Notes:

- none

### `builtin`

Syntax:

- NOT IMPLEMENTED!

        builtin
          builtin command name, and its params

Return Values:

- 0

Options:

- none

Notes:

- NOT IMPLEMENTED!

  Ensures that named command is builtin within the scheduler, and not a) external, b) script based.

### `car`

Syntax:

-       car
          object-reference

Return Values:

- Pointer to copied lisp-object of object-reference's `car` operation.

Options:

- none

Notes:

- This command is synonymous to the `channel` (at zmshref.channel), and `first` (at zmshref.first) functions.

  This version name is for die-hard LISP fans ;-)

### `cat`

Syntax:

-       cat
          filenames

Return Values:

- Output into `stdout`, which can be piped ZMailer router script internally to next receiver in a pipeline.

Options:

- none

Notes:

- The filenames to be "cat:ed" together need to be regular files.

### `cd`

Syntax:

-       cd
          directory

Return Values:

- 0

- `cd` successful.

1

- Error, can't find `$HOME` environment variable.

1

- Error, internal `chdir`(2) call failed. The `stderr` gets an error string.

64

- Bad parameters (too many). (Usage.)

Options:

- none

Notes:

- none

### `cdr`

Syntax:

-       cdr
          object-reference

Return Values:

- Pointer to copied lisp-object of object-reference's `cdr` operation.

Options:

- none

Notes:

- This command is synonymous to the `rest` function (at zmshref.rest).

  This version name is for die-hard LISP fans ;-)

### `channel`

Syntax:

-       channel
          object-reference

Return Values:

- The channel (1st) component of an address quad.

Options:

- none

Notes:

- The `car` (at zmshref.car), and `first` (at zmshref.first) functions are synonymous to this one.

### `continue`

Syntax:

-       continue

Return Values:

- 1

Options:

- none

Notes:

- This affects control flow by returning it into beginning of enclosing loop construction.

  Usage examples:

        while ...
        do
           if ... something ...
           then
             ... something too ...
             continue
           fi
           ... more something ...
        done

### `daemon`

Syntax:

-       daemon

Return Values:

- 0

Options:

- none

Notes:

- Starts the `router` running in daemon mode, scanning the `$`POSTOFFICE`/router/` directory every few seconds for message files to process. This function is invoked automatically by other code in the `router` program and has no other purpose.

### `db`

Syntax:

-      db
        add
        database
        key
        value
       db
        flush
        database
       db
        owner
        database
       db
        print
        database
       db
        remove
        database
        key
       db
        count
        database
       db
        toc

Return Values:

- 0

1

- Error.

Options:

- `a[dd]`

- Add a `key,value` entry to the database, if possible.

`f[lush]`

- For "incore" database this means deletion of the content, but for others this is IO buffer flush (in case of modifications.)

`o[wner]`

- Print the account name of the owner of the database, if possible. This is usually determined by the files associated with the database.

`p[rint]`

- Print all entries of the database, if possible.

`c[ount]`

- Iterate thru the database and count entries in there.

`r[emove]`

- Remove a `key` entry from the database, if possible.

`t[oc]`

- Print a table of defined relations and their associated information. This table has five columns, in order:

  - the name of the relation

  - its type and subtype

  - cache entries and maximum cache size

  - flags

  - and associated files

  See the `relation` function for more information. (zmshref.relation)

Notes:

- DB type | add | flush | owner | print | remove | count
  incore | yes | yes | yes | yes | yes | yes
  header | yes | yes | yes | yes | yes | yes
  ordered | no | yes | yes | yes | no | yes
  unordered | yes | yes | yes | yes | yes | yes
  hostsfile | no | no | no | yes | no | no
  bind | no | no | no | no | no | no
  ndbm | yes | yes | yes | yes | yes | yes
  gdbm | yes | yes | yes | yes | yes | yes
  dbm | yes | yes | yes | yes | yes | yes
  yp (NIS) | no | no | yes | yes | yes | no
  bhash | yes | yes | yes | yes | yes | yes
  btree | yes | yes | yes | yes | yes | yes
  ldap | no | no | yes | no | no | no
  selfmatch | no | no | no | yes | no | yes

### dblookup

Syntax:

- Does lookup via `relation` defined dblookup vector:

        dblookup
          key

             -: defaultkey
                  -- %subst1 %subst2 ... %subst9

        dblookup
          key

             -: defaultkey
                  -- %subst2 %subst2 ... %subst9

  The latter form is for databases which have any driver routine in use!

Return Values:

- cell

- Lookup result

`NULL`

- Lookup failed, variable `$defer` may be set if the reason is considered temporary and thus solvable latter.

Options:

- The '-:' does supply the "final case" lookup key in cases where various domain shortening lookups reach their end (and have the builtin ultimate default lookup of ".").

        relation -lm%:t $DBTYPE -f $MAILVAR/db/routes$DBEXT routesdb
         ...
        a=$(routesdb $lookupkey -: .:ERROR -- $subst1 $subst2)

  With those things the "routes" database can now contain data like:

        .:ERROR  smtp!
        cust.1   smtp!%0
        cust.2   smtp!%0!%1

  With "subst*" values below, results would be:

        subst1="foo1"
        subst2="foo2"

        smtp!
        smtp!foo1
        smtp!foo1!foo2

  respectively.

  Note: The %subst things are used only if the relation definition has -% option flag set!

Notes:

- The access function to the database facilities in the `router`.

  FIXME! Notes about %[0-9] substitution rules, and their controls. (That is: `relation`'s `-%` option! zmshref.relation)

  A complete example of "`-:`" usage from `p-routes.cf`:

      routes_neighbour (domain, address, A) {
          local tmp

          # We have Alternate default-lookup for cases of locally generated
          # ERROR MESSAGES -- for case where the dot (.) leads to error!
          # and we want to reply with DIFFERENT address, thus:  '.:ERROR' key.

          $(iserrormsg) &&
              tmp=$(routesdb "$domain" -: '.:ERROR') &&
                  tmp=$(routes_spec "$tmp" "$address" $A) &&
                      returns $tmp

          tmp=$(routesdb "$domain") &&
              tmp=$(routes_spec "$tmp" "$address" $A) &&
                  returns $tmp

      #| The routes_spec function interprets the return value from the
      #| routesdb lookup.

          return 1
      }

### `echo`

Syntax:

-       echo
          -n
          --
            string-expressions

Return Values:

- 0

Options:

- `-n`

- Don't print newline at end of string.

`--`

- End the option set, use this if there is even a small change of starting the the data with the hyphen character.

Notes:

- none

### `elements`

Syntax:

-       elements
          lisp-object

Return Values:

- lisp-object

Options:

- none

Notes:

- This does a side-effect on input list, which is need in "for" loops:

        for loopvar in $(elements $listvar)
        do
          ...
        done

### `envars`

Syntax:

-       envars

Return Values:

- 0

Options:

- none

Notes:

- A debug tool to print internal variable tree.

### `erraddron`

Syntax:

-       erraddron
          file

Return Values:

- 0

- Successfull operation.

64

- Wrong usage of arguments.

Options:

- Optional filename.

Notes:

- Without a filename this dissociates the possible pre-existing logging file definition.

  With a filename option this specifies a filename into which the router appends all address parsing error messages. This is primarily for curious postmasters or other collectors of address trivia.

  This is a debug tool; usage examples:

        erraddron $POSTOFFICE/postman/ERRADDRLOG

        erraddron

### `eval`

Syntax:

-       eval
          expression

Return Values:

- status

Options:

- none

Notes:

- This is the generic workhorse for self-modifying code execution within the zmsh, it creates the workhorse of following code-fragment:

      # Usage: newattribute <oldattribute> <key1> <value1> [ <key2> <value2> ] ...
      #
      # Returns a new attribute list symbol with the <keyN> <valueN>
      # attributes added to the contents of the <oldattribute> list.

      newattribute (oldattribute) {
              local a null value

              a=$(gensym)
              eval $a=\$$oldattribute
              while [ "$#" != 0 ];
              do
                      lreplace $a "$1" "$2"
                      shift ; shift
              done
              echo -- "$a"
      }

### `exit`

Syntax:

-       exit

Return Values:

- does not return, does `exit(2)` for the shell/router..

Options:

- none

Notes:

- Exit from the shell/router with exit code.

### `export`

Syntax:

-       export
          variable-name

Return Values:

- 0

- ??? FIXME

Options:

- none

Notes:

- Exports variable name(s). If no variables are given, export prints a list of which variables have been exported.

### `filepriv`

Syntax:

-       filepriv
          file
          uid

Return Values:

- 0

- ??? FIXME

1

- Error.

Options:

- none

Notes:

- Prints the numeric user id of the least privileged account that can modify the specified file.

  This is determined by an approximation that pessimistically assumes that any file or directory writable by group or others is insecure, and optimistically assumes that it is enough to check a file and its parent directory instead of all the way to the filesystem root. The reason for the latter is that if grandparent directories are insecure, the system is likely to have just as bad potential problems as can be created by using mail to run processes with forged powers (besides, doing the full check would be quite expensive).

  If a second argument is given, it is the numeric user id to assume for the file. This means only the parent directory will be checked for nonwritability and for having the same (or a 0) uid.

### `first`

Syntax:

-       first
          object-reference

Return Values:

- Pointer to copied lisp-object of object-reference's `car` operation.

Options:

- none

Notes:

- This command is synonymous to the `car` (at zmshref.car), and `channel` (at zmshref.channel) commands.

### `gensym`

Syntax:

-      gensym

Return Values:

- 0

Options:

- none

Notes:

- Generates and prints a new symbol name in the sequence `g0` to `gN` every time it is called. The sequence is reset and any symbol values destroyed after the `router` has processed a message. This function is used to generate new symbols, to hold attached address property lists, during alias expansion.

  Code-fragment showing a way how it is used inside the router scripts:

      # Usage: newattribute <oldattribute> <key1> <value1> [ <key2> <value2> ] ...
      #
      # Returns a new attribute list symbol with the <keyN> <valueN>
      # attributes added to the contents of the <oldattribute> list.

      newattribute (oldattribute) {
              local a null value

              a=$(gensym)
              eval $a=\$$oldattribute
              while [ "$#" != 0 ];
              do
                      lreplace $a "$1" "$2"
                      shift ; shift
              done
              echo -- "$a"
      }

### `get`

Syntax:

-      get
         property-list
         keyname

       get
         property-list-varname
         keyname

Return Values:

- property-list

Options:

- none

Notes:

- Returns a property-list corresponding to key string:

        listvar=(key1 value1 keyname value key3 value3)
        result1=$(get  listvar keyname)
        result2=$(get $listvar keyname)

### `getopts`

Syntax:

-       getopts
          optstring-name
          arguments

Return Values:

- 0

- success ?

1

- Error.

Options:

- none

Notes:

- Never used inside the zmsh scripts, usefullness questionable, and usage documentation missing.

### `grind`

Syntax:

-       grind
          lisp-object

Return Values:

- Pointer to list of varcell.

Options:

- none

Notes:

- This is a debug tool.

  The side-effect is to output the text form of the lisp-object.

### `groupmembers`

Syntax:

-       groupmembers
          groupname

Return Values:

- 0

- Found data, side-effect is described below.

1

- Didn't find anything. No side-effects.

64

- Usage (number of arguments) is wrong.

Options:

- none

Notes:

- Prints the accounts that are listed as members of a group in the system groups file, one per line. Note that accounts with the same login group id, but that are not listed in the groups file, will not appear in this list.

### `hash`

Syntax:

-       hash
          -r
          command names

Return Values:

- 0

- This value is returned always.

Options:

- `-r`

- Path is flushed.

`command names`

- These are looked up one by one via the PATH environment variable, and results are stored into internal quick-access hash table.

Notes:

- This is a part of the "zmsh" shell-script interpreter in good SH-tradition, but is not used in the ZMailer router in any way.

### `homedirectory`

Syntax:

-       homedirectory
          user

Return Values:

- 0

- Found home directory, side-effect is printing of that directory into `stdout`, whence it may be captured into e.g. some variable.

2

- Error, no such user.

3

- Error, some temporary lookup failure. Also sets "$defer" variable.

64

- Usage error, wrong number of arguments. (Usage.)

Options:

- none

Notes:

- Prints the home directory of the specified user account.

### `host`

Syntax:

-      host
         object-reference

Return Values:

- The host (2nd) component of an address quad.

Options:

- none

Notes:

- none

### `hostname`

Syntax:

-       hostname name

Return Values:

- 0

- Returns always this value.

Options:

- none

Notes:

- Sets the router's idea of the system hostname. Without an argument the name is retrieved from the system and printed. The router has no preconceived notion of what the hostname is, so "Message-Id:" and "Received:' headers will only be generated if a "hostname" has been set using this function.

### `ifssplit`

Syntax:

-       ifssplit
         any-string

Return Values:

- split list

Options:

- none

Notes:

- This splits given input string per IFS environment variable, and produces a list of substrings ready for further use.

### `lappend`

Syntax:

-       lappend
          varname
          anyvalue

Return Values:

- NULL; actually error cases output to `stderr`, all others are handled silently.

Options:

- none

Notes:

- This appends content of list object (anyvalue) to named varname variable:

      #
      # From  aliases.cf  of system standard scripts.
      #

      maprrouter (attribute, localpart, origaddr, plustail, domain) {
          local shh al

          al=()
          while read address
          do
              case "$address" in
              ") shh=(((error expansion "$localpart")))
                  lappend al $shh
                  continue
                  ;;
              esac

              defer="
              shh=$(rrouter "$address" "$origaddr" $attribute \
                   "$plustail" "$domain")
              [ -n "$defer" ] &&
                  shh=(((hold "$defer" "$address" $attribute)))
              defer="
              lappend al $shh
          done
          returns $al
      }

### `last`

Syntax:

-       last
          lisp-object

Return Values:

- Return a pointer to last cell of varcell's list.

Options:

- none

Notes:

- This is actually a unused relict from way way back..

### `length`

Syntax:

-      length
         lisp-object

Return Values:

- String of decimal numbers representing the number of varcell's in the lisp-object primary chain.

Options:

- none

Notes:

- This counts the number of elements in the chain, not length of any string.

### `list`

Syntax:

-      list
         objects

Return Values:

- List-wrapped lisp-object.

Options:

- none

Notes:

-     z# list 1 2 3
      (1 2 3)
      z# tt=(1 2 3)
      z# list $tt
      ((1 2 3))
      z# tt=$(list 1 2 3)
      z# grind $tt
      (1 2 3)

### `listaddresses`

Syntax:

-      listaddresses
        -e error-address
        -E errors-to-address
        -c comment

  The `stdin` feeds in the list of addresses.

Return Values:

- lisp-list

- Successfull processing result. There can still be an error-report sent to the error-address; see below.

NULL

- Error, `stderr` gets an error report text, and in some cases also the "`-e`" defined error-address, and "postmaster" will get email telling of problems in the file.

Options:

- `-e`

- Any syntax errors at list parsing will cause a report to be mailed to the given address.

`-E`

- If an error occurs while messages are being delivered, the `errors-to-address' can be used to force error message destination elsewhere than to the default `sender' of the message.

`-c`

- A comment will be inserted in the error report.

Notes:

- Filters an RFC822 address list on standard input to produce one normal form (no non-address tokens) address per line on its output. This function can be used to parse the alias file or .forward files or similar.

### `listexpand`

Syntax:

-       listexpand
          -c comment
          -e error-address
          -E errors-to-address
          -p privilege-integer
          -N notary-string
          $attribute
          $localpart
          $origaddr
          $plustail
            $domain

Return Values:

- lisp-list (or NULL)

Options:

- `-e`

- Any syntax errors at list parsing will cause a report to be mailed to the given address.

`-E`

- If an error occurs while messages are being delivered, the "errors-to-address" can be used to force error message destination elsewhere than to the default "sender" of the message.

`-c`

- A comment will be inserted in the error report.

`-p`

- Integer privilege code for expanded addresses

`-N`

- Notary string data, or "-" for "no DNS".

Notes:

- This implements the most common pipeline where `listaddresses` (at zmshref.listaddresses) was used with more efficient memory consumption handling. (System memory usage internals have changed over the time, and now this is no longer especially great memory expenditure saver.)

  The `stdin` will feed addresses from a file for parsing, and parameter mapping + routing.

  Comparison of previous `listaddresses` (at zmshref.listaddresses) -script implemented code, and new one using the `listexpand`:

  Old:

          l="$preowner$(basename "$lcuser" -mod)$postowner"
          nattr=$(newattribute $attr privilege $priv sender "$l")
          $(zapDSNnotify $nattr delivered "$sender" "$lcuser$domain")
          a=$(runas $priv cat "$a" | \
              listaddresses       -E "$l$domain"          \
                                  -e "$l"                 \
                                  -c "$a file expansion" |
              maprrouter $nattr "$a" "$host" "$plustail"  \
                          "$domain")
          postzapDSNnotify a
          returns $a

  New:

          l="$preowner$(basename "$lcuser" -mod)$postowner"
          if priv=$(getpriv "664" $priv "$a" maillist) &&
             nattr=$(newattribute $attr privilege $priv sender "$l") ; then
              $(zapDSNnotify $nattr delivered "$sender" "$lcuser$domain")
              a=$(runas $priv cat "$a" | \
                  listexpand      -E "$l" -e "$l" -p $priv        \
                                  -c "$a file expansion"          \
                                  $nattr  "$a" "$host" "" "$domain" )
              postzapDSNnotify a
              returns $a
          fi

### `login2uid`

Syntax:

-      login2uid
        username

Options:

- none

Return Values:

- "nobody-uid"

- Either uid of "nobody", or no lookup match for given userid.

uid

- UID of user.

Notes:

- Prints the uid associated with the specified account name, if any. A side-effect is to add the GECOS name field of the account to the fullname in-core database, to add the login name to uid mapping to the pwnam in-core database, and to add the uid to login name mapping to the pwuid in-core database.

### `lreplace`

Syntax1:

-      lreplace
         varname
         indexnum
         anyvalue

Syntax2:

-       lreplace
         varname
         fieldname
         anyvalue

Return Values:

- none

Options:

- none

Notes:

- This replaces designated field on varname variable containing list-like data with anyvalue value.

  The field designation can be given in numeric form, where the field index can be numeric (first field is zero), or keyname on key/value pair list.

  If a key is not found (with key/value pairs), then designated pair is added to the list.

        z$ tt=(aa 11 bb 22 cc 33 dd 44)
        z$ grind $tt
        (aa 11 bb 22 cc 33 dd 44)
        z$ lreplace tt bb zz
        z$ grind $tt
        (aa 11 bb zz cc 33 dd 44)
        z$ lreplace tt 0 aaa
        z$ grind $tt
        (aaa 11 bb 22 cc 33 dd 44)
        z$ lreplace tt zz aa
        z$ grind $tt
        (aaa 11 bb 22 cc 33 dd 44 zz aa)

  This is an example of "`lreplace`" use in the scripts:

      # Usage: newattribute <oldattribute> <key1> <value1> [ <key2> <value2> ] ...
      #
      # Returns a new attribute list symbol with the <keyN> <valueN>
      # attributes added to the contents of the <oldattribute> list.

      newattribute (oldattribute) {
              local a null value

              a=$(gensym)
              eval $a=\$$oldattribute
              while [ "$#" != 0 ];
              do
                      lreplace $a "$1" "$2"
                      shift ; shift
              done
              echo -- "$a"
      }

  A fragment of code from inside the `crossbar.cf` shows different usages:

      ....
          usenet)
              lreplace from 2 "$(uucproute "$(user $from)")"
              tsift $(user $from) in
              $hostname!.*    ;;
              .*
                  lreplace from 2 $hostname!$(user $from)
                  ;;
              tfist
              # newsgroup name only
              lreplace to 2 "$(localpart "$(user $to)")"
              ;;
      ....

### `malcontents`

Syntax:

-       malcontents

Return Values:

- none

Options:

- none

Notes:

- ZMSH Debugging thing.

### `printaliases`

Syntax:

-       printaliases
          -v
          -o indexoutputfile
          file

Return Values:

- 0

1

- Error.

Options:

- `-v`

- Verbose.

`-o` `indexoutputfile`

- Each header line will also generate a "header TAB byteoffset" line in the indexfile.

Notes:

- This function was used by the "newaliases(1)" program to generate the aliases database from a source file.

  That task has been moved into " `zmailer newdb`" (at zref-zmailer-newdb) process, along with all other router database refreshment tasks.

  Reads RFC822 syntax header lines from the specified file, parses them assuming contents must be an address list, and sorts and prints the header lines with all addresses in normal form. Comments are allowed; they extend from the character "#" at the beginning of a line, or after an address, to the end of line.

### `process`

Syntax:

-       process
          messagefile

Return Values:

- 0

- Successfull processing.

100

- File name parameter missing.

other

- Return value from the underlying scripts.

Options:

- none

Notes:

- The protocol switch function. It is called by the " `daemon`" function (at zmshref.daemon) to process a message found in the `$POSTOFFICE/router/` directory.

  This function will in turn call an internal protocol-specific function which knows the syntax and semantics of the message file. The current version knows about messages submitted using the `MSG_RFC822` parameter to mail_open(3). For that case, the protocol function is called "`rfc822`".

  router has a bit more complex directory semantics, than is stated above. See "zmailer(3)" for details.

  Although the "`process`" function is provided built in, it is usually overridden by a defined function in the router configuration file. (See `process.cf`, and the entrypoint text at zmshref.wke.process)

### `read`

Syntax:

-       read
          variable

Return Values:

- 0

- Successful read.

1

- Error. (End of input)

64

- Error. Missing mandatory variable name. (Usage.)

Options:

- none

Notes:

- The `read` will get one line of input, and if there are more than one variable name parameter, split it at the whitespaces (IFS chars).

  There appears to be a bug when there are less IFS separated sequences than there are varnames: The extra varnames do get things at a bit random.. (2001-Oct-15)

  If input line is zero length (or all IFS chars), the `read` will read another input line.

  If the input line ends with character: "\" as its very last, the line gets a catenation of next input line effectively unfolding multiline coded string.

      z# echo "1 2 3 4 5" | read v1 v2
      z# echo $?
      0
      z# echo $v1
      1
      z# echo $v2
      2 3 4 5
      z# echo "11111" | read v1 v2
      z# echo $?
      0
      z# echo $v1
      11111
      z# echo $v2
      11111

### `recase`

Syntax:

-      recase

            -u
            -l
            -p

          -- string

Return Values:

- 0

- Success, `stdout` gets the result string.

64

- Bad option. (Usage.)

Options:

- --

- End options.

-u

- Convert into uppercase.

-l

- Convert into lowercase.

-p

- Prettify.

Notes:

- A case-mapping function that prints the parameter string in either all-uppercase, all-lowercase, or capitalized (pretty).

  The input to be converted is expected to be single string, e.g. not multiple strings.

  Due to internal use of "getopt" for parameter pickup, if there is even the slightest change that the string begins with a hyphen (minus) character, invocation must use the -- pair to end the options, and to protect the parameter.

  Typical use in the router scripts:

         lcuser="$(recase -l -- "$user")"

### `recipient`

Syntax:

-       recipient

Return Values:

- 1

- Is a recipient address.

0

- Is not.

Options:

- none

Notes:

- A boolean function that returns the value of the statement "executing a header rewriting function and the address is a recipient address in a message header".

### `relation`

Syntax:

- Generic:

        relation
        -i
        -T
        -t dbtype/subtype
        -f file
        -e #
        -s #
        -:%blmnu
        -d driver
        -C configfile
        name

  The separator character between "dbtype" and "subtype" can be either a comma (",") or a slash ("/"), as user wishes. In case the subtype is a filepath (or otherwise begins with a slash), the user propably wants to use comma to reduce confusion.

  More specific versions:

        relation
        -t yp,yp-mapname
        -f yp-domain
        -e #
        -s #
        -:%blmnu
        -d driver
        name

        relation
        -t bind/query-type
        -f file
        -e #
        -s #
        -:%blmnu
        -d driver
        name

        relation
        -i
        -t ordered,filepath2
        -f filepath1
        -e #
        -s #
        -:%blmnu
        -d driver
        name

        relation
        -i
        -t unordered,filepath2
        -f filepath1
        -e #
        -s #
        -:%blmnu
        -d driver
        name

        relation
        -t ordered
        -f filepath
        -e #
        -s #
        -:%blmnu
        -d driver
        name

        relation
        -t unordered
        -f filepath
        -e #
        -s #
        -:%blmnu
        -d driver
        name

        relation
        -t dbtype
        -f file
        -e #
        -s #
        -:%blmnu
        -d driver
        name

  Note: "`zmailer newdb`" does not support "`-i`" option use! (FIXME! FIXME! 2001-Mar-8)

  Special support for testing of presence of support for given `dbtype`:

        relation
        -T -t dbtype
        dummy_name

  Options are listed below. `name` is the name of the relation that is wanted to be created. Examples:

      relation -t bind,mx mxhost
      relation -t ordered -f $MAILVAR/db/routes routes
      relation -t ordered -b -f /usr/lib/news/active.sorted newsgroups

Return Values:

- 0

- Relation is reated successfully, however possible database access are not tried yet.

1..7

- Error.

Options:

- `-T`

- Special flag enabling script to test for given db-type:

        relation -T -t btree dummy && echo "have BTREE database"

`-t `dbtype`[,`subtype`]`

- Below is a table to option interdependencies as they apply with different database types.

  #### `relation`'s option interdependencies

  Db-Type | Subtype meaning | `-f` option value
  incore | ignored | ignored
  header | ignored | ignored
  selfmatch | ignored | ignored
  hostsfile | ignored | ignored (?)
  ordered | ignored (without `-i` option) | path-to-file
  unordered | ignored (without `-i` option) | path-to-file
  ordered | path-to-file-2 (with `-i` option) | path-to-file-1
  unordered | path-to-file-2 (with `-i` option) | path-to-file-1
  bind | DNS-query-subtype | ignored
  yp | YP-mapname | YP-domain
  ldap | ignored?? | path-to-cfg-file
  dbm | ignored | basepath-to-db-file
  ndbm | ignored | basepath-to-db-file
  gdbm | ignored | basepath-to-db-file
  btree | ignored | basepath-to-db-file
  bhash | ignored | basepath-to-db-file

  One of the known types of databases, currently:

  `incore`

- A database maintained in virtual memory (using splay trees). This type should not be used for any database that must periodically be flushed, since all occupied memory can be freed.

`header`

- A special incore database type used to store RFC822 header semantics information. It is unlikely to be used for anything else.

`ordered`

- The `-f`-option defines the path of the file.

  A file with key-value pairs on every line, separated by whitespace, sorted by key. (See `sort`(1).)

      key_at_line_start   data at the same line

`unordered`

- The `-f`-option defines the path of the file.

  A file with key-value pairs on every line, separated by whitespace.

      key_at_line_start   data at the same line

`ordered,`path-to-file-2``

- The `-f`-option defines the path of the file-1.

  The version for antique "`-i`" mode.

`unordered,`path-to-file-2``

- The `-f`-option defines the path of the file-1.

  The version for antique "`-i`" mode.

`hostsfile`

- The `-f`-option defines the path of the file. (In theory...)

  A rather theorethical database looking into hosts(5) database file (often `/etc/hosts`).

`bind/query-subtype`

- The `-f`-option defines the path of the resolver configuration file. (Not implemented!)

  The BIND implementation of a Domain Name System resolver. The subtype for this type is the name of a Resource Record type in the `IN` class.

  Supported subtypes are:

  - A
  - AAAA
  - ANY
  - CNAME
  - MX
  - MXLOCAL
  - MXWKS
  - PTR
  - TXT
  - UINFO
  - WKS

  FIXME! FILL DETAILS! (About the return values)

`ndbm`

- The `-f`-option defines the base path of the files, and the NDBM appends ".pag" and ".dir" to each file.

  The newer DBM as created at (I think) BSD 4.2. This is two-file database with API utilizing nonglobal API, that is, multiple databases can be open simultaneously. This appends .dir and .pag to the supplied name!

  Limitation: The length of key plus the length of data must not exceed 1024 bytes. With certain kinds of alias databases this may be too low limit!

`dbm`

- The `-f`-option defines the base path of the files, and the DBM appends ".pag" and ".dir" to each file.

  The old ATT DBM library with even worse limitations than `ndbm` has. Avoid if you can. (ZMailer can manage with this also, each lookup is done by opening the DB, and closing immediately afterwards.)

  Some versions of ATT DBM did not contain externally callable `close`() function! ZMailer propably won't work at such a system anyway...

`gdbm`

- The `-f`-option defines the path of the database file, the GDBM does not append anything to the name.

  The GNU implementation of the new DBM library. Note: GDBM uses one file, which is named exactly as you parametrize it. This is unlike NDBM, which appends .dir and .pag to the supplied name!

`yp,`mapname``

- The Network Information Service from Sun Microsystems Inc. (Later renamed to be NIS, the still newer NIS+ is not supported).

  The ``mapname`` "subtype" passes knowledge about which YP-map the query is to be done from.

  The `-f`-option is used to pass the YP-domain information to the interface.

`btree`

- SleepyCat DB 1.x, 2.x, 3.x or 4.x B-Tree database

  The `-f`-option defines the path of the database file, the SleepyCat DB does not append anything to the name. (This is true with versions 1.x, 2.x, 3.x, and 4.x.)

  The `-C`-option defines SleepyCat DB environment configuration file, which can be used to define advanced features, mainly Concurrent Data Store function.

       FIXME! FIXME! config file!

      $ cat /opt/mail/db/sleepyenv.conf
      #
      # SleepyCat DB 3/4 environment settings
      #

      envhome  = /opt/mail/db
      #tmpdir = ...
      envmode  = 0600
      envflags = CDB, CREATE, RO

`bhash`

- SleepyCat DB 1.x, 2.x, 3.x or 4.x HASH database

  The `-f`-option defines the path of the database file, the SleepyCat DB does not append anything to the name. (This is true with versions 1.x, 2.x, 3.x, and 4.x.)

  The `-C`-option defines SleepyCat DB environment configuration file, which can be used to define advanced features, mainly Concurrent Data Store function.

       FIXME! FIXME! config file!

      $ cat /opt/mail/db/sleepyenv.conf
      #
      # SleepyCat DB 3/4 environment settings
      #

      envhome  = /opt/mail/db
      #tmpdir = ...
      envmode  = 0600
      envflags = CDB, CREATE, RO

`selfmatch`

- Given address literal without wrapping square brackets, this "database" decodes the address, and checks if presented IP address is one used by the system at the moment.

`ldap`

- FIXME! WRITEME!

`-f `file``

- A file associated with the database, typically the file containing the data, or the basename of DBM files or something similarly relevant to the database access routine.

`-e `#``

- The default time-to-live on cached information. When the information has been in the cache for this many seconds, it is discarded. The default is 0.

`-s `#``

- Sets the cache size to the specified number. The default is usually 10, depending on the database type.

`-b`

- If the key exists in the database, return the key as the value. ("Boolean relation")

`-i`

- If the key exists, its value is a byte offset into a file named by the subtype for this database. The value then becomes the concatenation of the data on the lines following that offset which start with whitespace.

  This was used for the aliases file back in early 1990, and is usable only with `ordered`, and `unordered` database types.

  (FIXME! IMPLEMENT? To think of it, this makes eminently sense also for `dbm`, and `ndbm` which have data size limitations. But then, SleepyCat DB is recommended for internal databases anyway.)

`-l`

- Map all keys to ASCII lowercase before searching.

`-m`

- Check for file content modification before every access. Reopen the file when a change is detected.

  This option is used when the `router` should discover changes to a database underfoot so it need not be restarted to use new data.

  This is recommended on relations which use unordered, or ordered datasets (aliases, routes, ...), and especially if the system is configured to use `mmap(2)` facility. Updating such databases should preferably use `mv` command to move a new version of the database in place of the old one.

`-n`

- If the key exists in the database and the value is null or list, return the key as value. Otherwise return the value retrieved, if any.

`-u`

- Map all keys to ASCII uppercase before searching.

`-d `[pathalias|pathalias.nodot|longestmatch]``

- Specifies a search driver that allows searching for structured keys using special knowledge. The argument to this option must be a known driver.

  FIXME! WRITEME! WRITE MORE!

`-%`

- We shall do positional parameter substitutions ("%0" thru "%9") on database lookup result data. [XREF??]

  The `zmailer newdb` configuration file `$`MAILVAR`/dbases.conf` uses presence of "%" to signal this aspect of relation wrapper generation. [XREF??]

`-:`

- Actually this is ignored if present, the `zmailer newdb` configuration file `$`MAILVAR`/dbases.conf` uses presence of ":" to signal certain aspects of relation wrapper generation. [XREF??]

Notes:

- On systems with `USE_MMAP` the ordered, and unordered databases are r/o mapped into memory, and for ordered case, a special line-index is generated for speeding up the binary search. (Makes less system calls that way.)

### `rest`

Syntax:

-       rest
          object-reference

Return Values:

- Pointer to copied lisp-object of object-reference's `cdr` operation.

Options:

- none

Notes:

- This command is synonymous to the `cdr` command (at zmshref.cdr).

### `return`

Syntax:

-      return lisp-object

Return Values:

- lisp-object

- The argument lisp-object contains a non ASCII digit character, or is a complex lisp-object.

string

- The argument lisp-object contains a non ASCII digit character, and is a simple string-object.

statuscode

- The argument lisp-object contains a all ASCII digit characters, and is a simple string-object.

  See the Notes below about this, too.

NULL

- Invalid lisp-object.

Options:

- none

Notes:

- The system has a weird dichtomy on returning numeric vs. other results.

  Presume a function call with two different possible results, failure indication, and successfull (arbitrary) string result:

        tmp=$(funcnnn args..) && returns $tmp
        return $tmp  # error code return!

### `returns`

Syntax:

-      returns lisp-object

Return Values:

- lisp-object

- This one will always return the lisp object without interpreting possible string value to be numeric return code.

Options:

- none

Notes:

- See notes of "`return`" above.

### `rfc822`

Syntax:

-       rfc822
          messagefile

Return Values:

- status

Options:

- none

Notes:

- This function controls the parsing and processing of the message file in RFC822/976/2822 format. It is called by the `process` function (at zmshref.process). .

### `rfc822date`

Syntax:

-       rfc822date

Return Values:

- 0

- Side effect: `stdout` gets current time string printed in RFC822/2822 format.

Options:

- none

Notes:

- Prints the current time in RFC822/2822 format.

### `rfc822syntax`

Syntax:

-       rfc822syntax
          address

Return Values:

- 0

- Given input matches RFC 822/976/2822 for "route-address" syntax specification.

1

- Error. Given input is syntactically somehow invalid.

64

- Argument count is not exactly 1. (Usage.)

Options:

- none

Notes:

- This is a simple interface to the address parser. If the command line argument is a syntactically valid RFC822/976/2822 address, this command is silent and returns 0 as status. If there is a parse error, a verbose error message is printed to `stdout` and the function yields a non-zero return status.

### `runas`

Syntax:

-      runas
         user
         function
         arguments

Return Values:

- Any of the values yielded by the executed "function", or:

  0

- Internal evaluation of "function" did yield 0.

1

- Setting target uid failed.

64

- Mandatory parameters missing. (Usage.)

abort

- Resetting target uid to system uid (root) failed.

Options:

- none

Notes:

- Changes the current effective user id of the router process to that given (which may be numeric or an account name), then runs the specified function with the specified arguments, then switches the effective user id of the process back (to root).

### `sender`

Syntax:

-       sender

Return Values:

- 1

- Is a sender address.

0

- Is not sender address.

Options:

- none

Notes:

- A boolean function that returns the value of the statement "executing a header rewriting function and the address is a sender address in a message header".

### `set`

Syntax:

-       set

            -a
            -e
            -f
            -h
            -n
            -t
            -u
            -v
            -x
            -L
            -C
            -P
            -S
            -k

          -
          variable

  Without parameters `set` prints variable values.

Return Values:

- Pointer to copied structure of `car` operation.

Options:

- `-a`

- Automatically export changed variables.

`-e`

- Exit on error exit status of any command.

`-f`

- Disable filename generation (no globbing).

`-h`

- Hash program locations.

`-n`

- Read commands but do not execute them.

`-t`

- Read and execute one command only.

`-u`

- Unset variables are error on substitution.

`-v`

- Print shell input lines as they are read.

`-x`

- Print commands as they are executed.

`-L`

- Trace LEXER processing (sslWalker).

`-C`

- Print branch and emit inputs (sslWalker).

`-P`

- Trace execution (sslWalker).

`-S`

- Print input buffers when used (sslWalker).

`-k`

- Not supported option.

`-`

- Do nothing.

Notes:

- none

### `shift`

Syntax:

-       shift
          number

Return Values:

- 0

- Success.

1

- Error, out of parameters to shift.

Options:

- none

Notes:

- Modifies caller's argument vector by shifting left one (or specified number) of argument(s) in current `ARGV`.

### `sleep`

Syntax:

-       sleep
          number

Return Values:

- 0

- Did sleep a bit, does not tell is anybody interrupted the sleep.

64

- Missing mandatory integer argument. (Usage.)

Options:

- none

Notes:

- Does not tell if the sleep has been interrupted somehow.

### `squirrel`

Syntax:

-       squirrel
          [-]event

Return Values:

- 0

1

- Error.

Options:

- `-`

- Set flag value to 0.

(none)

- Set flag value to 1.

  The events are:

  - `breakin`

  - `badheader`

  - `illheader`

  - `nochannel`

  - `nosender`

Notes:

- Sets the kinds of events that cause a message to be copied into the `$`POSTOFFICE`/postman/` directory. Whether or not a "`-`" is necessary for an event depends on the current state of the event's flag.

  The usage message will indicate what to do to toggle the event flag:

      z# squirrel
      Usage: squirrel [ breakin | -badheader | illheader | nochannel | nosender ]

### `stability`

Syntax:

-       stability

            on
            off

Return Values:

- 0

- Did the work successfully.

64

- Bad parameters. (Usage.)

Options:

- none

Notes:

- Determines whether the router will process incoming messages in arrival order (when on), or in random order determined by position in the router directory. The router will by default do the first queue scan in stable mode, and subsequent scans in unstable mode. The name of this command is the name for a similar characteristic of sorting algorithms.

### "`test`", "`[`"

See: "`[`", a.k.a. "`test`" at zmshref.test.

### `times`

Syntax:

-       times

Return Values:

- 0

- Prints to `stdout` the spent usermode time for process itself, and to all of its children.

1

- Error in `times`(2) system call.

64

- Usage error (no parameters allowed.)

Options:

- none

Notes:

- Prints to `stdout` the spent usermode time for process itself, and to all of its children.

  Sample output:

          12m33s  22m59s

### `trace`

Syntax:

-       trace
          key1 ... keyN
        untrace
          key1 ... keyN

  Enables tracing of the specified items. The valid keywords are listed in the options below.

Return Values:

- 0

- Successful setting/clearing.

64

- Parameter name error. (Usage.)

Options:

- `all`

- Turns on all tracing options.

  You only do this to test the I/O capabilities of your system. (`rfc822`, and `regexp` options generate a lot of output!)

`assign`

- Prints shell variable assignments.

`bind`

- Prints various information from the code that calls the DNS resolver.

`compare`

- Prints `*sift` statement pattern-selector comparisons.

`db`

- Prints database lookups, including cache search and update information.

`except`

- Inverts the sense of what is being done; e.g.:

        trace all except rfc822 regexp

  which is (nearly) exquivalent of:

        trace all
        untrace rfc822 regexp

`final`

- Prints the message envelope information after processing each message.

`functions`

- Prints shell function calls and return values, with nesting indicated by indentation.

`matched`

- Prints `*sift` statement pattern-selector matches.

`memory`

- Prints memory allocation information after each message.

`on`

- Same as `functions` -option.

`regexp`

- Prints regular expression matching execution.

`resolv`

- Turns on the `RES_DEBUG` flag in the BIND resolver library, and prints various information from the code that calls the DNS resolver.

`rewrite`

- Prints the tokenized addresses sent through the message header address rewriting functions.

`router`

- Prints the tokenized addresses sent through the `router` function.

`sequencer`

- Prints the procedural steps taken during message processing.

Notes:

- Authors most common "`trace`" incantation has been wrapped into standard script routine:

      #|
      #|  I kept typing in this trace command so frequently, that eventually
      #|  I just had to make for it into a single command... /Matti Aarnio
      #|

      rtrace () {
              trace all except rfc822 regexp
      }

### `trap`

Syntax:

-       trap

             script trap_nro

Return Values:

- 0

- Set successfully, or displayed successfully.

Options:

- none

Notes:

- If no parameters are given, `trap` prints all known traps.

  In all aspects this is quite alike any bourne-shell "`trap`" function.

  Set, and unset a trap:

        trap "db flush aliasesdb ; log flushed aliases" 16
        trap "" 16

### `type`

Syntax:

-       type
          command

Return Values:

- 0

- Always returns this value.

  The `stdout` gets the report.

Options:

- none

Notes:

-     z# type trap
      trap is a shell builtin
      z# type foobar
      foobar not found
      z# foobar () {echo foo}
      z# type foobar
      foobar is a shell function
      z# type rfc822
      rfc822 is a shell builtin
      z# type process
      process is a shell function
      z# echo $?
      0
      z# type no-such-thing
      no-such-thing not found
      z# echo $?
      0
      z# type
      z# echo $?
      0

### `uid2login`

Syntax:

-       uid2login
           uid

Return Values:

- 0

- Argument count ok, and "`uid`" begins with a digit.

  The `stdout` gets the username.

64

- Parameter error. (Usage.)

Options:

- none

Notes:

- Prints the first account name associated with a specified numeric user id, if any, or "`uid#uid`" if no account exists with that user id. It has the same side-effects as the `login2uid` function (at zmshref.login2uid).

### `umask`

Syntax:

-       umask
          octal-number-mask

Return Values:

- 0

- Successfull printing of the octal value, or setting new umask(2) value.

64

- Parameter error. (Usage.)

Options:

- none

Notes:

- Without parameters the new default mask is 077, and old is printed.

### `unset`

Syntax:

-       unset
          variable

Return Values:

- 0

- Had enough parameters, executed something, and possibly complained something to "`stderr`".

64

- Missing mandatory (at least one) argument. (Usage.)

Options:

- none

Notes:

- This throws away named variables from all variable scopes.

      z# echo $TERM
      xterm
      z# unset TERM
      z# echo "'$TERM'"
      ''

### `untrace`

Syntax:

-       trace
          key1 ... keyN
        untrace
          key1 ... keyN

  Disables tracing of the specified items. This is inverse of `trace` (at zmshref.trace).

Return Values:

- 0

- Successfull clearing/setting

64

- Parameter name error. (Usage.)

Options:

- See the `trace` function (at zmshref.trace) for valid keywords.

Notes:

- See the `trace` function (at zmshref.trace) for valid keywords.

### `user`

Syntax:

-       user
          object-reference

Return Values:

- The next-address (3rd) component of and address quad.

Options:

- none

Notes:

- This is essentially same as:

         $(cdr $(cdr $(cdr $addrquad)))

### `wait`

Syntax:

-       wait
          pid

Return Values:

- Besides of the return codes of processes being waited, this can yield:

  0

- no more processes

64

- Bad parameters. (Usage.)

Options:

- none

Notes:

- none