ircd/api/features

Overview
As of u2.10.11 (which is what ircd-darenet 1.x is based upon), most of the compile-time configuration options present in previous versions of ircu have been provided via the configuration file as "features." This document is intended not only to give an explanation of how to use the features subsystem in new code, but also how to define new features.

In the  header file is an   that lists all the features known to the features subsystem. The order of the entries in this list must match precisely the order of the features as listed in the  table in. There are four kinds of features, seven different flags that can be set for features, and seven different call-backs for more complex features.

Types of Features
There are at present four different types of features: NONE, INT, BOOL, and STR. Features of type "NONE" are complex features, such as the logging subsystem, that have complicated behavior that's managed through the use of call-backs. The call-backs available are set, which is called to set the value of the feature; reset, which is called to reset the value of the feature back to its default; get, which is called to send the user a  to describe the feature setting; unmark, which is called prior to reading the configuration file; mark, which is called after reading the configuration file; and report, which is used to send a user a list of   replies.

In comparison to type "NONE," the other types are very simple. Type "INT" is used for features that take an integer value; "BOOL" is for those features that are boolean types; and "STR" is for those features that take simple string values. The values for these feature types are handled directly by the features subsystem, and can be examined from code with the,  , and   functions, described below. These features have a notify callback, which is used to warn subsystems that use the values of particular features that the value has changed.

Feature Flags
There are seven feature flags, one of which is used internally by the feature subsystem. Three of these flags,,  , and  , are used to select who can see the settings of those features;   permits any operator anywhere on the network to examine the settings of a particular feature, whereas   only permits operators local to a server to examine feature values, and   prohibits display of the feature value altogether. If none of these three flags are specified, then any user may examine that feature's value.

Two other flags only have any meaning for string values; they are, which is used to specify that a feature of type "STR" may have a   value, and  , which specifies that the feature is case sensitive -- this may be used on file names, for example. Note that if you give "0" as the default value for a feature, you must also set the  flag.

The remaining non-internal flag is, which simply sets the feature to be read-only; a feature so marked may only be changed through the configuration file.

Marking Features
When the configuration file is read, there must be some way to determine if a particular feature (key/value pair) has been removed since the last time the configuration file was read. The way this is done in the features subsystem is to have a "mark" for each feature. Prior to reading the configuration file, all marks are cleared for all features (and all "unmark" call-backs are called). As each feature (key/value pair) is encountered and processed, that feature's mark is set. Finally, when the configuration file has been fully read, all remaining unmarked features are reset to their default values (and all "mark" call-backs are called).

Adding New Features
To add a new feature, first determine the feature's name (which must begin with the string "FEAT_") and its type ("NONE," "INT," "BOOL," or "STR"). Then add the feature to the  in an appropriate place (i.e., it's good to group all features affecting operators separate from those features affecting networking code), and a corresponding entry in the   table in. It will be best to use one of the F_? macros, which are documented below. Then, whenever you need to refer to the value of a specific feature, call the appropriate feature_ function, as documented below.

Types, Enumerations, Structures, Macros and Functions
enum Feature;

The "Feature" enum lists all of the features known to the feature subsystem. Each feature name *must* begin with "FEAT_"; the portion of the name following "FEAT_" will be what you use to set the feature from the configuration file or with the "set" or "reset" commands.

int feature_set(struct Client* from, const char* const* fields, int count);

The  function takes an array of strings and a count of the number of strings in the array. The first string is a feature name, and, for most features, the second string will be that feature's value. The from parameter is the  describing the user that issued the "set" command. This parameter may be  if   is being called from the configuration file subsystem.

int feature_reset(struct Client* from, const char* const* fields, int count);

The  function is very similar in arguments to the   function, except that it may not be called from the configuration file subsystem. It resets the named feature to its default value.

int feature_get(struct Client* from, const char* const* fields, int count);

Again,  is very similar in arguments to the   function, except that again it may not be called from the configuration file subsystem. It reports the value of the named feature to the user that issued the "get" command.

void feature_unmark(void);

This function is used to unmark all feature values, as described in the subsection "Marking Features." It takes no arguments and returns nothing.

void feature_mark(void);

The complement to,   resets all unchanged feature settings to their defaults. See the subsection on "Marking Features."

void feature_init(void);

This function initializes the feature interface by setting the default values for all features correctly.

void feature_report(struct Client* to);

Reports all features to a user using, except those which the user is not permitted to see due to flag settings.

int feature_int(enum Feature feat);</c>

To retrieve the values of integer features, call this function. Calling this function on a different type of feature, such as a "BOOL" feature, will result in an assertion failure.

int feature_bool(enum Feature feat);</c>

This function is the complement of  for features of type "BOOL."

const char *feature_str(enum Feature feat);</c>

Use this function to retrieve strings values for features of type "STR"; you may not modify nor free the string value.

#define F_N(type, flags, set, reset, get, notify, unmark, mark, report)</c>

This macro is used in the  table to simplify defining a feature of type "NONE." The type parameter is the name of the feature excluding the "FEAT_" prefix, and MUST NOT be in double-quotes. The flags parameter may be 0,, or   -- the bitwise OR of these two flags is permissible but would not make sense. The rest of the arguments are pointers to functions implementing the named call-back.

#define F_N(type, flags, set, reset, get, notify, unmark, mark, report)</c>

This macro is used in the  table to simplify defining a feature of type "NONE." The type parameter is the name of the feature excluding the "FEAT_" prefix, and MUST NOT be in double-quotes. The flags parameter may be 0,, or   the bitwise OR of these two flags is permissible but would not make sense. The rest of the arguments are pointers to functions implementing the named call-back.

#define F_B(type, flags, v_int, notify)</c>

This macro is used for defining features of type "BOOL"; it is very similar to, but v_int should either 0 (for a "FALSE" value) or 1 (for a "TRUE" value). The notify parameter, if non-zero, will be called whenever the value of the feature changes.

#define F_S(type, flags, v_str, notify)</c>

Also similar to,   defines features of type "STR." The flags argument may be the bitwise OR of one of  or   with the special string flags   and , which are described above in the section "Feature Flags." The notify parameter, if non-zero, will be called whenever the value of the feature changes. Note that  *must* be set if the default string v_str is set to.