diff options
| author | Wilmer van der Gaast <wilmer@gaast.net> | 2010-03-26 22:39:08 -0400 | 
|---|---|---|
| committer | Wilmer van der Gaast <wilmer@gaast.net> | 2010-03-26 22:39:08 -0400 | 
| commit | 4be823968d7f4cb1d11e4f6dda50ef606a0fd7b0 (patch) | |
| tree | 09ddd4ba6099791125506b54cf94f7bd08d4ee2c | |
| parent | ebaebfe35c82460581fa6db518d8848996c9a0f4 (diff) | |
Simple IRC channel interface, use it to represent the control channel.
| -rw-r--r-- | Makefile | 2 | ||||
| -rw-r--r-- | irc.c | 32 | ||||
| -rw-r--r-- | irc.h | 31 | ||||
| -rw-r--r-- | irc_channel.c | 88 | ||||
| -rw-r--r-- | irc_send.c | 97 | ||||
| -rw-r--r-- | protocols/bee.o | bin | 8692 -> 0 bytes | 
6 files changed, 216 insertions, 34 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_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 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 @@ -585,7 +585,39 @@ int irc_check_login( irc_t *irc )  		}  		else  		{ +			irc_channel_t *ic; +			irc_user_t *iu = irc->user; +			 +			irc->user = irc_user_new( irc, iu->nick ); +			irc->user->user = iu->user; +			irc->user->fullname = iu->fullname; +			g_free( iu->nick ); +			g_free( iu ); +			 +			irc->umode[0] = '\0'; +			/*irc_umode_set( irc, "+" UMODE, 1 );*/ +			 +			if( global.conf->runmode == RUNMODE_FORKDAEMON || global.conf->runmode == RUNMODE_DAEMON ) +				ipc_to_master_str( "CLIENT %s %s :%s\r\n", irc->user->host, irc->user->nick, irc->user->fullname ); +			 +			irc->status |= USTATUS_LOGGED_IN; +			 +			/* This is for bug #209 (use PASS to identify to NickServ). */ +			if( irc->password != NULL ) +			{ +				char *send_cmd[] = { "identify", g_strdup( irc->password ), NULL }; +				 +				/*irc_setpass( irc, NULL );*/ +				/*root_command( irc, send_cmd );*/ +				g_free( send_cmd[1] ); +			} +			  			irc_send_login( irc ); +			 +			ic = irc_channel_new( irc, ROOT_CHAN ); +			irc_channel_set_topic( ic, CONTROL_TOPIC ); +			irc_channel_add_user( ic, irc->user ); +			  			return 1;  		}  	} @@ -72,9 +72,8 @@ typedef struct irc  	struct query *queries;  	struct account *accounts;  	GSList *file_transfers; -	struct chat *chatrooms; -	GSList *users; +	GSList *users, *channels;  	GHashTable *nick_user_hash;  	GHashTable *watches; @@ -105,6 +104,22 @@ typedef struct irc_user  	//struct user *b;  } irc_user_t; +typedef enum +{ +	IRC_CHANNEL_JOINED = 1, +} irc_channel_flags_t; + +typedef struct irc_channel +{ +	irc_t *irc; +	int flags; +	char *name; +	char *topic; +	char mode[8]; +	GSList *users; +	struct set *set; +} irc_channel_t; +  #include "user.h"  /* irc.c */ @@ -124,6 +139,12 @@ void irc_vawrite( irc_t *irc, char *format, va_list params );  int irc_check_login( irc_t *irc ); +/* irc_channel.c */ +irc_channel_t *irc_channel_new( irc_t *irc, const char *name ); +int irc_channel_add_user( irc_channel_t *ic, irc_user_t *iu ); +int irc_channel_del_user( irc_channel_t *ic, irc_user_t *iu ); +int irc_channel_set_topic( irc_channel_t *ic, const char *topic ); +  /* irc_commands.c */  void irc_exec( irc_t *irc, char **cmd ); @@ -131,7 +152,11 @@ void irc_exec( irc_t *irc, char **cmd );  void irc_send_num( irc_t *irc, int code, char *format, ... ) G_GNUC_PRINTF( 3, 4 );  void irc_send_login( irc_t *irc );  void irc_send_motd( irc_t *irc ); -int irc_usermsg( irc_t *irc, char *format, ... ); +void irc_usermsg( irc_t *irc, char *format, ... ); +void irc_send_join( irc_channel_t *ic, irc_user_t *iu ); +void irc_send_part( irc_channel_t *ic, irc_user_t *iu, const char *reason ); +void irc_send_names( irc_channel_t *ic ); +void irc_send_topic( irc_channel_t *ic );  /* irc_user.c */  irc_user_t *irc_user_new( irc_t *irc, const char *nick ); diff --git a/irc_channel.c b/irc_channel.c new file mode 100644 index 00000000..3db01ee5 --- /dev/null +++ b/irc_channel.c @@ -0,0 +1,88 @@ +  /********************************************************************\ +  * BitlBee -- An IRC to other IM-networks gateway                     * +  *                                                                    * +  * Copyright 2002-2010 Wilmer van der Gaast and others                * +  \********************************************************************/ + +/* The IRC-based UI - Representing (virtual) channels.                  */ + +/* +  This program is free software; you can redistribute it and/or modify +  it under the terms of the GNU General Public License as published by +  the Free Software Foundation; either version 2 of the License, or +  (at your option) any later version. + +  This program is distributed in the hope that it will be useful, +  but WITHOUT ANY WARRANTY; without even the implied warranty of +  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the +  GNU General Public License for more details. + +  You should have received a copy of the GNU General Public License with +  the Debian GNU/Linux distribution in /usr/share/common-licenses/GPL; +  if not, write to the Free Software Foundation, Inc., 59 Temple Place, +  Suite 330, Boston, MA  02111-1307  USA +*/ + +#include "bitlbee.h" + +irc_channel_t *irc_channel_new( irc_t *irc, const char *name ) +{ +	irc_channel_t *ic; +	 +	if( strchr( CTYPES, name[0] ) == NULL || !nick_ok( name + 1 ) ) +		return NULL; +	 +	ic = g_new0( irc_channel_t, 1 ); +	ic->irc = irc; +	ic->name = g_strdup( name ); +	strcpy( ic->mode, CMODE ); +	 +	irc_channel_add_user( ic, irc->root ); +	 +	irc->channels = g_slist_prepend( irc->channels, ic ); +	 +	return ic; +} + +int irc_channel_add_user( irc_channel_t *ic, irc_user_t *iu ) +{ +	if( g_slist_find( ic->users, iu ) != NULL ) +		return 0; +	 +	ic->users = g_slist_insert_sorted( ic->users, iu, irc_user_cmp ); +	 +	if( iu == ic->irc->user || ic->flags & IRC_CHANNEL_JOINED ) +	{ +		ic->flags |= IRC_CHANNEL_JOINED; +		irc_send_join( ic, iu ); +	} +	 +	return 1; +} + +int irc_channel_del_user( irc_channel_t *ic, irc_user_t *iu ) +{ +	if( g_slist_find( ic->users, iu ) == NULL ) +		return 0; +	 +	ic->users = g_slist_remove( ic->users, iu ); +	 +	if( ic->flags & IRC_CHANNEL_JOINED ) +		irc_send_part( ic, iu, "" ); +	 +	if( iu == ic->irc->user ) +		ic->flags &= ~IRC_CHANNEL_JOINED; +	 +	return 1; +} + +int irc_channel_set_topic( irc_channel_t *ic, const char *topic ) +{ +	g_free( ic->topic ); +	ic->topic = g_strdup( topic ); +	 +	if( ic->flags & IRC_CHANNEL_JOINED ) +		irc_send_topic( ic ); +	 +	return 1; +} @@ -33,21 +33,12 @@ void irc_send_num( irc_t *irc, int code, char *format, ... )  	va_start( params, format );  	g_vsnprintf( text, IRC_MAX_LINE, format, params );  	va_end( params ); -	irc_write( irc, ":%s %03d %s %s", irc->root->host, code, irc->user->nick ? : "*", text ); -	return; +	irc_write( irc, ":%s %03d %s %s", irc->root->host, code, irc->user->nick ? : "*", text );  }  void irc_send_login( irc_t *irc )  { -	irc_user_t *iu = irc->user; -	 -	irc->user = irc_user_new( irc, iu->nick ); -	irc->user->user = iu->user; -	irc->user->fullname = iu->fullname; -	g_free( iu->nick ); -	g_free( iu ); -	  	irc_send_num( irc,   1, ":Welcome to the BitlBee gateway, %s", irc->user->nick );  	irc_send_num( irc,   2, ":Host %s is running BitlBee " BITLBEE_VERSION " " ARCH "/" CPU ".", irc->root->host );  	irc_send_num( irc,   3, ":%s", IRCD_INFO ); @@ -56,8 +47,6 @@ void irc_send_login( irc_t *irc )  	                        "CASEMAPPING=rfc1459 MAXTARGETS=1 WATCH=128 :are supported by this server",  	                        CTYPES, CMODES, MAX_NICK_LENGTH - 1 );  	irc_send_motd( irc ); -	irc->umode[0] = '\0'; -	/*irc_umode_set( irc, "+" UMODE, 1 );*/  	irc_usermsg( irc, "Welcome to the BitlBee gateway!\n\n"  	                  "If you've never used BitlBee before, please do read the help " @@ -65,21 +54,6 @@ void irc_send_login( irc_t *irc )  	                  "answered there.\n"  	                  "If you already have an account on this server, just use the "  	                  "\x02identify\x02 command to identify yourself." ); -	 -	if( global.conf->runmode == RUNMODE_FORKDAEMON || global.conf->runmode == RUNMODE_DAEMON ) -		ipc_to_master_str( "CLIENT %s %s :%s\r\n", irc->user->host, irc->user->nick, irc->user->fullname ); -	 -	irc->status |= USTATUS_LOGGED_IN; -	 -	/* This is for bug #209 (use PASS to identify to NickServ). */ -	if( irc->password != NULL ) -	{ -		char *send_cmd[] = { "identify", g_strdup( irc->password ), NULL }; -		 -		/*irc_setpass( irc, NULL );*/ -		/*root_command( irc, send_cmd );*/ -		g_free( send_cmd[1] ); -	}  }  void irc_send_motd( irc_t *irc ) @@ -135,7 +109,7 @@ void irc_send_motd( irc_t *irc )  }  /* FIXME/REPLACEME */ -int irc_usermsg( irc_t *irc, char *format, ... ) +void irc_usermsg( irc_t *irc, char *format, ... )  {  	char text[1024];  	va_list params; @@ -147,7 +121,70 @@ int irc_usermsg( irc_t *irc, char *format, ... )  	fprintf( stderr, "%s\n", text ); -	return 1; -	  	/*return( irc_msgfrom( irc, u->nick, text ) );*/  } + +void irc_send_join( irc_channel_t *ic, irc_user_t *iu ) +{ +	irc_t *irc = ic->irc; +	 +	irc_write( irc, ":%s!%s@%s JOIN :%s", iu->nick, iu->user, iu->host, ic->name ); +	 +	if( iu == irc->user ) +	{ +		irc_write( irc, ":%s MODE %s +%s", irc->root->host, ic->name, ic->mode ); +		irc_send_names( ic ); +		irc_send_topic( ic ); +	} +} + +void irc_send_part( irc_channel_t *ic, irc_user_t *iu, const char *reason ) +{ +	irc_write( ic->irc, ":%s!%s@%s PART %s :%s", iu->nick, iu->user, iu->host, ic->name, 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" ); +	 +	/* RFCs say there is no error reply allowed on NAMES, so when the +	   channel is invalid, just give an empty reply. */ +	for( l = ic->users; l; l = l->next ) +	{ +		irc_user_t *iu = l->data; +		 +		if( strlen( namelist ) + strlen( iu->nick ) > sizeof( namelist ) - 4 ) +		{ +			irc_send_num( ic->irc, 353, "= %s :%s", ic->name, namelist ); +			*namelist = 0; +		} +		 +		/* +		if( u->ic && !u->away && set_getbool( &irc->set, "away_devoice" ) ) +			strcat( namelist, "+" ); +		else if( ( strcmp( u->nick, irc->mynick ) == 0 && ( strcmp( ops, "root" ) == 0 || strcmp( ops, "both" ) == 0 ) ) || +		         ( strcmp( u->nick, irc->nick ) == 0 && ( strcmp( ops, "user" ) == 0 || strcmp( ops, "both" ) == 0 ) ) ) +			strcat( namelist, "@" ); +		*/ +		 +		strcat( namelist, iu->nick ); +		strcat( namelist, " " ); +	} +	 +	if( *namelist ) +		irc_send_num( ic->irc, 353, "= %s :%s", ic->name, namelist ); +	 +	irc_send_num( ic->irc, 366, "%s :End of /NAMES list", ic->name ); +} + +void irc_send_topic( irc_channel_t *ic ) +{ +	if( ic->topic ) +		irc_send_num( ic->irc, 332, "%s :%s", ic->name, ic->topic ); +	else +		irc_send_num( ic->irc, 331, "%s :No topic for this channel", ic->name ); +} diff --git a/protocols/bee.o b/protocols/bee.oBinary files differ deleted file mode 100644 index 38c9044f..00000000 --- a/protocols/bee.o +++ /dev/null | 
