|
@@ -1,23 +1,23 @@
|
|
|
-/*
|
|
|
|
|
|
|
+/*
|
|
|
* channels.c -- part of channels.mod
|
|
* channels.c -- part of channels.mod
|
|
|
* support for channels within the bot
|
|
* support for channels within the bot
|
|
|
- *
|
|
|
|
|
- * $Id: channels.c,v 1.34 2000/01/08 21:23:15 per Exp $
|
|
|
|
|
|
|
+ *
|
|
|
|
|
+ * $Id: channels.c,v 1.67 2002/07/18 19:01:44 guppy Exp $
|
|
|
*/
|
|
*/
|
|
|
-/*
|
|
|
|
|
- * Copyright (C) 1997 Robey Pointer
|
|
|
|
|
- * Copyright (C) 1999, 2000 Eggheads
|
|
|
|
|
- *
|
|
|
|
|
|
|
+/*
|
|
|
|
|
+ * Copyright (C) 1997 Robey Pointer
|
|
|
|
|
+ * Copyright (C) 1999, 2000, 2001, 2002 Eggheads Development Team
|
|
|
|
|
+ *
|
|
|
* This program is free software; you can redistribute it and/or
|
|
* This program is free software; you can redistribute it and/or
|
|
|
* modify it under the terms of the GNU General Public License
|
|
* modify it under the terms of the GNU General Public License
|
|
|
* as published by the Free Software Foundation; either version 2
|
|
* as published by the Free Software Foundation; either version 2
|
|
|
* of the License, or (at your option) any later version.
|
|
* of the License, or (at your option) any later version.
|
|
|
- *
|
|
|
|
|
|
|
+ *
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
* GNU General Public License for more details.
|
|
* GNU General Public License for more details.
|
|
|
- *
|
|
|
|
|
|
|
+ *
|
|
|
* You should have received a copy of the GNU General Public License
|
|
* You should have received a copy of the GNU General Public License
|
|
|
* along with this program; if not, write to the Free Software
|
|
* along with this program; if not, write to the Free Software
|
|
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
@@ -25,32 +25,33 @@
|
|
|
|
|
|
|
|
#define MODULE_NAME "channels"
|
|
#define MODULE_NAME "channels"
|
|
|
#define MAKING_CHANNELS
|
|
#define MAKING_CHANNELS
|
|
|
-#include "../module.h"
|
|
|
|
|
#include <sys/stat.h>
|
|
#include <sys/stat.h>
|
|
|
-
|
|
|
|
|
-static int setstatic = 0;
|
|
|
|
|
-static int use_info = 1;
|
|
|
|
|
-static int ban_time = 60;
|
|
|
|
|
-static int exempt_time = 0; /* if exempt_time = 0, never remove them */
|
|
|
|
|
-static int invite_time = 0; /* if invite_time = 0, never remove them */
|
|
|
|
|
-static char chanfile[121] = "chanfile";
|
|
|
|
|
-static Function *global = NULL;
|
|
|
|
|
-static int chan_hack = 0;
|
|
|
|
|
-static int must_be_owner = 0;
|
|
|
|
|
-static int quiet_save = 0;
|
|
|
|
|
-
|
|
|
|
|
-/* global channel settings (drummer/dw) */
|
|
|
|
|
-static char glob_chanset[512] = "\
|
|
|
|
|
--clearbans -enforcebans +dynamicbans +userbans -autoop -bitch +greet \
|
|
|
|
|
-+protectops +statuslog +stopnethack -revenge -secret -autovoice +cycle \
|
|
|
|
|
-+dontkickops -wasoptest -inactive -protectfriends +shared -seen \
|
|
|
|
|
-+userexempts +dynamicexempts +userinvites +dynamicinvites -revengebot ";
|
|
|
|
|
-/* DO NOT remove the extra space at the end of the string! */
|
|
|
|
|
-
|
|
|
|
|
-/* default chanmode (drummer,990731) */
|
|
|
|
|
-static char glob_chanmode[64] = "nt";
|
|
|
|
|
-
|
|
|
|
|
-/* global flood settings */
|
|
|
|
|
|
|
+#include "src/mod/module.h"
|
|
|
|
|
+
|
|
|
|
|
+static Function *global = NULL;
|
|
|
|
|
+
|
|
|
|
|
+static int setstatic;
|
|
|
|
|
+static int use_info;
|
|
|
|
|
+static int ban_time;
|
|
|
|
|
+static int exempt_time; /* If exempt_time = 0, never remove
|
|
|
|
|
+ them */
|
|
|
|
|
+static int invite_time; /* If invite_time = 0, never remove
|
|
|
|
|
+ them */
|
|
|
|
|
+static char chanfile[121];
|
|
|
|
|
+static int chan_hack;
|
|
|
|
|
+static int quiet_save;
|
|
|
|
|
+static char glob_chanmode[64]; /* Default chanmode (drummer,990731) */
|
|
|
|
|
+static struct udef_struct *udef;
|
|
|
|
|
+static int global_stopnethack_mode;
|
|
|
|
|
+static int global_revenge_mode;
|
|
|
|
|
+static int global_idle_kick; /* Default idle-kick setting. */
|
|
|
|
|
+static int global_aop_min;
|
|
|
|
|
+static int global_aop_max;
|
|
|
|
|
+
|
|
|
|
|
+/* Global channel settings (drummer/dw) */
|
|
|
|
|
+static char glob_chanset[512];
|
|
|
|
|
+
|
|
|
|
|
+/* Global flood settings */
|
|
|
static int gfld_chan_thr;
|
|
static int gfld_chan_thr;
|
|
|
static int gfld_chan_time;
|
|
static int gfld_chan_time;
|
|
|
static int gfld_deop_thr;
|
|
static int gfld_deop_thr;
|
|
@@ -61,15 +62,17 @@ static int gfld_join_thr;
|
|
|
static int gfld_join_time;
|
|
static int gfld_join_time;
|
|
|
static int gfld_ctcp_thr;
|
|
static int gfld_ctcp_thr;
|
|
|
static int gfld_ctcp_time;
|
|
static int gfld_ctcp_time;
|
|
|
-
|
|
|
|
|
-static void remove_channel(struct chanset_t *);
|
|
|
|
|
|
|
+static int gfld_nick_thr;
|
|
|
|
|
+static int gfld_nick_time;
|
|
|
|
|
|
|
|
#include "channels.h"
|
|
#include "channels.h"
|
|
|
#include "cmdschan.c"
|
|
#include "cmdschan.c"
|
|
|
#include "tclchan.c"
|
|
#include "tclchan.c"
|
|
|
#include "userchan.c"
|
|
#include "userchan.c"
|
|
|
|
|
+#include "udefchan.c"
|
|
|
|
|
+
|
|
|
|
|
|
|
|
-void *channel_malloc(int size, char *file, int line)
|
|
|
|
|
|
|
+static void *channel_malloc(int size, char *file, int line)
|
|
|
{
|
|
{
|
|
|
char *p;
|
|
char *p;
|
|
|
|
|
|
|
@@ -78,7 +81,7 @@ void *channel_malloc(int size, char *file, int line)
|
|
|
#else
|
|
#else
|
|
|
p = nmalloc(size);
|
|
p = nmalloc(size);
|
|
|
#endif
|
|
#endif
|
|
|
- bzero(p, size);
|
|
|
|
|
|
|
+ egg_bzero(p, size);
|
|
|
return p;
|
|
return p;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -87,9 +90,9 @@ static void set_mode_protect(struct chanset_t *chan, char *set)
|
|
|
int i, pos = 1;
|
|
int i, pos = 1;
|
|
|
char *s, *s1;
|
|
char *s, *s1;
|
|
|
|
|
|
|
|
- /* clear old modes */
|
|
|
|
|
|
|
+ /* Clear old modes */
|
|
|
chan->mode_mns_prot = chan->mode_pls_prot = 0;
|
|
chan->mode_mns_prot = chan->mode_pls_prot = 0;
|
|
|
- chan->limit_prot = (-1);
|
|
|
|
|
|
|
+ chan->limit_prot = 0;
|
|
|
chan->key_prot[0] = 0;
|
|
chan->key_prot[0] = 0;
|
|
|
for (s = newsplit(&set); *s; s++) {
|
|
for (s = newsplit(&set); *s; s++) {
|
|
|
i = 0;
|
|
i = 0;
|
|
@@ -112,6 +115,21 @@ static void set_mode_protect(struct chanset_t *chan, char *set)
|
|
|
case 'm':
|
|
case 'm':
|
|
|
i = CHANMODER;
|
|
i = CHANMODER;
|
|
|
break;
|
|
break;
|
|
|
|
|
+ case 'c':
|
|
|
|
|
+ i = CHANNOCLR;
|
|
|
|
|
+ break;
|
|
|
|
|
+ case 'C':
|
|
|
|
|
+ i = CHANNOCTCP;
|
|
|
|
|
+ break;
|
|
|
|
|
+ case 'R':
|
|
|
|
|
+ i = CHANREGON;
|
|
|
|
|
+ break;
|
|
|
|
|
+ case 'M':
|
|
|
|
|
+ i = CHANMODR;
|
|
|
|
|
+ break;
|
|
|
|
|
+ case 'r':
|
|
|
|
|
+ i = CHANLONLY;
|
|
|
|
|
+ break;
|
|
|
case 't':
|
|
case 't':
|
|
|
i = CHANTOPIC;
|
|
i = CHANTOPIC;
|
|
|
break;
|
|
break;
|
|
@@ -126,7 +144,7 @@ static void set_mode_protect(struct chanset_t *chan, char *set)
|
|
|
break;
|
|
break;
|
|
|
case 'l':
|
|
case 'l':
|
|
|
i = CHANLIMIT;
|
|
i = CHANLIMIT;
|
|
|
- chan->limit_prot = (-1);
|
|
|
|
|
|
|
+ chan->limit_prot = 0;
|
|
|
if (pos) {
|
|
if (pos) {
|
|
|
s1 = newsplit(&set);
|
|
s1 = newsplit(&set);
|
|
|
if (s1[0])
|
|
if (s1[0])
|
|
@@ -153,7 +171,7 @@ static void set_mode_protect(struct chanset_t *chan, char *set)
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
- /* drummer: +s-p +p-s flood fixed. */
|
|
|
|
|
|
|
+ /* Prevents a +s-p +p-s flood (fixed by drummer) */
|
|
|
if (chan->mode_pls_prot & CHANSEC)
|
|
if (chan->mode_pls_prot & CHANSEC)
|
|
|
chan->mode_pls_prot &= ~CHANPRIV;
|
|
chan->mode_pls_prot &= ~CHANPRIV;
|
|
|
}
|
|
}
|
|
@@ -168,9 +186,9 @@ static void get_mode_protect(struct chanset_t *chan, char *s)
|
|
|
ok = 0;
|
|
ok = 0;
|
|
|
if (i == 0) {
|
|
if (i == 0) {
|
|
|
tst = chan->mode_pls_prot;
|
|
tst = chan->mode_pls_prot;
|
|
|
- if ((tst) || (chan->limit_prot != (-1)) || (chan->key_prot[0]))
|
|
|
|
|
|
|
+ if ((tst) || (chan->limit_prot != 0) || (chan->key_prot[0]))
|
|
|
*p++ = '+';
|
|
*p++ = '+';
|
|
|
- if (chan->limit_prot != (-1)) {
|
|
|
|
|
|
|
+ if (chan->limit_prot != 0) {
|
|
|
*p++ = 'l';
|
|
*p++ = 'l';
|
|
|
sprintf(&s1[strlen(s1)], "%d ", chan->limit_prot);
|
|
sprintf(&s1[strlen(s1)], "%d ", chan->limit_prot);
|
|
|
}
|
|
}
|
|
@@ -195,6 +213,16 @@ static void get_mode_protect(struct chanset_t *chan, char *s)
|
|
|
*p++ = 's';
|
|
*p++ = 's';
|
|
|
if (tst & CHANMODER)
|
|
if (tst & CHANMODER)
|
|
|
*p++ = 'm';
|
|
*p++ = 'm';
|
|
|
|
|
+ if (tst & CHANNOCLR)
|
|
|
|
|
+ *p++ = 'c';
|
|
|
|
|
+ if (tst & CHANNOCTCP)
|
|
|
|
|
+ *p++ = 'C';
|
|
|
|
|
+ if (tst & CHANREGON)
|
|
|
|
|
+ *p++ = 'R';
|
|
|
|
|
+ if (tst & CHANMODR)
|
|
|
|
|
+ *p++ = 'M';
|
|
|
|
|
+ if (tst & CHANLONLY)
|
|
|
|
|
+ *p++ = 'r';
|
|
|
if (tst & CHANTOPIC)
|
|
if (tst & CHANTOPIC)
|
|
|
*p++ = 't';
|
|
*p++ = 't';
|
|
|
if (tst & CHANNOMSG)
|
|
if (tst & CHANNOMSG)
|
|
@@ -212,55 +240,61 @@ static void get_mode_protect(struct chanset_t *chan, char *s)
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-/* returns true if this is one of the channel masks */
|
|
|
|
|
|
|
+/* Returns true if this is one of the channel masks
|
|
|
|
|
+ */
|
|
|
static int ismodeline(masklist *m, char *user)
|
|
static int ismodeline(masklist *m, char *user)
|
|
|
{
|
|
{
|
|
|
- while (m && m->mask[0]) {
|
|
|
|
|
|
|
+ for (; m && m->mask[0]; m = m->next)
|
|
|
if (!rfc_casecmp(m->mask, user))
|
|
if (!rfc_casecmp(m->mask, user))
|
|
|
return 1;
|
|
return 1;
|
|
|
- m = m->next;
|
|
|
|
|
- }
|
|
|
|
|
return 0;
|
|
return 0;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-/* returns true if user matches one of the masklist -- drummer */
|
|
|
|
|
|
|
+/* Returns true if user matches one of the masklist -- drummer
|
|
|
|
|
+ */
|
|
|
static int ismasked(masklist *m, char *user)
|
|
static int ismasked(masklist *m, char *user)
|
|
|
{
|
|
{
|
|
|
- while (m && m->mask[0]) {
|
|
|
|
|
|
|
+ for (; m && m->mask[0]; m = m->next)
|
|
|
if (wild_match(m->mask, user))
|
|
if (wild_match(m->mask, user))
|
|
|
return 1;
|
|
return 1;
|
|
|
- m = m->next;
|
|
|
|
|
- }
|
|
|
|
|
return 0;
|
|
return 0;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-/* destroy a chanset in the list */
|
|
|
|
|
-/* does NOT free up memory associated with channel data inside the chanset! */
|
|
|
|
|
-static int killchanset(struct chanset_t *chan)
|
|
|
|
|
|
|
+/* Unlink chanset element from chanset list.
|
|
|
|
|
+ */
|
|
|
|
|
+inline static int chanset_unlink(struct chanset_t *chan)
|
|
|
{
|
|
{
|
|
|
- struct chanset_t *c = chanset, *old = NULL;
|
|
|
|
|
|
|
+ struct chanset_t *c, *c_old = NULL;
|
|
|
|
|
|
|
|
- while (c) {
|
|
|
|
|
|
|
+ for (c = chanset; c; c_old = c, c = c->next) {
|
|
|
if (c == chan) {
|
|
if (c == chan) {
|
|
|
- if (old)
|
|
|
|
|
- old->next = c->next;
|
|
|
|
|
|
|
+ if (c_old)
|
|
|
|
|
+ c_old->next = c->next;
|
|
|
else
|
|
else
|
|
|
chanset = c->next;
|
|
chanset = c->next;
|
|
|
- nfree(c);
|
|
|
|
|
return 1;
|
|
return 1;
|
|
|
}
|
|
}
|
|
|
- old = c;
|
|
|
|
|
- c = c->next;
|
|
|
|
|
}
|
|
}
|
|
|
return 0;
|
|
return 0;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/* Completely removes a channel.
|
|
/* Completely removes a channel.
|
|
|
|
|
+ *
|
|
|
* This includes the removal of all channel-bans, -exempts and -invites, as
|
|
* This includes the removal of all channel-bans, -exempts and -invites, as
|
|
|
* well as all user flags related to the channel.
|
|
* well as all user flags related to the channel.
|
|
|
*/
|
|
*/
|
|
|
static void remove_channel(struct chanset_t *chan)
|
|
static void remove_channel(struct chanset_t *chan)
|
|
|
{
|
|
{
|
|
|
|
|
+ int i;
|
|
|
|
|
+ module_entry *me;
|
|
|
|
|
+
|
|
|
|
|
+ /* Remove the channel from the list, so that noone can pull it
|
|
|
|
|
+ away from under our feet during the check_tcl_part() call. */
|
|
|
|
|
+ (void) chanset_unlink(chan);
|
|
|
|
|
+
|
|
|
|
|
+ if ((me = module_find("irc", 1, 3)) != NULL)
|
|
|
|
|
+ (me->funcs[IRC_DO_CHANNEL_PART])(chan);
|
|
|
|
|
+
|
|
|
clear_channel(chan, 0);
|
|
clear_channel(chan, 0);
|
|
|
noshare = 1;
|
|
noshare = 1;
|
|
|
/* Remove channel-bans */
|
|
/* Remove channel-bans */
|
|
@@ -273,13 +307,21 @@ static void remove_channel(struct chanset_t *chan)
|
|
|
while (chan->invites)
|
|
while (chan->invites)
|
|
|
u_delinvite(chan, chan->invites->mask, 1);
|
|
u_delinvite(chan, chan->invites->mask, 1);
|
|
|
/* Remove channel specific user flags */
|
|
/* Remove channel specific user flags */
|
|
|
- user_del_chan(chan->name);
|
|
|
|
|
|
|
+ user_del_chan(chan->dname);
|
|
|
noshare = 0;
|
|
noshare = 0;
|
|
|
- killchanset(chan);
|
|
|
|
|
|
|
+ nfree(chan->channel.key);
|
|
|
|
|
+ for (i = 0; i < 6 && chan->cmode[i].op; i++)
|
|
|
|
|
+ nfree(chan->cmode[i].op);
|
|
|
|
|
+ if (chan->key)
|
|
|
|
|
+ nfree(chan->key);
|
|
|
|
|
+ if (chan->rmkey)
|
|
|
|
|
+ nfree(chan->rmkey);
|
|
|
|
|
+ nfree(chan);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-/* bind this to chon and *if* the users console channel == ***
|
|
|
|
|
- * then set it to a specific channel */
|
|
|
|
|
|
|
+/* Bind this to chon and *if* the users console channel == ***
|
|
|
|
|
+ * then set it to a specific channel
|
|
|
|
|
+ */
|
|
|
static int channels_chon(char *handle, int idx)
|
|
static int channels_chon(char *handle, int idx)
|
|
|
{
|
|
{
|
|
|
struct flag_record fr = {FR_CHAN | FR_ANYWH | FR_GLOBAL, 0, 0, 0, 0, 0};
|
|
struct flag_record fr = {FR_CHAN | FR_ANYWH | FR_GLOBAL, 0, 0, 0, 0, 0};
|
|
@@ -287,7 +329,7 @@ static int channels_chon(char *handle, int idx)
|
|
|
struct chanset_t *chan = chanset;
|
|
struct chanset_t *chan = chanset;
|
|
|
|
|
|
|
|
if (dcc[idx].type == &DCC_CHAT) {
|
|
if (dcc[idx].type == &DCC_CHAT) {
|
|
|
- if (!findchan(dcc[idx].u.chat->con_chan) &&
|
|
|
|
|
|
|
+ if (!findchan_by_dname(dcc[idx].u.chat->con_chan) &&
|
|
|
((dcc[idx].u.chat->con_chan[0] != '*') ||
|
|
((dcc[idx].u.chat->con_chan[0] != '*') ||
|
|
|
(dcc[idx].u.chat->con_chan[1] != 0))) {
|
|
(dcc[idx].u.chat->con_chan[1] != 0))) {
|
|
|
get_user_flagrec(dcc[idx].user, &fr, NULL);
|
|
get_user_flagrec(dcc[idx].user, &fr, NULL);
|
|
@@ -301,7 +343,7 @@ static int channels_chon(char *handle, int idx)
|
|
|
find = USER_OP;
|
|
find = USER_OP;
|
|
|
fr.match = FR_CHAN;
|
|
fr.match = FR_CHAN;
|
|
|
while (chan && !found) {
|
|
while (chan && !found) {
|
|
|
- get_user_flagrec(dcc[idx].user, &fr, chan->name);
|
|
|
|
|
|
|
+ get_user_flagrec(dcc[idx].user, &fr, chan->dname);
|
|
|
if (fr.chan & find)
|
|
if (fr.chan & find)
|
|
|
found = 1;
|
|
found = 1;
|
|
|
else
|
|
else
|
|
@@ -310,7 +352,7 @@ static int channels_chon(char *handle, int idx)
|
|
|
if (!chan)
|
|
if (!chan)
|
|
|
chan = chanset;
|
|
chan = chanset;
|
|
|
if (chan)
|
|
if (chan)
|
|
|
- strcpy(dcc[idx].u.chat->con_chan, chan->name);
|
|
|
|
|
|
|
+ strcpy(dcc[idx].u.chat->con_chan, chan->dname);
|
|
|
else
|
|
else
|
|
|
strcpy(dcc[idx].u.chat->con_chan, "*");
|
|
strcpy(dcc[idx].u.chat->con_chan, "*");
|
|
|
}
|
|
}
|
|
@@ -329,29 +371,35 @@ static char *convert_element(char *src, char *dst)
|
|
|
|
|
|
|
|
#define PLSMNS(x) (x ? '+' : '-')
|
|
#define PLSMNS(x) (x ? '+' : '-')
|
|
|
|
|
|
|
|
|
|
+/*
|
|
|
|
|
+ * Note:
|
|
|
|
|
+ * - We write chanmode "" too, so that the bot won't use default-chanmode
|
|
|
|
|
+ * instead of ""
|
|
|
|
|
+ * - We will write empty need-xxxx too, why not? (less code + lazyness)
|
|
|
|
|
+ */
|
|
|
static void write_channels()
|
|
static void write_channels()
|
|
|
{
|
|
{
|
|
|
FILE *f;
|
|
FILE *f;
|
|
|
char s[121], w[1024], w2[1024], name[163];
|
|
char s[121], w[1024], w2[1024], name[163];
|
|
|
char need1[242], need2[242], need3[242], need4[242], need5[242];
|
|
char need1[242], need2[242], need3[242], need4[242], need5[242];
|
|
|
struct chanset_t *chan;
|
|
struct chanset_t *chan;
|
|
|
|
|
+ struct udef_struct *ul;
|
|
|
|
|
|
|
|
- Context;
|
|
|
|
|
if (!chanfile[0])
|
|
if (!chanfile[0])
|
|
|
return;
|
|
return;
|
|
|
sprintf(s, "%s~new", chanfile);
|
|
sprintf(s, "%s~new", chanfile);
|
|
|
f = fopen(s, "w");
|
|
f = fopen(s, "w");
|
|
|
- chmod(s, 0600);
|
|
|
|
|
|
|
+ chmod(s, userfile_perm);
|
|
|
if (f == NULL) {
|
|
if (f == NULL) {
|
|
|
putlog(LOG_MISC, "*", "ERROR writing channel file.");
|
|
putlog(LOG_MISC, "*", "ERROR writing channel file.");
|
|
|
return;
|
|
return;
|
|
|
}
|
|
}
|
|
|
if (!quiet_save)
|
|
if (!quiet_save)
|
|
|
- putlog(LOG_MISC, "*", "Writing channel file ...");
|
|
|
|
|
|
|
+ putlog(LOG_MISC, "*", "Writing channel file...");
|
|
|
fprintf(f, "#Dynamic Channel File for %s (%s) -- written %s\n",
|
|
fprintf(f, "#Dynamic Channel File for %s (%s) -- written %s\n",
|
|
|
- origbotname, ver, ctime(&now));
|
|
|
|
|
|
|
+ botnetnick, ver, ctime(&now));
|
|
|
for (chan = chanset; chan; chan = chan->next) {
|
|
for (chan = chanset; chan; chan = chan->next) {
|
|
|
- convert_element(chan->name, name);
|
|
|
|
|
|
|
+ convert_element(chan->dname, name);
|
|
|
get_mode_protect(chan, w);
|
|
get_mode_protect(chan, w);
|
|
|
convert_element(w, w2);
|
|
convert_element(w, w2);
|
|
|
convert_element(chan->need_op, need1);
|
|
convert_element(chan->need_op, need1);
|
|
@@ -359,43 +407,43 @@ static void write_channels()
|
|
|
convert_element(chan->need_key, need3);
|
|
convert_element(chan->need_key, need3);
|
|
|
convert_element(chan->need_unban, need4);
|
|
convert_element(chan->need_unban, need4);
|
|
|
convert_element(chan->need_limit, need5);
|
|
convert_element(chan->need_limit, need5);
|
|
|
- fprintf(f, "channel %s %s%schanmode %s idle-kick %d \
|
|
|
|
|
|
|
+ fprintf(f, "channel %s %s%schanmode %s idle-kick %d stopnethack-mode %d \
|
|
|
|
|
+revenge-mode %d \
|
|
|
need-op %s need-invite %s need-key %s need-unban %s need-limit %s \
|
|
need-op %s need-invite %s need-key %s need-unban %s need-limit %s \
|
|
|
flood-chan %d:%d flood-ctcp %d:%d flood-join %d:%d \
|
|
flood-chan %d:%d flood-ctcp %d:%d flood-join %d:%d \
|
|
|
-flood-kick %d:%d flood-deop %d:%d \
|
|
|
|
|
-%cclearbans %cenforcebans %cdynamicbans %cuserbans %cautoop %cbitch \
|
|
|
|
|
-%cgreet %cprotectops %cprotectfriends %cdontkickops %cwasoptest \
|
|
|
|
|
-%cstatuslog %cstopnethack %crevenge %crevengebot %cautovoice %csecret \
|
|
|
|
|
|
|
+flood-kick %d:%d flood-deop %d:%d flood-nick %d:%d aop-delay %d:%d \
|
|
|
|
|
+%cenforcebans %cdynamicbans %cuserbans %cautoop %cautohalfop %cbitch \
|
|
|
|
|
+%cgreet %cprotectops %cprotecthalfops %cprotectfriends %cdontkickops \
|
|
|
|
|
+%cstatuslog %crevenge %crevengebot %cautovoice %csecret \
|
|
|
%cshared %ccycle %cseen %cinactive %cdynamicexempts %cuserexempts \
|
|
%cshared %ccycle %cseen %cinactive %cdynamicexempts %cuserexempts \
|
|
|
-%cdynamicinvites %cuserinvites%s\n",
|
|
|
|
|
|
|
+%cdynamicinvites %cuserinvites %cnodesynch ",
|
|
|
channel_static(chan) ? "set" : "add",
|
|
channel_static(chan) ? "set" : "add",
|
|
|
name,
|
|
name,
|
|
|
channel_static(chan) ? " " : " { ",
|
|
channel_static(chan) ? " " : " { ",
|
|
|
w2,
|
|
w2,
|
|
|
-/* now bot write chanmode "" too,
|
|
|
|
|
- * so bot wont use default-chanmode instead of "" -- bugfix
|
|
|
|
|
- */
|
|
|
|
|
chan->idle_kick, /* idle-kick 0 is same as dont-idle-kick (less code)*/
|
|
chan->idle_kick, /* idle-kick 0 is same as dont-idle-kick (less code)*/
|
|
|
|
|
+ chan->stopnethack_mode,
|
|
|
|
|
+ chan->revenge_mode,
|
|
|
need1, need2, need3, need4, need5,
|
|
need1, need2, need3, need4, need5,
|
|
|
-/* yes we will write empty need-xxxx too, why not? (less code + lazyness) */
|
|
|
|
|
chan->flood_pub_thr, chan->flood_pub_time,
|
|
chan->flood_pub_thr, chan->flood_pub_time,
|
|
|
chan->flood_ctcp_thr, chan->flood_ctcp_time,
|
|
chan->flood_ctcp_thr, chan->flood_ctcp_time,
|
|
|
chan->flood_join_thr, chan->flood_join_time,
|
|
chan->flood_join_thr, chan->flood_join_time,
|
|
|
chan->flood_kick_thr, chan->flood_kick_time,
|
|
chan->flood_kick_thr, chan->flood_kick_time,
|
|
|
chan->flood_deop_thr, chan->flood_deop_time,
|
|
chan->flood_deop_thr, chan->flood_deop_time,
|
|
|
- PLSMNS(channel_clearbans(chan)),
|
|
|
|
|
|
|
+ chan->flood_nick_thr, chan->flood_nick_time,
|
|
|
|
|
+ chan->aop_min, chan->aop_max,
|
|
|
PLSMNS(channel_enforcebans(chan)),
|
|
PLSMNS(channel_enforcebans(chan)),
|
|
|
PLSMNS(channel_dynamicbans(chan)),
|
|
PLSMNS(channel_dynamicbans(chan)),
|
|
|
PLSMNS(!channel_nouserbans(chan)),
|
|
PLSMNS(!channel_nouserbans(chan)),
|
|
|
PLSMNS(channel_autoop(chan)),
|
|
PLSMNS(channel_autoop(chan)),
|
|
|
|
|
+ PLSMNS(channel_autohalfop(chan)),
|
|
|
PLSMNS(channel_bitch(chan)),
|
|
PLSMNS(channel_bitch(chan)),
|
|
|
PLSMNS(channel_greet(chan)),
|
|
PLSMNS(channel_greet(chan)),
|
|
|
PLSMNS(channel_protectops(chan)),
|
|
PLSMNS(channel_protectops(chan)),
|
|
|
- PLSMNS(channel_protectfriends(chan)),
|
|
|
|
|
|
|
+ PLSMNS(channel_protecthalfops(chan)),
|
|
|
|
|
+ PLSMNS(channel_protectfriends(chan)),
|
|
|
PLSMNS(channel_dontkickops(chan)),
|
|
PLSMNS(channel_dontkickops(chan)),
|
|
|
- PLSMNS(channel_wasoptest(chan)),
|
|
|
|
|
PLSMNS(channel_logstatus(chan)),
|
|
PLSMNS(channel_logstatus(chan)),
|
|
|
- PLSMNS(channel_stopnethack(chan)),
|
|
|
|
|
PLSMNS(channel_revenge(chan)),
|
|
PLSMNS(channel_revenge(chan)),
|
|
|
PLSMNS(channel_revengebot(chan)),
|
|
PLSMNS(channel_revengebot(chan)),
|
|
|
PLSMNS(channel_autovoice(chan)),
|
|
PLSMNS(channel_autovoice(chan)),
|
|
@@ -404,11 +452,24 @@ flood-kick %d:%d flood-deop %d:%d \
|
|
|
PLSMNS(channel_cycle(chan)),
|
|
PLSMNS(channel_cycle(chan)),
|
|
|
PLSMNS(channel_seen(chan)),
|
|
PLSMNS(channel_seen(chan)),
|
|
|
PLSMNS(channel_inactive(chan)),
|
|
PLSMNS(channel_inactive(chan)),
|
|
|
- PLSMNS(channel_dynamicexempts(chan)),
|
|
|
|
|
- PLSMNS(!channel_nouserexempts(chan)),
|
|
|
|
|
|
|
+ PLSMNS(channel_dynamicexempts(chan)),
|
|
|
|
|
+ PLSMNS(!channel_nouserexempts(chan)),
|
|
|
PLSMNS(channel_dynamicinvites(chan)),
|
|
PLSMNS(channel_dynamicinvites(chan)),
|
|
|
- PLSMNS(!channel_nouserinvites(chan)),
|
|
|
|
|
- channel_static(chan) ? "" : " }");
|
|
|
|
|
|
|
+ PLSMNS(!channel_nouserinvites(chan)),
|
|
|
|
|
+ PLSMNS(channel_nodesynch(chan)));
|
|
|
|
|
+ for (ul = udef; ul; ul = ul->next) {
|
|
|
|
|
+ if (ul->defined && ul->name) {
|
|
|
|
|
+ if (ul->type == UDEF_FLAG)
|
|
|
|
|
+ fprintf(f, "%c%s%s ", getudef(ul->values, chan->dname) ? '+' : '-',
|
|
|
|
|
+ "udef-flag-", ul->name);
|
|
|
|
|
+ else if (ul->type == UDEF_INT)
|
|
|
|
|
+ fprintf(f, "%s%s %d ", "udef-int-", ul->name, getudef(ul->values,
|
|
|
|
|
+ chan->dname));
|
|
|
|
|
+ else
|
|
|
|
|
+ debug1("UDEF-ERROR: unknown type %d", ul->type);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ fprintf(f, "%s\n", channel_static(chan) ? "" : "}");
|
|
|
if (fflush(f)) {
|
|
if (fflush(f)) {
|
|
|
putlog(LOG_MISC, "*", "ERROR writing channel file.");
|
|
putlog(LOG_MISC, "*", "ERROR writing channel file.");
|
|
|
fclose(f);
|
|
fclose(f);
|
|
@@ -422,7 +483,7 @@ flood-kick %d:%d flood-deop %d:%d \
|
|
|
|
|
|
|
|
static void read_channels(int create)
|
|
static void read_channels(int create)
|
|
|
{
|
|
{
|
|
|
- struct chanset_t *chan, *chan2;
|
|
|
|
|
|
|
+ struct chanset_t *chan, *chan_next;
|
|
|
|
|
|
|
|
if (!chanfile[0])
|
|
if (!chanfile[0])
|
|
|
return;
|
|
return;
|
|
@@ -433,40 +494,46 @@ static void read_channels(int create)
|
|
|
if (!readtclprog(chanfile) && create) {
|
|
if (!readtclprog(chanfile) && create) {
|
|
|
FILE *f;
|
|
FILE *f;
|
|
|
|
|
|
|
|
- /* assume file isnt there & therfore make it */
|
|
|
|
|
|
|
+ /* Assume file isnt there & therfore make it */
|
|
|
putlog(LOG_MISC, "*", "Creating channel file");
|
|
putlog(LOG_MISC, "*", "Creating channel file");
|
|
|
f = fopen(chanfile, "w");
|
|
f = fopen(chanfile, "w");
|
|
|
if (!f)
|
|
if (!f)
|
|
|
putlog(LOG_MISC, "*", "Couldn't create channel file: %s. Dropping",
|
|
putlog(LOG_MISC, "*", "Couldn't create channel file: %s. Dropping",
|
|
|
chanfile);
|
|
chanfile);
|
|
|
- else fclose(f);
|
|
|
|
|
|
|
+ else
|
|
|
|
|
+ fclose(f);
|
|
|
}
|
|
}
|
|
|
chan_hack = 0;
|
|
chan_hack = 0;
|
|
|
- chan = chanset;
|
|
|
|
|
- while (chan != NULL) {
|
|
|
|
|
|
|
+ for (chan = chanset; chan; chan = chan_next) {
|
|
|
|
|
+ chan_next = chan->next;
|
|
|
if (chan->status & CHAN_FLAGGED) {
|
|
if (chan->status & CHAN_FLAGGED) {
|
|
|
- putlog(LOG_MISC, "*", "No longer supporting channel %s", chan->name);
|
|
|
|
|
- if (!channel_inactive(chan))
|
|
|
|
|
- dprintf(DP_SERVER, "PART %s\n", chan->name);
|
|
|
|
|
- chan2 = chan->next;
|
|
|
|
|
|
|
+ putlog(LOG_MISC, "*", "No longer supporting channel %s", chan->dname);
|
|
|
remove_channel(chan);
|
|
remove_channel(chan);
|
|
|
- chan = chan2;
|
|
|
|
|
- } else
|
|
|
|
|
- chan = chan->next;
|
|
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+static void backup_chanfile()
|
|
|
|
|
+{
|
|
|
|
|
+ char s[125];
|
|
|
|
|
+
|
|
|
|
|
+ putlog(LOG_MISC, "*", "Backing up channel file...");
|
|
|
|
|
+ egg_snprintf(s, sizeof s, "%s~bak", chanfile);
|
|
|
|
|
+ copyfile(chanfile, s);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
static void channels_prerehash()
|
|
static void channels_prerehash()
|
|
|
{
|
|
{
|
|
|
struct chanset_t *chan;
|
|
struct chanset_t *chan;
|
|
|
|
|
|
|
|
|
|
+ /* Flag will be cleared as the channels are re-added by the
|
|
|
|
|
+ * config file. Any still flagged afterwards will be removed.
|
|
|
|
|
+ */
|
|
|
for (chan = chanset; chan; chan = chan->next) {
|
|
for (chan = chanset; chan; chan = chan->next) {
|
|
|
chan->status |= CHAN_FLAGGED;
|
|
chan->status |= CHAN_FLAGGED;
|
|
|
- /* flag will be cleared as the channels are re-added by the config file */
|
|
|
|
|
- /* any still flagged afterwards will be removed */
|
|
|
|
|
|
|
+ /* Flag is only added to channels read from config file */
|
|
|
if (chan->status & CHAN_STATIC)
|
|
if (chan->status & CHAN_STATIC)
|
|
|
chan->status &= ~CHAN_STATIC;
|
|
chan->status &= ~CHAN_STATIC;
|
|
|
- /* flag is added to channels read from config file */
|
|
|
|
|
}
|
|
}
|
|
|
setstatic = 1;
|
|
setstatic = 1;
|
|
|
}
|
|
}
|
|
@@ -477,13 +544,11 @@ static void channels_rehash()
|
|
|
|
|
|
|
|
setstatic = 0;
|
|
setstatic = 0;
|
|
|
read_channels(1);
|
|
read_channels(1);
|
|
|
- /* remove any extra channels */
|
|
|
|
|
|
|
+ /* Remove any extra channels, by checking the flag. */
|
|
|
chan = chanset;
|
|
chan = chanset;
|
|
|
- while (chan) {
|
|
|
|
|
|
|
+ for (chan = chanset; chan;) {
|
|
|
if (chan->status & CHAN_FLAGGED) {
|
|
if (chan->status & CHAN_FLAGGED) {
|
|
|
- putlog(LOG_MISC, "*", "No longer supporting channel %s", chan->name);
|
|
|
|
|
- if (!channel_inactive(chan))
|
|
|
|
|
- dprintf(DP_SERVER, "PART %s\n", chan->name);
|
|
|
|
|
|
|
+ putlog(LOG_MISC, "*", "No longer supporting channel %s", chan->dname);
|
|
|
remove_channel(chan);
|
|
remove_channel(chan);
|
|
|
chan = chanset;
|
|
chan = chanset;
|
|
|
} else
|
|
} else
|
|
@@ -491,11 +556,10 @@ static void channels_rehash()
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-/* update the add/rem_builtins in channels.c if you add to this list!! */
|
|
|
|
|
static cmd_t my_chon[] =
|
|
static cmd_t my_chon[] =
|
|
|
{
|
|
{
|
|
|
- {"*", "", (Function) channels_chon, "channels:chon"},
|
|
|
|
|
- {0, 0, 0, 0}
|
|
|
|
|
|
|
+ {"*", "", (Function) channels_chon, "channels:chon"},
|
|
|
|
|
+ {NULL, NULL, NULL, NULL}
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
static void channels_report(int idx, int details)
|
|
static void channels_report(int idx, int details)
|
|
@@ -503,13 +567,11 @@ static void channels_report(int idx, int details)
|
|
|
struct chanset_t *chan;
|
|
struct chanset_t *chan;
|
|
|
int i;
|
|
int i;
|
|
|
char s[1024], s2[100];
|
|
char s[1024], s2[100];
|
|
|
- struct flag_record fr =
|
|
|
|
|
- {FR_CHAN | FR_GLOBAL, 0, 0, 0, 0, 0};
|
|
|
|
|
|
|
+ struct flag_record fr = {FR_CHAN | FR_GLOBAL, 0, 0, 0, 0, 0};
|
|
|
|
|
|
|
|
- chan = chanset;
|
|
|
|
|
- while (chan != NULL) {
|
|
|
|
|
|
|
+ for (chan = chanset; chan; chan = chan->next) {
|
|
|
if (idx != DP_STDOUT)
|
|
if (idx != DP_STDOUT)
|
|
|
- get_user_flagrec(dcc[idx].user, &fr, chan->name);
|
|
|
|
|
|
|
+ get_user_flagrec(dcc[idx].user, &fr, chan->dname);
|
|
|
if ((idx == DP_STDOUT) || glob_master(fr) || chan_master(fr)) {
|
|
if ((idx == DP_STDOUT) || glob_master(fr) || chan_master(fr)) {
|
|
|
s[0] = 0;
|
|
s[0] = 0;
|
|
|
if (channel_greet(chan))
|
|
if (channel_greet(chan))
|
|
@@ -525,46 +587,53 @@ static void channels_report(int idx, int details)
|
|
|
get_mode_protect(chan, s2);
|
|
get_mode_protect(chan, s2);
|
|
|
if (!channel_inactive(chan)) {
|
|
if (!channel_inactive(chan)) {
|
|
|
if (channel_active(chan)) {
|
|
if (channel_active(chan)) {
|
|
|
- dprintf(idx, " %-10s: %2d member%s enforcing \"%s\" (%s)\n", chan->name,
|
|
|
|
|
- chan->channel.members, chan->channel.members == 1 ? "," : "s,", s2, s);
|
|
|
|
|
|
|
+ /* If it's a !chan, we want to display it's unique name too <cybah> */
|
|
|
|
|
+ if (chan->dname[0]=='!') {
|
|
|
|
|
+ dprintf(idx, " %-10s: %2d member%s enforcing \"%s\" (%s), "
|
|
|
|
|
+ "unique name %s\n", chan->dname, chan->channel.members,
|
|
|
|
|
+ (chan->channel.members==1) ? "," : "s,", s2, s, chan->name);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ dprintf(idx, " %-10s: %2d member%s enforcing \"%s\" (%s)\n",
|
|
|
|
|
+ chan->dname, chan->channel.members,
|
|
|
|
|
+ chan->channel.members == 1 ? "," : "s,", s2, s);
|
|
|
|
|
+ }
|
|
|
} else {
|
|
} else {
|
|
|
- dprintf(idx, " %-10s: (%s), enforcing \"%s\" (%s)\n", chan->name,
|
|
|
|
|
- channel_pending(chan) ? "pending" : "inactive", s2, s);
|
|
|
|
|
|
|
+ dprintf(idx, " %-10s: (%s), enforcing \"%s\" (%s)\n", chan->dname,
|
|
|
|
|
+ channel_pending(chan) ? "pending" : "not on channel", s2, s);
|
|
|
}
|
|
}
|
|
|
} else {
|
|
} else {
|
|
|
- dprintf(idx, " %-10s: no IRC support for this channel\n", chan->name);
|
|
|
|
|
|
|
+ dprintf(idx, " %-10s: channel is set +inactive\n",
|
|
|
|
|
+ chan->dname);
|
|
|
}
|
|
}
|
|
|
if (details) {
|
|
if (details) {
|
|
|
s[0] = 0;
|
|
s[0] = 0;
|
|
|
i = 0;
|
|
i = 0;
|
|
|
- if (channel_clearbans(chan))
|
|
|
|
|
- i += my_strcpy(s + i, "clear-bans ");
|
|
|
|
|
if (channel_enforcebans(chan))
|
|
if (channel_enforcebans(chan))
|
|
|
- i += my_strcpy(s + i, "enforce-bans ");
|
|
|
|
|
|
|
+ i += my_strcpy(s + i, "enforcebans ");
|
|
|
if (channel_dynamicbans(chan))
|
|
if (channel_dynamicbans(chan))
|
|
|
- i += my_strcpy(s + i, "dynamic-bans ");
|
|
|
|
|
- if (channel_nouserbans(chan))
|
|
|
|
|
- i += my_strcpy(s + i, "forbid-user-bans ");
|
|
|
|
|
|
|
+ i += my_strcpy(s + i, "dynamicbans ");
|
|
|
|
|
+ if (!channel_nouserbans(chan))
|
|
|
|
|
+ i += my_strcpy(s + i, "userbans ");
|
|
|
if (channel_autoop(chan))
|
|
if (channel_autoop(chan))
|
|
|
- i += my_strcpy(s + i, "op-on-join ");
|
|
|
|
|
|
|
+ i += my_strcpy(s + i, "autoop ");
|
|
|
if (channel_bitch(chan))
|
|
if (channel_bitch(chan))
|
|
|
i += my_strcpy(s + i, "bitch ");
|
|
i += my_strcpy(s + i, "bitch ");
|
|
|
if (channel_greet(chan))
|
|
if (channel_greet(chan))
|
|
|
i += my_strcpy(s + i, "greet ");
|
|
i += my_strcpy(s + i, "greet ");
|
|
|
if (channel_protectops(chan))
|
|
if (channel_protectops(chan))
|
|
|
- i += my_strcpy(s + i, "protect-ops ");
|
|
|
|
|
- if (channel_protectfriends(chan))
|
|
|
|
|
- i += my_strcpy(s + i, "protect-friends ");
|
|
|
|
|
|
|
+ i += my_strcpy(s + i, "protectops ");
|
|
|
|
|
+ if (channel_protecthalfops(chan))
|
|
|
|
|
+ i += my_strcpy(s + i, "protecthalfops ");
|
|
|
|
|
+ if (channel_protectfriends(chan))
|
|
|
|
|
+ i += my_strcpy(s + i, "protectfriends ");
|
|
|
if (channel_dontkickops(chan))
|
|
if (channel_dontkickops(chan))
|
|
|
- i += my_strcpy(s + i, "dont-kick-ops ");
|
|
|
|
|
- if (channel_wasoptest(chan))
|
|
|
|
|
- i += my_strcpy(s + i, "was-op-test ");
|
|
|
|
|
|
|
+ i += my_strcpy(s + i, "dontkickops ");
|
|
|
if (channel_logstatus(chan))
|
|
if (channel_logstatus(chan))
|
|
|
- i += my_strcpy(s + i, "log-status ");
|
|
|
|
|
|
|
+ i += my_strcpy(s + i, "statuslog ");
|
|
|
if (channel_revenge(chan))
|
|
if (channel_revenge(chan))
|
|
|
i += my_strcpy(s + i, "revenge ");
|
|
i += my_strcpy(s + i, "revenge ");
|
|
|
- if (channel_stopnethack(chan))
|
|
|
|
|
- i += my_strcpy(s + i, "stopnethack ");
|
|
|
|
|
|
|
+ if (channel_revenge(chan))
|
|
|
|
|
+ i += my_strcpy(s + i, "revengebot ");
|
|
|
if (channel_secret(chan))
|
|
if (channel_secret(chan))
|
|
|
i += my_strcpy(s + i, "secret ");
|
|
i += my_strcpy(s + i, "secret ");
|
|
|
if (channel_shared(chan))
|
|
if (channel_shared(chan))
|
|
@@ -573,36 +642,48 @@ static void channels_report(int idx, int details)
|
|
|
i += my_strcpy(s + i, "dynamic ");
|
|
i += my_strcpy(s + i, "dynamic ");
|
|
|
if (channel_autovoice(chan))
|
|
if (channel_autovoice(chan))
|
|
|
i += my_strcpy(s + i, "autovoice ");
|
|
i += my_strcpy(s + i, "autovoice ");
|
|
|
|
|
+ if (channel_autohalfop(chan))
|
|
|
|
|
+ i += my_strcpy(s + i, "autohalfop ");
|
|
|
if (channel_cycle(chan))
|
|
if (channel_cycle(chan))
|
|
|
i += my_strcpy(s + i, "cycle ");
|
|
i += my_strcpy(s + i, "cycle ");
|
|
|
if (channel_seen(chan))
|
|
if (channel_seen(chan))
|
|
|
i += my_strcpy(s + i, "seen ");
|
|
i += my_strcpy(s + i, "seen ");
|
|
|
if (channel_dynamicexempts(chan))
|
|
if (channel_dynamicexempts(chan))
|
|
|
- i += my_strcpy(s + i, "dynamic-exempts ");
|
|
|
|
|
- if (channel_nouserexempts(chan))
|
|
|
|
|
- i += my_strcpy(s + i, "forbid-user-exempts ");
|
|
|
|
|
|
|
+ i += my_strcpy(s + i, "dynamicexempts ");
|
|
|
|
|
+ if (!channel_nouserexempts(chan))
|
|
|
|
|
+ i += my_strcpy(s + i, "userexempts ");
|
|
|
if (channel_dynamicinvites(chan))
|
|
if (channel_dynamicinvites(chan))
|
|
|
- i += my_strcpy(s + i, "dynamic-invites ");
|
|
|
|
|
- if (channel_nouserinvites(chan))
|
|
|
|
|
- i += my_strcpy(s + i, "forbid-user-invites ");
|
|
|
|
|
|
|
+ i += my_strcpy(s + i, "dynamicinvites ");
|
|
|
|
|
+ if (!channel_nouserinvites(chan))
|
|
|
|
|
+ i += my_strcpy(s + i, "userinvites ");
|
|
|
if (channel_inactive(chan))
|
|
if (channel_inactive(chan))
|
|
|
i += my_strcpy(s + i, "inactive ");
|
|
i += my_strcpy(s + i, "inactive ");
|
|
|
|
|
+ if (channel_nodesynch(chan))
|
|
|
|
|
+ i += my_strcpy(s + i, "nodesynch ");
|
|
|
dprintf(idx, " Options: %s\n", s);
|
|
dprintf(idx, " Options: %s\n", s);
|
|
|
if (chan->need_op[0])
|
|
if (chan->need_op[0])
|
|
|
dprintf(idx, " To get ops I do: %s\n", chan->need_op);
|
|
dprintf(idx, " To get ops I do: %s\n", chan->need_op);
|
|
|
if (chan->need_invite[0])
|
|
if (chan->need_invite[0])
|
|
|
dprintf(idx, " To get invited I do: %s\n", chan->need_invite);
|
|
dprintf(idx, " To get invited I do: %s\n", chan->need_invite);
|
|
|
if (chan->need_limit[0])
|
|
if (chan->need_limit[0])
|
|
|
- dprintf(idx, " To get the channel limit up'd I do: %s\n", chan->need_limit);
|
|
|
|
|
|
|
+ dprintf(idx, " To get the channel limit up'd I do: %s\n",
|
|
|
|
|
+ chan->need_limit);
|
|
|
if (chan->need_unban[0])
|
|
if (chan->need_unban[0])
|
|
|
dprintf(idx, " To get unbanned I do: %s\n", chan->need_unban);
|
|
dprintf(idx, " To get unbanned I do: %s\n", chan->need_unban);
|
|
|
if (chan->need_key[0])
|
|
if (chan->need_key[0])
|
|
|
- dprintf(idx, " To get the channel key I do: %s\n", chan->need_key);
|
|
|
|
|
|
|
+ dprintf(idx, " To get the channel key I do: %s\n",
|
|
|
|
|
+ chan->need_key);
|
|
|
if (chan->idle_kick)
|
|
if (chan->idle_kick)
|
|
|
- dprintf(idx, " Kicking idle users after %d min\n", chan->idle_kick);
|
|
|
|
|
|
|
+ dprintf(idx, " Kicking idle users after %d min\n",
|
|
|
|
|
+ chan->idle_kick);
|
|
|
|
|
+ if (chan->stopnethack_mode)
|
|
|
|
|
+ dprintf(idx, " stopnethack-mode %d\n",
|
|
|
|
|
+ chan->stopnethack_mode);
|
|
|
|
|
+ if (chan->revenge_mode)
|
|
|
|
|
+ dprintf(idx, " revenge-mode %d\n",
|
|
|
|
|
+ chan->revenge_mode);
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
- chan = chan->next;
|
|
|
|
|
}
|
|
}
|
|
|
if (details) {
|
|
if (details) {
|
|
|
dprintf(idx, " Bans last %d mins.\n", ban_time);
|
|
dprintf(idx, " Bans last %d mins.\n", ban_time);
|
|
@@ -615,24 +696,22 @@ static int expmem_masklist(masklist *m)
|
|
|
{
|
|
{
|
|
|
int result = 0;
|
|
int result = 0;
|
|
|
|
|
|
|
|
- while (m) {
|
|
|
|
|
|
|
+ for (; m; m = m->next) {
|
|
|
result += sizeof(masklist);
|
|
result += sizeof(masklist);
|
|
|
if (m->mask)
|
|
if (m->mask)
|
|
|
result += strlen(m->mask) + 1;
|
|
result += strlen(m->mask) + 1;
|
|
|
if (m->who)
|
|
if (m->who)
|
|
|
result += strlen(m->who) + 1;
|
|
result += strlen(m->who) + 1;
|
|
|
- m = m->next;
|
|
|
|
|
}
|
|
}
|
|
|
return result;
|
|
return result;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
static int channels_expmem()
|
|
static int channels_expmem()
|
|
|
{
|
|
{
|
|
|
- int tot = 0;
|
|
|
|
|
- struct chanset_t *chan = chanset;
|
|
|
|
|
|
|
+ int tot = 0, i;
|
|
|
|
|
+ struct chanset_t *chan;
|
|
|
|
|
|
|
|
- Context;
|
|
|
|
|
- while (chan != NULL) {
|
|
|
|
|
|
|
+ for (chan = chanset; chan; chan = chan->next) {
|
|
|
tot += sizeof(struct chanset_t);
|
|
tot += sizeof(struct chanset_t);
|
|
|
|
|
|
|
|
tot += strlen(chan->channel.key) + 1;
|
|
tot += strlen(chan->channel.key) + 1;
|
|
@@ -644,37 +723,49 @@ static int channels_expmem()
|
|
|
tot += expmem_masklist(chan->channel.exempt);
|
|
tot += expmem_masklist(chan->channel.exempt);
|
|
|
tot += expmem_masklist(chan->channel.invite);
|
|
tot += expmem_masklist(chan->channel.invite);
|
|
|
|
|
|
|
|
- chan = chan->next;
|
|
|
|
|
|
|
+ for (i = 0; i < 6 && chan->cmode[i].op; i++)
|
|
|
|
|
+ tot += strlen(chan->cmode[i].op) + 1;
|
|
|
|
|
+ if (chan->key)
|
|
|
|
|
+ tot += strlen(chan->key) + 1;
|
|
|
|
|
+ if (chan->rmkey)
|
|
|
|
|
+ tot += strlen(chan->rmkey) + 1;
|
|
|
}
|
|
}
|
|
|
|
|
+ tot += expmem_udef(udef);
|
|
|
return tot;
|
|
return tot;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+#if ((TCL_MAJOR_VERSION == 8) && (TCL_MINOR_VERSION >= 4))
|
|
|
static char *traced_globchanset(ClientData cdata, Tcl_Interp * irp,
|
|
static char *traced_globchanset(ClientData cdata, Tcl_Interp * irp,
|
|
|
- char *name1, char *name2, int flags)
|
|
|
|
|
|
|
+ char *name1, CONST char *name2, int flags)
|
|
|
|
|
+#else
|
|
|
|
|
+static char *traced_globchanset(ClientData cdata, Tcl_Interp * irp,
|
|
|
|
|
+ char *name1, char *name2, int flags)
|
|
|
|
|
+#endif
|
|
|
{
|
|
{
|
|
|
char *s;
|
|
char *s;
|
|
|
char *t;
|
|
char *t;
|
|
|
int i;
|
|
int i;
|
|
|
int items;
|
|
int items;
|
|
|
|
|
+#if ((TCL_MAJOR_VERSION == 8) && (TCL_MINOR_VERSION >= 4))
|
|
|
|
|
+ CONST char **item;
|
|
|
|
|
+#else
|
|
|
char **item;
|
|
char **item;
|
|
|
|
|
+#endif
|
|
|
|
|
|
|
|
- Context;
|
|
|
|
|
if (flags & (TCL_TRACE_READS | TCL_TRACE_UNSETS)) {
|
|
if (flags & (TCL_TRACE_READS | TCL_TRACE_UNSETS)) {
|
|
|
Tcl_SetVar2(interp, name1, name2, glob_chanset, TCL_GLOBAL_ONLY);
|
|
Tcl_SetVar2(interp, name1, name2, glob_chanset, TCL_GLOBAL_ONLY);
|
|
|
if (flags & TCL_TRACE_UNSETS)
|
|
if (flags & TCL_TRACE_UNSETS)
|
|
|
Tcl_TraceVar(interp, "global-chanset",
|
|
Tcl_TraceVar(interp, "global-chanset",
|
|
|
TCL_TRACE_READS | TCL_TRACE_WRITES | TCL_TRACE_UNSETS,
|
|
TCL_TRACE_READS | TCL_TRACE_WRITES | TCL_TRACE_UNSETS,
|
|
|
traced_globchanset, NULL);
|
|
traced_globchanset, NULL);
|
|
|
- } else { /* write */
|
|
|
|
|
|
|
+ } else { /* Write */
|
|
|
s = Tcl_GetVar2(interp, name1, name2, TCL_GLOBAL_ONLY);
|
|
s = Tcl_GetVar2(interp, name1, name2, TCL_GLOBAL_ONLY);
|
|
|
Tcl_SplitList(interp, s, &items, &item);
|
|
Tcl_SplitList(interp, s, &items, &item);
|
|
|
- Context;
|
|
|
|
|
for (i = 0; i<items; i++) {
|
|
for (i = 0; i<items; i++) {
|
|
|
if (!(item[i]) || (strlen(item[i]) < 2)) continue;
|
|
if (!(item[i]) || (strlen(item[i]) < 2)) continue;
|
|
|
s = glob_chanset;
|
|
s = glob_chanset;
|
|
|
while (s[0]) {
|
|
while (s[0]) {
|
|
|
- t = strchr(s, ' '); /* cant be NULL coz of the extra space */
|
|
|
|
|
- Context;
|
|
|
|
|
|
|
+ t = strchr(s, ' '); /* Can't be NULL coz of the extra space */
|
|
|
t[0] = 0;
|
|
t[0] = 0;
|
|
|
if (!strcmp(s + 1, item[i] + 1)) {
|
|
if (!strcmp(s + 1, item[i] + 1)) {
|
|
|
s[0] = item[i][0]; /* +- */
|
|
s[0] = item[i][0]; /* +- */
|
|
@@ -694,37 +785,41 @@ static char *traced_globchanset(ClientData cdata, Tcl_Interp * irp,
|
|
|
|
|
|
|
|
static tcl_ints my_tcl_ints[] =
|
|
static tcl_ints my_tcl_ints[] =
|
|
|
{
|
|
{
|
|
|
- {"share-greet", 0, 0},
|
|
|
|
|
- {"use-info", &use_info, 0},
|
|
|
|
|
- {"ban-time", &ban_time, 0},
|
|
|
|
|
- {"exempt-time", &exempt_time, 0},
|
|
|
|
|
- {"invite-time", &invite_time, 0},
|
|
|
|
|
- {"must-be-owner", &must_be_owner, 0},
|
|
|
|
|
- {"quiet-save", &quiet_save, 0},
|
|
|
|
|
- {0, 0, 0}
|
|
|
|
|
|
|
+ {"share-greet", NULL, 0},
|
|
|
|
|
+ {"use-info", &use_info, 0},
|
|
|
|
|
+ {"ban-time", &ban_time, 0},
|
|
|
|
|
+ {"exempt-time", &exempt_time, 0},
|
|
|
|
|
+ {"invite-time", &invite_time, 0},
|
|
|
|
|
+ {"quiet-save", &quiet_save, 0},
|
|
|
|
|
+ {"global-stopnethack-mode", &global_stopnethack_mode, 0},
|
|
|
|
|
+ {"global-revenge-mode", &global_revenge_mode, 0},
|
|
|
|
|
+ {"global-idle-kick", &global_idle_kick, 0},
|
|
|
|
|
+ {NULL, NULL, 0}
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
static tcl_coups mychan_tcl_coups[] =
|
|
static tcl_coups mychan_tcl_coups[] =
|
|
|
{
|
|
{
|
|
|
- {"global-flood-chan", &gfld_chan_thr, &gfld_chan_time},
|
|
|
|
|
- {"global-flood-deop", &gfld_deop_thr, &gfld_deop_time},
|
|
|
|
|
- {"global-flood-kick", &gfld_kick_thr, &gfld_kick_time},
|
|
|
|
|
- {"global-flood-join", &gfld_join_thr, &gfld_join_time},
|
|
|
|
|
- {"global-flood-ctcp", &gfld_ctcp_thr, &gfld_ctcp_time},
|
|
|
|
|
- {0, 0, 0}
|
|
|
|
|
|
|
+ {"global-flood-chan", &gfld_chan_thr, &gfld_chan_time},
|
|
|
|
|
+ {"global-flood-deop", &gfld_deop_thr, &gfld_deop_time},
|
|
|
|
|
+ {"global-flood-kick", &gfld_kick_thr, &gfld_kick_time},
|
|
|
|
|
+ {"global-flood-join", &gfld_join_thr, &gfld_join_time},
|
|
|
|
|
+ {"global-flood-ctcp", &gfld_ctcp_thr, &gfld_ctcp_time},
|
|
|
|
|
+ {"global-flood-nick", &gfld_nick_thr, &gfld_nick_time},
|
|
|
|
|
+ {"global-aop-delay", &global_aop_min, &global_aop_max},
|
|
|
|
|
+ {NULL, NULL, NULL}
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
static tcl_strings my_tcl_strings[] =
|
|
static tcl_strings my_tcl_strings[] =
|
|
|
{
|
|
{
|
|
|
- {"chanfile", chanfile, 120, STR_PROTECT},
|
|
|
|
|
- {"global-chanmode", glob_chanmode, 64, 0},
|
|
|
|
|
- {0, 0, 0, 0}
|
|
|
|
|
|
|
+ {"chanfile", chanfile, 120, STR_PROTECT},
|
|
|
|
|
+ {"global-chanmode", glob_chanmode, 64, 0},
|
|
|
|
|
+ {NULL, NULL, 0, 0}
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
static char *channels_close()
|
|
static char *channels_close()
|
|
|
{
|
|
{
|
|
|
- Context;
|
|
|
|
|
write_channels();
|
|
write_channels();
|
|
|
|
|
+ free_udef(udef);
|
|
|
rem_builtins(H_chon, my_chon);
|
|
rem_builtins(H_chon, my_chon);
|
|
|
rem_builtins(H_dcc, C_dcc_irc);
|
|
rem_builtins(H_dcc, C_dcc_irc);
|
|
|
rem_tcl_commands(channels_cmds);
|
|
rem_tcl_commands(channels_cmds);
|
|
@@ -732,6 +827,7 @@ static char *channels_close()
|
|
|
rem_tcl_ints(my_tcl_ints);
|
|
rem_tcl_ints(my_tcl_ints);
|
|
|
rem_tcl_coups(mychan_tcl_coups);
|
|
rem_tcl_coups(mychan_tcl_coups);
|
|
|
del_hook(HOOK_USERFILE, (Function) channels_writeuserfile);
|
|
del_hook(HOOK_USERFILE, (Function) channels_writeuserfile);
|
|
|
|
|
+ del_hook(HOOK_BACKUP, (Function) backup_chanfile);
|
|
|
del_hook(HOOK_REHASH, (Function) channels_rehash);
|
|
del_hook(HOOK_REHASH, (Function) channels_rehash);
|
|
|
del_hook(HOOK_PRE_REHASH, (Function) channels_prerehash);
|
|
del_hook(HOOK_PRE_REHASH, (Function) channels_prerehash);
|
|
|
del_hook(HOOK_MINUTELY, (Function) check_expired_bans);
|
|
del_hook(HOOK_MINUTELY, (Function) check_expired_bans);
|
|
@@ -746,7 +842,7 @@ static char *channels_close()
|
|
|
return NULL;
|
|
return NULL;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-char *channels_start();
|
|
|
|
|
|
|
+EXPORT_SCOPE char *channels_start();
|
|
|
|
|
|
|
|
static Function channels_table[] =
|
|
static Function channels_table[] =
|
|
|
{
|
|
{
|
|
@@ -779,25 +875,21 @@ static Function channels_table[] =
|
|
|
(Function) u_sticky_mask,
|
|
(Function) u_sticky_mask,
|
|
|
(Function) ismasked,
|
|
(Function) ismasked,
|
|
|
(Function) add_chanrec_by_handle,
|
|
(Function) add_chanrec_by_handle,
|
|
|
-/* *HOLE* channels_funcs[23] used to be isexempted() <cybah> */
|
|
|
|
|
- (Function) NULL,
|
|
|
|
|
|
|
+ (Function) NULL, /* [23] used to be isexempted() <cybah> */
|
|
|
/* 24 - 27 */
|
|
/* 24 - 27 */
|
|
|
(Function) & exempt_time,
|
|
(Function) & exempt_time,
|
|
|
-/* *HOLE* channels_funcs[25] used to be isinvited() <cybah> */
|
|
|
|
|
- (Function) NULL,
|
|
|
|
|
|
|
+ (Function) NULL, /* [25] used to be isinvited() <cybah> */
|
|
|
(Function) & invite_time,
|
|
(Function) & invite_time,
|
|
|
(Function) NULL,
|
|
(Function) NULL,
|
|
|
/* 28 - 31 */
|
|
/* 28 - 31 */
|
|
|
-/* *HOLE* channels_funcs[28] used to be u_setsticky_exempt() <cybah> */
|
|
|
|
|
- (Function) NULL,
|
|
|
|
|
|
|
+ (Function) NULL, /* [28] used to be u_setsticky_exempt() <cybah> */
|
|
|
(Function) u_delexempt,
|
|
(Function) u_delexempt,
|
|
|
(Function) u_addexempt,
|
|
(Function) u_addexempt,
|
|
|
(Function) NULL,
|
|
(Function) NULL,
|
|
|
/* 32 - 35 */
|
|
/* 32 - 35 */
|
|
|
-/* *HOLE* channels_funcs[32] used to be u_sticky_exempt() <cybah> */
|
|
|
|
|
- (Function) NULL,
|
|
|
|
|
|
|
+ (Function) NULL,/* [32] used to be u_sticky_exempt() <cybah> */
|
|
|
(Function) NULL,
|
|
(Function) NULL,
|
|
|
- (Function) killchanset,
|
|
|
|
|
|
|
+ (Function) NULL, /* [34] used to be killchanset(). */
|
|
|
(Function) u_delinvite,
|
|
(Function) u_delinvite,
|
|
|
/* 36 - 39 */
|
|
/* 36 - 39 */
|
|
|
(Function) u_addinvite,
|
|
(Function) u_addinvite,
|
|
@@ -807,6 +899,11 @@ static Function channels_table[] =
|
|
|
/* 40 - 43 */
|
|
/* 40 - 43 */
|
|
|
(Function) write_invites,
|
|
(Function) write_invites,
|
|
|
(Function) ismodeline,
|
|
(Function) ismodeline,
|
|
|
|
|
+ (Function) initudef,
|
|
|
|
|
+ (Function) ngetudef,
|
|
|
|
|
+ /* 44 - 47 */
|
|
|
|
|
+ (Function) expired_mask,
|
|
|
|
|
+ (Function) remove_channel,
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
char *channels_start(Function * global_funcs)
|
|
char *channels_start(Function * global_funcs)
|
|
@@ -823,14 +920,57 @@ char *channels_start(Function * global_funcs)
|
|
|
gfld_join_time = 60;
|
|
gfld_join_time = 60;
|
|
|
gfld_ctcp_thr = 5;
|
|
gfld_ctcp_thr = 5;
|
|
|
gfld_ctcp_time = 60;
|
|
gfld_ctcp_time = 60;
|
|
|
- Context;
|
|
|
|
|
|
|
+ global_idle_kick = 0;
|
|
|
|
|
+ global_aop_min = 5;
|
|
|
|
|
+ global_aop_max = 30;
|
|
|
|
|
+ setstatic = 0;
|
|
|
|
|
+ use_info = 1;
|
|
|
|
|
+ ban_time = 60;
|
|
|
|
|
+ exempt_time = 0;
|
|
|
|
|
+ invite_time = 0;
|
|
|
|
|
+ strcpy(chanfile, "chanfile");
|
|
|
|
|
+ chan_hack = 0;
|
|
|
|
|
+ quiet_save = 0;
|
|
|
|
|
+ strcpy(glob_chanmode, "nt");
|
|
|
|
|
+ udef = NULL;
|
|
|
|
|
+ global_stopnethack_mode = 0;
|
|
|
|
|
+ global_revenge_mode = 1;
|
|
|
|
|
+ strcpy(glob_chanset,
|
|
|
|
|
+ "-enforcebans "
|
|
|
|
|
+ "+dynamicbans "
|
|
|
|
|
+ "+userbans "
|
|
|
|
|
+ "-autoop "
|
|
|
|
|
+ "-bitch "
|
|
|
|
|
+ "+greet "
|
|
|
|
|
+ "+protectops "
|
|
|
|
|
+ "+statuslog "
|
|
|
|
|
+ "-revenge "
|
|
|
|
|
+ "-secret "
|
|
|
|
|
+ "-autovoice "
|
|
|
|
|
+ "+cycle "
|
|
|
|
|
+ "+dontkickops "
|
|
|
|
|
+ "-inactive "
|
|
|
|
|
+ "-protectfriends "
|
|
|
|
|
+ "+shared "
|
|
|
|
|
+ "-seen "
|
|
|
|
|
+ "+userexempts "
|
|
|
|
|
+ "+dynamicexempts "
|
|
|
|
|
+ "+userinvites "
|
|
|
|
|
+ "+dynamicinvites "
|
|
|
|
|
+ "-revengebot "
|
|
|
|
|
+ "-protecthalfops "
|
|
|
|
|
+ "-autohalfop "
|
|
|
|
|
+ "-nodesynch ");
|
|
|
module_register(MODULE_NAME, channels_table, 1, 0);
|
|
module_register(MODULE_NAME, channels_table, 1, 0);
|
|
|
- if (!module_depend(MODULE_NAME, "eggdrop", 104, 0))
|
|
|
|
|
- return "This module needs eggdrop1.4.0 or later";
|
|
|
|
|
|
|
+ if (!module_depend(MODULE_NAME, "eggdrop", 106, 7)) {
|
|
|
|
|
+ module_undepend(MODULE_NAME);
|
|
|
|
|
+ return "This module requires Eggdrop 1.6.7 or later.";
|
|
|
|
|
+ }
|
|
|
add_hook(HOOK_MINUTELY, (Function) check_expired_bans);
|
|
add_hook(HOOK_MINUTELY, (Function) check_expired_bans);
|
|
|
add_hook(HOOK_MINUTELY, (Function) check_expired_exempts);
|
|
add_hook(HOOK_MINUTELY, (Function) check_expired_exempts);
|
|
|
add_hook(HOOK_MINUTELY, (Function) check_expired_invites);
|
|
add_hook(HOOK_MINUTELY, (Function) check_expired_invites);
|
|
|
add_hook(HOOK_USERFILE, (Function) channels_writeuserfile);
|
|
add_hook(HOOK_USERFILE, (Function) channels_writeuserfile);
|
|
|
|
|
+ add_hook(HOOK_BACKUP, (Function) backup_chanfile);
|
|
|
add_hook(HOOK_REHASH, (Function) channels_rehash);
|
|
add_hook(HOOK_REHASH, (Function) channels_rehash);
|
|
|
add_hook(HOOK_PRE_REHASH, (Function) channels_prerehash);
|
|
add_hook(HOOK_PRE_REHASH, (Function) channels_prerehash);
|
|
|
Tcl_TraceVar(interp, "global-chanset",
|
|
Tcl_TraceVar(interp, "global-chanset",
|