aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--irc.c2
-rw-r--r--irc.h3
-rw-r--r--irc_channel.c50
3 files changed, 54 insertions, 1 deletions
diff --git a/irc.c b/irc.c
index cbbd21a3..e4af555c 100644
--- a/irc.c
+++ b/irc.c
@@ -763,6 +763,8 @@ int irc_check_login( irc_t *irc )
}
}
+/* TODO: This is a mess, but this function is a bit too complicated to be
+ converted to something more generic. */
void irc_umode_set( irc_t *irc, const char *s, gboolean allow_priv )
{
/* allow_priv: Set to 0 if s contains user input, 1 if you want
diff --git a/irc.h b/irc.h
index efc5cd40..aee9dccd 100644
--- a/irc.h
+++ b/irc.h
@@ -35,7 +35,7 @@
#define UMODES "abisw" /* Allowed umodes (although they mostly do nothing) */
#define UMODES_PRIV "Ro" /* Allowed, but not by user directly */
#define UMODES_KEEP "R" /* Don't allow unsetting using /MODE */
-#define CMODES "nt" /* Allowed modes */
+#define CMODES "ntC" /* Allowed modes */
#define CMODE "t" /* Default mode */
#define UMODE "s" /* Default mode */
@@ -249,6 +249,7 @@ int irc_channel_del_user( irc_channel_t *ic, irc_user_t *iu, irc_channel_del_use
irc_channel_user_t *irc_channel_has_user( irc_channel_t *ic, irc_user_t *iu );
int irc_channel_set_topic( irc_channel_t *ic, const char *topic, const irc_user_t *who );
void irc_channel_user_set_mode( irc_channel_t *ic, irc_user_t *iu, irc_channel_user_flags_t flags );
+void irc_channel_set_mode( irc_channel_t *ic, const char *s );
void irc_channel_auto_joins( irc_t *irc, struct account *acc );
void irc_channel_printf( irc_channel_t *ic, char *format, ... );
gboolean irc_channel_name_ok( const char *name );
diff --git a/irc_channel.c b/irc_channel.c
index dfb2161e..0498cffa 100644
--- a/irc_channel.c
+++ b/irc_channel.c
@@ -323,6 +323,50 @@ void irc_channel_user_set_mode( irc_channel_t *ic, irc_user_t *iu, irc_channel_u
icu->flags = flags;
}
+void irc_channel_set_mode( irc_channel_t *ic, const char *s )
+{
+ irc_t *irc = ic->irc;
+ char m[128], st = 1;
+ const char *t;
+ int i;
+ char changes[512], *p, st2 = 2;
+
+ memset( m, 0, sizeof( m ) );
+
+ for( t = ic->mode; *t; t ++ )
+ if( *t < sizeof( m ) )
+ m[(int)*t] = 1;
+
+ p = changes;
+ for( t = s; *t; t ++ )
+ {
+ if( *t == '+' || *t == '-' )
+ st = *t == '+';
+ else if( strchr( CMODES, *t ) )
+ {
+ if( m[(int)*t] != st)
+ {
+ if( st != st2 )
+ st2 = st, *p++ = st ? '+' : '-';
+ *p++ = *t;
+ }
+ m[(int)*t] = st;
+ }
+ }
+ *p = '\0';
+
+ memset( ic->mode, 0, sizeof( ic->mode ) );
+
+ for( i = 'A'; i <= 'z' && strlen( ic->mode ) < ( sizeof( ic->mode ) - 1 ); i ++ )
+ if( m[i] )
+ ic->mode[strlen(ic->mode)] = i;
+
+ if( *changes && ( ic->flags & IRC_CHANNEL_JOINED ) )
+ irc_write( irc, ":%s!%s@%s MODE %s :%s", irc->root->nick,
+ irc->root->user, irc->root->host, ic->name,
+ changes );
+}
+
void irc_channel_auto_joins( irc_t *irc, account_t *acc )
{
GSList *l;
@@ -559,6 +603,9 @@ static gboolean control_channel_init( irc_channel_t *ic )
/* Have to run the evaluator to initialize icc->modes. */
set_setstr( &ic->set, "show_users", "online+,away" );
+ /* For scripts that care. */
+ irc_channel_set_mode( ic, "+C" );
+
return TRUE;
}
@@ -690,6 +737,9 @@ static gboolean control_channel_free( irc_channel_t *ic )
g_free( icc );
ic->data = NULL;
+ /* For scripts that care. */
+ irc_channel_set_mode( ic, "-C" );
+
return TRUE;
}