#define KEY_NODELETE_LEVEL "nodelete_level"
#define KEY_MAX_USERINFO_LENGTH "max_userinfo_length"
#define KEY_GIVEOWNERSHIP_PERIOD "giveownership_timeout"
+#define KEY_INVITED_INTERVAL "invite_timeout"
/* ChanServ database */
#define KEY_CHANNELS "channels"
unsigned long db_backup_frequency;
unsigned long channel_expire_frequency;
unsigned long dnr_expire_frequency;
+
+ unsigned long invited_timeout;
unsigned long info_delay;
unsigned long adjust_delay;
struct helpfile_table table;
};
+struct ChanUser
+{
+ struct userNode *user;
+ struct chanNode *chan;
+};
+
enum note_access_type
{
NOTE_SET_CHANNEL_ACCESS,
return 1;
}
+static void
+chanserv_del_invite_mark(void *data)
+{
+ struct ChanUser *chanuser = data;
+ struct chanNode *channel = chanuser->chan;
+ unsigned int i;
+ if(!channel) return;
+ for(i = 0; i < channel->invited.used; i++)
+ {
+ if(channel->invited.list[i] == chanuser->user) {
+ userList_remove(&channel->invited, chanuser->user);
+ }
+ }
+ free(chanuser);
+}
+
static CHANSERV_FUNC(cmd_invite)
{
struct userData *uData;
struct userNode *invite;
+ struct ChanUser *chanuser;
+ unsigned int i;
uData = GetChannelUser(channel->channel_info, user->handle_info);
reply("CSMSG_ALREADY_PRESENT", invite->nick, channel->name);
return 0;
}
+
+ for(i = 0; i < channel->invited.used; i++)
+ {
+ if(channel->invited.list[i] == invite) {
+ reply("CSMSG_ALREADY_INVITED", invite->nick, channel->name);
+ return 0;
+ }
+ }
if(user != invite)
{
if(argc > 1)
reply("CSMSG_INVITED_USER", argv[1], channel->name);
+ userList_append(&channel->invited, invite);
+ chanuser = calloc(1, sizeof(*chanuser));
+ chanuser->user=invite;
+ chanuser->chan=channel;
+ timeq_add(now + chanserv_conf.invited_timeout, chanserv_del_invite_mark, chanuser);
+
return 1;
}
if(channel->members.used > cData->max)
cData->max = channel->members.used;
+ for(i = 0; i < channel->invited.used; i++)
+ {
+ if(channel->invited.list[i] == user) {
+ userList_remove(&channel->invited, user);
+ }
+ }
+
/* Check for bans. If they're joining through a ban, one of two
* cases applies:
* 1: Join during a netburst, by riding the break. Kick them
chanserv_conf.channel_expire_delay = str ? ParseInterval(str) : 86400*30;
str = database_get_data(conf_node, KEY_DNR_EXPIRE_FREQ, RECDB_QSTRING);
chanserv_conf.dnr_expire_frequency = str ? ParseInterval(str) : 3600;
+ str = database_get_data(conf_node, KEY_INVITED_INTERVAL, RECDB_QSTRING);
+ chanserv_conf.invited_timeout = str ? ParseInterval(str) : 600*2;
str = database_get_data(conf_node, KEY_NODELETE_LEVEL, RECDB_QSTRING);
chanserv_conf.nodelete_level = str ? atoi(str) : 1;
str = database_get_data(conf_node, KEY_MAX_CHAN_USERS, RECDB_QSTRING);
strcpy(cNode->name, name);
banList_init(&cNode->banlist);
modeList_init(&cNode->members);
+ userList_init(&cNode->invited);
mod_chanmode(NULL, cNode, argv, nn, MCP_FROM_SERVER);
dict_insert(channels, cNode->name, cNode);
cNode->timestamp = time_;
modeList_clean(&channel->members);
banList_clean(&channel->banlist);
+ userList_clean(&channel->invited);
free(channel);
}