aboutsummaryrefslogtreecommitdiffstats
path: root/irc.c
diff options
context:
space:
mode:
authorJelmer Vernooij <jelmer@samba.org>2006-12-05 21:40:17 +0100
committerJelmer Vernooij <jelmer@samba.org>2006-12-05 21:40:17 +0100
commitd8d63a27dcfd38245927af95521b6f8918b23795 (patch)
tree75e4675b12970db6645c087ab75ec35c1b1ba9fd /irc.c
parentf4aa393b221dcc709f189ed04945ee67e956872a (diff)
parent55078f59c8e9f52f1d10bed55511e5e58ec3e53b (diff)
[merge] wilmer
Diffstat (limited to 'irc.c')
-rw-r--r--irc.c176
1 files changed, 78 insertions, 98 deletions
diff --git a/irc.c b/irc.c
index 816b69d9..f9654034 100644
--- a/irc.c
+++ b/irc.c
@@ -32,10 +32,13 @@ static gboolean irc_userping( gpointer _irc, int fd, b_input_condition cond );
GSList *irc_connection_list = NULL;
-static char *passchange (irc_t *irc, void *set, char *value)
+static char *passchange( set_t *set, char *value )
{
- irc_setpass (irc, value);
- return (NULL);
+ irc_t *irc = set->data;
+
+ irc_setpass( irc, value );
+ irc_usermsg( irc, "Password successfully changed" );
+ return NULL;
}
irc_t *irc_new( int fd )
@@ -45,10 +48,10 @@ irc_t *irc_new( int fd )
unsigned int i;
char buf[128];
#ifdef IPV6
- struct sockaddr_in6 sock[1];
-#else
- struct sockaddr_in sock[1];
+ struct sockaddr_in6 sock6[1];
+ unsigned int i6;
#endif
+ struct sockaddr_in sock[1];
irc = g_new0( irc_t, 1 );
@@ -68,45 +71,48 @@ irc_t *irc_new( int fd )
irc->channel = g_strdup( ROOT_CHAN );
i = sizeof( *sock );
+#ifdef IPV6
+ i6 = sizeof( *sock6 );
+#endif
if( global.conf->hostname )
irc->myhost = g_strdup( global.conf->hostname );
#ifdef IPV6
- else if( getsockname( irc->fd, (struct sockaddr*) sock, &i ) == 0 && sock->sin6_family == AF_INETx )
+ else if( getsockname( irc->fd, (struct sockaddr*) sock6, &i6 ) == 0 && sock6->sin6_family == AF_INET6 )
{
- if( ( peer = gethostbyaddr( (char*) &sock->sin6_addr, sizeof( sock->sin6_addr ), AF_INETx ) ) )
+ if( ( peer = gethostbyaddr( (char*) &sock6->sin6_addr, sizeof( sock6->sin6_addr ), AF_INET6 ) ) )
irc->myhost = g_strdup( peer->h_name );
- else if( inet_ntop( AF_INETx, &sock->sin6_addr, buf, sizeof( buf ) - 1 ) != NULL )
+ else if( inet_ntop( AF_INET6, &sock6->sin6_addr, buf, sizeof( buf ) - 1 ) != NULL )
irc->myhost = g_strdup( ipv6_unwrap( buf ) );
}
-#else
- else if( getsockname( irc->fd, (struct sockaddr*) sock, &i ) == 0 && sock->sin_family == AF_INETx )
+#endif
+ else if( getsockname( irc->fd, (struct sockaddr*) sock, &i ) == 0 && sock->sin_family == AF_INET )
{
- if( ( peer = gethostbyaddr( (char*) &sock->sin_addr, sizeof( sock->sin_addr ), AF_INETx ) ) )
+ if( ( peer = gethostbyaddr( (char*) &sock->sin_addr, sizeof( sock->sin_addr ), AF_INET ) ) )
irc->myhost = g_strdup( peer->h_name );
- else if( inet_ntop( AF_INETx, &sock->sin_addr, buf, sizeof( buf ) - 1 ) != NULL )
+ else if( inet_ntop( AF_INET, &sock->sin_addr, buf, sizeof( buf ) - 1 ) != NULL )
irc->myhost = g_strdup( buf );
}
-#endif
i = sizeof( *sock );
#ifdef IPV6
- if( getpeername( irc->fd, (struct sockaddr*) sock, &i ) == 0 && sock->sin6_family == AF_INETx )
+ i6 = sizeof( *sock6 );
+ if( getpeername( irc->fd, (struct sockaddr*) sock6, &i6 ) == 0 && sock6->sin6_family == AF_INET6 )
{
- if( ( peer = gethostbyaddr( (char*) &sock->sin6_addr, sizeof( sock->sin6_addr ), AF_INETx ) ) )
+ if( ( peer = gethostbyaddr( (char*) &sock6->sin6_addr, sizeof( sock6->sin6_addr ), AF_INET6 ) ) )
irc->host = g_strdup( peer->h_name );
- else if( inet_ntop( AF_INETx, &sock->sin6_addr, buf, sizeof( buf ) - 1 ) != NULL )
+ else if( inet_ntop( AF_INET6, &sock6->sin6_addr, buf, sizeof( buf ) - 1 ) != NULL )
irc->host = g_strdup( ipv6_unwrap( buf ) );
}
-#else
- if( getpeername( irc->fd, (struct sockaddr*) sock, &i ) == 0 && sock->sin_family == AF_INETx )
+ else
+#endif
+ if( getpeername( irc->fd, (struct sockaddr*) sock, &i ) == 0 && sock->sin_family == AF_INET )
{
- if( ( peer = gethostbyaddr( (char*) &sock->sin_addr, sizeof( sock->sin_addr ), AF_INETx ) ) )
+ if( ( peer = gethostbyaddr( (char*) &sock->sin_addr, sizeof( sock->sin_addr ), AF_INET ) ) )
irc->host = g_strdup( peer->h_name );
- else if( inet_ntop( AF_INETx, &sock->sin_addr, buf, sizeof( buf ) - 1 ) != NULL )
+ else if( inet_ntop( AF_INET, &sock->sin_addr, buf, sizeof( buf ) - 1 ) != NULL )
irc->host = g_strdup( buf );
}
-#endif
/* Rare, but possible. */
if( !irc->host ) irc->host = g_strdup( "localhost." );
@@ -119,26 +125,26 @@ irc_t *irc_new( int fd )
irc_connection_list = g_slist_append( irc_connection_list, irc );
- set_add( irc, "away_devoice", "true", set_eval_away_devoice );
- set_add( irc, "auto_connect", "true", set_eval_bool );
- set_add( irc, "auto_reconnect", "false", set_eval_bool );
- set_add( irc, "auto_reconnect_delay", "300", set_eval_int );
- set_add( irc, "buddy_sendbuffer", "false", set_eval_bool );
- set_add( irc, "buddy_sendbuffer_delay", "200", set_eval_int );
- set_add( irc, "charset", "iso8859-1", set_eval_charset );
- set_add( irc, "debug", "false", set_eval_bool );
- set_add( irc, "default_target", "root", NULL );
- set_add( irc, "display_namechanges", "false", set_eval_bool );
- set_add( irc, "handle_unknown", "root", NULL );
- set_add( irc, "lcnicks", "true", set_eval_bool );
- set_add( irc, "ops", "both", set_eval_ops );
- set_add( irc, "private", "true", set_eval_bool );
- set_add( irc, "query_order", "lifo", NULL );
- set_add( irc, "save_on_quit", "true", set_eval_bool );
- set_add( irc, "strip_html", "true", NULL );
- set_add( irc, "to_char", ": ", set_eval_to_char );
- set_add( irc, "typing_notice", "false", set_eval_bool );
- set_add( irc, "password", NULL, passchange);
+ set_add( &irc->set, "away_devoice", "true", set_eval_away_devoice, irc );
+ set_add( &irc->set, "auto_connect", "true", set_eval_bool, irc );
+ set_add( &irc->set, "auto_reconnect", "false", set_eval_bool, irc );
+ set_add( &irc->set, "auto_reconnect_delay", "300", set_eval_int, irc );
+ set_add( &irc->set, "buddy_sendbuffer", "false", set_eval_bool, irc );
+ set_add( &irc->set, "buddy_sendbuffer_delay", "200", set_eval_int, irc );
+ set_add( &irc->set, "charset", "iso8859-1", set_eval_charset, irc );
+ set_add( &irc->set, "debug", "false", set_eval_bool, irc );
+ set_add( &irc->set, "default_target", "root", NULL, irc );
+ set_add( &irc->set, "display_namechanges", "false", set_eval_bool, irc );
+ set_add( &irc->set, "handle_unknown", "root", NULL, irc );
+ set_add( &irc->set, "lcnicks", "true", set_eval_bool, irc );
+ set_add( &irc->set, "ops", "both", set_eval_ops, irc );
+ set_add( &irc->set, "password", NULL, passchange, irc );
+ set_add( &irc->set, "private", "true", set_eval_bool, irc );
+ set_add( &irc->set, "query_order", "lifo", NULL, irc );
+ set_add( &irc->set, "save_on_quit", "true", set_eval_bool, irc );
+ set_add( &irc->set, "strip_html", "true", NULL, irc );
+ set_add( &irc->set, "to_char", ": ", set_eval_to_char, irc );
+ set_add( &irc->set, "typing_notice", "false", set_eval_bool, irc );
conf_loaddefaults( irc );
@@ -202,15 +208,13 @@ static gboolean irc_free_hashkey( gpointer key, gpointer value, gpointer data )
/* Because we have no garbage collection, this is quite annoying */
void irc_free(irc_t * irc)
{
- account_t *account, *accounttmp;
+ account_t *account;
user_t *user, *usertmp;
- nick_t *nick, *nicktmp;
help_t *helpnode, *helpnodetmp;
- set_t *setnode, *setnodetmp;
log_message( LOGLVL_INFO, "Destroying connection with fd %d", irc->fd );
- if( irc->status & USTATUS_IDENTIFIED && set_getint( irc, "save_on_quit" ) )
+ if( irc->status & USTATUS_IDENTIFIED && set_getbool( &irc->set, "save_on_quit" ) )
if( storage_save( irc, TRUE ) != STORAGE_OK )
irc_usermsg( irc, "Error while saving settings!" );
@@ -250,17 +254,11 @@ void irc_free(irc_t * irc)
while (irc->queries != NULL)
query_del(irc, irc->queries);
- if (irc->accounts != NULL) {
- account = irc->accounts;
- while (account != NULL) {
- g_free(account->user);
- g_free(account->pass);
- g_free(account->server);
- accounttmp = account;
- account = account->next;
- g_free(accounttmp);
- }
- }
+ while (irc->accounts)
+ account_del(irc, irc->accounts);
+
+ while (irc->set)
+ set_del(&irc->set, irc->set->key);
if (irc->users != NULL) {
user = irc->users;
@@ -285,17 +283,6 @@ void irc_free(irc_t * irc)
g_hash_table_foreach_remove(irc->watches, irc_free_hashkey, NULL);
g_hash_table_destroy(irc->watches);
- if (irc->nicks != NULL) {
- nick = irc->nicks;
- while (nick != NULL) {
- g_free(nick->nick);
- g_free(nick->handle);
-
- nicktmp = nick;
- nick = nick->next;
- g_free(nicktmp);
- }
- }
if (irc->help != NULL) {
helpnode = irc->help;
while (helpnode != NULL) {
@@ -306,18 +293,6 @@ void irc_free(irc_t * irc)
g_free(helpnodetmp);
}
}
- if (irc->set != NULL) {
- setnode = irc->set;
- while (setnode != NULL) {
- g_free(setnode->key);
- g_free(setnode->def);
- g_free(setnode->value);
-
- setnodetmp = setnode;
- setnode = setnode->next;
- g_free(setnodetmp);
- }
- }
g_free(irc);
if( global.conf->runmode == RUNMODE_INETD || global.conf->runmode == RUNMODE_FORKDAEMON )
@@ -328,11 +303,10 @@ void irc_free(irc_t * irc)
Sets pass without checking */
void irc_setpass (irc_t *irc, const char *pass)
{
- if (irc->password) g_free (irc->password);
+ g_free (irc->password);
if (pass) {
irc->password = g_strdup (pass);
- irc_usermsg (irc, "Password successfully changed");
} else {
irc->password = NULL;
}
@@ -363,7 +337,7 @@ void irc_process( irc_t *irc )
break;
}
- if( ( cs = set_getstr( irc, "charset" ) ) && ( g_strcasecmp( cs, "utf-8" ) != 0 ) )
+ if( ( cs = set_getstr( &irc->set, "charset" ) ) && ( g_strcasecmp( cs, "utf-8" ) != 0 ) )
{
conv[IRC_MAX_LINE] = 0;
if( do_iconv( cs, "UTF-8", lines[i], conv, 0, IRC_MAX_LINE - 2 ) != -1 )
@@ -583,7 +557,7 @@ void irc_vawrite( irc_t *irc, char *format, va_list params )
g_vsnprintf( line, IRC_MAX_LINE - 2, format, params );
strip_newlines( line );
- if( ( cs = set_getstr( irc, "charset" ) ) && ( g_strcasecmp( cs, "utf-8" ) != 0 ) )
+ if( ( cs = set_getstr( &irc->set, "charset" ) ) && ( g_strcasecmp( cs, "utf-8" ) != 0 ) )
{
char conv[IRC_MAX_LINE+1];
@@ -610,8 +584,11 @@ void irc_vawrite( irc_t *irc, char *format, va_list params )
immediately. If it returns TRUE, it should be called again, so add the event to
the queue. If it's FALSE, we emptied the buffer and saved ourselves some work
in the event queue. */
- if( bitlbee_io_current_client_write( irc, irc->fd, GAIM_INPUT_WRITE ) )
- irc->w_watch_source_id = b_input_add( irc->fd, GAIM_INPUT_WRITE, bitlbee_io_current_client_write, irc );
+ /* Really can't be done as long as the code doesn't do error checking very well:
+ if( bitlbee_io_current_client_write( irc, irc->fd, GAIM_INPUT_WRITE ) ) */
+
+ /* So just always do it via the event handler. */
+ irc->w_watch_source_id = b_input_add( irc->fd, GAIM_INPUT_WRITE, bitlbee_io_current_client_write, irc );
}
return;
@@ -651,6 +628,7 @@ void irc_names( irc_t *irc, char *channel )
user_t *u;
char namelist[385] = "";
struct conversation *c = NULL;
+ char *ops = set_getstr( &irc->set, "ops" );
/* RFCs say there is no error reply allowed on NAMES, so when the
channel is invalid, just give an empty reply. */
@@ -665,8 +643,11 @@ void irc_names( irc_t *irc, char *channel )
*namelist = 0;
}
- if( u->gc && !u->away && set_getint( irc, "away_devoice" ) )
+ if( u->gc && !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, u->nick );
strcat( namelist, " " );
@@ -675,7 +656,6 @@ void irc_names( irc_t *irc, char *channel )
else if( ( c = conv_findchannel( channel ) ) )
{
GList *l;
- char *ops = set_getstr( irc, "ops" );
/* root and the user aren't in the channel userlist but should
show up in /NAMES, so list them first: */
@@ -923,19 +903,19 @@ void irc_kick( irc_t *irc, user_t *u, char *channel, user_t *kicker )
void irc_kill( irc_t *irc, user_t *u )
{
char *nick, *s;
- char reason[64];
+ char reason[128];
if( u->gc && u->gc->flags & OPT_LOGGING_OUT )
{
- if( u->gc->user->proto_opt[0][0] )
+ if( u->gc->acc->server )
g_snprintf( reason, sizeof( reason ), "%s %s", irc->myhost,
- u->gc->user->proto_opt[0] );
+ u->gc->acc->server );
else if( ( s = strchr( u->gc->username, '@' ) ) )
g_snprintf( reason, sizeof( reason ), "%s %s", irc->myhost,
s + 1 );
else
g_snprintf( reason, sizeof( reason ), "%s %s.%s", irc->myhost,
- u->gc->prpl->name, irc->myhost );
+ u->gc->acc->prpl->name, irc->myhost );
/* proto_opt might contain garbage after the : */
if( ( s = strchr( reason, ':' ) ) )
@@ -1011,13 +991,13 @@ int irc_send( irc_t *irc, char *nick, char *s, int flags )
}
else if( g_strncasecmp( s + 1, "TYPING", 6 ) == 0 )
{
- if( u && u->gc && u->gc->prpl->send_typing && strlen( s ) >= 10 )
+ if( u && u->gc && u->gc->acc->prpl->send_typing && strlen( s ) >= 10 )
{
time_t current_typing_notice = time( NULL );
if( current_typing_notice - u->last_typing_notice >= 5 )
{
- u->gc->prpl->send_typing( u->gc, u->handle, s[8] == '1' );
+ u->gc->acc->prpl->send_typing( u->gc, u->handle, s[8] == '1' );
u->last_typing_notice = current_typing_notice;
}
}
@@ -1050,7 +1030,7 @@ int irc_send( irc_t *irc, char *nick, char *s, int flags )
return 1;
}
}
- else if( c && c->gc && c->gc->prpl )
+ else if( c && c->gc && c->gc->acc && c->gc->acc->prpl )
{
return( bim_chat_msg( c->gc, c->id, s ) );
}
@@ -1082,7 +1062,7 @@ void buddy_send_handler( irc_t *irc, user_t *u, char *msg, int flags )
{
if( !u || !u->gc ) return;
- if( set_getint( irc, "buddy_sendbuffer" ) && set_getint( irc, "buddy_sendbuffer_delay" ) > 0 )
+ if( set_getbool( &irc->set, "buddy_sendbuffer" ) && set_getint( &irc->set, "buddy_sendbuffer_delay" ) > 0 )
{
int delay;
@@ -1109,7 +1089,7 @@ void buddy_send_handler( irc_t *irc, user_t *u, char *msg, int flags )
strcat( u->sendbuf, msg );
strcat( u->sendbuf, "\n" );
- delay = set_getint( irc, "buddy_sendbuffer_delay" );
+ delay = set_getint( &irc->set, "buddy_sendbuffer_delay" );
if( delay <= 5 )
delay *= 1000;
@@ -1174,7 +1154,7 @@ int irc_msgfrom( irc_t *irc, char *nick, char *msg )
{
int len = strlen( irc->nick) + 3;
prefix = g_new (char, len );
- g_snprintf( prefix, len, "%s%s", irc->nick, set_getstr( irc, "to_char" ) );
+ g_snprintf( prefix, len, "%s%s", irc->nick, set_getstr( &irc->set, "to_char" ) );
prefix[len-1] = 0;
}
else