Author: Sam Varshavchik

## Internal Structures

The following structures are used internally by courierd.

#### drvinfo

This is an array of modules configured into Courier. This array is actually allocated by process A, upon startup (but the initialization is completed in process B, so changes to maxdels, maxhost, and other parameters, can affect a live system).

    class drvinfo {
        struct rw_transport *module;   // Points to the rw_transport structure libcourier.a has
                                       // allocated for the module.
        CArray<delinfo> delinfo_list;  // Current delivery attempts.  Array allocated at startup,
                                       // and never deallocated.  Size of the array is specified
                                       // by maxdels from the module config file
        CArray<dlvrhosts> hosts_list;   // Hosts where current delivery attempts are going to.
                                       // Array allocated at startup.  Size of the array is specified
                                       // by maxdels from the module config file
        unsigned maxhost, maxrcpt;     // From the config file

        struct delinfo *delpfreefirst; // Link list of unused delinfos in delinfo_list,
                                       // linked by freenext.

        struct dlvrhost *hdlvrpfree;   // Link list of unused drvhosts in hosts_list, linked by next.

        struct dlvrhost *hdlvrpfirst, *hdlvrplast; // MRU list of drvhosts in hosts_list, linked by
                                                   // next and prevfo
        CList<pendelinfo> pendelinfo_list;  // List of pending deliveries that haven't been scheduled
                                            // because max # of deliveries have been reached
    } ;

#### dlvrhost

This array is allocated for each module, and is used to keep count of how many deliveries are pending for the same host.

    class dlvrhost {
        struct dlvrhost *next, *prev; /* next used on hdlvrpfree list, else
                                     this is the first/last list, in MRU order */
        CString hostname;            /* Name of this host */
        unsigned dlvrcount;        /* How many deliveries to this host are in progress */
        pendelinfo *pending_list;  // List of recipients NOT being delivered
    } ;

#### delinfo

    class delinfo {
        struct delinfo *freenext; // List of unused delinfo in the same module.
        unsigned delid;           // My index in delinfo_list array
        dlvrhost *dlvrphost;      // Host we're delivering to
        rcptinfo *rcptlist;       // List of recipients being delivered
    } ;

#### msgq

This structure represents a message that is either being delivered to, or which has a delivery attempt coming up. An array of msgq structures is allocated when process B starts, and its individual members are sorted based on the nextdel field.

    class msgq {
        struct msgq *next, *prev; // Sorted by nextdel
        struct msgq *nexthash, *prevhash; // Same hash bucket
        ino_t        msgnum;      // Queue message number
        time_t       nextdel;     // Next delivery attempt (used to find the filename in msgq)
        CArray<rcptinfo> rcptinfo_list;  // The recipients
        unsigned     rcptcount;   // # of deliveries pending or in progress
    } ;

#### rcptinfo

An array of rcptinfos is allocated to list all recipients for a given message.

    class rcptinfo {
        msgq     *msg;     // Message we belong to

        drvinfo       *delmodule;    // Use this module
        pendelinfo    *pending;      // Not NULL if we're not delivering this recipient list yet.
        POSITION       pendingpos;   // The position of the pointer in pending->recipient_list
        CString        envsender;    // Envelope sender rewritten to the transport format
        CString        delhost; // Deliver to this host
        CStringArray   addresses;     // Deliver to these addresses
        CUIntArray     addressesidx;  // Indexes of addresses in control file
    } ;

#### pendelinfo

A list of all hosts for which we have rcptinfos that have not been allocated a delinfo yet.

    class pendelinfo {
        POSITION pos;        // My position in drvp->pendelinfo_list
        drvinfo *drvp;       // My module
        CString hostname;
        CList<rcptinfo *> receipient_list;
        dlvrhost *hostp;     //
    } ;