aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWilmer van der Gaast <wilmer@gaast.net>2010-03-27 13:36:47 -0400
committerWilmer van der Gaast <wilmer@gaast.net>2010-03-27 13:36:47 -0400
commit280c56a7b24dc08b35a1ecd98c8f4b61435d1100 (patch)
tree81340377a433898775385ee070beea1e4ea5e65b
parent2f53ada73d7d43b538c157563ab5eb39b7592137 (diff)
Added privmsg handlers to users/channels. root commands are coming back.
-rw-r--r--Makefile2
-rw-r--r--irc.c3
-rw-r--r--irc.h25
-rw-r--r--irc_channel.c15
-rw-r--r--irc_commands.c99
-rw-r--r--irc_send.c10
-rw-r--r--irc_user.c32
-rw-r--r--nick.c2
-rw-r--r--root_commands.c6
9 files changed, 142 insertions, 52 deletions
diff --git a/Makefile b/Makefile
index 9e300c12..ed0316a4 100644
--- a/Makefile
+++ b/Makefile
@@ -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
diff --git a/irc.c b/irc.c
index 6dc88825..51bf8acd 100644
--- a/irc.c
+++ b/irc.c
@@ -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 );
diff --git a/irc.h b/irc.h
index 33f25538..b72fdf76 100644
--- a/irc.h
+++ b/irc.h
@@ -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 },
diff --git a/irc_send.c b/irc_send.c
index 97fb3071..23298ef4 100644
--- a/irc_send.c
+++ b/irc_send.c
@@ -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 );
+}
diff --git a/irc_user.c b/irc_user.c
index 1de0c4e3..a54fc09e 100644
--- a/irc_user.c
+++ b/irc_user.c
@@ -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,
+};
diff --git a/nick.c b/nick.c
index 6d798bc6..002d2501 100644
--- a/nick.c
+++ b/nick.c
@@ -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 }
};