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.");
}
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 !");
}
#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);
}
make module MODFILE=test
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);
mycallback
function everytime a user connects.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);
parv
. Please copy it before. You have been warned.
nptr : NULL
uptr : NULL
chptr : NULL
parv[0] : sender
parv[1] : command
parv[2] : tail
sender
will contain :foo, command
will contain MODE and tail
will contain #bar +i.
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.
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.
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.
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.
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.
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).
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.
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);
name
: the name of the command.type
: the type of the function (listed in include/commands.h).func
: callback function (params may vary).desc
: the description of the command. Only used in HELP commands.subtype
: command subtype (listed in include/commands.h).level
: the level required to use the command.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.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).
deleteCommand
function. Example :
deleteCommand("nick",CMD_BASE,0);
addNickCommand
macro. Example :
addNickCommand("drop",nick_drop,1);
all
param is one word further (if someone type /msg C nick foo bar blah, all
would contain bar blah).delNickCommand
macro. Example :
delNickCommand("drop");
addNickSetCommand
macro. Example :
addNickSetCommand("password", nick_set_password, 1);
all
param contain the params given to the NICK SET command.delNickSetCommand
macro. Example :
delNickSetCommand("password");
addChanCommand
macro. Example :
addChanCommand("op",chan_op,1);
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).
delChanCommand
macro. Example :
delChanCommand("op");
addChanSetCommand
macro. Example :
addChanSetCommand("nojoin", chan_set_nojoin, 1);
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).delChanSetCommand
macro. Example :
delChanSetCommand("nojoin);
me.level_oper
(usually 100), since the base oper command is added like that :
addBaseCommand("oper", do_oper, me.level_oper);
addOperCommand
macro. Example :
addOperCommand("die", oper_global, me.level_root);
delOperCommand
marcro. Example :
delOperCommand("die");
addHostCommand
macro. Example :
addHostCommand("list" host_list, me.level_oper);
delHostCommand
macro. Example :
delHostCommand("list");
addBotCommand
macro. Example :
addBotCommand("!op", bot_op, 1);
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.
delBotCommand
macro. Example :
delBotCommand("!op");
addCommand
macro. Example :
addCommand("chan", CMD_HELP, help_chan, 0);
Nick *nptr, User *uptr, char *all
. A description of these params can be found above.deleteCommand
macro. Example :
deleteCommand("chan", CMD_HELP, 0);
addHelpNickCommand
macro. Example :
addHelpNickCommand("register", help_nick_register, "Register your nick", 0);
Nick *nptr
the pointer to the nick structure of the sender.delHelpNickCommand
. Example :
delHelpNickCommand("register");
addHelpNickSetCommand
macro. Example :
addHelpNickSetCommand("password", help_nick_set_password, "Change your password", 0);
delHelpNickSetCommand
macro. Example :
delHelpNickSetCommand("password");
addHelpChanCommand
macro. Example :
addHelpChanCommand("access", help_chan_access, "Manage access list", 0);
delHelpChanCommand
macro. Example :
delHelpChanCommand("access");
addHelpChanSetCommand
macro. Example :
addHelpChanSetCommand("founder", help_chan_set_founder, "Set the founder", 0);
delHelpChanSetCommand
macro. Example :
delHelpChanSetCommand("founder");
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);
delHelpOperCommand
macro. Example :
delHelpOperCommand("global");
addHelpHostCommand
macro. Example :
addHelpHostCommand("list", help_host_list, "List all users having a vhost", me.level_oper);
delHelpHostCommand
macro. Example :
delHelpHostCommand("list");
addHelpBotCommand
macro. Example :
addHelpBotCommand("!op", "Give op");
delHelpBotCommand
macro. Example :
delHelpBotCommand("!op");
tyoedef struct bot {
char nick[NICKLEN+1];
char ident[NICKLEN+1];
char host[HOSTLEN+1];
struct bot *next,*prev;
} Bot;
Bot *addBot (char *, char *, char *); /* nick, ident, host */
inline void delBot (Bot *);
Bot *find_bot (char *); /* nick */
typedef struct chanbot {
char name[CHANLEN+1];
char bot[NICKLEN+1];
struct chanbot *next,*prev;
} Chanbot;
Chanbot *addChanbot (char *, char *); /* channelname, botnick */
inline void delChanbot (Chanbot *);
Chanbot *find_chanbot (char *); /* channelname */
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;
Chan *find_channel (char *);
Chan *CreateChannel (char *, char *, int);
void DeleteChannel(Chan *);
#define SetOption(x, y) ((x)->options |= (y))
#define ClearOption(x, y) ((x)->options &= ~(y))
#define HasOption(x, y) ((x)->options & (y))
typedef struct cflag {
char channel[CHANLEN + 1];
char nick[NICKLEN + MASKLEN + 1];
int flags; /* access level */
struct cflag *next,*prev;
} Cflag;
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 */
typedef struct wchan {
char chname[CHANLEN + 1];
struct wchan *next,*prev;
} Wchan;
Wchan *find_wchan (char *);
Wchan *CreateWchan(char *);
inline void DeleteWchan(Wchan *);
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;
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. */
/* 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))
ClearOwner(member);
SetChanFlag(member, CHFL_OP|CHFL_PROTECT);
typedef struct trust {
char host[HOSTLEN + 1];
int limit; /* max clones number */
struct trust *next,*prev;
} Trust;
Trust *find_trust_strict (char *);
Trust *find_trust (char *);
Trust *AddTrust (char *, int);
void DeleteTrust (Trust *);
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;
#define SetOption(x, y) ((x)->options |= (y))
#define ClearOption(x, y) ((x)->options &= ~(y))
#define HasOption(x, y) ((x)->options & (y))
User *find_user (char *);
User *AddUser (char *, int); /* nick, level */
inline void DeleteAccount (User *);
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;
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))
if (IsSSL(nptr))
SetRegistered(nptr);
ClearNokick(nptr);
SetUmode(nptr, UMODE_OPER | UMODE_ADMIN | UMODE_NADMIN);
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 *);
userquit
function is only used when QUITs and KILLs occur. It removes all data regarding the specified online user.
#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 */
#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. */
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 */