Previous | Next | Contents | Index |
There are two logging interfaces for the popstore. The first is the normal PMDF logging interface as described in Section 13.1. This interface should suit the needs of most sites.
For sites needing more sophisticated logging facilities, there is a subroutine level interface. When enabled, the popstore dynamically loads and links to a site-supplied subroutine and then calls that subroutine each time an event is to be logged. The loggable events are summarized below and discussed in Section 13.2:
13.1 PMDF-style Logging
Normal PMDF logging facilities can be used to track messages into the
popstore and POP3 client access to the store. The former is activated
with the logging
channel keyword; the latter by enabling
logging in the POP3 server itself. Both will produce log file entries
in the PMDF log file, mail.log_current
, found in the PMDF
log directory.
To use the logging
channel keyword, edit the PMDF
configuration file, popstore.chans
found in the PMDF table
directory, /pmdf/table/
on UNIX and NT systems and
PMDF_TABLE:
on OpenVMS. In that file, add the
logging
keyword to the end of the line beginning with
holdexquota
so that that line reads
holdexquota description "popstore channel" logging |
See the PMDF System Manager's Guide for further information on
the logging
channel keyword and the format of the PMDF log
file.
Use the LOGGING option of the POP3 server to enable logging in that server. See the POP3 server documentation in the PMDF System Manager's Guide for details on enabling that option.
13.2 The Site-Supplied Logging Interface
Sites needing very detailed popstore activity logging can obtain such
detail by providing a subroutine for the popstore to call. The
subroutine is provided to the popstore as a shareable image and made
known to the popstore via the LOG_ACTIVITY option described in
Section 3.3. By default, any "loggable" event will be
passed to the site supplied logging routine. Optionally, the
LOGGING_ACTIVITY_MASK option can be used to select which events are
logged.
The site-supplied subroutine must have the name
log_activity
and takes the form
#ifndef __VMS # include "/pmdf/com/popstore.h" #else # include "PMDF_COM:POPSTORE.H" #endif void log_activity (*log_id, log_subid, log_type, *log_data, log_len) char *log_id; uint32 log_subid; int32 log_type; void *log_data; int32 log_len; |
Character string of length at most 20 bytes which remains the same amongst a related sequence of popstore activities bounded by
log_id
POPSTORE_init()
andPOPSTORE_end()
calls.Thirty-two bit unsigned integer identifying a related sequence of popstore activities bounded by
log_subid
POPSTORE_user_begin()
andPOPSTORE_user_end()
calls.The type of activity being logged. See Section 13.2.2 for a description of the different values for this parameter.
log_type
A pointer to the information to be logged. The nature of the data and its organization varies with the type of activity being logged. Refer to Section 13.2.2 for details.
log_data
The length in bytes of the information to be logged.
log_len
The intent behind the log_id
and log_subid
parameters is to provide a means of grouping related activity threads
together. For instance, if logging activity to a file, then start each
record of the file with the values of the log_id
and
log_subid
parameters. The log file can then be sorted to
produce a file in which related events are grouped together within the
(sorted) file.
Each call the popstore makes to the LOG_ACTIVITY
subroutine reports an event which the subroutine can then log or
discard as it sees fit. The subroutine does not need to be reentrant or
thread-safe: within a given process context, the popstore will
serialize its calls to the subroutine. However, several processes can
simultaneously call the same subroutine. Consequently, if the
subroutine, for instance, appends records to a log file, the subroutine
must ensure that the writes to that file support simultaneous writers.
In the file popstore_log_activity.c
, a sample
log_activity
subroutine is provided. This file is in the
/pmdf/doc/examples
directory on UNIX and NT systems and,
on OpenVMS systems, the directory PMDF_ROOT:[DOC.EXAMPLES]
.
13.2.1 Linking a Shared Library
Solaris Systems
On Solaris systems, linking a C program into a shared library is accomplished with the command:
# cc -mt -KPIC -G -h filename.so -o filename.so filename.c |
filename.c
is the name of the program to compile
link and filename.so
is the name of the shared library to
create.
On Linux systems, linking a C program into a shared library is accomplished with the command:
# gcc -shared -o filename.so filename.c |
filename.c
is the name of the program to compile and
link and filename.so
is the name of the shared library to
create.
On OpenVMS VAX systems, the link command should be of the form
$ DEFINE/SYSTEM/EXECUTIVE_MODE POP_LOG_ACTIVITY - _$ disk:[device]filename.EXE $ LINK/SHAREABLE=POP_LOG_ACTIVITY object-file-spec,SYS$INPUT:/OPT UNIVERSAL=log_activity [CTRL/Z] $ INSTALL CREATE POP_LOG_ACTIVITY |
$ DEFINE/SYSTEM/EXECUTIVE_MODE POP_LOG_ACTIVITY - _$ disk:[device]filename.EXE $ LINK/SHAREABLE=POP_LOG_ACTIVITY object-file-spec,SYS$INPUT:/OPT SYMBOL_VECTOR=(log_activity=PROCEDURE) [CTRL/Z] $ INSTALL CREATE POP_LOG_ACTIVITY |
object-file-spec
is the name of the object file to
be linked to produce the resulting shared image
disk:[device]filename.EXE
. The choice of logical name is
arbitrary. Use whatever name you see fit and then use the
LOG_ACTIVITY
option to tell the popstore the logical name
to use.
When relinking the image, be sure to issue the command
$ INSTALL REPLACE POP_LOG_ACTIVITY |
13.2.2 Logging Data Types
The value of the log_type
parameter indicates the type of
activity being logged and the type of data referenced by the
log_data
pointer. The symbolic names of the values are
defined in the popstore.h
header file and are summarized
in Table 13-1. They are fully discussed below.
Symbolic name | Value | log_data data type |
---|---|---|
POPSTORE_LOG_START
|
1 |
char *
|
POPSTORE_LOG_END
|
2 |
NULL
|
POPSTORE_LOG_LOGIN_START
|
3 |
POPSTORE_user_log *
|
POPSTORE_LOG_LOGIN_PW_MATCH
|
4 |
POPSTORE_user_log *
|
POPSTORE_LOG_LOGIN_PW_NOMATCH
|
5 |
POPSTORE_user_log *
|
POPSTORE_LOG_LOGIN_END
|
6 |
POPSTORE_user_log *
|
POPSTORE_LOG_MSG_STORE
|
7 |
POPSTORE_message_log *
|
POPSTORE_LOG_MSG_OPEN
|
8 |
POPSTORE_message_log *
|
POPSTORE_LOG_MSG_DELETE
|
9 |
POPSTORE_message_log *
|
POPSTORE_LOG_USER_CREATE
|
10 |
POPSTORE_user_log *
|
POPSTORE_LOG_USER_DELETE
|
11 |
POPSTORE_user_log *
|
POPSTORE_LOG_USER_MODIFY
|
12 |
POPSTORE_user_log *
|
LOG_ACTIVITY_MASK=-1
. Each bit in the value of
LOG_ACTIVITY_MASK
indicates whether a particular event
should be logged (and hence when it has a value of -1
all
events are logged). You can therefore control which events are logged
by specifying a non-default value for the
LOG_ACTIVITY_MASK
option as shown in Table 13-2 below.
In that table, bit 0 is the lowest (first) bit.
Symbolic name | Bit to set |
---|---|
POPSTORE_LOG_START
|
Always logged |
POPSTORE_LOG_END
|
Always logged |
POPSTORE_LOG_LOGIN_START
|
0 |
POPSTORE_LOG_LOGIN_PW_MATCH
|
1 |
POPSTORE_LOG_LOGIN_PW_NOMATCH
|
2 |
POPSTORE_LOG_LOGIN_END
|
3 |
POPSTORE_LOG_MSG_STORE
|
4 |
POPSTORE_LOG_MSG_OPEN
|
5 |
POPSTORE_LOG_MSG_DELETE
|
6 |
POPSTORE_LOG_USER_CREATE
|
7 |
POPSTORE_LOG_USER_DELETE
|
8 |
POPSTORE_LOG_USER_MODIFY
|
9 |
Each of these logging data types are described below.
POPSTORE_LOG_START
Whenlog_type
has the valuePOPSTORE_LOG_START
,log_data
is a pointer to a character string. This logging type arises when thePOPSTORE_init()
subroutine is called and signifies the initialization of the popstore API by a popstore client program.log_data
points to a string identifying the client program and information about it. Standard popstore subroutines provide the following usage strings:
00:cgi:user@server-host (server-ip-addr+server-tcp-port):
client@client-host (client-ip-addr+client-tcp-port)
The indicated user on the indicated host is running the popstore's management HTTP CGI and is processing a request from the indicated host.
01:user_cgi:user@server-host (server-ip-addr+server-tcp-port):
client@client-host (client-ip-addr+client-tcp-port)
The indicated user on the indicated host is running the popstore's user-mode informational HTTP CGI and is processing a request from the indicated host.
02:master:user@host:channel
The indicated user on the indicated host is running the inbound popstore delivery channel under the indicated channel name, channel.
03:pop3::
This indicates that the POP3 server has initialized the popstore. At this point, the POP3 server does not have useful information to record. However, as it processes connections from POP3 clients, it will provide more detailed information. See the description of thePOPSTORE_LOG_LOGIN_START
logging type.
04:popmgr:user@host
The indicated user on the indicated host is running the command line management utility. The username is the user's login username on the host and not their popstore username.
05:poppassd::
This indicates that the poppassd server has initialized the popstore. At this point, the poppassd server does not have useful information to record. However, as it processes connections from POP3 clients, it will provide more detailed information. See the description of thePOPSTORE_LOG_LOGIN_START
logging type.
06:return:user@host:channel
The indicated user on the indicated host is running the popstore message bouncer under the indicated channel name, channel.
07:mbxmove:user@host
The indicated user on the indicated host is running the mail box migration utility to migrate one or more mail boxes to the popstore.
08:pwd_cgi:user@server-host (server-ip-addr+server-tcp-port):
client@client-host (client-ip-addr+client-tcp-port)
The indicated user on the indicated host is running the popstore's user-mode password HTTP CGI and is processing a request from the indicated host. Site-supplied and third-party popstore clients can use other usage strings. Usage strings beginning with 00 through 20 are reserved for use by Process Software.POPSTORE_LOG_END
Whenlog_type
has the valuePOPSTORE_LOG_END
,log_data
has the valueNULL
andlog_len
has the value0
. This logging type arises when the subroutinePOPSTORE_end()
is called and signifies the end of use of the popstore by a popstore client program.POPSTORE_LOG_LOGIN_START
Whenlog_type
has the valuePOPSTORE_LOG_LOGIN_START
,log_data
is a pointer to aPOPSTORE_user_log
structure. See Section 13.2.4 for a description of that structure. This logging type arises when the subroutinePOPSTORE_user_begin()
is called to begin a user context. The fields of the logging data will be as follows:The caller supplied fields should be treated as suspect. For instance, the ulen field can have an incorrect value. Standard popstore subroutines provide the following usage strings
Field name Description stat
Set to the value POPSTORE_SUCCESS
profile
Set to the value NULL
username
As supplied by the caller of POPSTORE_user_begin()
ulen
As supplied by the caller of POPSTORE_user_begin()
usage
As supplied by the caller of POPSTORE_user_begin()
usagelen
As supplied by the caller of POPSTORE_user_begin()
00:cgi:user@server-host (server-ip-addr+server-tcp-port):
client@client-host (client-ip-addr+client-tcp-port)
The popstore's management HTTP CGI running on the host server-host is processing a request from the indicated host, client-host.
01:user_cgi:user@server-host (server-ip-addr+server-tcp-port):
client@client-host (client-ip-addr+client-tcp-port)
The popstore's user-mode HTTP CGI running on the host server-host is processing a request from the indicated host, client-host.
03:pop3:server-ip-addr+server-tcp-port:client-ip-addr+client-tcp-port
A POP3 client running on the host with IP address client-ip-addr has made a connection to the POP3 server at the IP address server-ip-addr.
05:poppassd:user@server-host (server-ip-addr+server-tcp-port):
client@client-host(client-ip-addr+client-tcp-port)
A POP3 client running on the host client-host has made a connection to the poppassd server on the host server-host.
08:pwd_cgi:user@server-host (server-ip-addr+server-tcp-port):
client@client-host (client-ip-addr+client-tcp-port)
The popstore's user-mode password HTTP CGI running on the host server-host is processing a request from the indicated host, client-host. This logging type also arises when an error is encountered within the API subroutinePOPSTORE_user_begin()
. In that case, fields of the logging data will be as shown below:
Field name Description stat
Set to the popstore error code value indicating the error which occurred profile
Set to the value NULL
username
As supplied by the caller of POPSTORE_user_begin()
ulen
As supplied by the caller of POPSTORE_user_begin()
usage
Set to the value NULL
usagelen
Set to the value 0
POPSTORE_LOG_LOGIN_PW_MATCH
POPSTORE_LOG_LOGIN_PW_NOMATCH
Whenlog_type
has the either the valuePOPSTORE_LOG_LOGIN_PW_MATCH
or the valuePOPSTORE_LOG_LOGIN_PW_NOMATCH
,log_data
is a pointer to aPOPSTORE_user_log
structure. See Section 13.2.4 for a description of that structure. This logging type arises when the subroutinePOPSTORE_user_pw_check()
has been called to validate a popstore username and password pair. The first type occurs when the password or challenge response is correct; the second type when the password or challenge response is incorrect. The logging data, which is of typePOPSTORE_user_log
, will have the field values indicated below:
Field name Description stat
Return value which will be returned by POPSTORE_user_pw_check()
to the callerprofile
Pointer to the popstore user context username
Username associated with the user context ulen
Length of the username associated with the popstore user context usage
Set to the value NULL
usagelen
Set to the value 0
POPSTORE_LOG_LOGIN_END
Whenlog_type
has the valuePOPSTORE_LOG_LOGIN_END
,log_data
is a pointer to aPOPSTORE_user_log
structure. See Section 13.2.4 for a description of that structure. This logging type arises when the subroutinePOPSTORE_user_end()
has been called to end a popstore user context. The fields of the logging data will be as follows:
Field name Description stat
Return value which will be returned by POPSTORE_user_end()
to the callerprofile
Pointer to the popstore user context being ended username
Username associated with the user context ulen
Length of the username associated with the popstore user context usage
Set to the value NULL
usagelen
Set to the value 0
POPSTORE_LOG_MSG_STORE
Whenlog_type
has the valuePOPSTORE_LOG_MSG_STORE
,log_data
is a pointer to aPOPSTORE_message_store_log
structure. See Section 13.2.6 for a description of that structure. This logging type arises when the inbound message delivery subroutine stores a message into the popstore. The contents of the logging data are as described in Section 13.2.6.POPSTORE_LOG_MSG_OPEN
Whenlog_type
has the valuePOPSTORE_LOG_MSG_OPEN
,log_data
is a pointer to aPOPSTORE_message_log
structure. See Section 13.2.5 for a description of that structure. This logging type arises when a stored message file is accessed with the API subroutinePOPSTORE_message_begin()
. The contents of the logging data are as described in Section 13.2.5.POPSTORE_LOG_MSG_DELETE
Whenlog_type
has the valuePOPSTORE_LOG_MSG_DELETE
,log_data
is a pointer to aPOPSTORE_message_log
structure. See Section 13.2.5 for a description of that structure. This logging type arises when a stored message file is deleted for one of its recipients. The contents of the logging data are as described in Section 13.2.5 with the exception that the four envelope and message id fields will have the valuesNULL
and0
.POPSTORE_LOG_USER_CREATE
Whenlog_type
has the valuePOPSTORE_LOG_USER_CREATE
,log_data
is a pointer to aPOPSTORE_user_log
structure. See Section 13.2.4 for a description of that structure. This logging type arises when the subroutinePOPSTORE_user_add()
has been called to create a new user account. The fields of the log data will be as follows:
Field name Description stat
Return value which will be returned by POPSTORE_user_add()
to the callerprofile
Pointer to the user context describing the new account username
Username associated with the user context ulen
Length of the username associated with the user context usage
Set to the value NULL
usagelen
Set to the value 0
POPSTORE_LOG_USER_DELETE
Whenlog_type
has the valuePOPSTORE_LOG_USER_DELETE
,log_data
is a pointer to aPOPSTORE_user_log
structure. See Section 13.2.4 for a description of that structure. This logging type arises when the subroutinePOPSTORE_user_delete()
has been called to delete a user account. The fields of the log data will be as follows:
Field name Description stat
Return value which will be returned by POPSTORE_user_add()
to the callerprofile
Pointer to the user context describing the account being deleted username
Username associated with the user context ulen
Length of the username associated with the user context usage
Set to the value NULL
usagelen
Set to the value 0
POPSTORE_LOG_USER_MODIFY
Whenlog_type
has the valuePOPSTORE_LOG_USER_MODIFY
,log_data
is a pointer to aPOPSTORE_user_log
structure. See Section 13.2.4 for a description of that structure. This logging type arises when the subroutinePOPSTORE_user_update()
has been called to modify a user account. The fields of the logging data will be as follows:
Field name Description stat
Return value which will be returned by POPSTORE_user_update()
to the callerprofile
Pointer to an array of two user contexts: the first context describes the original settings for the account, the second context describes the new settings for the account username
Username associated with the user context ulen
Length of the username associated with the user context usage
Set to the value NULL
usagelen
Set to the value 0
13.2.3 Logging Samples
The following samples illustrate some of the logging possibilities
realized through the logging interface. In these examples, the
site-supplied log_activity
subroutine outputs records
containing the log_id
and log_subid
values
separated by a dot and then followed by the date and time. That is then
followed by the value of the log_type
parameter which is
then followed by information pertinent to the type of data being logged.
In the first example, Example 13-1, the logging samples correspond to
the UNIX login user bob
issuing the commands
# pmdf popstore popstore> modify jdoe -quota=20480 popstore> quit |
Example 13-1 Logging of a user profile modification |
---|
X9TC0008T6.1 11:30:11 - POPSTORE_LOG_START: X9TC0008T6.1 11:30:11 - usage = 04:popmgr:bob@gate.plastic.com X9TC0008T6.1 11:30:15 - POPSTORE_LOG_USER_MODIFY: user="jdoe" X9TC0008T6.1 11:30:15 - quota:10240 -> 20480 X9TC0008T6.1 11:30:15 - POPSTORE_LOG_END |
The next example, Example 13-2, corresponds to the popstore user
jdoe
reading a mail message and then deleting it with
their POP3 client.
Example 13-2 Logging of a POP3 client downloading and deleting a message |
---|
27I80009GF.0 11:30:16 - POPSTORE_LOG_START: 27I80009GF.0 11:30:16 - usage = "03:pop3::" 27I80009GF.0 11:31:45 - POPSTORE_LOG_LOGIN_START: 27I80009GF.0 11:31:45 - usage = "03:pop3:192.160.0.1+14080:192.160.0.5+12839" 27I80009GF.0 11:31:45 - user = "jdoe" 27I80009GF.0 11:31:45 - POPSTORE_LOG_LOGIN_PW_MATCH: user="jdoe" 27I80009GF.0 11:32:20 - POPSTORE_LOG_MSG_OPEN 27I80009GF.0 11:32:20 - UIDL = !!!"01IDYVUZOFEO0008IH0 27I80009GF.0 11:32:20 - envelope ID = 01IDYTN79MU2000882@gate.plastic.com 27I80009GF.0 11:32:20 - message ID = <01IDEQPFAOH@foo.albany.edu> 27I80009GF.0 11:32:21 - POPSTORE_LOG_MSG_DELETE: 27I80009GF.0 11:32:21 - user = "jdoe" 27I80009GF.0 11:32:21 - UIDL = !!!"01IDYVUZOFEO0008IH0 27I80009GF.0 11:32:21 - POPSTORE_LOG_LOGIN_END: user="jdoe" 27I80009GF.0 11:32:22 - POPSTORE_LOG_END |
The final example, Example 13-3, shows the inbound delivery agent delivering a message for two recipients to the popstore.
Example 13-3 Logging of the storage of a message |
---|
GMU8000B5V.0 16:12:39 - POPSTORE_LOG_START: GMU8000B5V.0 16:12:39 - usage = 02:master:SYSTEM@gate.plastic.com:popstore GMU8000B5V.0 16:12:43 - 2 recipient, 2218 byte message from a@example.com stored GMU8000B5V.0 16:12:43 - envelope ID = 01IDZ5RYTUKU000882@gate.plastic.com GMU8000B5V.0 16:12:43 - message ID = <97008157_132305@emout1.mail.aol.com> GMU8000B5V.0 16:12:43 - filename = 01IDZ5S85JTU000B5V0 GMU8000B5V.0 16:12:43 - 1 !!!! asmith GMU8000B5V.0 16:12:43 - 1 !!!" jdoe GMU8000B5V.0 16:12:45 - POPSTORE_LOG_END |
13.2.4 POPSTORE_user_log Structure
The POPSTORE_user_log
structure is used to log events
associated with the processing of user accounts. The C language
declaration of the structure is provided by the popstore.h
header file and shown below:
typedef struct { int32 stat; POPSTORE_user_data *profile; char *username; int32 ulen; char *usage; int32 usagelen; } POPSTORE_user_log; |
log_type
parameter. See Section 13.2.2 for details. Note
that the username
and usage
strings can not
be NULL
terminated.
13.2.5 POPSTORE_message_log Structure
The POPSTORE_message_log
structure is used to log events
associated with the processing of stored message files. The C language
declaration of the structure is provided by the popstore.h
header file and repeated below:
typedef struct { char *user; int32 user_len; char *uidl; int32 uidl_len; char *env_id; int32 env_id_len; char *msg_id; int32 msg_id_len; } POPSTORE_message_log; |
user
The username and length in bytes of the username associated with the popstore account for which the message operation is being performed. This information can be omitted in which case the fields will have the values
user_len
NULL
and0
. The username string can not beNULL
terminated.
uidl
UIDL and length in bytes of the UIDL referencing the message. The UIDL string can not be
uidl_len
NULL
terminated.
env_id
The envelope identification and length in bytes of the envelope identification associated with the message. This information can not be provided, in which case the fields will have the values
env_id_len
NULL
and0
. The envelope identification string can not beNULL
terminated.
msg_id
The value of the message's RFC822 message-id header line and length in bytes of that value. This information can not be provided, in which case the fields will have the values
msg_id_len
NULL
and0
. The message-id string can not beNULL
terminated.
13.2.6 POPSTORE_message_store_log Structure
The POPSTORE_message_store_log
structure is used to log
the delivery a message to the message store. The C language declaration
of the structure is provided by the popstore.h
header file
and repeated below:
typedef struct { uint32 version; uint32 size; time_t creation_date; uint32 recipient_count; uint32 reference_count; char *env_from; int32 env_from_len; char *env_id; int32 env_id_len; char *msg_id; int32 msg_id_len; char *filename; int32 filename_len; char channel[40]; POPSTORE_recipient_list *users; } POPSTORE_message_store_log; |
Message file format version used for the message file.
version
Length in bytes of the stored message content.
size
Creation date and time for the message file as measured in seconds since 0:00:00.00 on 1 January 1970.
creation_date
Count of popstore envelope recipients for the message.
recipient_count
Count of active envelope recipients for the message; that is, the number of popstore accounts with references to the message. This number will be less than or equal to the
reference_count
recipient_count
. Usually it will be equal to therecipient_count
, but it can be less if some sort of problem arose making delivery to a recipient impossible.
env_from
The message's envelope
env_from_len
From:
address and length of that address. Theenv_from
field need not beNULL
terminated.
env_id
The message's envelope id and length of that id. The
env_id_len
env_id
field need not beNULL
terminated.
msg_id
The message's RFC822 message-id and length of that id. The
msg_id_len
msg_id
field need not beNULL
terminated.
filename
The name of the file in which the message is stored. The
filename_len
filename
field need not beNULL
terminated.The name of the channel which delivered this message. The
channel
channel
field is space (0x20 hex) padded and is notNULL
terminated.Pointer to an array of
users
POPSTORE_recipient_list
structures. The number of entries in the array is given by thereference_count
field. ThePOPSTORE_recipient_list
structure is described in Section 13.2.7.
13.2.7 POPSTORE_recipient_list Structure
The POPSTORE_recipient_list
structure is used to log the
envelope recipient list for a message stored in the popstore. The C
language declaration of the structure is provided by the
popstore.h
header file and repeated below:
typedef struct { char *user; int user_len; char uidl[4]; int status; } POPSTORE_recipient_list; |
user
Popstore username and length of that username. The
user_len
username
field can not beNULL
terminated.The first four characters of the UIDL for this user's instance of the message.
uidl
Status of this recipient:
status
Value Interpretation 1
Message was successfully delivered to this recipient. 2
Message was not delivered to this recipient; temporary error; will retry later. 3
Message was not delivered to this recipient; no such recipient. 4
Message was not delivered to this recipient; recipient is over quota. 5
Message was not delivered to this recipient; recipient is marked DISMAIL.
Previous | Next | Contents | Index |