diff options
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | irc.c | 3 | ||||
-rw-r--r-- | irc.h | 25 | ||||
-rw-r--r-- | irc_channel.c | 15 | ||||
-rw-r--r-- | irc_commands.c | 99 | ||||
-rw-r--r-- | irc_send.c | 10 | ||||
-rw-r--r-- | irc_user.c | 32 | ||||
-rw-r--r-- | nick.c | 2 | ||||
-rw-r--r-- | root_commands.c | 6 |
9 files changed, 142 insertions, 52 deletions
@@ -10,7 +10,7 @@ # Program variables #objects = bitlbee.o chat.o dcc.o help.o ipc.o irc.o irc_commands.o nick.o query.o root_commands.o set.o storage.o $(STORAGE_OBJS) -objects = bitlbee.o help.o ipc.o irc.o irc_channel.o irc_commands.o irc_send.o irc_user.o nick.o set.o +objects = bitlbee.o help.o ipc.o irc.o irc_channel.o irc_commands.o irc_send.o irc_user.o nick.o root_commands.o set.o headers = account.h bitlbee.h commands.h conf.h config.h help.h ipc.h irc.h log.h nick.h query.h set.h sock.h storage.h user.h lib/events.h lib/ftutil.h lib/http_client.h lib/ini.h lib/md5.h lib/misc.h lib/proxy.h lib/sha1.h lib/ssl_client.h lib/url.h protocols/ft.h protocols/nogaim.h subdirs = lib protocols @@ -113,10 +113,12 @@ irc_t *irc_new( int fd ) irc->root = iu = irc_user_new( irc, ROOT_NICK ); iu->host = g_strdup( myhost ); iu->fullname = g_strdup( ROOT_FN ); + iu->f = &irc_user_root_funcs; iu = irc_user_new( irc, NS_NICK ); iu->host = g_strdup( myhost ); iu->fullname = g_strdup( ROOT_FN ); + iu->f = &irc_user_root_funcs; irc->user = g_new0( irc_user_t, 1 ); irc->user->host = g_strdup( host ); @@ -593,6 +595,7 @@ int irc_check_login( irc_t *irc ) irc->user->user = iu->user; irc->user->host = iu->host; irc->user->fullname = iu->fullname; + irc->user->f = &irc_user_self_funcs; g_free( iu->nick ); g_free( iu ); @@ -106,8 +106,18 @@ typedef struct irc_user int sendbuf_flags; //struct user *b; + + const struct irc_user_funcs *f; } irc_user_t; +struct irc_user_funcs +{ + gboolean (*privmsg)( irc_user_t *iu, const char *msg ); +}; + +extern const struct irc_user_funcs irc_user_root_funcs; +extern const struct irc_user_funcs irc_user_self_funcs; + typedef enum { IRC_CHANNEL_JOINED = 1, @@ -116,16 +126,25 @@ typedef enum typedef struct irc_channel { irc_t *irc; - int flags; char *name; + char mode[8]; + int flags; + char *topic; char *topic_who; time_t topic_time; - char mode[8]; + GSList *users; struct set *set; + + const struct irc_channel_funcs *f; } irc_channel_t; +struct irc_channel_funcs +{ + gboolean (*privmsg)( irc_channel_t *iu, const char *msg ); +}; + #include "user.h" /* irc.c */ @@ -174,7 +193,7 @@ void irc_send_who( irc_t *irc, GSList *l, const char *channel ); /* irc_user.c */ irc_user_t *irc_user_new( irc_t *irc, const char *nick ); int irc_user_free( irc_t *irc, const char *nick ); -irc_user_t *irc_user_find( irc_t *irc, const char *nick ); +irc_user_t *irc_user_by_name( irc_t *irc, const char *nick ); int irc_user_rename( irc_t *irc, const char *old, const char *new ); gint irc_user_cmp( gconstpointer a_, gconstpointer b_ ); diff --git a/irc_channel.c b/irc_channel.c index c2e2c685..ec0433c1 100644 --- a/irc_channel.c +++ b/irc_channel.c @@ -25,6 +25,8 @@ #include "bitlbee.h" +static const struct irc_channel_funcs control_channel_funcs; + irc_channel_t *irc_channel_new( irc_t *irc, const char *name ) { irc_channel_t *ic; @@ -33,6 +35,7 @@ irc_channel_t *irc_channel_new( irc_t *irc, const char *name ) return NULL; ic = g_new0( irc_channel_t, 1 ); + ic->f = &control_channel_funcs; ic->irc = irc; ic->name = g_strdup( name ); strcpy( ic->mode, CMODE ); @@ -131,3 +134,15 @@ gboolean irc_channel_name_ok( const char *name ) { return strchr( CTYPES, name[0] ) != NULL && nick_ok( name + 1 ); } + +/* Channel-type dependent functions, for control channels: */ +static gboolean control_channel_privmsg( irc_channel_t *ic, const char *msg ) +{ + root_command_string( ic->irc, msg ); + + return TRUE; +} + +static const struct irc_channel_funcs control_channel_funcs = { + control_channel_privmsg, +}; diff --git a/irc_commands.c b/irc_commands.c index b06e59bd..e5c6a95f 100644 --- a/irc_commands.c +++ b/irc_commands.c @@ -76,7 +76,7 @@ static void irc_cmd_nick( irc_t *irc, char **cmd ) { irc_send_num( irc, 438, ":The hand of the deity is upon thee, thy nick may not change" ); } - else if( irc_user_find( irc, cmd[1] ) ) + else if( irc_user_by_name( irc, cmd[1] ) ) { irc_send_num( irc, 433, ":This nick is already in use" ); } @@ -159,7 +159,7 @@ static void irc_cmd_part( irc_t *irc, char **cmd ) static void irc_cmd_whois( irc_t *irc, char **cmd ) { char *nick = cmd[1]; - irc_user_t *iu = irc_user_find( irc, nick ); + irc_user_t *iu = irc_user_by_name( irc, nick ); if( iu ) irc_send_whois( iu ); @@ -219,8 +219,6 @@ static void irc_cmd_who( irc_t *irc, char **cmd ) { char *channel = cmd[1]; irc_channel_t *ic; - struct groupchat *c; - GList *l; if( !channel || *channel == '0' || *channel == '*' || !*channel ) irc_send_who( irc, irc->users, "**" ); @@ -230,50 +228,35 @@ static void irc_cmd_who( irc_t *irc, char **cmd ) irc_send_num( irc, 403, "%s :No such channel", channel ); } -#if 0 -//#if 0 -static void irc_cmd_oper( irc_t *irc, char **cmd ) +static void irc_cmd_privmsg( irc_t *irc, char **cmd ) { - if( global.conf->oper_pass && - ( strncmp( global.conf->oper_pass, "md5:", 4 ) == 0 ? - md5_verify_password( cmd[2], global.conf->oper_pass + 4 ) == 0 : - strcmp( cmd[2], global.conf->oper_pass ) == 0 ) ) + irc_channel_t *ic; + irc_user_t *iu; + + if( !cmd[2] ) { - irc_umode_set( irc, "+o", 1 ); - irc_send_num( irc, 381, ":Password accepted" ); + irc_send_num( irc, 412, ":No text to send" ); + } + else if( irc_channel_name_ok( cmd[1] ) && + ( ic = irc_channel_by_name( irc, cmd[1] ) ) ) + { + if( ic->f->privmsg ) + ic->f->privmsg( ic, cmd[2] ); + } + else if( ( iu = irc_user_by_name( irc, cmd[1] ) ) ) + { + if( iu->f->privmsg ) + iu->f->privmsg( iu, cmd[2] ); } else { - irc_send_num( irc, 432, ":Incorrect password" ); + irc_send_num( irc, 401, "%s :No such nick/channel", cmd[1] ); } -} -static void irc_cmd_invite( irc_t *irc, char **cmd ) -{ - char *nick = cmd[1], *channel = cmd[2]; - struct groupchat *c = irc_chat_by_channel( irc, channel ); - user_t *u = user_find( irc, nick ); - - if( u && c && ( u->ic == c->ic ) ) - if( c->ic && c->ic->acc->prpl->chat_invite ) - { - c->ic->acc->prpl->chat_invite( c, u->handle, NULL ); - irc_send_num( irc, 341, "%s %s", nick, channel ); - return; - } - - irc_send_num( irc, 482, "%s :Invite impossible; User/Channel non-existent or incompatible", channel ); -} -static void irc_cmd_privmsg( irc_t *irc, char **cmd ) -{ - if( !cmd[2] ) - { - irc_send_num( irc, 412, ":No text to send" ); - } +#if 0 else if( irc->nick && g_strcasecmp( cmd[1], irc->nick ) == 0 ) { - irc_write( irc, ":%s!%s@%s %s %s :%s", irc->nick, irc->user, irc->host, cmd[0], cmd[1], cmd[2] ); } else { @@ -314,6 +297,44 @@ static void irc_cmd_privmsg( irc_t *irc, char **cmd ) } irc_send( irc, cmd[1], cmd[2], ( g_strcasecmp( cmd[0], "NOTICE" ) == 0 ) ? OPT_AWAY : 0 ); } +#endif +} + + + +#if 0 +//#if 0 +static void irc_cmd_oper( irc_t *irc, char **cmd ) +{ + if( global.conf->oper_pass && + ( strncmp( global.conf->oper_pass, "md5:", 4 ) == 0 ? + md5_verify_password( cmd[2], global.conf->oper_pass + 4 ) == 0 : + strcmp( cmd[2], global.conf->oper_pass ) == 0 ) ) + { + irc_umode_set( irc, "+o", 1 ); + irc_send_num( irc, 381, ":Password accepted" ); + } + else + { + irc_send_num( irc, 432, ":Incorrect password" ); + } +} + +static void irc_cmd_invite( irc_t *irc, char **cmd ) +{ + char *nick = cmd[1], *channel = cmd[2]; + struct groupchat *c = irc_chat_by_channel( irc, channel ); + user_t *u = user_find( irc, nick ); + + if( u && c && ( u->ic == c->ic ) ) + if( c->ic && c->ic->acc->prpl->chat_invite ) + { + c->ic->acc->prpl->chat_invite( c, u->handle, NULL ); + irc_send_num( irc, 341, "%s %s", nick, channel ); + return; + } + + irc_send_num( irc, 482, "%s :Invite impossible; User/Channel non-existent or incompatible", channel ); } static void irc_cmd_userhost( irc_t *irc, char **cmd ) @@ -554,10 +575,10 @@ static const command_t irc_commands[] = { { "motd", 0, irc_cmd_motd, IRC_CMD_LOGGED_IN }, { "mode", 1, irc_cmd_mode, IRC_CMD_LOGGED_IN }, { "who", 0, irc_cmd_who, IRC_CMD_LOGGED_IN }, + { "privmsg", 1, irc_cmd_privmsg, IRC_CMD_LOGGED_IN }, #if 0 { "oper", 2, irc_cmd_oper, IRC_CMD_LOGGED_IN }, { "invite", 2, irc_cmd_invite, IRC_CMD_LOGGED_IN }, - { "privmsg", 1, irc_cmd_privmsg, IRC_CMD_LOGGED_IN }, { "notice", 1, irc_cmd_privmsg, IRC_CMD_LOGGED_IN }, { "userhost", 1, irc_cmd_userhost, IRC_CMD_LOGGED_IN }, { "ison", 1, irc_cmd_ison, IRC_CMD_LOGGED_IN }, @@ -146,10 +146,8 @@ void irc_send_part( irc_channel_t *ic, irc_user_t *iu, const char *reason ) void irc_send_names( irc_channel_t *ic ) { GSList *l; - irc_user_t *iu; char namelist[385] = ""; - struct groupchat *c = NULL; - char *ops = set_getstr( &ic->irc->b->set, "ops" ); + //char *ops = set_getstr( &ic->irc->b->set, "ops" ); /* RFCs say there is no error reply allowed on NAMES, so when the channel is invalid, just give an empty reply. */ @@ -239,3 +237,9 @@ void irc_send_who( irc_t *irc, GSList *l, const char *channel ) irc_send_num( irc, 315, "%s :End of /WHO list", channel ); } + +void irc_send_msg( irc_user_t *iu, const char *type, const char *dst, const char *msg ) +{ + irc_write( iu->irc, ":%s!%s@%s %s %s :%s", + iu->nick, iu->user, iu->host, type, dst, msg ); +} @@ -50,7 +50,7 @@ int irc_user_free( irc_t *irc, const char *nick ) { irc_user_t *iu; - if( !( iu = irc_user_find( irc, nick ) ) ) + if( !( iu = irc_user_by_name( irc, nick ) ) ) return 0; irc->users = g_slist_remove( irc->users, iu ); @@ -67,7 +67,7 @@ int irc_user_free( irc_t *irc, const char *nick ) return 1; } -irc_user_t *irc_user_find( irc_t *irc, const char *nick ) +irc_user_t *irc_user_by_name( irc_t *irc, const char *nick ) { char key[strlen(nick)+1]; @@ -80,11 +80,11 @@ irc_user_t *irc_user_find( irc_t *irc, const char *nick ) int irc_user_rename( irc_t *irc, const char *old, const char *new ) { - irc_user_t *iu = irc_user_find( irc, old ); + irc_user_t *iu = irc_user_by_name( irc, old ); char key[strlen(new)+1]; strcpy( key, new ); - if( iu == NULL || !nick_lc( key ) || irc_user_find( irc, new ) ) + if( iu == NULL || !nick_lc( key ) || irc_user_by_name( irc, new ) ) return 0; irc->users = g_slist_remove( irc->users, iu ); @@ -112,3 +112,27 @@ gint irc_user_cmp( gconstpointer a_, gconstpointer b_ ) return strcmp( a->key, b->key ); } + +/* User-type dependent functions, for root/NickServ: */ +static gboolean root_privmsg( irc_user_t *iu, const char *msg ) +{ + root_command_string( iu->irc, msg ); + + return TRUE; +} + +const struct irc_user_funcs irc_user_root_funcs = { + root_privmsg, +}; + +/* Echo to yourself: */ +static gboolean self_privmsg( irc_user_t *iu, const char *msg ) +{ + irc_send_msg( iu, "PRIVMSG", iu->nick, msg ); + + return TRUE; +} + +const struct irc_user_funcs irc_user_self_funcs = { + self_privmsg, +}; @@ -95,7 +95,7 @@ void nick_dedupe( account_t *acc, const char *handle, char nick[MAX_NICK_LENGTH+ /* Now, find out if the nick is already in use at the moment, and make subtle changes to make it unique. */ - while( !nick_ok( nick ) || irc_user_find( acc->irc, nick ) ) + while( !nick_ok( nick ) || irc_user_by_name( acc->irc, nick ) ) { if( strlen( nick ) < ( MAX_NICK_LENGTH - 1 ) ) { diff --git a/root_commands.c b/root_commands.c index d3b0c7d3..9b396379 100644 --- a/root_commands.c +++ b/root_commands.c @@ -31,7 +31,7 @@ #include <string.h> -void root_command_string( irc_t *irc, user_t *u, char *command, int flags ) +void root_command_string( irc_t *irc, char *command ) { char *cmd[IRC_MAX_ARGS]; char *s; @@ -135,6 +135,7 @@ static void cmd_help( irc_t *irc, char **cmd ) } } +#if 0 static void cmd_account( irc_t *irc, char **cmd ); static void cmd_identify( irc_t *irc, char **cmd ) @@ -1216,9 +1217,11 @@ static void cmd_transfer( irc_t *irc, char **cmd ) } } } +#endif const command_t commands[] = { { "help", 0, cmd_help, 0 }, +#if 0 { "identify", 1, cmd_identify, 0 }, { "register", 1, cmd_register, 0 }, { "drop", 1, cmd_drop, 0 }, @@ -1239,5 +1242,6 @@ const command_t commands[] = { { "join_chat", 2, cmd_join_chat, 0 }, { "chat", 1, cmd_chat, 0 }, { "transfer", 0, cmd_transfer, 0 }, +#endif { NULL } }; |