irc_channel_t *irc_channel_new(irc_t *irc, const char *name) { irc_channel_t *ic; set_t *s; if (!irc_channel_name_ok(name) || irc_channel_by_name(irc, name)) { 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_append(irc->channels, ic); set_add(&ic->set, "auto_join", "false", set_eval_bool, ic); s = set_add(&ic->set, "type", "control", set_eval_channel_type, ic); s->flags |= SET_NOSAVE; /* Layer violation (XML format detail) */ if (name[0] == '&') { set_setstr(&ic->set, "type", "control"); } else { /* if( name[0] == '#' ) */ set_setstr(&ic->set, "type", "chat"); } return ic; }
void bee_irc_channel_update( irc_t *irc, irc_channel_t *ic, irc_user_t *iu ) { GSList *l; if( ic == NULL ) { for( l = irc->channels; l; l = l->next ) { ic = l->data; /* TODO: Just add a type flag or so.. */ if( ic->f == irc->default_channel->f && ( ic->flags & IRC_CHANNEL_JOINED ) ) bee_irc_channel_update( irc, ic, iu ); } return; } if( iu == NULL ) { for( l = irc->users; l; l = l->next ) { iu = l->data; if( iu->bu ) bee_irc_channel_update( irc, ic, l->data ); } return; } if( !irc_channel_wants_user( ic, iu ) ) { irc_channel_del_user( ic, iu, IRC_CDU_PART, NULL ); } else { struct irc_control_channel *icc = ic->data; int mode = 0; if( !( iu->bu->flags & BEE_USER_ONLINE ) ) mode = icc->modes[0]; else if( iu->bu->flags & BEE_USER_AWAY ) mode = icc->modes[1]; else mode = icc->modes[2]; if( !mode ) irc_channel_del_user( ic, iu, IRC_CDU_PART, NULL ); else { irc_channel_add_user( ic, iu ); irc_channel_user_set_mode( ic, iu, mode ); } } }
static void irc_cmd_join( irc_t *irc, char **cmd ) { char *comma, *s = cmd[1]; while( s ) { irc_channel_t *ic; if( ( comma = strchr( s, ',' ) ) ) *comma = '\0'; if( ( ic = irc_channel_by_name( irc, s ) ) == NULL && ( ic = irc_channel_new( irc, s ) ) ) { if( strcmp( set_getstr( &ic->set, "type" ), "control" ) != 0 ) { /* Autoconfiguration is for control channels only ATM. */ } else if( bee_group_by_name( ic->irc->b, ic->name + 1, FALSE ) ) { set_setstr( &ic->set, "group", ic->name + 1 ); set_setstr( &ic->set, "fill_by", "group" ); } else if( set_setstr( &ic->set, "protocol", ic->name + 1 ) ) { set_setstr( &ic->set, "fill_by", "protocol" ); } else if( set_setstr( &ic->set, "account", ic->name + 1 ) ) { set_setstr( &ic->set, "fill_by", "account" ); } else { /* The set commands above will run this already, but if we didn't hit any, we have to fill the channel with the default population. */ bee_irc_channel_update( ic->irc, ic, NULL ); } } else if( ic == NULL ) { irc_send_num( irc, 479, "%s :Invalid channel name", s ); goto next; } if( ic->flags & IRC_CHANNEL_JOINED ) /* Dude, you're already there... RFC doesn't have any reply for that though? */ goto next; if( ic->f->join && !ic->f->join( ic ) ) /* The story is: FALSE either means the handler showed an error message, or is doing some work before the join should be confirmed. (In the latter case, the caller should take care of that confirmation.) TRUE means all's good, let the user join the channel right away. */ goto next; irc_channel_add_user( ic, irc->user ); next: if( comma ) { s = comma + 1; *comma = ','; } else break; } }