repo: ngircd
action: commit
revision: 
path_from: 
revision_from: cfd7d4288ebf55e6b65f33900a9ffac63a6ac6e2:
path_to: 
revision_to: 
git.thebackupbox.net
ngircd
git clone git://git.thebackupbox.net/ngircd
commit cfd7d4288ebf55e6b65f33900a9ffac63a6ac6e2
Author: Ivan Agarkov 
Date:   Sun Dec 13 21:57:41 2020 +0300

    Channel autojoin functionality

diff --git a/doc/sample-ngircd.conf.tmpl b/doc/sample-ngircd.conf.tmpl
index 5892557920f669985b413218e2f90de793ad66ad..
index ..2dbc3b992cd6e1e2083db9502a9687a2f572f96c 100644
--- a/doc/sample-ngircd.conf.tmpl
+++ b/doc/sample-ngircd.conf.tmpl
@@ -394,6 +394,9 @@
 	# Key file, syntax for each line: "::".
 	# Default: none.
 	;KeyFile = :ETCDIR:/#chan.key
+	
+	# Autojoin - set to yes to force all users to join this channel on connect
+	;Autojoin = yes

 [Channel]
 	# More [Channel] sections, if you like ...
diff --git a/man/ngircd.conf.5.tmpl b/man/ngircd.conf.5.tmpl
index 5878c02dc0a3af4fba1a3bd9ef3d84501e027a23..
index ..55b034c33cd262fceefcf971f0e1ca6b93830f26 100644
--- a/man/ngircd.conf.5.tmpl
+++ b/man/ngircd.conf.5.tmpl
@@ -517,6 +517,9 @@ invite list, exception list) is supported.
 This option can be specified multiple times, evaluated top to bottom.
 .RE
 .TP
+\fBAutojoin\fR (boolean)
+Forces users to join this channel on connect. Users must have access to the channel to make it work.
+.TP
 \fBKeyFile\fR (string)
 Path and file name of a "key file" containing individual channel keys for
 different users. The file consists of plain text lines with the following
diff --git a/src/ngircd/channel.c b/src/ngircd/channel.c
index d47b16f2c3737f9fa7462c251e1d5e5422814fb6..
index ..03af496baf6631374aaa51fc7e6d664a86334709 100644
--- a/src/ngircd/channel.c
+++ b/src/ngircd/channel.c
@@ -186,8 +186,6 @@ Channel_InitPredefined( void )
 		    new_chan->name, new_chan->modes, new_chan->key,
 		    new_chan->maxusers);
 	}
-	if (channel_count)
-		array_free(&Conf_Channels);

 	/* Make sure the local &SERVER channel exists */
 	if (!Channel_Search("&SERVER")) {
diff --git a/src/ngircd/conf.c b/src/ngircd/conf.c
index 860aea8f607f12aeecc849fdd1af68d0bb38bce8..
index ..5ee552e64d67fb63050b0b6f0021555527f58e3f 100644
--- a/src/ngircd/conf.c
+++ b/src/ngircd/conf.c
@@ -2000,6 +2000,9 @@ Handle_CHANNEL(const char *File, int Line, char *Var, char *Arg)
 			Config_Error_TooLong(File, Line, Var);
 		return;
 	}
+	if( strcasecmp( Var, "Autojoin" ) == 0 )
+		/* Check autojoin */
+		chan->autojoin = Check_ArgIsTrue(Arg);
 	if( strcasecmp( Var, "Key" ) == 0 ) {
 		/* Initial Channel Key (mode k) */
 		len = strlcpy(chan->key, Arg, sizeof(chan->key));
diff --git a/src/ngircd/conf.h b/src/ngircd/conf.h
index 97ce336d0796d7f4c4324d0e0332c043d7b5e114..
index ..f3e2c5a573936a8df5588cba342d8b5f63566f71 100644
--- a/src/ngircd/conf.h
+++ b/src/ngircd/conf.h
@@ -87,6 +87,7 @@ struct Conf_Channel {
 	char key[CLIENT_PASS_LEN];      /**< Channel key ("password", mode "k" ) */
 	char topic[COMMAND_LEN];	/**< Initial topic */
 	char keyfile[512];		/**< Path and name of channel key file */
+	bool autojoin;			/**< 1 to make all users autojoin this channel */
 	unsigned long maxusers;		/**< User limit for this channel, mode "l" */
 	unsigned int modes_num;		/**< Number of channel modes to evaluate */
 };
diff --git a/src/ngircd/login.c b/src/ngircd/login.c
index 38b9a3532d3dda01baeb3671d95e02377b22b1f8..
index ..0dd0bd892bb030c9cd6ac48584e27748c4d684a0 100644
--- a/src/ngircd/login.c
+++ b/src/ngircd/login.c
@@ -201,9 +201,40 @@ Login_User_PostAuth(CLIENT *Client)
 	} else
 		IRC_SetPenalty(Client, 1);

+  /* Autojoin clients to the channels */
+  Login_Autojoin(Client);
+
 	return CONNECTED;
 }

+/**
+ * Autojoin clients to the channels set by administrator
+ * If autojoin is not set in Config or the channel is not available for search - do nothing
+ *
+ **/
+GLOBAL void
+Login_Autojoin(CLIENT *Client)
+{
+	/** make an autojoin to each channel that is good for it **/
+	REQUEST Req;
+	const struct Conf_Channel *conf_chan;
+	size_t i, n, channel_count = array_length(&Conf_Channels, sizeof(*conf_chan));
+	conf_chan = array_start(&Conf_Channels);
+	assert(channel_count == 0 || conf_chan != NULL);
+
+	for (i = 0; i < channel_count; i++, conf_chan++) {
+		if(!conf_chan->autojoin)
+			continue;
+		if (!Channel_Search(conf_chan->name))
+			continue;
+		Req.prefix = Client_ID(Client_ThisServer());
+		Req.command = "JOIN";
+		Req.argc = 1;
+		Req.argv[0] = conf_chan->name;
+		IRC_JOIN(Client, &Req);
+	}
+}
+
 #ifdef PAM

 /**
diff --git a/src/ngircd/login.h b/src/ngircd/login.h
index 6e3a21d6befa1d0afe380c91fc56d79fdbd045c8..
index ..b5d7be1e3b705739b4f050fe2fd13edc9813192e 100644
--- a/src/ngircd/login.h
+++ b/src/ngircd/login.h
@@ -19,6 +19,7 @@

 GLOBAL bool Login_User PARAMS((CLIENT * Client));
 GLOBAL bool Login_User_PostAuth PARAMS((CLIENT *Client));
+GLOBAL void Login_Autojoin PARAMS((CLIENT *Client));

 #endif

-----END OF PAGE-----