Information about database modules
==================================

Database modules provide the means for Services to store and access
permanent data (nickname and channel registrations, autokills, etc.).
This is done by means of functions which are imported by other Services
modules, as follows:

NickServ
--------
    NickInfo *add_nickinfo(NickInfo *ni)
	Inserts the record specified by `ni' into the database.  Returns a
	pointer to a NickInfo structure which will be used for all future
	references to the nick data (while valid; see get_nickinfo() below).
	The pointer need not be the same as the pointer passed in, but if
	not, the original pointer should be freed before returning.

    void del_nickinfo(NickInfo *ni)
	Removes the record specified by `ni' from the database and frees
	all memory used by the record.

    NickInfo *get_nickinfo(const char *nick)
	Returns a pointer to the NickInfo structure corresponding to the
	given nick.  This structure may be newly allocated if the record
	must be loaded into memory; however, if the structure is already
	in memory, a pointer to the same structure must be returned.

	For database modules which do not keep all records in memory,
	records may be flushed from memory whenever get_nickinfo(),
	first_nickinfo(), or next_nickinfo() are called.  However, for
	records with a "locked" field (NickInfo, NickGroupInfo,
	ChannelInfo), any record with locked > 0 must not be flushed.

    void put_nickinfo(NickInfo *ni)
	Called whenever the data for a nickname has been changed.  This
	routine may store the changed data directly into external storage,
	mark the record as changed (e.g. to store later using
	sync_nickinfo_db()), or do nothing at all, depending on the type
	of database.

    NickInfo *first_nickinfo(int match, void *value)
	Returns a pointer to the NickInfo structure for the alpbabetically
	first registered nick that matches the given query (see below).
	Returns NULL if no nicks are registered or none match the query.
	For databases which do not keep all records in memory, this
	function and next_nickinfo() may use a common static buffer to
	return the nick in question.

	Valid values for the `match' parameter are as follows:
	   - NI_MATCH_LINK: Return nicks whose `link' parameter points to
		the given NickInfo.  `value' is a NickInfo *.

    NickInfo *next_nickinfo()
	Returns a pointer to the alphabetically next nick after the last
	one returned by first_nickinfo() or next_nickinfo().  Returns NULL
	when there are no more nicks, or if the previous return value was
	NULL.  (However, it may be assumed that next_nickinfo() will be
	called less than 10,000 times after NULL is first returned.)
	NOTE: This routine must return the correct value even when the
	record returned by the previous call to {first,next}_nickinfo()
	has been deleted.

    NickGroupInfo *add_nickgroupinfo(NickGroupInfo *ngi)
    void del_nickgroupinfo(NickGroupInfo *ngi)
    NickGroupInfo *get_nickgroupinfo(nickgroupid_t id)
    void put_nickgroupinfo(NickGroupInfo *ngi)
    NickGroupInfo *first_nickgroupinfo()
    NickGroupInfo *next_nickgroupinfo()
	As above, but for NickGroupInfo records.  nickgroupid_t is an
	unsigned integer type (defined as uint32 in nickserv.h).
	first_ and next_nickgroupinfo() may return records in any order.

    int open_nick_db(const char *dbname)
	Performs any operations necessary to prepare the nickname database
	for use.

    int sync_nick_db(const char *dbname)
	Ensures that all modified nickname data is written to external
	storage.

    int close_nick_db(const char *dbname)
	Writes out all modified data and closes the nickname database.

ChanServ
--------
    ChannelInfo *add_channelinfo(ChannelInfo *ci)
    void del_channelinfo(ChannelInfo *ci)
    ChannelInfo *get_channelinfo(const char *chan)
    void put_channelinfo(ChannelInfo *ci)
    ChannelInfo *first_channelinfo()
    ChannelInfo *next_channelinfo()
    int open_channel_db(const char *dbname)
    int sync_channel_db(const char *dbname)
    int close_channel_db(const char *dbname)
	These function identically to the NickServ functions, except that
	they operate on channels instead.  first_ and next_channelinfo()
	should return records in alphabetical order.

OperServ (main data)
--------
    int get_operserv_data(int which, void *ptr)
    int put_operserv_data(int which, void *ptr)
	Reads or writes OperServ data, returning 1 on success and 0 on
	failure.  `which' indicates which data to read/write, and `ptr'
	specifies the address to read into or write from, as follows:

	         Constant      | Meaning
	    -------------------+-------------------------------------------
	    OSDATA_SERVADMINS  | Array of Services admin nicknames
	    OSDATA_SERVOPERS   | Array of Services oper nicknames
	    OSDATA_MAXUSERCNT  | Maximum number of simultaneous users
	    OSDATA_MAXUSERTIME | Time at which maximum was reached
	    OSDATA_SUPASS      | SU password (NULL == no password)

	         Constant      |          Read type         |  Write type
	    -------------------+----------------------------+--------------
	    OSDATA_SERVADMINS  | nickname_t[MAX_SERVADMINS] | (same)
	    OSDATA_SERVOPERS   | nickname_t[MAX_SERVOPERS]  | (same)
	    OSDATA_MAXUSERCNT  | int32 *                    | (same)
	    OSDATA_MAXUSERTIME | time_t *                   | (same)
	    OSDATA_SUPASS      | char **                    | char *

    int open_operserv_db(const char *dbname)
    int sync_operserv_db(const char *dbname)
    int close_operserv_db(const char *dbname)
	Like the NickServ functions.

Autokill data
-------------
    void add_akill(Akill *akill)
    void del_akill(Akill *akill)
    Akill *get_akill(const char *mask)
    void put_akill(Akill *akill)
    Akill *first_akill()
    Akill *next_akill()
    int open_akill_db(const char *dbname)
    int sync_akill_db(const char *dbname)
    int close_akill_db(const char *dbname)
	Like the NickServ functions.  first_ and next_akill() may return
	records in any order.

    Akill *get_matching_akill(const char *userhost)
	If there is an autokill which `userhost' matches, returns that
	autokill, else returns NULL.  If more than one autokill matches
	`userhost', any of them may be returned.

    int akill_count()
	Returns the number of autokills currently registered.

News data
---------
    void add_news(NewsItem *news)
    void del_news(NewsItem *news)
    NewsItem *get_news(int16 type, int32 num)
    void put_news(NewsItem *news)
    NewsItem *first_news()
    NewsItem *next_news()
    int open_news_db(const char *dbname)
    int sync_news_db(const char *dbname)
    int close_news_db(const char *dbname)
	Like the NickServ functions.  first_ and next_news() should return
	news items in date order, most recent first.

    int news_count()
	Returns the number of news items currently registered.

Session exception data
----------------------
    void add_exception(Exception *except)
    void del_exception(Exception *except)
    Exception *get_exception(const char *mask)
    void put_exception(Exception *except)
    Exception *first_exception()
    Exception *next_exception()
    int open_exception_db(const char *dbname)
    int sync_exception_db(const char *dbname)
    int close_exception_db(const char *dbname)
	Like the NickServ functions.  first_ and next_exception() should
	return records in ascending numerical order by the `num' field.

    Exception *get_exception_by_num(int num)
	Returns the exception with the given index number, or NULL if no
	such exception exists.

    Exception *get_matching_exception(const char *host)
	Returns the numerically first (sorted by the `num' field) exception
	which matches the given host.  If there is no exception which
	matches the host, returns NULL.

    void move_exception(Exception *except, int newnum)
	Performs the same actions as put_exception() on `except', then
	assigns the index number `newnum' to it.  If there is already an
	exception with that index number, it is renumbered so that `except'
	comes before it.  Renumbering may be implemented in whatever way is
	desired, as long as:
	    - Relative order of exceptions is preserved.
	    - The exception being moved comes before the exception that
	      used to have the given index number.
	For example, an implementation may increment all exception numbers
	above the given index by one, or may increment only those which are
	necessary to fulfill the conditions above; either way is acceptable.

    int exception_count()
	Returns the number of exceptions currently registered.
