Note that classes are separate from macros, so they may both use the
same letter or name with no conflict.
The C form of the class command causes values to
be assigned from within the configuration file.
In general, the class command looks like this:
CX list
values from configuration file
C{XX} list
values from configuration file
Here, a list is a list
of string elements (delimited by whitespace) that follows
on the same line as the C command. Each word in
list is appended to the array of values in the class
X in the first case and to the class {XX} in
the second.
[1]
Multiple declarations of the same named class may coexist
in the configuration file.
Each declaration after the first appends its string elements to the
preceding list. That is,
CX string1 string2
CX string3 string4
produces the same class as does
CX string1 string2 string3 string4
Both create a class with four strings as elements.
When an array of values is built, whitespace is used to
separate one value from another. Whitespace is defined by
the C language isspace(3) routine and usually includes
the space, tab, newline, carriage-return, and form-feed characters.
Each line of text assigned to a class is broken up by sendmail
into whitespace delimited words.
When a line
is indented with a space or a tab, that line is joined by sendmail
to the preceding line. Thus the following three declarations
also append four words to the class X:
CX string1
CX string2
CX string3
string4
tab
Words that are added to a class cannot be removed after sendmail
has read them. Instead, they must be edited out of whatever file
or program produced them, and the sendmail daemon must
be killed and restarted.
The list of words in a class declaration can include macros. For example
the following assigns the same values to class X as did
the above example:
D{LIST} string1 string2 string3 string4
CX ${LIST}
Macros used in class declarations are expanded when the configuration file
is read. Deferred macros (those with the $& prefix) may not be used
in class declarations. But conditionals may:
CX ourhost$?{Domain}.${Domain}$.
The F form of the class configuration command allows values
to be appended to a class from outside the configuration file.
In general, the file command looks like either of the following:
FX file 
values from a disk file
FX |program 
values via another program (V8.7 and above, or IDA)
The F is immediately followed by the name of the class. This can be either a
single-character name, as shown, or a multicharacter name.
The name is followed by optional whitespace and then the name of
a file or program.
If the file or program begins with the pipe
character (|), it is taken to be the name of
a program to run.
[2]
Otherwise, it is taken to be the name of a file
to read.
If SCANF was defined when sendmail was compiled
(see Section 18.8.39, SCANF),
each line that is read from a file or program
is parsed by the C language scanf(3) library routine.
The formatting pattern given to scanf(3) is %s,
which tells scanf(3) to read only the first whitespace-delimited word from each line of text.
The file is opened for reading
or the program is executed when the configuration file is processed.
If either cannot be opened (for reading or execution), sendmail
syslog(3)'s the following error and ignores that configuration command:
cannot open what: why
file
cannot exec what: why
program
Here, the what is the exact text that was given in the configuration
file, and why is the text of a system error.
For the file form only,
if the file may optionally not exist, you can prefix its name
with a -o switch:
FX -o file
okay for file to not exist
This tells sendmail to remain silent if the file does not exit.
The -o switch is useful when a configuration file is
shared by several machines, only some of which need the external class
macro file.
The C and F forms of the configuration command may be
intermixed for any given class name. For example, consider a file
named /etc/local/names with the following contents:
string3
string4
The following two configuration commands add the same
four strings to the class X as did the C command alone
in the previous section:
CX string1 string2
FX /etc/local/names
This creates a class with four strings as array elements. Whitespace
delimits one string from the others in the C line declaration,
and they are stored in the order in which they are listed.
The file /etc/local/names is then opened and read,
and each of the two words in that file is appended to the two words
that are already in the class.
The file form of the class configuration command
allows different formatting patterns to be used with scanf(3).
[3]
But the program form does not
allow any variation,
and so its scanf(3) pattern is always %s,
which tells scanf(3) to read only the first whitespace-delimited
word from each line of text:
FX file pat
with scanf(3) pattern
FX |program
always ``%s''
If the optional pat argument to the file form is missing, the pattern
given to scanf(3) is %s.
The pat argument is separated from the file
argument by one or more spaces or tabs. It should not be quoted, and it consists
of everything from its first character to the end of the line.
Internally, scanf(3) is called with:
sscanf(result, pat, input)
Here, result is the string array element to be added
to the class definition. The pat is the scanf(3) pattern,
and input is the line of text read from the file.
[4]
After each line of text is read from the file and filtered with
the scanf(3) pattern, it is further subdivided by sendmail
into individual words. That subdividing uses whitespace (as
defined by the C language isspace(3) routine) to separate
words. Each separate word is then appended as an individual element
to the class array.
Consider the contents of
the following file named /etc/local/myhosts:
server1 server2 # my two nets
uuhost # my uucp alias
#mailhost # mail server alias (retired 06,23,91)
This file contains three hostname aliases to be added
to a class, say H. The following configuration command
does just that:
FH /etc/local/myhosts %[^\#]
The pattern %[^#] causes scanf(3) to read all characters
in each line up to, but not including, the first # character.
The first line includes two white-space delimited words
that are appended to the class H. The second line
contains one word, and the third contains none. The \
character prevents sendmail from treating the # as a
comment character.