about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorAlexander Barton <alex@barton.de>2009-01-04 17:26:50 +0100
committerAlexander Barton <alex@barton.de>2009-01-20 17:20:30 +0100
commitd09094812f5a8998e779fd75d265396486878117 (patch)
tree6ef891d929ea5c340f6db07161dd9bafb7cb964b /src
parentc5000694d16da0a205e7dde49681d589d552d144 (diff)
downloadngircd-d09094812f5a8998e779fd75d265396486878117.tar.gz
ngircd-d09094812f5a8998e779fd75d265396486878117.zip
Channel key file: store file name and open on each access.
Store the file name of channel key files and reopen them on each access
(on each JOIN command) insted of just storing the file handles.

This eliminates the special requirements (no delete) and makes sure
that always the actual file contents are used in all circumstances.
Diffstat (limited to 'src')
-rw-r--r--src/ngircd/channel.c75
-rw-r--r--src/ngircd/channel.h2
2 files changed, 41 insertions, 36 deletions
diff --git a/src/ngircd/channel.c b/src/ngircd/channel.c
index 6d23b249..8408ccb8 100644
--- a/src/ngircd/channel.c
+++ b/src/ngircd/channel.c
@@ -61,9 +61,7 @@ static CL2CHAN *Get_First_Cl2Chan PARAMS(( CLIENT *Client, CHANNEL *Chan ));
 static CL2CHAN *Get_Next_Cl2Chan PARAMS(( CL2CHAN *Start, CLIENT *Client, CHANNEL *Chan ));
 static void Delete_Channel PARAMS(( CHANNEL *Chan ));
 static void Free_Channel PARAMS(( CHANNEL *Chan ));
-static void Update_Predefined PARAMS((CHANNEL *Chan,
-				      const struct Conf_Channel *Conf_Chan));
-static void Set_Key_File PARAMS((CHANNEL *Chan, FILE *KeyFile));
+static void Set_KeyFile PARAMS((CHANNEL *Chan, const char *KeyFile));
 
 
 GLOBAL void
@@ -124,7 +122,7 @@ Channel_InitPredefined( void )
 			Log(LOG_INFO,
 			    "Can't create pre-defined channel \"%s\": name already in use.",
 			    conf_chan->name);
-			Update_Predefined(new_chan, conf_chan);
+			Set_KeyFile(new_chan, conf_chan->keyfile);
 			continue;
 		}
 
@@ -148,7 +146,7 @@ Channel_InitPredefined( void )
 
 		Channel_SetKey(new_chan, conf_chan->key);
 		Channel_SetMaxUsers(new_chan, conf_chan->maxusers);
-		Update_Predefined(new_chan, conf_chan);
+		Set_KeyFile(new_chan, conf_chan->keyfile);
 	}
 	if (channel_count)
 		array_free(&Conf_Channels);
@@ -159,10 +157,9 @@ static void
 Free_Channel(CHANNEL *chan)
 {
 	array_free(&chan->topic);
+	array_free(&chan->keyfile);
 	Lists_Free(&chan->list_bans);
 	Lists_Free(&chan->list_invites);
-	if (Chan->keyfile)
-		fclose(Chan->keyfile);
 
 	free(chan);
 }
@@ -1064,7 +1061,8 @@ Channel_LogServer(char *msg)
 GLOBAL bool
 Channel_CheckKey(CHANNEL *Chan, CLIENT *Client, const char *Key)
 {
-	char line[COMMAND_LEN], *nick, *pass;
+	char *file_name, line[COMMAND_LEN], *nick, *pass;
+	FILE *fd;
 
 	assert(Chan != NULL);
 	assert(Client != NULL);
@@ -1074,11 +1072,20 @@ Channel_CheckKey(CHANNEL *Chan, CLIENT *Client, const char *Key)
 		return true;
 	if (strcmp(Chan->key, Key) == 0)
 		return true;
-	if (!Chan->keyfile)
+	if (*Key == '\0')
+		return false;
+
+	file_name = array_start(&Chan->keyfile);
+	if (!file_name)
 		return false;
+	fd = fopen(file_name, "r");
+	if (!fd) {
+		Log(LOG_ERR, "Can't open channek key file \"%s\" for %s: %s",
+		    file_name, Chan->name, strerror(errno));
+		return false;
+	}
 
-	Chan->keyfile = freopen(NULL, "r", Chan->keyfile);
-	while (fgets(line, sizeof(line), Chan->keyfile) != NULL) {
+	while (fgets(line, sizeof(line), fd) != NULL) {
 		ngt_TrimStr(line);
 		if (! (nick = strchr(line, ':')))
 			continue;
@@ -1093,8 +1100,10 @@ Channel_CheckKey(CHANNEL *Chan, CLIENT *Client, const char *Key)
 		if (strcmp(Key, pass) != 0)
 			continue;
 
+		fclose(fd);
 		return true;
 	}
+	fclose(fd);
 	return false;
 } /* Channel_CheckKey */
 
@@ -1157,35 +1166,31 @@ Delete_Channel(CHANNEL *Chan)
 
 
 static void
-Update_Predefined(CHANNEL *Chan, const struct Conf_Channel *Conf_Chan)
+Set_KeyFile(CHANNEL *Chan, const char *KeyFile)
 {
-	FILE *fd;
-
-	if (! Conf_Chan->keyfile || ! *Conf_Chan->keyfile)
-		return;
+	size_t len;
 
-	fd = fopen(Conf_Chan->keyfile, "r");
-	if (! fd)
-		Log(LOG_ERR,
-		    "Can't open channel key file for \"%s\", \"%s\": %s",
-		    Conf_Chan->name, Conf_Chan->keyfile,
-		    strerror(errno));
-	else
-		Set_Key_File(Chan, fd);
-} /* Update_Predefined */
+	assert(Chan != NULL);
+	assert(KeyFile != NULL);
 
+	len = strlen(KeyFile);
+	if (len < array_bytes(&Chan->keyfile)) {
+		Log(LOG_INFO, "Channel key file of %s removed.", Chan->name);
+		array_free(&Chan->keyfile);
+	}
 
-static void
-Set_Key_File(CHANNEL *Chan, FILE *KeyFile)
-{
-	assert(Chan != NULL);
+	if (len < 1)
+		return;
 
-	if (Chan->keyfile)
-		fclose(Chan->keyfile);
-	Chan->keyfile = KeyFile;
-	Log(LOG_INFO|LOG_snotice,
-	    "New local channel key file for \"%s\" activated.", Chan->name);
-} /* Set_Key_File */
+	if (!array_copyb(&Chan->keyfile, KeyFile, len+1))
+		Log(LOG_WARNING,
+		    "Could not set new channel key file \"%s\" for %s: %s",
+		    KeyFile, Chan->name, strerror(errno));
+	else
+		Log(LOG_INFO|LOG_snotice,
+		    "New local channel key file \"%s\" for %s activated.",
+		    KeyFile, Chan->name);
+} /* Set_KeyFile */
 
 
 /* -eof- */
diff --git a/src/ngircd/channel.h b/src/ngircd/channel.h
index 3aa1853d..411c3458 100644
--- a/src/ngircd/channel.h
+++ b/src/ngircd/channel.h
@@ -37,7 +37,7 @@ typedef struct _CHANNEL
 	unsigned long maxusers;		/* Maximum number of members (mode "l") */
 	struct list_head list_bans;	/* list head of banned users */
 	struct list_head list_invites;	/* list head of invited users */
-	FILE *keyfile;			/* handle of the channel key file */
+	array keyfile;			/* Name of the channel key file */
 } CHANNEL;
 
 typedef struct _CLIENT2CHAN