1 |
/* |
2 |
* botbinds.c -- part of botnetop.mod |
3 |
* |
4 |
* $Id$ |
5 |
*/ |
6 |
/* |
7 |
* Copyright (C) 2000, 2001, 2002 Teemu Hjelt <temex@iki.fi> |
8 |
* |
9 |
* This program is free software; you can redistribute it and/or |
10 |
* modify it under the terms of the GNU General Public License |
11 |
* as published by the Free Software Foundation; either version 2 |
12 |
* of the License, or (at your option) any later version. |
13 |
* |
14 |
* This program is distributed in the hope that it will be useful, |
15 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
16 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
17 |
* GNU General Public License for more details. |
18 |
* |
19 |
* You should have received a copy of the GNU General Public License |
20 |
* along with this program; if not, write to the Free Software |
21 |
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
22 |
*/ |
23 |
|
24 |
static int bnop_linkop(char *bot, char *via) |
25 |
{ |
26 |
struct chanset_t *chan = NULL; |
27 |
|
28 |
if (bop_linkop && (!egg_strcasecmp(bot, botnetnick) || !egg_strcasecmp(via, botnetnick))) { |
29 |
for (chan = chanset; chan != NULL; chan = chan->next) { |
30 |
if (!isop(botname, chan)) |
31 |
bnop_reqop(chan->dname, "op"); |
32 |
} |
33 |
} |
34 |
|
35 |
return 0; |
36 |
} |
37 |
|
38 |
static int bnop_reqtmr(char *bot, char *code, char *par) |
39 |
{ |
40 |
char *chname = NULL; |
41 |
struct chanset_t *chan = NULL; |
42 |
struct delay_t *d = NULL; |
43 |
struct userrec *u = NULL; |
44 |
|
45 |
chname = newsplit(&par); |
46 |
if (!(chan = findchan_by_dname(chname)) || !(u = get_user_by_handle(userlist, bot))) |
47 |
return 0; |
48 |
if (!matchattr(u, "b|-", chan->dname) || !matchattr(u, "o|o", chan->dname) || matchattr(u, "d|d", chan->dname)) |
49 |
return 0; |
50 |
if (check_request_status(bot, chan->dname)) |
51 |
return 0; |
52 |
if (check_flood_status(chan->dname)) |
53 |
return 0; |
54 |
if (!bop_delay || lowbots(chan)) |
55 |
bnop_askbot(bot, chan->dname); |
56 |
else { |
57 |
if (!(d = find_delay(chan->dname, bot))) { |
58 |
if (!(d = add_delay(chan->dname, bot))) |
59 |
return 0; |
60 |
} |
61 |
d->reqtime = now + (random() % bop_delay) + 2; |
62 |
strncpyz(d->handle, bot, strlen(bot) + 1); |
63 |
} |
64 |
|
65 |
return 0; |
66 |
} |
67 |
|
68 |
static int bnop_doiwantops(char *bot, char *code, char *par) |
69 |
{ |
70 |
int i, bufsize; |
71 |
char *chname = NULL, *fromnick = NULL, *buf = NULL; |
72 |
struct chanset_t *chan = NULL; |
73 |
|
74 |
chname = newsplit(&par); |
75 |
fromnick = newsplit(&par); |
76 |
if (!(chan = findchan_by_dname(chname))) |
77 |
return 0; |
78 |
if ((i = nextbot(bot)) >= 0) { |
79 |
if (check_flood_status(chan->dname)) |
80 |
return 0; |
81 |
if (check_delay_status(chan->dname, bot)) |
82 |
return 0; |
83 |
bufsize = strlen(chan->dname) + strlen(botname) + strlen(botuserhost) + 14 + 1; |
84 |
buf = (char *) nmalloc(bufsize); |
85 |
if (buf == NULL) |
86 |
return 0; |
87 |
egg_snprintf(buf, bufsize, "yesiwantops %s %s %s", chan->dname, botname, |
88 |
strchr("~+-^=", botuserhost[0]) ? botuserhost + 1 : botuserhost); |
89 |
botnet_send_zapf(i, botnetnick, bot, buf); |
90 |
nfree(buf); |
91 |
if (bop_log >= 2) |
92 |
putlog(LOG_MISC, "*", "botnetop.mod: " BOTNETOP_REQOPS, bot, chan->dname); |
93 |
} |
94 |
|
95 |
return 0; |
96 |
} |
97 |
|
98 |
static int bnop_botwantsops(char *bot, char *code, char *par) |
99 |
{ |
100 |
char *chname = NULL, *fromnick = NULL, *fromhost = NULL, s[UHOSTLEN]; |
101 |
struct chanset_t *chan = NULL; |
102 |
struct userrec *u = NULL; |
103 |
memberlist *m = NULL; |
104 |
|
105 |
chname = newsplit(&par); |
106 |
fromnick = newsplit(&par); |
107 |
fromhost = newsplit(&par); |
108 |
if (!(chan = findchan_by_dname(chname)) || !(u = get_user_by_handle(userlist, bot))) |
109 |
return 0; |
110 |
if (!ismember(chan, botname) || !isop(botname, chan)) |
111 |
return 0; |
112 |
if (!(m = ismember(chan, fromnick)) || chan_issplit(m)) |
113 |
return 0; |
114 |
if (!matchattr(u, "b|-", chan->dname) && !matchattr(u, "o|o", chan->dname) && matchattr(u, "d|d", chan->dname)) |
115 |
return 0; |
116 |
egg_snprintf(s, sizeof s, "%s!%s", m->nick, m->userhost); |
117 |
if (!(u = get_user_by_host(s))) |
118 |
return 0; |
119 |
if (bop_hcheck && fromhost[0] && |
120 |
egg_strcasecmp(fromhost, strchr("~^+=-", m->userhost[0]) ? m->userhost + 1 : m->userhost)) |
121 |
return 0; |
122 |
if (!matchattr(u, "o|o", chan->dname)) { |
123 |
if (!fromhost[0] || !bop_addhost) |
124 |
return 0; |
125 |
if (strchr("~^+=-", m->userhost[0])) |
126 |
egg_snprintf(s, sizeof s, "*!%s%s", strict_host ? "?" : "", m->userhost + 1); |
127 |
else |
128 |
egg_snprintf(s, sizeof s, "*!%s", m->userhost); |
129 |
addhost_by_handle(bot, s); |
130 |
putlog(LOG_MISC, "*", "botnetop.mod: " BOTNETOP_ADDHOST, s, bot); |
131 |
} |
132 |
if (bop_quickop) { |
133 |
if (!isop(fromnick, chan) || bop_osync) |
134 |
dprintf(DP_MODE, "MODE %s +o %s\n", chan->dname, fromnick); |
135 |
else |
136 |
return 0; |
137 |
} else { |
138 |
if (!isop(fromnick, chan)) |
139 |
add_mode(chan, '+', 'o', fromnick); |
140 |
else if (bop_osync) |
141 |
dprintf(DP_MODE, "MODE %s +o %s\n", chan->dname, fromnick); |
142 |
else |
143 |
return 0; |
144 |
} |
145 |
if (bop_log >= 2) { |
146 |
if (egg_strcasecmp(fromnick, bot)) |
147 |
putlog(LOG_MISC, "*", "botnetop.mod: " BOTNETOP_GAVEOPS2, bot, fromnick, chan->dname); |
148 |
else |
149 |
putlog(LOG_MISC, "*", "botnetop.mod: " BOTNETOP_GAVEOPS, bot, chan->dname); |
150 |
} |
151 |
|
152 |
return 0; |
153 |
} |
154 |
|
155 |
static int bnop_botwantsin(char *bot, char *code, char *par) |
156 |
{ |
157 |
int i, bufsize, bans = 0; |
158 |
char *chname = NULL, *fromnick = NULL, *fromhost = NULL, *buf = NULL, *mask = NULL, s[UHOSTLEN]; |
159 |
struct chanset_t *chan = NULL; |
160 |
struct userrec *u = NULL; |
161 |
masklist *b = NULL; |
162 |
|
163 |
chname = newsplit(&par); |
164 |
fromnick = newsplit(&par); |
165 |
fromhost = newsplit(&par); |
166 |
if (!(chan = findchan_by_dname(chname)) || !(u = get_user_by_handle(userlist, bot))) |
167 |
return 0; |
168 |
if (!isop(botname, chan) || !matchattr(u, "b|-", chan->dname) || !matchattr(u, "fo|fo", chan->dname)) |
169 |
return 0; |
170 |
if (fromhost[0]) { |
171 |
if ((mask = strchr(fromhost, '!'))) |
172 |
mask++; |
173 |
else |
174 |
mask = fromhost; |
175 |
egg_snprintf(s, sizeof s, "*!*%s", strchr("~^+=-", mask[0]) ? mask + 1 : mask); |
176 |
if (strlen(s) > 70) { |
177 |
s[69] = '*'; |
178 |
s[70] = 0; |
179 |
} |
180 |
} |
181 |
if (!strcmp(code, "wantkey") && (chan->channel.mode & CHANKEY)) { |
182 |
if (bop_onkey == 1) |
183 |
bnop_invite(chan, fromnick, bot, fromhost); |
184 |
else { |
185 |
if ((i = nextbot(bot)) >= 0) { |
186 |
if (check_flood_status(chan->dname)) |
187 |
return 0; |
188 |
bufsize = strlen(chan->dname) + strlen(chan->channel.key) + 8 + 1; |
189 |
buf = (char *) nmalloc(bufsize); |
190 |
if (buf == NULL) |
191 |
return 0; |
192 |
egg_snprintf(buf, bufsize, "thekey %s %s", chan->dname, chan->channel.key); |
193 |
botnet_send_zapf(i, botnetnick, bot, buf); |
194 |
nfree(buf); |
195 |
if (bop_log >= 1) |
196 |
putlog(LOG_MISC, "*", "botnetop.mod: " BOTNETOP_GAVEKEY, chan->dname, bot); |
197 |
} |
198 |
} |
199 |
} else if (!strcmp(code, "wantinvite") && (chan->channel.mode & CHANINV)) { |
200 |
if ((bop_oninvite == 1) && s[0]) { |
201 |
add_mode(chan, '+', 'I', s); |
202 |
if (bop_log >= 1) |
203 |
putlog(LOG_MISC, "*", "botnetop.mod: " BOTNETOP_SETINVITE, s, chan->dname, bot); |
204 |
} else |
205 |
bnop_invite(chan, fromnick, bot, fromhost); |
206 |
} else if (!strcmp(code, "wantlimit") && (chan->channel.maxmembers != 0)) { |
207 |
if (bop_onlimit == 1) |
208 |
bnop_invite(chan, fromnick, bot, fromhost); |
209 |
else { |
210 |
add_mode(chan, '+', 'l', int_to_base10(chan->channel.members + 1)); |
211 |
if (bop_log >= 1) |
212 |
putlog(LOG_MISC, "*", "botnetop.mod: " BOTNETOP_RAISEDLIMIT, chan->dname, bot); |
213 |
} |
214 |
} else if (!strcmp(code, "wantunban")) { |
215 |
if ((bop_onunban == 1) && s[0]) { |
216 |
add_mode(chan, '+', 'e', s); |
217 |
if (bop_log >= 1) |
218 |
putlog(LOG_MISC, "*", "botnetop.mod: " BOTNETOP_SETEXEMPT, s, chan->dname, bot); |
219 |
} else if (bop_onunban == 2) |
220 |
bnop_invite(chan, fromnick, bot, strchr("~+-^=", mask[0]) ? mask + 1 : mask); |
221 |
else { |
222 |
for (b = chan->channel.ban; b->mask[0]; b = b->next) { |
223 |
if (wild_match(b->mask, fromhost)) { |
224 |
add_mode(chan, '-', 'b', b->mask); |
225 |
bans++; |
226 |
} |
227 |
} |
228 |
if ((bop_log >= 1) && (bans > 0)) |
229 |
putlog(LOG_MISC, "*", "botnetop.mod: " BOTNETOP_UNBANNED, bot, chan->dname, bans); |
230 |
} |
231 |
} |
232 |
|
233 |
return 0; |
234 |
} |
235 |
|
236 |
static int bnop_joinkey(char *bot, char *code, char *par) |
237 |
{ |
238 |
char *chname = NULL, *key = NULL; |
239 |
struct chanset_t *chan = NULL; |
240 |
|
241 |
chname = newsplit(&par); |
242 |
key = newsplit(&par); |
243 |
if (!(chan = findchan_by_dname(chname)) || ismember(chan, botname)) |
244 |
return 0; |
245 |
dprintf(DP_SERVER, "JOIN %s %s\n", chan->dname, key); |
246 |
|
247 |
return 0; |
248 |
} |
249 |
|
250 |
static cmd_t botnetop_link[] = |
251 |
{ |
252 |
{"*", "", (Function) bnop_linkop, "bop_linkop"}, |
253 |
{0, 0, 0, 0} |
254 |
}; |
255 |
|
256 |
static cmd_t botnetop_bot[] = |
257 |
{ |
258 |
{"doyawantops", "", (Function) bnop_doiwantops, "bop_doiwantops"}, |
259 |
{"yesiwantops", "", (Function) bnop_botwantsops, "bop_botwantsops"}, |
260 |
{"reqops", "", (Function) bnop_reqtmr, "bop_reqtmr"}, |
261 |
{"wantkey", "", (Function) bnop_botwantsin, "bop_botwantsin"}, |
262 |
{"wantinvite", "", (Function) bnop_botwantsin, "bop_botwantsin"}, |
263 |
{"wantlimit", "", (Function) bnop_botwantsin, "bop_botwantsin"}, |
264 |
{"wantunban", "", (Function) bnop_botwantsin, "bop_botwantsin"}, |
265 |
{"thekey", "", (Function) bnop_joinkey, "bop_joinkey"}, |
266 |
{0, 0, 0, 0} |
267 |
}; |