/home/dev/child/doc

Child API documentation for modules writing

Last update: 15 aug. 2006
For services version: 1.0


Documentation : written by target0
Second reading : thanks to cortex and Godspeed

Index

1. Basic module API
  1.1. Init function
  1.2. Cleanup function
  1.3. Module example
2. Hooks
  2.1. Raw
  2.2. Join (before applying modes)
  2.3. Join (after applying modes)
  2.4. Nick change
  2.5. User connection
  2.6. User quit
  2.7. Server ping
  2.8. Change of user modes
  2.9. Kill
  2.10. Creation of DBs
  2.11. Load of DBs
  2.12. Save of DBs
  2.13. Connected to server (start of burst sequence)
  2.14. Emergency mode on
  2.15. Emergency mode off
3. Commands API
  3.1. Base commands
  3.2. NICK commands
    3.2.1. NICK SET commands
  3.3. CHAN commands
    3.3.1. CHAN SET commands
  3.4. OPER commands
  3.5. HOST commands
  3.6. Bot commands
  3.7. HELP commands
    3.7.1. HELP NICK commands
      3.7.1.1. HELP NICK SET commands
    3.7.2. HELP CHAN commands
      3.7.2.1. HELP CHAN SET commands
    3.7.3. HELP OPER commands
    3.7.4. HELP HOST commands
    3.7.5. HELP BOT commands
4. Botserv
    4.1. Bots
    4.2. Channels
5. Channels
  5.1. Registered channels
  5.2. Channel access
  5.3. Formed channels
  5.4. Channel members
6. Trusts
7. Users
  7.1. Registered users
  7.2. Online users
8. Others useful functions and macros
  8.1. Channels
  8.2. Users
  8.3. Misc

1. Basic module API

1.1. Init function

The module init function child_init is called when the module is loaded. It may contain hooking functions and/or commands functions. It takes no params and has type void. Example :

void child_init()
{
    MsgToChan("#opers","Hello operators, I'm a test module.");
}

1.2. Cleanup function

The child_cleanup function is called when the module is unloaded. Usually it contains commands removing and memory freeing functions. Like child_init, it takes no params and has type void. Example :

void child_cleanup()
{
    MsgToChan("#opers","Help ! They're unloading me !");
}

1.3. Module example

This example module is so easy to understand that I let you guess what it does.

#include <child.h>
#include <globals.h>

static int starttime;
void child_init()
{
    starttime = time(NULL);
    MsgToChan("#opers","Hello, I'm a test module.");
}

void child_cleanup()
{
    MsgToChan("#opers","Bye ! I have been up %d seconds.",time(NULL) - starttime);
}

You can put this source in src/modules/test.c and compile it with the following command (in the child root directory) :

make module MODFILE=test

2. Hooks

Hooks are ways for modules to execute code when special events occur. Hook adding is done via AddHook function, and hook removing via DelHook function. Note that each hook of a module is removed on unloading. Here is an example of AddHook :

AddHook(HOOK_NICKCREATE, &mycallback, "mycallback", modname);

This will execute mycallback function everytime a user connects.
Here is the prototypes of AddHook and DelHook :

Hook *AddHook (long int hook, int (*fptr)(Nick *nptr, User *uptr, Chan *chptr, char **parv), char *hookname, char *modname);
int DelHook (char *hookname, char *modname);

Callbacks function must return either MOD_CONTINUE or MOD_STOP. MOD_CONTINUE will continue execution of the calling function, while MOD_STOP will stop its execution. Note that's not true for every hook, some doesn't check the return value.

WARNING: DO NOT MAKE ANY CHANGE DIRECTLY TO DATA POINTED BY parv. Please copy it before. You have been warned.

2.1. Raw

The HOOK_RAW is executed just after minimal line parsing is done (just after sender, command, and tail are seperated).

nptr : NULL
uptr : NULL
chptr : NULL
parv[0] : sender
parv[1] : command
parv[2] : tail

Example: if the server sent :foo MODE #bar +i, sender will contain :foo, command will contain MODE and tail will contain #bar +i.
If MOD_STOP is returned, the calling function returns (use it with care !).

2.2. Join (before applying modes)

The HOOK_PRE_JOIN is executed in the beginning of JOIN command parsing, before checking user access and modes to apply.

nptr : pointer to the nick structure of the sender. Can't be NULL.
uptr : pointer to the user structure of the sender. Can be NULL.
chptr : pointer to the chan structure of the joined channel. Can be NULL.
parv[0] : pointer to the name of the joined channel. Can't be NULL.

If MOD_STOP is returned, child either continue parsing of the next channel if several channels are joined, or terminate the calling function.

2.3. Join (after applying modes)

The HOOK_JOIN is executed at the end of JOIN command parsing.

nptr : pointer to the nick structure of the sender. Can't be NULL.
uptr : pointer to the user structure of the sender. Can be NULL.
chptr : pointer to the chan structure of the joined channel. Can't be NULL.
parv : NULL.

MOD_STOP has no effect.

2.4. Nick change

The HOOK_NICKCHANGE is executed after parsing NICK command.

nptr : pointer to the nick structure of the new nick. Can be NULL, but shouldn't be. Actually if it's NULL then you just discovered a enormous bug.
uptr : pointer to the user structure of the new nick. Can be NULL.
chptr : NULL.
parv[0] : pointer to the name of the old nick. Can't be NULL.

MOD_STOP has no effect.

2.5. User connection

The HOOK_NICKCREATE is executed on user connecting (after checking modes, trusts, accounts, etc).

nptr : pointer to the nick structure of the new user. Can't be NULL. If it was NULL then child would have already segfault.
uptr : pointer to the user structure of the new user. Can be NULL.
chptr : NULL.
parv : NULL.

MOD_STOP has no effect.

2.6. User quit

The HOOK_QUIT is executed at the beginning of QUIT command parsing.

nptr : pointer to the nick structure of the quitted user. Can't be NULL.
uptr : pointer to the user structure of the quitted user. Can be NULL.
chptr : NULL.
parv : NULL.

If MOD_STOP is returned, the calling function returns and the quitted user is not removed from memory.

2.7. Server ping

The HOOK_PING is executed after replying to server PINGs. All params are NULL.
MOD_STOP has no effect.

2.8. Change of user modes

The HOOK_UMODE is executed after parsing umodes changing.

nptr : pointer to the nick structure of the sender. Can't be NULL.
uptr : pointer to the user structure of the sender. Can be NULL.
chptr : NULL.
parv[0] : modes (example: +osgw).

MOD_STOP has no effect.

2.9. Kill

The HOOK_KILL is executed after parsing KILL command, but before removing killed user from memory.

nptr : pointer to the nick structure of the killed user. Can be NULL, it would mean that the killed user is a fakeuser.
uptr : pointer to the user structure of the killed user. Can be NULL.
chptr : NULL.
parv : NULL.

If MOD_STOP is returned, the calling function returns before removing the killed user from memory.

2.10. Creation of DBs

The HOOK_CREATEDB is executed after creating mysql tables (-c command line option). All params are NULL.
MOD_STOP has no effect.

2.11. Load of DBs

The HOOK_LOADDB is executed after loading database. All params are NULL.
MOD_STOP has no effect.

2.12. Save of DBs

The HOOK_SAVEDB is executed after saving database. All params are NULL.
MOD_STOP has no effect.

2.13. Connected to server (start of burst sequence)

The HOOK_CONNECTED is executed when burst sequence is started and after creating and joining botserv bots. All params are NULL.
MOD_STOP has no effect.

2.14. Emergency mode on

The HOOK_EMERG_ON is executed when emergency mode is activated by entering the activation code in the partyline. All params are NULL.
MOD_STOP has no effect.

2.15. Emergency mode off

The HOOK_EMERG_OFF is executed when emergency mode is deactivated. All params are NULL.
MOD_STOP has no effect.

3. Commands API

Commands API functions are an easy way to add and remove commands on the fly. The most part of the API are macros, but there are some base functions.

Command *__addCommand (char *name, int type, void (*func)(), char *desc, int subtype, int level);
inline void delCommand (Command *cmd);
int deleteCommand (char *name, int type, int subtype);
Command *find_command (char *name, int type, int subtype);

Here is the explanation of params :
Normally you won't use these functions. You should use macros listed in include/commands.h and introduced below.

3.1. Base commands

Base command mean the first param sent with /msg C. For example, in /msg C nick, nick is the base command.
A base command is added with the addBaseCommand macro. Example :

addBaseCommand("nick",do_nick,0);

nick is the name of the command, do_nick is the callback and 0 is the required level to use the command. Note that a level 0 means all users, even not registered ones.
The callback takes the following params (they all can be NULL excepted nptr, and uptr if you set a level > 0) :

Nick *nptr : pointer to the nick structure of the sender.
User *uptr : pointer to the user structure of the sender.
char *all : command arguments (example: in /msg C nick foo bar, foo bar are the arguments).

You can remove a base command with the deleteCommand function. Example :

deleteCommand("nick",CMD_BASE,0);

CMD_BASE and 0 doesn't have to be changed.

3.2. NICK commands

NICK commands are the ones used with /msg C nick command. You can add one with the addNickCommand macro. Example :

addNickCommand("drop",nick_drop,1);

The callback takes the same parameters as base commands, excepted that all param is one word further (if someone type /msg C nick foo bar blah, all would contain bar blah).
You can remove a NICK command with the delNickCommand macro. Example :

delNickCommand("drop");

3.2.1. NICK SET commands

NICK SET commands are options to be set with /msg C nick set command. You can add one with the addNickSetCommand macro. Example :

addNickSetCommand("password", nick_set_password, 1);

The callback takes the same parameters as NICK commands. As usual, the all param contain the params given to the NICK SET command.
A NICK SET command is removed with the delNickSetCommand macro. Example :

delNickSetCommand("password");

3.3. CHAN commands

CHAN commands are the ones used with /msg C chan command. You can add one with the addChanCommand macro. Example :

addChanCommand("op",chan_op,1);

The callback takes the following params (they all can be NULL excepted nptr, and uptr if you set a level > 0) :

Nick *nptr : pointer to the nick structure of the sender.
User *uptr : pointer to the user structure of the sender.
Chan *chptr : pointer to the chan structure of the channel given as parameter.
char *all : params given to the command (including the channel).

You can remove a CHAN command with the delChanCommand macro. Example :

delChanCommand("op");

3.3.1. CHAN SET commands

CHAN SET commands are channel options to be set with /msg C chan set command. You can add one with the addChanSetCommand macro. Example :

addChanSetCommand("nojoin", chan_set_nojoin, 1);

The callback takes the same params as CHAN commands, excepted that chptr can't be NULL. The all param contain the parameters given to the CHAN SET command, without the channel and the option name (if someone sent /msg C chan set #troll nojoin on then all would contain on).
You can remove a CHAN SET command with the delChanSetCommand macro. Example :

delChanSetCommand("nojoin);

3.4. OPER commands

OPER commands are /msg C oper commands. The minimum required level is me.level_oper (usually 100), since the base oper command is added like that :

addBaseCommand("oper", do_oper, me.level_oper);

You can add an OPER command with the addOperCommand macro. Example :

addOperCommand("die", oper_global, me.level_root);

The callback takes the same parameters as NICK commands.
You can remove an OPER command with the delOperCommand marcro. Example :

delOperCommand("die");

3.5. HOST commands

HOST commands are the ones sent with /msg C host command. The minimum required level is the same as OPER commands. You can add a HOST command with the addHostCommand macro. Example :

addHostCommand("list" host_list, me.level_oper);

The callback takes the same parameters as NICK and OPER commands.
You can remove a HOST command with the delHostCommand macro. Example :

delHostCommand("list");

3.6. Bot commands

Bot commands are commands sent in a channel, with the '!' prefix. (!op, !deop, etc). You can add a bot command with the addBotCommand macro. Example :

addBotCommand("!op", bot_op, 1);

The callback takes the following parameters (Only nptr and wchan can't be NULL, but uptr also can't be NULL if the required level is > 0) :

Nick *nptr : pointer to the nick structure of the sender.
User *uptr : pointer to the user structure of the sender.
Chan *chptr : pointer to the chan structure of the channel where the message is sent.
Wchan *wchan : pointer to the wchan structure of the channel where the message is sent.
char *all : arguments given the the command.

You can remove a bot command with the delBotCommand macro. Example :

delBotCommand("!op");

3.7. HELP commands

HELP commands are commands accessed with /msg C help command. A base help command is the param given just after help. There are 5 base help commands, the same as base commands : bot, chan, host, nick, oper. You can add a base help command with the addCommand macro. Example :

addCommand("chan", CMD_HELP, help_chan, 0);

The last param is the required level.
The callback takes 3 params: Nick *nptr, User *uptr, char *all. A description of these params can be found above.
You can remove a base help command with the deleteCommand macro. Example :

deleteCommand("chan", CMD_HELP, 0);

Note that the last param is not the level but the subtype, and doesn't have to be changed.

3.7.1. HELP NICK commands

HELP NICK commands are /msg C help nick commands. You can add one with the addHelpNickCommand macro. Example :

addHelpNickCommand("register", help_nick_register, "Register your nick", 0);

The first param is the name, the second one is the callback, the third one is the description used in commands listing, and the last one is the required level to see the command in /msg C help nick (in this case) and to use /msg C help nick register (also in this case).
The callback takes only one non-NULL param: Nick *nptr the pointer to the nick structure of the sender.
You can remove a HELP NICK command with the delHelpNickCommand. Example :

delHelpNickCommand("register");

3.7.1.1. HELP NICK SET commands

HELP NICK SET commands are the ones accessed with /msg C help nick set. You can add one with the addHelpNickSetCommand macro. Example :

addHelpNickSetCommand("password", help_nick_set_password, "Change your password", 0);

The arguments are the same as HELP NICK commands. The callback params are also the same as HELP NICK callbacks.
You can remove a HELP NICK SET command with the delHelpNickSetCommand macro. Example :

delHelpNickSetCommand("password");

3.7.2. HELP CHAN commands

HELP CHAN commands are /msg C help chan commands. You can add one with the addHelpChanCommand macro. Example :

addHelpChanCommand("access", help_chan_access, "Manage access list", 0);

The arguments are the same as HELP NICK macro. The callback params are also the same as HELP NICK callbacks.
You can remove a HELP CHAN command via the delHelpChanCommand macro. Example :

delHelpChanCommand("access");

3.7.2.1. HELP CHAN SET commands

HELP CHAN SET commands are the ones accessed with /msg C help chan set. You can add one with the addHelpChanSetCommand macro. Example :

addHelpChanSetCommand("founder", help_chan_set_founder, "Set the founder", 0);

The arguments are the same as HELP CHAN commands. The callback params are also the same as HELP CHAN callbacks.
You can remove a HELP CHAN SET command with the delHelpChanSetCommand macro. Example :

delHelpChanSetCommand("founder");

3.7.3. HELP OPER commands

HELP OPER commands are /msg C help oper commands. The minimum level required is me.level_oper (usually 100) since the oper base help command require at least this level. You can add a HELP OPER command with the addHelpOperCommand macro. Example :

addHelpOperCommand("global", help_oper_global, "Send a global notice", me.level_oper);

The arguments and callback params are the same as HELP NICK and HELP CHAN commands.
You can remove a HELP OPER command with the delHelpOperCommand macro. Example :

delHelpOperCommand("global");

3.7.4. HELP HOST commands

HELP HOST commands are accessed via /msg C help host. The minimum required level is the same as HELP OPER commands. You can add a HELP HOST command with the addHelpHostCommand macro. Example :

addHelpHostCommand("list", help_host_list, "List all users having a vhost", me.level_oper);

The arguments and callback params are the same as HELP OPER commands.
You can remove a HELP HOST command with the delHelpHostCommand macro. Example :

delHelpHostCommand("list");

3.7.5. HELP BOT commands

HELP BOT commands are a bit different from others help commands. The main difference is that there is no advanced help for these commands, only listing with command description. They're accessed via /msg C help bot. You can add a HELP BOT command with the addHelpBotCommand macro. Example :

addHelpBotCommand("!op", "Give op");

You can remove one with the delHelpBotCommand macro. Example :

delHelpBotCommand("!op");

4. Botserv

When a channel is registered, C joins it by default. There is a way to assign a bot with another nick than C. This way is botserv bots. These bots have exactly the same features as C, it's just the nick that's different. When another bot than C is assigned to a channel, the option NOJOIN is automatically set and enforced until the bot is unassigned, to prevent having 2 bots in the same channel.

4.1. Bots

Here is the definition of bot structure :

tyoedef struct bot {
    char nick[NICKLEN+1];
    char ident[NICKLEN+1];
    char host[HOSTLEN+1];
    struct bot *next,*prev;
} Bot;

There are 3 functions to manipulate bots :

Bot *addBot (char *, char *, char *); /* nick, ident, host */
inline void delBot (Bot *);
Bot *find_bot (char *); /* nick */

4.2. Channels

A botserv channel is a channel where another bot than C has been assigned.
Here is the definition of chanbot structure :

typedef struct chanbot {
    char name[CHANLEN+1];
    char bot[NICKLEN+1];
    struct chanbot *next,*prev;
} Chanbot;

There are 3 functions to manipulate chanbots :

Chanbot *addChanbot (char *, char *); /* channelname, botnick */
inline void delChanbot (Chanbot *);
Chanbot *find_chanbot (char *); /* channelname */

5. Channels

Child knows 2 types of channel : registered channels and formed channels. A formed channel is a channel existing on the network but not necessary registered.

5.1. Registered channels

Here is the definition of the chan structure :

typedef struct chan {
    char channelname[CHANLEN + 1];
    char owner[NICKLEN + 1];
    long int options;
    char entrymsg[250+1];
    char mlock[20+1];
    int autolimit, lastseen;
    struct chan *next,*prev;
} Chan;

There are several functions to manipulate registered channels. They all can be found in src/channel.c. Here are the main ones :

Chan *find_channel (char *);
Chan *CreateChannel (char *, char *, int);
void DeleteChannel(Chan *);

Channel options are defined in include/channel.h. They can be manipulated with 3 macros :

#define SetOption(x, y) ((x)->options |= (y))
#define ClearOption(x, y) ((x)->options &= ~(y))
#define HasOption(x, y) ((x)->options & (y))

They take 2 arguments of type Chan * and int. They can also be used for users options.

5.2. Channel access

Channel access are currently in the range from -3 to 9999. Their features are listed in /msg C help chan access.
Here is the definition of the cflag structure :

typedef struct cflag {
    char channel[CHANLEN + 1];
    char nick[NICKLEN + MASKLEN + 1];
    int flags; /* access level */
    struct cflag *next,*prev;
} Cflag;

Here is some functions to manipulate cflags :

Cflag *find_cflag (char *, char *); /* nick, channelname */
Cflag *AddUserToChannel (User *, Chan *, int);
void DeleteUserFromChannel (User *, Chan *);
Cflag *AddMaskToChannel (char *, Chan *, int); /* explanation below */
void DeleteMaskFromChannel (char *, Chan *); /* explanation below */
int GetFlag (User *, char *); /* returns access level */
void DeleteUserFromChannels (User *); /* remove all channel access of a user */
void DeleteUsersFromChannel (Chan *); /* remove all access of a channel */

On a channel access list there could be usernames and masks. To allow the usage of masks, the option ENABLEMASK must be enabled. A mask is composed of three parts : nick!ident@host. Wildcards and any C regular expressions are accepted. However, there is a restriction : masks can't have a level higher than me.chlev_op (usually 5) because of security issues (that may change in the future).

5.3. Formed channels

All channels existing on the network are put in wchan structures.
Here is the definition of the wchan structure :

typedef struct wchan {
    char chname[CHANLEN + 1];
    struct wchan *next,*prev;
} Wchan;

Here are some functions to manipulate wchans :

Wchan *find_wchan (char *);
Wchan *CreateWchan(char *);
inline void DeleteWchan(Wchan *);

5.4. Channel members

All channel members are listed in member structures.
Here is the member structure definition :

typedef struct member_ {
    char nick[NICKLEN + 1];
    char channel[CHANLEN + 1];
    long int flags; /* voice, op, protect, etc. Can be ORed. See below. */
    struct member_ *next,*prev;
} Member;

Here are some functions to manipulate channel members :

Member *AddUserToWchan(Nick *, Wchan *);
void DeleteUserFromWchan (Nick *, Wchan *);
void KickUser(char *, char *, char *, char *, ...); /* botnick, targetnick, channelname, reason */
Member *find_member (char *, char *);
void SetStatus (Nick *, char *, long int, int, char *); /* nptr, channelname, flag (can be ORed, see below), give (1) or take (0), botnick */
void DeleteUserFromWchans(Nick *); /* remove a user from its channels */
int member_exists (Wchan *); /* returns 1 if there is someone in a channel, otherwise 0 */
int members_num (Wchan *); /* returns the number of members in a channel */
int IsMember(char *, char *); /* nick, channel. Returns 1 if the user is a member of the channel, otherwise 0. */

Member's flags are defined in include/channel.h. They can be modified with some macros :

/* These macros take 2 arguments of type char * and Wchan *. (nickname and wchan pointer) */
#define IsOwner(a,b) IsChanFlag(a,b,CHFL_OWNER)
#define IsProtect(a,b) IsChanFlag(a,b,CHFL_PROTECT)
#define IsOp(a,b) IsChanFlag(a,b,CHFL_OP)
#define IsHalfop(a,b) IsChanFlag(a,b,CHFL_HALFOP)
#define IsVoice(a,b) IsChanFlag(a,b,CHFL_VOICE)

/* These macros take one argument of type Member *. */
#define SetOp(x) SetChanFlag(x, CHFL_OP)
#define SetHalfop(x) SetChanFlag(x, CHFL_HALFOP)
#define SetVoice(x) SetChanFlag(x, CHFL_VOICE)
#define SetProtect(x) SetChanFlag(x, CHFL_PROTECT)
#define SetOwner(x) SetChanFlag(x, CHFL_OWNER)

/* These macros take one argument of type Member *. */
#define ClearOp(x) ClearChanFlag(x, CHFL_OP)
#define ClearHalfop(x) ClearChanFlag(x, CHFL_HALFOP)
#define ClearVoice(x) ClearChanFlag(x, CHFL_VOICE)
#define ClearProtect(x) ClearChanFlag(x, CHFL_PROTECT)
#define ClearOwner(x) ClearChanFlag(x, CHFL_OWNER)

/* These macros take two arguments of type Member * and int. */
#define SetChanFlag(x, y) ((x)->flags |= (y))
#define ClearChanFlag(x, y) ((x)->flags &= ~(y))
#define HasChanFlag(x, y) ((x)->flags & (y))

Example :

ClearOwner(member);
SetChanFlag(member, CHFL_OP|CHFL_PROTECT);

Remember that these functions are only used to change flags internally, not on the remote server. Otherwise you have to send the modes change to the remote server.

6. Trusts

Trusts are a way to modify the maximum clones number for a specified IP/hostname/range. IPv4 and IPv6 are supported. CIDR notation is only supported for IPv4.
Note that if a IP range is specified (CIDR notation), the max clones number is for each IP, not for the whole range (may change in the future).
Here is the trust structure definition :

typedef struct trust {
    char host[HOSTLEN + 1];
    int limit; /* max clones number */
    struct trust *next,*prev;
} Trust;

Here are functions to manipulate trusts :

Trust *find_trust_strict (char *);
Trust *find_trust (char *);
Trust *AddTrust (char *, int);
void DeleteTrust (Trust *);

The find_trust_strict function searches a trust by doing only a strcasecmp.
The find_trust function searches a trust by doing first a strcasecmp. If not found, and if the trust is a CIDR notation, it extracts the bitmask and check if the given IP matches with the trust range.

7. Users

There are 2 types of users : registered users and online users.

7.1. Registered users

Here is the user structure definition :

typedef struct user_ {
    char nick[NICKLEN + 1];
    int authed,level;
    char md5_pass[35];
    int lastseen,timeout;
    long int options;
    char vhost[HOSTLEN + 1];
    char email[EMAILLEN + 1];
    struct user_ *next,*prev;
} User;

The user options are defined in include/user.h. They can be manipulated with 3 macros :

#define SetOption(x, y) ((x)->options |= (y))
#define ClearOption(x, y) ((x)->options &= ~(y))
#define HasOption(x, y) ((x)->options & (y))

The arguments are of type User * and int.
Here are some options to manipulate registered users :

User *find_user (char *);
User *AddUser (char *, int); /* nick, level */
inline void DeleteAccount (User *);

7.2. Online users

Here is the nick structure definition :

typedef struct nick {
    char nick[NICKLEN + 1];
    char ident[NICKLEN + 1];
    char host[HOSTLEN + 1]; /* cleartext hostname */
    char server[HOSTLEN + 1];
    char hiddenhost[HOSTLEN + 1]; /* cloaked hostname */
    char reshost[HOSTLEN + 1]; /* resolved hostname (IP) */
    long int umodes;
    int msgtime,msgnb;
    int ignored,ignoretime;
    int loginattempts,lasttry;
    struct nick *next,*prev;
} Nick;

User modes (umodes field) are defined in include/user.h. There are several macros to manipulate them :

/* These macros take one argument of type Nick * */ #define IsOper(x) HasUmode(x, UMODE_OPER)
#define IsAdmin(x) HasUmode(x, UMODE_ADMIN)
#define IsSAdmin(x) HasUmode(x, UMODE_SADMIN)
#define IsNAdmin(x) HasUmode(x, UMODE_NADMIN)
#define IsBot(x) HasUmode(x, UMODE_BOT)
#define IsService(x) HasUmode(x, UMODE_SERVICE)
#define IsNokick(x) HasUmode(x, UMODE_NOKICK) /* umode +q */
#define IsSSL(x) HasUmode(x, UMODE_SSL)
#define IsRegistered(x) HasUmode(x, UMODE_REGISTERED)

#define SetOper(x) SetUmode(x, UMODE_OPER)
#define SetAdmin(x) SetUmode(x, UMODE_ADMIN)
#define SetSAdmin(x) SetUmode(x, UMODE_SADMIN)
#define SetNAdmin(x) SetUmode(x, UMODE_NADMIN)
#define SetBot(x) SetUmode(x, UMODE_BOT)
#define SetService(x) SetUmode(x, UMODE_SERVICE)
#define SetNokick(x) SetUmode(x, UMODE_NOKICK)
#define SetSSL(x) SetUmode(x, UMODE_SSL)
#define SetRegistered(x) SetUmode(x, UMODE_REGISTERED)

#define ClearOper(x) ClearUmode(x, UMODE_OPER)
#define ClearAdmin(x) ClearUmode(x, UMODE_ADMIN)
#define ClearSAdmin(x) ClearUmode(x, UMODE_SADMIN)
#define ClearNAdmin(x) ClearUmode(x, UMODE_NADMIN)
#define ClearBot(x) ClearUmode(x, UMODE_BOT)
#define ClearService(x) ClearUmode(x, UMODE_SERVICE)
#define ClearNokick(x) ClearUmode(x, UMODE_NOKICK)
#define ClearSSL(x) ClearUmode(x, UMODE_SSL)
#define ClearRegistered(x) ClearUmode(x, UMODE_REGISTERED)

/* These macros take two arguments of type Nick * and int. */
#define SetUmode(x, y) ((x)->umodes |= (y))
#define ClearUmode(x, y) ((x)->umodes &= ~(y))
#define HasUmode(x, y) ((x)->umodes & (y))

Example :

if (IsSSL(nptr))
    SetRegistered(nptr);

ClearNokick(nptr);
SetUmode(nptr, UMODE_OPER | UMODE_ADMIN | UMODE_NADMIN);

Here are some functions to manipulate online users :

Nick *find_nick (char *);
Nick *AddNick (char *, char *, char *, char *, char *, long int); /* nick, ident, host, server, hiddenhost, umodes */
inline void DeleteWildNick (Nick *);
void userquit (char *);

The userquit function is only used when QUITs and KILLs occur. It removes all data regarding the specified online user.

8. Others useful functions and macros

8.1. Channels

#define IsFounder(x,y) (GetFlag(x,(y)->channelname) == CHLEV_OWNER) /* Check if a user is the founder of a channel. Arguments: char *, Wchan *. */
#define MsgToChan(a,b,...) FakeMsg(me.nick,a,b,##__VA_ARGS__) /* Makes C talk in a channel. Arguments, char *, char * (channel, message). */

void JoinChannel(char *, char *); /* Makes a bot join a channel and op itself. Arguments: botnick, channelname */
int chansreg (char *); /* Returns the number of a channel a user registered. Arguments: usernick */
char *whatbot (char *); /* Return the name of the bot managing a channel (me.nick or a botserv bot nick). Argument: channelname */

8.2. Users

#define IsAuthed(x) ((x) && (x)->authed == 1) /* Check if a user is authed. Argument type: User *. */
#define fakeuser(a,b,c,d) SendRaw("NICK %s 1 %ld %s %s %s 0 +%s * :%s",a,time(NULL),b,c,me.name,d,b) /* Create a fake user. Arguments: char *nick, char *ident, char *host, char *umodes. */
#define fakejoin(x,y) SendRaw(":%s JOIN %s",x,y) /* Makes a fakeuser join a channel. Arguments: char *nick, char *channelname. */
#define fakekill(x,y) SendRaw(":%s QUIT :%s",x,y) /* Kill a fakeuser. Arguments: char *nick, char *reason. */
#define fakesay(x,y,z) SendRaw(":%s PRIVMSG %s :%s",x,y,z) /* Makes a fakeuser say something. Arguments: char *nick, char *targetname, char *message. */
#define killuser(x,y,z) _killuser(x,y,z); \
                         userquit(x) /* Kill a user. Arguments: char *botnick, char *nick, char *reason. */
#define NoticeToUser(a,b,...) FakeNotice(me.nick,a,b,##__VA_ARGS__) /* Send a notice to someone. Arguments: Nick *nptr, char *notice. */

void Global (char *, ...); /* Send a global notice. */
int howmanyclones (char *); /* Returns how many clones a user have. */

8.3. Misc

void child_die (int); /* Stop services. Param: 1 to save DBs, 0 to don't. */
void child_restart (int); /* Restart services. Same param as child_die */
void child_clean (void) __attribute__((noreturn)); /* free all memory, remove pid file, exit. */
void init_srandom (void); /* Init pseudo-random number generator. */

/* Obvious meaning */
inline void savealldb (void);
inline void loadalldb (void);

int hash (char *); /* Generate a hash from a string. */
char *md5_hash (char *); /* Generate a md5 hash from a string. /!\ The returned pointer is malloc-ed. So you have to free it when you no longer use it. */

int connect_to_db (void); /* Connect to mysql server */
int reconnect_to_db (void); /* Close current mysql connection and call connect_to_db */

char *SeperateWord (char *); /* Seperate word in a sentence. Have a look in the code to see examples. */
int Strcmp (const char *, const char *); /* Case insensitive string comparison */
int match_regex (char *, char *); /* Check if a string matches against a C-style regular expression. Arguments: string, regex. */
char *gen_rand_string (char *, char *, int); /* Generate a random string. The first argument is the destination pointer. The second one is the range (example: A-Za-z0-9). The last one is the length of the string to generate. */

void unloadallmod (void); /* unload all modules */
inline void nodreload (char *); /* Prevent the specified module to be unloaded by hand with /msg C oper modunload command. */

void SendRaw (char *, ...); /* Send data to the remove server */