Parent Directory
|
Revision Log
|
Revision Graph
* Removed protection stuff, will be added back in a module later. * Removed klined, ques5, sentinel, and notes2 as they won't be compatable and are not maintained by us.
1 | guppy | 1.49 | /* |
2 | tothwolf | 1.102 | * cmds.c -- |
3 | guppy | 1.49 | * |
4 | tothwolf | 1.102 | * commands from a user via dcc |
5 | * (split in 2, this portion contains no-irc commands) | ||
6 | segfault | 1.1 | */ |
7 | guppy | 1.49 | /* |
8 | * Copyright (C) 1997 Robey Pointer | ||
9 | wcc | 1.110 | * Copyright (C) 1999, 2000, 2001, 2002, 2003 Eggheads Development Team |
10 | guppy | 1.49 | * |
11 | fabian | 1.15 | * This program is free software; you can redistribute it and/or |
12 | * modify it under the terms of the GNU General Public License | ||
13 | * as published by the Free Software Foundation; either version 2 | ||
14 | * of the License, or (at your option) any later version. | ||
15 | guppy | 1.49 | * |
16 | fabian | 1.15 | * This program is distributed in the hope that it will be useful, |
17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
19 | * GNU General Public License for more details. | ||
20 | guppy | 1.49 | * |
21 | fabian | 1.15 | * You should have received a copy of the GNU General Public License |
22 | * along with this program; if not, write to the Free Software | ||
23 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
24 | segfault | 1.1 | */ |
25 | tothwolf | 1.102 | |
26 | #ifndef lint | ||
27 | wcc | 1.111 | static const char rcsid[] = "$Id: cmds.c,v 1.110 2003/01/02 21:33:15 wcc Exp $"; |
28 | tothwolf | 1.102 | #endif |
29 | segfault | 1.1 | |
30 | #include "main.h" | ||
31 | #include "modules.h" | ||
32 | ite | 1.87 | #include "logfile.h" |
33 | #include "misc.h" | ||
34 | wingman | 1.101 | #include "cmdt.h" /* cmd_t */ |
35 | stdarg | 1.104 | #include "core_binds.h" /* check_bind_act, check_bind_chpt, |
36 | check_bind_chjn, check_bind_chof */ | ||
37 | wingman | 1.101 | #include "users.h" /* get_user_by_host, set_user, |
38 | USERENTRY_PASS */ | ||
39 | #include "chanprog.h" /* masktype, tell_verbose_status, | ||
40 | tell_settings, maskname, logmodes | ||
41 | isowner, reload */ | ||
42 | #include "dccutil.h" /* dprintf_eggdrop, not_away, set_away | ||
43 | tell_dcc, do_boot, chanout_but, | ||
44 | dcc_chatter, flush_lines */ | ||
45 | #include "net.h" /* tell_netdebug, killsock */ | ||
46 | #include "cmds.h" /* prototypes */ | ||
47 | |||
48 | segfault | 1.1 | #include <ctype.h> |
49 | stdarg | 1.100 | #include "traffic.h" /* egg_traffic_t */ |
50 | segfault | 1.1 | |
51 | fabian | 1.22 | extern struct chanset_t *chanset; |
52 | extern struct dcc_t *dcc; | ||
53 | stdarg | 1.108 | extern user_t *userlist; |
54 | fabian | 1.22 | extern int dcc_total, remote_boots, backgrd, make_userfile, |
55 | guppy | 1.81 | do_restart, conmask, strict_host, |
56 | guppy | 1.80 | term_z, con_chan; |
57 | stdarg | 1.100 | extern egg_traffic_t traffic; |
58 | ite | 1.86 | extern char botnetnick[], ver[], network[], |
59 | guppy | 1.62 | owner[], spaces[], quit_msg[]; |
60 | fabian | 1.22 | extern time_t now, online_since; |
61 | guppy | 1.83 | extern module_entry *module_list; |
62 | wingman | 1.101 | |
63 | #ifndef MAKING_MODS | ||
64 | extern struct dcc_table DCC_CHAT, DCC_BOT, DCC_RELAY, DCC_FORK_BOT, | ||
65 | DCC_CHAT_PASS; | ||
66 | #endif /* MAKING_MODS */ | ||
67 | fabian | 1.22 | |
68 | guppy | 1.46 | static char *btos(unsigned long); |
69 | fabian | 1.22 | |
70 | segfault | 1.1 | |
71 | stdarg | 1.108 | static void tell_who(user_t *u, int idx, int chan) |
72 | segfault | 1.1 | { |
73 | int i, k, ok = 0, atr = u ? u->flags : 0, len; | ||
74 | char s[1024]; /* temp fix - 1.4 has a better one */ | ||
75 | |||
76 | guppy | 1.45 | if (!chan) |
77 | segfault | 1.1 | dprintf(idx, "Party line members: (* = owner, + = master, @ = op)\n"); |
78 | else { | ||
79 | stdarg | 1.93 | dprintf(idx, |
80 | segfault | 1.1 | "People on channel %s%d: (* = owner, + = master, @ = op)\n", |
81 | (chan < 100000) ? "" : "*", chan % 100000); | ||
82 | } | ||
83 | for (i = 0; i < dcc_total; i++) | ||
84 | if (dcc[i].type == &DCC_CHAT) | ||
85 | if (dcc[i].u.chat->channel == chan) { | ||
86 | spaces[len = HANDLEN - strlen(dcc[i].nick)] = 0; | ||
87 | if (atr & USER_OWNER) { | ||
88 | ite | 1.88 | sprintf(s, " [%.2lu] %c%s%s %s", dcc[i].sock, |
89 | (geticon(dcc[i].user) == '-' ? ' ' : geticon(dcc[i].user)), | ||
90 | segfault | 1.1 | dcc[i].nick, spaces, dcc[i].host); |
91 | } else { | ||
92 | sprintf(s, " %c%s%s %s", | ||
93 | ite | 1.88 | (geticon(dcc[i].user) == '-' ? ' ' : geticon(dcc[i].user)), |
94 | segfault | 1.1 | dcc[i].nick, spaces, dcc[i].host); |
95 | } | ||
96 | spaces[len] = ' '; | ||
97 | if (atr & USER_MASTER) { | ||
98 | if (dcc[i].u.chat->con_flags) | ||
99 | sprintf(&s[strlen(s)], " (con:%s)", | ||
100 | masktype(dcc[i].u.chat->con_flags)); | ||
101 | } | ||
102 | if (now - dcc[i].timeval > 300) { | ||
103 | unsigned long days, hrs, mins; | ||
104 | |||
105 | days = (now - dcc[i].timeval) / 86400; | ||
106 | hrs = ((now - dcc[i].timeval) - (days * 86400)) / 3600; | ||
107 | mins = ((now - dcc[i].timeval) - (hrs * 3600)) / 60; | ||
108 | if (days > 0) | ||
109 | sprintf(&s[strlen(s)], " (idle %lud%luh)", days, hrs); | ||
110 | else if (hrs > 0) | ||
111 | sprintf(&s[strlen(s)], " (idle %luh%lum)", hrs, mins); | ||
112 | else | ||
113 | sprintf(&s[strlen(s)], " (idle %lum)", mins); | ||
114 | } | ||
115 | dprintf(idx, "%s\n", s); | ||
116 | if (dcc[i].u.chat->away != NULL) | ||
117 | dprintf(idx, " AWAY: %s\n", dcc[i].u.chat->away); | ||
118 | } | ||
119 | ok = 0; | ||
120 | for (i = 0; i < dcc_total; i++) { | ||
121 | if ((dcc[i].type == &DCC_CHAT) && (dcc[i].u.chat->channel != chan)) { | ||
122 | if (!ok) { | ||
123 | ok = 1; | ||
124 | ite | 1.89 | dprintf(idx, _("Other people on the bot:\n")); |
125 | segfault | 1.1 | } |
126 | spaces[len = HANDLEN - strlen(dcc[i].nick)] = 0; | ||
127 | if (atr & USER_OWNER) { | ||
128 | sprintf(s, " [%.2lu] %c%s%s ", | ||
129 | dcc[i].sock, | ||
130 | ite | 1.88 | (geticon(dcc[i].user) == '-' ? ' ' : geticon(dcc[i].user)), |
131 | dcc[i].nick, spaces); | ||
132 | segfault | 1.1 | } else { |
133 | sprintf(s, " %c%s%s ", | ||
134 | ite | 1.88 | (geticon(dcc[i].user) == '-' ? ' ' : geticon(dcc[i].user)), |
135 | dcc[i].nick, spaces); | ||
136 | segfault | 1.1 | } |
137 | spaces[len] = ' '; | ||
138 | if (atr & USER_MASTER) { | ||
139 | if (dcc[i].u.chat->channel < 0) | ||
140 | strcat(s, "(-OFF-) "); | ||
141 | guppy | 1.45 | else if (!dcc[i].u.chat->channel) |
142 | segfault | 1.1 | strcat(s, "(party) "); |
143 | else | ||
144 | sprintf(&s[strlen(s)], "(%5d) ", dcc[i].u.chat->channel); | ||
145 | } | ||
146 | strcat(s, dcc[i].host); | ||
147 | if (atr & USER_MASTER) { | ||
148 | if (dcc[i].u.chat->con_flags) | ||
149 | sprintf(&s[strlen(s)], " (con:%s)", | ||
150 | masktype(dcc[i].u.chat->con_flags)); | ||
151 | } | ||
152 | if (now - dcc[i].timeval > 300) { | ||
153 | k = (now - dcc[i].timeval) / 60; | ||
154 | if (k < 60) | ||
155 | sprintf(&s[strlen(s)], " (idle %dm)", k); | ||
156 | else | ||
157 | sprintf(&s[strlen(s)], " (idle %dh%dm)", k / 60, k % 60); | ||
158 | } | ||
159 | dprintf(idx, "%s\n", s); | ||
160 | if (dcc[i].u.chat->away != NULL) | ||
161 | dprintf(idx, " AWAY: %s\n", dcc[i].u.chat->away); | ||
162 | } | ||
163 | stdarg | 1.84 | if ((atr & USER_MASTER) && dcc[i].type && (dcc[i].type->flags & DCT_SHOWWHO) && |
164 | segfault | 1.1 | (dcc[i].type != &DCC_CHAT)) { |
165 | if (!ok) { | ||
166 | ok = 1; | ||
167 | ite | 1.89 | dprintf(idx, _("Other people on the bot:\n")); |
168 | segfault | 1.1 | } |
169 | spaces[len = HANDLEN - strlen(dcc[i].nick)] = 0; | ||
170 | if (atr & USER_OWNER) { | ||
171 | sprintf(s, " [%.2lu] %c%s%s (files) %s", | ||
172 | dcc[i].sock, dcc[i].status & STAT_CHAT ? '+' : ' ', | ||
173 | dcc[i].nick, spaces, dcc[i].host); | ||
174 | } else { | ||
175 | sprintf(s, " %c%s%s (files) %s", | ||
176 | dcc[i].status & STAT_CHAT ? '+' : ' ', | ||
177 | dcc[i].nick, spaces, dcc[i].host); | ||
178 | } | ||
179 | spaces[len] = ' '; | ||
180 | dprintf(idx, "%s\n", s); | ||
181 | } | ||
182 | } | ||
183 | } | ||
184 | |||
185 | stdarg | 1.108 | static int cmd_me(user_t *u, int idx, char *par) |
186 | segfault | 1.1 | { |
187 | int i; | ||
188 | |||
189 | if (dcc[idx].u.chat->channel < 0) { | ||
190 | ite | 1.89 | dprintf(idx, _("You have chat turned off.\n")); |
191 | stdarg | 1.103 | return(0); |
192 | segfault | 1.1 | } |
193 | if (!par[0]) { | ||
194 | dprintf(idx, "Usage: me <action>\n"); | ||
195 | stdarg | 1.103 | return(0); |
196 | segfault | 1.1 | } |
197 | if (dcc[idx].u.chat->away != NULL) | ||
198 | not_away(idx); | ||
199 | for (i = 0; i < dcc_total; i++) | ||
200 | stdarg | 1.104 | check_bind_act(dcc[idx].nick, dcc[idx].u.chat->channel, par); |
201 | stdarg | 1.103 | return(0); |
202 | segfault | 1.1 | } |
203 | |||
204 | stdarg | 1.108 | static int cmd_motd(user_t *u, int idx, char *par) |
205 | segfault | 1.1 | { |
206 | show_motd(idx); | ||
207 | stdarg | 1.103 | return(1); |
208 | segfault | 1.1 | } |
209 | |||
210 | stdarg | 1.108 | static int cmd_away(user_t *u, int idx, char *par) |
211 | segfault | 1.1 | { |
212 | if (strlen(par) > 60) | ||
213 | par[60] = 0; | ||
214 | set_away(idx, par); | ||
215 | stdarg | 1.107 | return(1); |
216 | segfault | 1.1 | } |
217 | |||
218 | stdarg | 1.108 | static int cmd_back(user_t *u, int idx, char *par) |
219 | segfault | 1.1 | { |
220 | not_away(idx); | ||
221 | stdarg | 1.107 | return(1); |
222 | segfault | 1.1 | } |
223 | |||
224 | stdarg | 1.108 | static int cmd_newpass(user_t *u, int idx, char *par) |
225 | segfault | 1.1 | { |
226 | char *new; | ||
227 | |||
228 | if (!par[0]) { | ||
229 | dprintf(idx, "Usage: newpass <newpassword>\n"); | ||
230 | stdarg | 1.103 | return(0); |
231 | segfault | 1.1 | } |
232 | new = newsplit(&par); | ||
233 | if (strlen(new) > 16) | ||
234 | new[16] = 0; | ||
235 | if (strlen(new) < 6) { | ||
236 | ite | 1.89 | dprintf(idx, _("Please use at least 6 characters.\n")); |
237 | stdarg | 1.103 | return(0); |
238 | segfault | 1.1 | } |
239 | set_user(&USERENTRY_PASS, u, new); | ||
240 | stdarg | 1.103 | putlog(LOG_CMDS, "*", "#%s# newpass ...", dcc[idx].nick); |
241 | ite | 1.89 | dprintf(idx, _("Changed password to '%s'\n"), new); |
242 | stdarg | 1.103 | return(0); |
243 | segfault | 1.1 | } |
244 | |||
245 | stdarg | 1.108 | static int cmd_rehelp(user_t *u, int idx, char *par) |
246 | segfault | 1.1 | { |
247 | ite | 1.89 | dprintf(idx, _("Reload help cache...\n")); |
248 | segfault | 1.1 | reload_help_data(); |
249 | stdarg | 1.103 | return(1); |
250 | segfault | 1.1 | } |
251 | |||
252 | stdarg | 1.108 | static int cmd_help(user_t *u, int idx, char *par) |
253 | segfault | 1.1 | { |
254 | fabian | 1.4 | struct flag_record fr = {FR_GLOBAL | FR_CHAN, 0, 0, 0, 0, 0}; |
255 | segfault | 1.1 | |
256 | get_user_flagrec(u, &fr, dcc[idx].u.chat->con_chan); | ||
257 | if (par[0]) { | ||
258 | if (!strcmp(par, "all")) | ||
259 | tellallhelp(idx, "all", &fr); | ||
260 | fabian | 1.4 | else if (strchr(par, '*') || strchr(par, '?')) { |
261 | char *p = par; | ||
262 | |||
263 | /* Check if the search pattern only consists of '*' and/or '?' | ||
264 | * If it does, show help for "all" instead of listing all help | ||
265 | fabian | 1.22 | * entries. |
266 | */ | ||
267 | fabian | 1.4 | for (p = par; *p && ((*p == '*') || (*p == '?')); p++); |
268 | if (*p) | ||
269 | tellwildhelp(idx, par, &fr); | ||
270 | else | ||
271 | tellallhelp(idx, "all", &fr); | ||
272 | } else | ||
273 | segfault | 1.1 | tellhelp(idx, par, &fr, 0); |
274 | } else { | ||
275 | if (glob_op(fr) || glob_botmast(fr) || chan_op(fr)) | ||
276 | tellhelp(idx, "help", &fr, 0); | ||
277 | else | ||
278 | tellhelp(idx, "helpparty", &fr, 0); | ||
279 | } | ||
280 | stdarg | 1.103 | return(1); |
281 | segfault | 1.1 | } |
282 | |||
283 | stdarg | 1.108 | static int cmd_who(user_t *u, int idx, char *par) |
284 | segfault | 1.1 | { |
285 | putlog(LOG_CMDS, "*", "#%s# who", dcc[idx].nick); | ||
286 | if (dcc[idx].u.chat->channel < 0) | ||
287 | tell_who(u, idx, 0); | ||
288 | else | ||
289 | tell_who(u, idx, dcc[idx].u.chat->channel); | ||
290 | stdarg | 1.107 | |
291 | stdarg | 1.103 | return(1); |
292 | segfault | 1.1 | } |
293 | |||
294 | stdarg | 1.108 | static int cmd_whois(user_t *u, int idx, char *par) |
295 | segfault | 1.1 | { |
296 | if (!par[0]) { | ||
297 | dprintf(idx, "Usage: whois <handle>\n"); | ||
298 | stdarg | 1.103 | return(0); |
299 | segfault | 1.1 | } |
300 | tell_user_ident(idx, par, u ? (u->flags & USER_MASTER) : 0); | ||
301 | stdarg | 1.103 | return(1); |
302 | segfault | 1.1 | } |
303 | |||
304 | stdarg | 1.108 | static int cmd_match(user_t *u, int idx, char *par) |
305 | segfault | 1.1 | { |
306 | int start = 1, limit = 20; | ||
307 | char *s, *s1, *chname; | ||
308 | |||
309 | if (!par[0]) { | ||
310 | dprintf(idx, "Usage: match <nick/host> [[skip] count]\n"); | ||
311 | stdarg | 1.103 | return(0); |
312 | segfault | 1.1 | } |
313 | s = newsplit(&par); | ||
314 | if (strchr(CHANMETA, par[0]) != NULL) | ||
315 | chname = newsplit(&par); | ||
316 | else | ||
317 | chname = ""; | ||
318 | if (atoi(par) > 0) { | ||
319 | s1 = newsplit(&par); | ||
320 | if (atoi(par) > 0) { | ||
321 | start = atoi(s1); | ||
322 | limit = atoi(par); | ||
323 | } else | ||
324 | limit = atoi(s1); | ||
325 | } | ||
326 | tell_users_match(idx, s, start, limit, u ? (u->flags & USER_MASTER) : 0, | ||
327 | chname); | ||
328 | stdarg | 1.103 | return(1); |
329 | segfault | 1.1 | } |
330 | |||
331 | stdarg | 1.108 | static int cmd_uptime(user_t *u, int idx, char *par) |
332 | segfault | 1.1 | { |
333 | guppy | 1.64 | char s[256]; |
334 | unsigned long uptime, tmp, hr, min; | ||
335 | |||
336 | uptime = now - online_since; | ||
337 | s[0] = 0; | ||
338 | if (uptime > 86400) { | ||
339 | tmp = (uptime / 86400); | ||
340 | sprintf(s, "%lu day%s, ", tmp, (tmp == 1) ? "" : "s"); | ||
341 | uptime -= (tmp * 86400); | ||
342 | } | ||
343 | hr = (uptime / 3600); | ||
344 | uptime -= (hr * 3600); | ||
345 | min = (uptime / 60); | ||
346 | sprintf(&s[strlen(s)], "%02lu:%02lu", hr, min); | ||
347 | |||
348 | dprintf(idx, "%s %s (%s)\n", _("Online for"), s, backgrd ? | ||
349 | _("background") : term_z ? _("terminal mode") : con_chan ? | ||
350 | _("status mode") : _("log dump mode")); | ||
351 | stdarg | 1.103 | return(1); |
352 | segfault | 1.1 | } |
353 | |||
354 | stdarg | 1.108 | static int cmd_status(user_t *u, int idx, char *par) |
355 | segfault | 1.1 | { |
356 | int atr = u ? u->flags : 0; | ||
357 | |||
358 | tothwolf | 1.74 | if (!strcasecmp(par, "all")) { |
359 | segfault | 1.1 | if (!(atr & USER_MASTER)) { |
360 | ite | 1.89 | dprintf(idx, _("You do not have Bot Master privileges.\n")); |
361 | stdarg | 1.103 | return(0); |
362 | segfault | 1.1 | } |
363 | tell_verbose_status(idx); | ||
364 | dprintf(idx, "\n"); | ||
365 | tell_settings(idx); | ||
366 | do_module_report(idx, 1, NULL); | ||
367 | } else { | ||
368 | tell_verbose_status(idx); | ||
369 | do_module_report(idx, 0, NULL); | ||
370 | } | ||
371 | stdarg | 1.103 | return(1); |
372 | segfault | 1.1 | } |
373 | |||
374 | stdarg | 1.108 | static int cmd_dccstat(user_t *u, int idx, char *par) |
375 | segfault | 1.1 | { |
376 | tell_dcc(idx); | ||
377 | stdarg | 1.103 | return(1); |
378 | segfault | 1.1 | } |
379 | |||
380 | stdarg | 1.108 | static int cmd_boot(user_t *u, int idx, char *par) |
381 | segfault | 1.1 | { |
382 | int i, files = 0, ok = 0; | ||
383 | char *who; | ||
384 | stdarg | 1.108 | user_t *u2; |
385 | segfault | 1.1 | |
386 | if (!par[0]) { | ||
387 | dprintf(idx, "Usage: boot nick[@bot]\n"); | ||
388 | stdarg | 1.103 | return(0); |
389 | segfault | 1.1 | } |
390 | who = newsplit(&par); | ||
391 | for (i = 0; i < dcc_total; i++) | ||
392 | stdarg | 1.99 | if (dcc[i].type && !strcasecmp(dcc[i].nick, who) |
393 | fabian | 1.39 | && !ok && (dcc[i].type->flags & DCT_CANBOOT)) { |
394 | segfault | 1.1 | u2 = get_user_by_handle(userlist, dcc[i].nick); |
395 | fabian | 1.39 | if (u2 && (u2->flags & USER_OWNER) |
396 | tothwolf | 1.74 | && strcasecmp(dcc[idx].nick, who)) { |
397 | wcc | 1.92 | dprintf(idx, _("You can't boot a bot owner.\n")); |
398 | stdarg | 1.103 | return(0); |
399 | fabian | 1.39 | } |
400 | if (u2 && (u2->flags & USER_MASTER) && !(u && (u->flags & USER_MASTER))) { | ||
401 | wcc | 1.92 | dprintf(idx, _("You can't boot a bot master.\n")); |
402 | stdarg | 1.103 | return(0); |
403 | segfault | 1.1 | } |
404 | files = (dcc[i].type->flags & DCT_FILES); | ||
405 | if (files) | ||
406 | wcc | 1.92 | dprintf(idx, _("Booted %s from the file area.\n"), dcc[i].nick); |
407 | segfault | 1.1 | else |
408 | wcc | 1.92 | dprintf(idx, _("Booted %s from the party line.\n"), dcc[i].nick); |
409 | segfault | 1.1 | do_boot(i, dcc[idx].nick, par); |
410 | ok = 1; | ||
411 | } | ||
412 | stdarg | 1.103 | if (!ok) { |
413 | ite | 1.89 | dprintf(idx, _("Who? No such person on the party line.\n")); |
414 | stdarg | 1.103 | return(0); |
415 | } | ||
416 | return(1); | ||
417 | segfault | 1.1 | } |
418 | |||
419 | stdarg | 1.108 | static int cmd_console(user_t *u, int idx, char *par) |
420 | segfault | 1.1 | { |
421 | char *nick, s[2], s1[512]; | ||
422 | int dest = 0, i, ok = 0, pls, md; | ||
423 | fabian | 1.8 | struct flag_record fr = {FR_GLOBAL | FR_CHAN, 0, 0, 0, 0, 0}; |
424 | segfault | 1.1 | module_entry *me; |
425 | |||
426 | if (!par[0]) { | ||
427 | wcc | 1.92 | dprintf(idx, "Your console is %s: %s (%s).\n", |
428 | segfault | 1.1 | dcc[idx].u.chat->con_chan, |
429 | masktype(dcc[idx].u.chat->con_flags), | ||
430 | maskname(dcc[idx].u.chat->con_flags)); | ||
431 | stdarg | 1.103 | return(1); |
432 | segfault | 1.1 | } |
433 | get_user_flagrec(u, &fr, dcc[idx].u.chat->con_chan); | ||
434 | strcpy(s1, par); | ||
435 | nick = newsplit(&par); | ||
436 | guppy | 1.49 | /* Don't remove '+' as someone couldn't have '+' in CHANMETA cause |
437 | fabian | 1.22 | * he doesn't use IRCnet ++rtc. |
438 | */ | ||
439 | fabian | 1.6 | if (nick[0] && !strchr(CHANMETA "+-*", nick[0]) && glob_master(fr)) { |
440 | segfault | 1.1 | for (i = 0; i < dcc_total; i++) |
441 | stdarg | 1.99 | if (dcc[i].type && !strcasecmp(nick, dcc[i].nick) && |
442 | segfault | 1.1 | (dcc[i].type == &DCC_CHAT) && (!ok)) { |
443 | ok = 1; | ||
444 | dest = i; | ||
445 | } | ||
446 | if (!ok) { | ||
447 | dprintf(idx, "No such user on the party line!\n"); | ||
448 | stdarg | 1.103 | return(0); |
449 | segfault | 1.1 | } |
450 | nick[0] = 0; | ||
451 | } else | ||
452 | dest = idx; | ||
453 | if (!nick[0]) | ||
454 | nick = newsplit(&par); | ||
455 | fabian | 1.22 | /* Consider modeless channels, starting with '+' */ |
456 | guppy | 1.49 | if ((nick [0] == '+' && findchan_by_dname(nick)) || |
457 | fabian | 1.6 | (nick [0] != '+' && strchr(CHANMETA "*", nick[0]))) { |
458 | fabian | 1.8 | if (strcmp(nick, "*") && !findchan_by_dname(nick)) { |
459 | wcc | 1.92 | dprintf(idx, "Invalid console channel: %s.\n", nick); |
460 | stdarg | 1.103 | return(0); |
461 | segfault | 1.1 | } |
462 | get_user_flagrec(u, &fr, nick); | ||
463 | wcc | 1.111 | if (!chan_op(fr) && !glob_op(fr)) { |
464 | wcc | 1.92 | dprintf(idx, "You don't have op or master access to channel %s.\n", |
465 | segfault | 1.1 | nick); |
466 | stdarg | 1.103 | return(0); |
467 | segfault | 1.1 | } |
468 | ite | 1.97 | strlcpy(dcc[dest].u.chat->con_chan, nick, 81); |
469 | segfault | 1.1 | nick[0] = 0; |
470 | if ((dest == idx) && !glob_master(fr) && !chan_master(fr)) | ||
471 | fabian | 1.22 | /* Consoling to another channel for self */ |
472 | segfault | 1.1 | dcc[dest].u.chat->con_flags &= ~(LOG_MISC | LOG_CMDS | LOG_WALL); |
473 | } | ||
474 | if (!nick[0]) | ||
475 | nick = newsplit(&par); | ||
476 | pls = 1; | ||
477 | if (nick[0]) { | ||
478 | if ((nick[0] != '+') && (nick[0] != '-')) | ||
479 | dcc[dest].u.chat->con_flags = 0; | ||
480 | for (; *nick; nick++) { | ||
481 | if (*nick == '+') | ||
482 | pls = 1; | ||
483 | else if (*nick == '-') | ||
484 | pls = 0; | ||
485 | else { | ||
486 | s[0] = *nick; | ||
487 | s[1] = 0; | ||
488 | md = logmodes(s); | ||
489 | if ((dest == idx) && !glob_master(fr) && pls) { | ||
490 | if (chan_master(fr)) | ||
491 | md &= ~(LOG_FILES | LOG_LEV1 | LOG_LEV2 | LOG_LEV3 | | ||
492 | LOG_LEV4 | LOG_LEV5 | LOG_LEV6 | LOG_LEV7 | | ||
493 | LOG_LEV8 | LOG_DEBUG); | ||
494 | else | ||
495 | md &= ~(LOG_MISC | LOG_CMDS | LOG_FILES | LOG_LEV1 | | ||
496 | LOG_LEV2 | LOG_LEV3 | LOG_LEV4 | LOG_LEV5 | | ||
497 | LOG_LEV6 | LOG_LEV7 | LOG_LEV8 | LOG_WALL | | ||
498 | LOG_DEBUG); | ||
499 | } | ||
500 | if (!glob_owner(fr) && pls) | ||
501 | md &= ~(LOG_RAW | LOG_SRVOUT | LOG_BOTNET | LOG_BOTSHARE); | ||
502 | if (!glob_botmast(fr) && pls) | ||
503 | md &= ~LOG_BOTS; | ||
504 | if (pls) | ||
505 | dcc[dest].u.chat->con_flags |= md; | ||
506 | else | ||
507 | dcc[dest].u.chat->con_flags &= ~md; | ||
508 | } | ||
509 | } | ||
510 | } | ||
511 | if (dest == idx) { | ||
512 | wcc | 1.92 | dprintf(idx, "Set your console to %s: %s (%s).\n", |
513 | segfault | 1.1 | dcc[idx].u.chat->con_chan, |
514 | masktype(dcc[idx].u.chat->con_flags), | ||
515 | maskname(dcc[idx].u.chat->con_flags)); | ||
516 | } else { | ||
517 | wcc | 1.92 | dprintf(idx, "Set console of %s to %s: %s (%s).\n", dcc[dest].nick, |
518 | segfault | 1.1 | dcc[dest].u.chat->con_chan, |
519 | masktype(dcc[dest].u.chat->con_flags), | ||
520 | maskname(dcc[dest].u.chat->con_flags)); | ||
521 | wcc | 1.92 | dprintf(dest, "%s set your console to %s: %s (%s).\n", dcc[idx].nick, |
522 | segfault | 1.1 | dcc[dest].u.chat->con_chan, |
523 | masktype(dcc[dest].u.chat->con_flags), | ||
524 | maskname(dcc[dest].u.chat->con_flags)); | ||
525 | } | ||
526 | fabian | 1.22 | /* New style autosave -- drummer,07/25/1999*/ |
527 | fabian | 1.2 | if ((me = module_find("console", 1, 1))) { |
528 | segfault | 1.1 | Function *func = me->funcs; |
529 | fabian | 1.3 | (func[CONSOLE_DOSTORE]) (dest); |
530 | segfault | 1.1 | } |
531 | stdarg | 1.103 | return(1); |
532 | segfault | 1.1 | } |
533 | |||
534 | stdarg | 1.108 | static int cmd_pls_bot(user_t *u, int idx, char *par) |
535 | segfault | 1.1 | { |
536 | char *handle, *addr, *p, *q, *host; | ||
537 | stdarg | 1.108 | user_t *u1; |
538 | segfault | 1.1 | struct bot_addr *bi; |
539 | drummer | 1.61 | int addrlen; |
540 | segfault | 1.1 | |
541 | if (!par[0]) | ||
542 | dprintf(idx, "Usage: +bot <handle> <address[:telnet-port[/relay-port]]> [host]\n"); | ||
543 | else { | ||
544 | handle = newsplit(&par); | ||
545 | addr = newsplit(&par); | ||
546 | if (strlen(handle) > HANDLEN) | ||
547 | handle[HANDLEN] = 0; /* max len = XX .. for the moment :) */ | ||
548 | if (get_user_by_handle(userlist, handle)) | ||
549 | ite | 1.89 | dprintf(idx, _("Someone already exists by that name.\n")); |
550 | fabian | 1.6 | else if (strchr(BADHANDCHARS, handle[0]) != NULL) |
551 | ite | 1.89 | dprintf(idx, _("You can't start a botnick with '%c'.\n"), handle[0]); |
552 | segfault | 1.1 | else { |
553 | if (strlen(addr) > 60) | ||
554 | addr[60] = 0; | ||
555 | userlist = adduser(userlist, handle, "none", "-", USER_BOT); | ||
556 | u1 = get_user_by_handle(userlist, handle); | ||
557 | tothwolf | 1.70 | bi = malloc(sizeof(struct bot_addr)); |
558 | segfault | 1.1 | |
559 | drummer | 1.61 | if (*addr == '[') { |
560 | addr++; | ||
561 | if ((q = strchr(addr, ']'))) { | ||
562 | addrlen = q - addr; | ||
563 | q++; | ||
564 | if (*q != ':') | ||
565 | q = 0; | ||
566 | } else | ||
567 | addrlen = strlen(addr); | ||
568 | } else { | ||
569 | if ((q = strchr(addr, ':'))) | ||
570 | addrlen = q - addr; | ||
571 | else | ||
572 | addrlen = strlen(addr); | ||
573 | } | ||
574 | segfault | 1.1 | if (!q) { |
575 | ite | 1.85 | bi->address = strdup(addr); |
576 | segfault | 1.1 | bi->telnet_port = 3333; |
577 | bi->relay_port = 3333; | ||
578 | } else { | ||
579 | tothwolf | 1.70 | bi->address = malloc(addrlen + 1); |
580 | ite | 1.97 | strlcpy(bi->address, addr, addrlen + 1); |
581 | segfault | 1.1 | p = q + 1; |
582 | bi->telnet_port = atoi(p); | ||
583 | q = strchr(p, '/'); | ||
584 | if (!q) { | ||
585 | bi->relay_port = bi->telnet_port; | ||
586 | } else { | ||
587 | bi->relay_port = atoi(q + 1); | ||
588 | } | ||
589 | } | ||
590 | set_user(&USERENTRY_BOTADDR, u1, bi); | ||
591 | ite | 1.89 | dprintf(idx, _("Added bot '%s' with address '%s' and no password.\n"), |
592 | segfault | 1.1 | handle, addr); |
593 | host = newsplit(&par); | ||
594 | if (host[0]) { | ||
595 | addhost_by_handle(handle, host); | ||
596 | } else if (!add_bot_hostmask(idx, handle)) | ||
597 | ite | 1.89 | dprintf(idx, _("You'll want to add a hostmask if this bot will ever be on any channels that I'm on.\n")); |
598 | segfault | 1.1 | } |
599 | } | ||
600 | stdarg | 1.103 | return(1); |
601 | segfault | 1.1 | } |
602 | |||
603 | stdarg | 1.108 | static int cmd_chhandle(user_t *u, int idx, char *par) |
604 | segfault | 1.1 | { |
605 | fabian | 1.2 | char hand[HANDLEN + 1], newhand[HANDLEN + 1]; |
606 | segfault | 1.1 | int i, atr = u ? u->flags : 0, atr2; |
607 | stdarg | 1.108 | user_t *u2; |
608 | segfault | 1.1 | |
609 | ite | 1.97 | strlcpy(hand, newsplit(&par), sizeof hand); |
610 | strlcpy(newhand, newsplit(&par), sizeof newhand); | ||
611 | fabian | 1.2 | |
612 | if (!hand[0] || !newhand[0]) { | ||
613 | fabian | 1.27 | dprintf(idx, "Usage: chhandle <oldhandle> <newhandle>\n"); |
614 | stdarg | 1.103 | return(0); |
615 | fabian | 1.2 | } |
616 | for (i = 0; i < strlen(newhand); i++) | ||
617 | if ((newhand[i] <= 32) || (newhand[i] >= 127) || (newhand[i] == '@')) | ||
618 | newhand[i] = '?'; | ||
619 | fabian | 1.6 | if (strchr(BADHANDCHARS, newhand[0]) != NULL) |
620 | wcc | 1.92 | dprintf(idx, _("Bizarre quantum forces prevent nicknames from starting with %c.\n"), |
621 | fabian | 1.2 | newhand[0]); |
622 | else if (get_user_by_handle(userlist, newhand) && | ||
623 | tothwolf | 1.74 | strcasecmp(hand, newhand)) |
624 | ite | 1.89 | dprintf(idx, _("Somebody is already using %s.\n"), newhand); |
625 | segfault | 1.1 | else { |
626 | fabian | 1.2 | u2 = get_user_by_handle(userlist, hand); |
627 | atr2 = u2 ? u2->flags : 0; | ||
628 | if ((atr & USER_BOTMAST) && !(atr & USER_MASTER) && | ||
629 | !(atr2 & USER_BOT)) | ||
630 | wcc | 1.92 | dprintf(idx, _("You can't change handles for non-bots.\n")); |
631 | fabian | 1.2 | else if ((bot_flags(u2) & BOT_SHARE) && !(atr & USER_OWNER)) |
632 | wcc | 1.92 | dprintf(idx, _("You can't change a share bot's handle.\n")); |
633 | fabian | 1.2 | else if ((atr2 & USER_OWNER) && !(atr & USER_OWNER) && |
634 | tothwolf | 1.74 | strcasecmp(dcc[idx].nick, hand)) |
635 | wcc | 1.92 | dprintf(idx, _("You can't change a bot owner's handle.\n")); |
636 | tothwolf | 1.74 | else if (isowner(hand) && strcasecmp(dcc[idx].nick, hand)) |
637 | wcc | 1.92 | dprintf(idx, _("You can't change a permanent bot owner's handle.\n")); |
638 | stdarg | 1.107 | else if (!strcasecmp(newhand, botnetnick) && !(atr2 & USER_BOT)) |
639 | ite | 1.89 | dprintf(idx, _("Hey! That's MY name!\n")); |
640 | fabian | 1.2 | else if (change_handle(u2, newhand)) { |
641 | ite | 1.89 | dprintf(idx, _("Changed.\n")); |
642 | fabian | 1.2 | } else |
643 | ite | 1.89 | dprintf(idx, _("Failed.\n")); |
644 | segfault | 1.1 | } |
645 | stdarg | 1.103 | return(1); |
646 | segfault | 1.1 | } |
647 | |||
648 | stdarg | 1.108 | static int cmd_handle(user_t *u, int idx, char *par) |
649 | segfault | 1.1 | { |
650 | fabian | 1.27 | char oldhandle[HANDLEN + 1], newhandle[HANDLEN + 1]; |
651 | fabian | 1.2 | int i; |
652 | |||
653 | ite | 1.97 | strlcpy(newhandle, newsplit(&par), sizeof newhandle); |
654 | segfault | 1.1 | |
655 | fabian | 1.27 | if (!newhandle[0]) { |
656 | dprintf(idx, "Usage: handle <new-handle>\n"); | ||
657 | stdarg | 1.77 | return(0); |
658 | segfault | 1.1 | } |
659 | fabian | 1.27 | for (i = 0; i < strlen(newhandle); i++) |
660 | if ((newhandle[i] <= 32) || (newhandle[i] >= 127) || (newhandle[i] == '@')) | ||
661 | newhandle[i] = '?'; | ||
662 | if (strchr(BADHANDCHARS, newhandle[0]) != NULL) { | ||
663 | ite | 1.89 | dprintf(idx, _("Bizarre quantum forces prevent handle from starting with '%c'\n"), |
664 | fabian | 1.27 | newhandle[0]); |
665 | } else if (get_user_by_handle(userlist, newhandle) && | ||
666 | tothwolf | 1.74 | strcasecmp(dcc[idx].nick, newhandle)) { |
667 | ite | 1.89 | dprintf(idx, _("Somebody is already using %s.\n"), newhandle); |
668 | tothwolf | 1.74 | } else if (!strcasecmp(newhandle, botnetnick)) { |
669 | ite | 1.89 | dprintf(idx, _("Hey! That's MY name!\n")); |
670 | segfault | 1.1 | } else { |
671 | ite | 1.97 | strlcpy(oldhandle, dcc[idx].nick, sizeof oldhandle); |
672 | fabian | 1.27 | if (change_handle(u, newhandle)) { |
673 | ite | 1.89 | dprintf(idx, _("Okay, changed.\n")); |
674 | segfault | 1.1 | } else |
675 | ite | 1.89 | dprintf(idx, _("Failed.\n")); |
676 | segfault | 1.1 | } |
677 | stdarg | 1.77 | return(1); |
678 | segfault | 1.1 | } |
679 | |||
680 | stdarg | 1.108 | static int cmd_chpass(user_t *u, int idx, char *par) |
681 | segfault | 1.1 | { |
682 | char *handle, *new; | ||
683 | int atr = u ? u->flags : 0, l; | ||
684 | |||
685 | if (!par[0]) | ||
686 | dprintf(idx, "Usage: chpass <handle> [password]\n"); | ||
687 | else { | ||
688 | handle = newsplit(&par); | ||
689 | u = get_user_by_handle(userlist, handle); | ||
690 | if (!u) | ||
691 | ite | 1.89 | dprintf(idx, _("No such user.\n")); |
692 | segfault | 1.1 | else if ((atr & USER_BOTMAST) && !(atr & USER_MASTER) && |
693 | !(u->flags & USER_BOT)) | ||
694 | wcc | 1.92 | dprintf(idx, _("You can't change passwords for non-bots.\n")); |
695 | segfault | 1.1 | else if ((bot_flags(u) & BOT_SHARE) && !(atr & USER_OWNER)) |
696 | wcc | 1.92 | dprintf(idx, _("You can't change a share bot's password.\n")); |
697 | segfault | 1.1 | else if ((u->flags & USER_OWNER) && !(atr & USER_OWNER) && |
698 | tothwolf | 1.74 | strcasecmp(handle, dcc[idx].nick)) |
699 | wcc | 1.92 | dprintf(idx, _("You can't change a bot owner's password.\n")); |
700 | tothwolf | 1.74 | else if (isowner(handle) && strcasecmp(dcc[idx].nick, handle)) |
701 | wcc | 1.92 | dprintf(idx, _("You can't change a permanent bot owner's password.\n")); |
702 | segfault | 1.1 | else if (!par[0]) { |
703 | set_user(&USERENTRY_PASS, u, NULL); | ||
704 | ite | 1.89 | dprintf(idx, _("Removed password.\n")); |
705 | segfault | 1.1 | } else { |
706 | l = strlen(new = newsplit(&par)); | ||
707 | if (l > 16) | ||
708 | new[16] = 0; | ||
709 | if (l < 6) | ||
710 | ite | 1.89 | dprintf(idx, _("Please use at least 6 characters.\n")); |
711 | segfault | 1.1 | else { |
712 | set_user(&USERENTRY_PASS, u, new); | ||
713 | ite | 1.89 | dprintf(idx, _("Changed password.\n")); |
714 | segfault | 1.1 | } |
715 | } | ||
716 | } | ||
717 | stdarg | 1.103 | return(0); |
718 | segfault | 1.1 | } |
719 | |||
720 | stdarg | 1.108 | static int cmd_chaddr(user_t *u, int idx, char *par) |
721 | segfault | 1.1 | { |
722 | guppy | 1.51 | int telnet_port = 3333, relay_port = 3333; |
723 | segfault | 1.1 | char *handle, *addr, *p, *q; |
724 | struct bot_addr *bi; | ||
725 | stdarg | 1.108 | user_t *u1; |
726 | drummer | 1.61 | int addrlen; |
727 | segfault | 1.1 | |
728 | if (!par[0]) { | ||
729 | guppy | 1.51 | dprintf(idx, "Usage: chaddr <botname> <address[:telnet-port[/relay-port]]>\n"); |
730 | stdarg | 1.103 | return(0); |
731 | segfault | 1.1 | } |
732 | handle = newsplit(&par); | ||
733 | addr = newsplit(&par); | ||
734 | fabian | 1.6 | if (strlen(addr) > UHOSTMAX) |
735 | addr[UHOSTMAX] = 0; | ||
736 | segfault | 1.1 | u1 = get_user_by_handle(userlist, handle); |
737 | if (!u1 || !(u1->flags & USER_BOT)) { | ||
738 | wcc | 1.92 | dprintf(idx, _("This command is only useful for tandem bots.\n")); |
739 | stdarg | 1.103 | return(0); |
740 | segfault | 1.1 | } |
741 | if ((bot_flags(u1) & BOT_SHARE) && (!u || !u->flags & USER_OWNER)) { | ||
742 | wcc | 1.92 | dprintf(idx, _("You can't change a share bot's address.\n")); |
743 | stdarg | 1.103 | return(0); |
744 | segfault | 1.1 | } |
745 | ite | 1.89 | dprintf(idx, _("Changed bot's address.\n")); |
746 | guppy | 1.51 | |
747 | bi = (struct bot_addr *) get_user(&USERENTRY_BOTADDR, u1); | ||
748 | if (bi) { | ||
749 | telnet_port = bi->telnet_port; | ||
750 | relay_port = bi->relay_port; | ||
751 | } | ||
752 | |||
753 | tothwolf | 1.70 | bi = malloc(sizeof(struct bot_addr)); |
754 | segfault | 1.1 | |
755 | drummer | 1.61 | if (*addr == '[') { |
756 | addr++; | ||
757 | if ((q = strchr(addr, ']'))) { | ||
758 | addrlen = q - addr; | ||
759 | q++; | ||
760 | if (*q != ':') | ||
761 | q = 0; | ||
762 | } else | ||
763 | addrlen = strlen(addr); | ||
764 | } else { | ||
765 | if ((q = strchr(addr, ':'))) | ||
766 | addrlen = q - addr; | ||
767 | else | ||
768 | addrlen = strlen(addr); | ||
769 | } | ||
770 | segfault | 1.1 | if (!q) { |
771 | ite | 1.85 | bi->address = strdup(addr); |
772 | guppy | 1.51 | bi->telnet_port = telnet_port; |
773 | bi->relay_port = relay_port; | ||
774 | segfault | 1.1 | } else { |
775 | tothwolf | 1.70 | bi->address = malloc(addrlen + 1); |
776 | ite | 1.97 | strlcpy(bi->address, addr, addrlen + 1); |
777 | segfault | 1.1 | p = q + 1; |
778 | bi->telnet_port = atoi(p); | ||
779 | q = strchr(p, '/'); | ||
780 | if (!q) { | ||
781 | bi->relay_port = bi->telnet_port; | ||
782 | } else { | ||
783 | bi->relay_port = atoi(q + 1); | ||
784 | } | ||
785 | } | ||
786 | set_user(&USERENTRY_BOTADDR, u1, bi); | ||
787 | stdarg | 1.103 | return(1); |
788 | segfault | 1.1 | } |
789 | |||
790 | stdarg | 1.108 | static int cmd_comment(user_t *u, int idx, char *par) |
791 | segfault | 1.1 | { |
792 | char *handle; | ||
793 | stdarg | 1.108 | user_t *u1; |
794 | segfault | 1.1 | |
795 | if (!par[0]) { | ||
796 | dprintf(idx, "Usage: comment <handle> <newcomment>\n"); | ||
797 | stdarg | 1.103 | return(0); |
798 | segfault | 1.1 | } |
799 | handle = newsplit(&par); | ||
800 | u1 = get_user_by_handle(userlist, handle); | ||
801 | if (!u1) { | ||
802 | ite | 1.89 | dprintf(idx, _("No such user!\n")); |
803 | stdarg | 1.103 | return(0); |
804 | segfault | 1.1 | } |
805 | if ((u1->flags & USER_OWNER) && !(u && (u->flags & USER_OWNER)) && | ||
806 | tothwolf | 1.74 | strcasecmp(handle, dcc[idx].nick)) { |
807 | ite | 1.89 | dprintf(idx, _("Can't change comment on the bot owner.\n")); |
808 | stdarg | 1.103 | return(0); |
809 | segfault | 1.1 | } |
810 | tothwolf | 1.74 | if (!strcasecmp(par, "none")) { |
811 | ite | 1.89 | dprintf(idx, _("Okay, comment blanked.\n")); |
812 | segfault | 1.1 | set_user(&USERENTRY_COMMENT, u1, NULL); |
813 | stdarg | 1.103 | return(0); |
814 | segfault | 1.1 | } |
815 | ite | 1.89 | dprintf(idx, _("Changed comment.\n")); |
816 | segfault | 1.1 | set_user(&USERENTRY_COMMENT, u1, par); |
817 | stdarg | 1.103 | return(1); |
818 | segfault | 1.1 | } |
819 | |||
820 | stdarg | 1.108 | static int cmd_restart(user_t *u, int idx, char *par) |
821 | segfault | 1.1 | { |
822 | if (!backgrd) { | ||
823 | stdarg | 1.103 | dprintf(idx, "%s\n", _("You cannot .restart a bot when running -n (due to tcl).")); |
824 | return(0); | ||
825 | segfault | 1.1 | } |
826 | ite | 1.89 | dprintf(idx, _("Restarting.\n")); |
827 | guppy | 1.64 | if (make_userfile) |
828 | segfault | 1.1 | make_userfile = 0; |
829 | write_userfile(-1); | ||
830 | guppy | 1.64 | putlog(LOG_MISC, "*", "%s", _("Restarting ...")); |
831 | segfault | 1.1 | do_restart = idx; |
832 | stdarg | 1.103 | return(1); |
833 | segfault | 1.1 | } |
834 | |||
835 | stdarg | 1.108 | static int cmd_rehash(user_t *u, int idx, char *par) |
836 | segfault | 1.1 | { |
837 | guppy | 1.64 | dprintf(idx, "%s\n", _("Rehashing.")); |
838 | if (make_userfile) | ||
839 | segfault | 1.1 | make_userfile = 0; |
840 | write_userfile(-1); | ||
841 | guppy | 1.64 | putlog(LOG_MISC, "*", "%s", _("Rehashing...")); |
842 | segfault | 1.1 | do_restart = -2; |
843 | stdarg | 1.103 | return(1); |
844 | segfault | 1.1 | } |
845 | |||
846 | stdarg | 1.108 | static int cmd_reload(user_t *u, int idx, char *par) |
847 | segfault | 1.1 | { |
848 | guppy | 1.64 | dprintf(idx, "%s\n", _("Reloading user file...")); |
849 | segfault | 1.1 | reload(); |
850 | stdarg | 1.107 | return(1); |
851 | segfault | 1.1 | } |
852 | |||
853 | stdarg | 1.108 | void cmd_die(user_t *u, int idx, char *par) |
854 | segfault | 1.1 | { |
855 | guppy | 1.62 | char s1[1024], s2[1024]; |
856 | segfault | 1.1 | |
857 | if (par[0]) { | ||
858 | tothwolf | 1.74 | snprintf(s1, sizeof s1, "%s (%s: %s)", _("BOT SHUTDOWN"), dcc[idx].nick, |
859 | guppy | 1.64 | par); |
860 | tothwolf | 1.74 | snprintf(s2, sizeof s2, "%s %s!%s (%s)", _("DIE BY"), dcc[idx].nick, |
861 | guppy | 1.64 | dcc[idx].host, par); |
862 | ite | 1.97 | strlcpy(quit_msg, par, 1024); |
863 | segfault | 1.1 | } else { |
864 | tothwolf | 1.74 | snprintf(s1, sizeof s1, "%s (%s %s)", _("BOT SHUTDOWN"), _("Authorized by"), |
865 | guppy | 1.64 | dcc[idx].nick); |
866 | tothwolf | 1.74 | snprintf(s2, sizeof s2, "%s %s!%s (%s)", _("DIE BY"), dcc[idx].nick, |
867 | guppy | 1.64 | dcc[idx].host, _("requested")); |
868 | ite | 1.97 | strlcpy(quit_msg, dcc[idx].nick, 1024); |
869 | segfault | 1.1 | } |
870 | guppy | 1.62 | kill_bot(s1, s2); |
871 | segfault | 1.1 | } |
872 | |||
873 | stdarg | 1.108 | static int cmd_simul(user_t *u, int idx, char *par) |
874 | segfault | 1.1 | { |
875 | char *nick; | ||
876 | int i, ok = 0; | ||
877 | |||
878 | nick = newsplit(&par); | ||
879 | if (!par[0]) { | ||
880 | johoho | 1.32 | dprintf(idx, "Usage: simul <hand> <text>\n"); |
881 | stdarg | 1.103 | return(0); |
882 | segfault | 1.1 | } |
883 | if (isowner(nick)) { | ||
884 | ite | 1.89 | dprintf(idx, _("Unable to '.simul' permanent owners.\n")); |
885 | stdarg | 1.103 | return(0); |
886 | segfault | 1.1 | } |
887 | for (i = 0; i < dcc_total; i++) | ||
888 | stdarg | 1.99 | if (dcc[i].type && !strcasecmp(nick, dcc[i].nick) && !ok && |
889 | segfault | 1.1 | (dcc[i].type->flags & DCT_SIMUL)) { |
890 | if (dcc[i].type && dcc[i].type->activity) { | ||
891 | dcc[i].type->activity(i, par, strlen(par)); | ||
892 | ok = 1; | ||
893 | } | ||
894 | } | ||
895 | if (!ok) | ||
896 | ite | 1.89 | dprintf(idx, _("No such user on the party line.\n")); |
897 | stdarg | 1.103 | return(1); |
898 | segfault | 1.1 | } |
899 | |||
900 | stdarg | 1.108 | static int cmd_save(user_t *u, int idx, char *par) |
901 | segfault | 1.1 | { |
902 | ite | 1.89 | dprintf(idx, _("Saving user file...\n")); |
903 | segfault | 1.1 | write_userfile(-1); |
904 | stdarg | 1.103 | return(1); |
905 | segfault | 1.1 | } |
906 | |||
907 | stdarg | 1.108 | static int cmd_backup(user_t *u, int idx, char *par) |
908 | segfault | 1.1 | { |
909 | wcc | 1.92 | dprintf(idx, _("Backing up the channel & user files...\n")); |
910 | guppy | 1.60 | call_hook(HOOK_BACKUP); |
911 | stdarg | 1.103 | return(1); |
912 | segfault | 1.1 | } |
913 | |||
914 | fabian | 1.22 | /* After messing with someone's user flags, make sure the dcc-chat flags |
915 | * are set correctly. | ||
916 | */ | ||
917 | stdarg | 1.108 | int check_dcc_attrs(user_t *u, int oatr) |
918 | segfault | 1.1 | { |
919 | int i, stat; | ||
920 | |||
921 | if (!u) | ||
922 | return 0; | ||
923 | fabian | 1.22 | /* Make sure default owners are +n */ |
924 | poptix | 1.57 | if (isowner(u->handle)) { |
925 | u->flags = sanity_check(u->flags | USER_OWNER); | ||
926 | segfault | 1.1 | } |
927 | for (i = 0; i < dcc_total; i++) { | ||
928 | stdarg | 1.76 | if (dcc[i].type && (dcc[i].type->flags & DCT_MASTER) && |
929 | tothwolf | 1.74 | (!strcasecmp(u->handle, dcc[i].nick))) { |
930 | segfault | 1.1 | stat = dcc[i].status; |
931 | if ((oatr & USER_MASTER) && !(u->flags & USER_MASTER)) { | ||
932 | fabian | 1.22 | struct flag_record fr = {FR_CHAN | FR_ANYWH, 0, 0, 0, 0, 0}; |
933 | segfault | 1.1 | |
934 | dcc[i].u.chat->con_flags &= ~(LOG_MISC | LOG_CMDS | LOG_RAW | | ||
935 | LOG_FILES | LOG_LEV1 | LOG_LEV2 | | ||
936 | LOG_LEV3 | LOG_LEV4 | LOG_LEV5 | | ||
937 | LOG_LEV6 | LOG_LEV7 | LOG_LEV8 | | ||
938 | LOG_WALL | LOG_DEBUG); | ||
939 | get_user_flagrec(u, &fr, NULL); | ||
940 | if (!chan_master(fr)) | ||
941 | dcc[i].u.chat->con_flags |= (LOG_MISC | LOG_CMDS); | ||
942 | dprintf(i, "*** POOF! ***\n"); | ||
943 | ite | 1.89 | dprintf(i, _("You are no longer a master on this bot.\n")); |
944 | segfault | 1.1 | } |
945 | if (!(oatr & USER_MASTER) && (u->flags & USER_MASTER)) { | ||
946 | dcc[i].u.chat->con_flags |= conmask; | ||
947 | dprintf(i, "*** POOF! ***\n"); | ||
948 | ite | 1.89 | dprintf(i, _("You are now a master on this bot.\n")); |
949 | segfault | 1.1 | } |
950 | if (!(oatr & USER_BOTMAST) && (u->flags & USER_BOTMAST)) { | ||
951 | dprintf(i, "### POOF! ###\n"); | ||
952 | ite | 1.89 | dprintf(i, _("You are now a botnet master on this bot.\n")); |
953 | segfault | 1.1 | } |
954 | if ((oatr & USER_BOTMAST) && !(u->flags & USER_BOTMAST)) { | ||
955 | dprintf(i, "### POOF! ###\n"); | ||
956 | ite | 1.89 | dprintf(i, _("You are no longer a botnet master on this bot.\n")); |
957 | segfault | 1.1 | } |
958 | if (!(oatr & USER_OWNER) && (u->flags & USER_OWNER)) { | ||
959 | dprintf(i, "@@@ POOF! @@@\n"); | ||
960 | ite | 1.89 | dprintf(i, _("You are now an OWNER of this bot.\n")); |
961 | segfault | 1.1 | } |
962 | if ((oatr & USER_OWNER) && !(u->flags & USER_OWNER)) { | ||
963 | dprintf(i, "@@@ POOF! @@@\n"); | ||
964 | ite | 1.89 | dprintf(i, _("You are no longer an owner of this bot.\n")); |
965 | segfault | 1.1 | } |
966 | if ((stat & STAT_PARTY) && (u->flags & USER_OP)) | ||
967 | stat &= ~STAT_PARTY; | ||
968 | if (!(stat & STAT_PARTY) && !(u->flags & USER_OP) && | ||
969 | !(u->flags & USER_MASTER)) | ||
970 | stat |= STAT_PARTY; | ||
971 | if ((stat & STAT_CHAT) && !(u->flags & USER_PARTY) && | ||
972 | guppy | 1.81 | !(u->flags & USER_MASTER)) |
973 | segfault | 1.1 | stat &= ~STAT_CHAT; |
974 | if ((dcc[i].type->flags & DCT_FILES) && !(stat & STAT_CHAT) && | ||
975 | guppy | 1.81 | ((u->flags & USER_MASTER) || (u->flags & USER_PARTY))) |
976 | segfault | 1.1 | stat |= STAT_CHAT; |
977 | dcc[i].status = stat; | ||
978 | fabian | 1.22 | /* Check if they no longer have access to wherever they are. |
979 | guppy | 1.49 | * |
980 | fabian | 1.22 | * NOTE: DON'T kick someone off the party line just cuz they lost +p |
981 | * (pinvite script removes +p after 5 mins automatically) | ||
982 | */ | ||
983 | segfault | 1.1 | if ((dcc[i].type->flags & DCT_FILES) && !(u->flags & USER_XFER) && |
984 | !(u->flags & USER_MASTER)) { | ||
985 | dprintf(i, "-+- POOF! -+-\n"); | ||
986 | ite | 1.89 | dprintf(i, _("You no longer have file area access.\n\n")); |
987 | putlog(LOG_MISC, "*", _("DCC user [%s]%s removed from file system"), | ||
988 | segfault | 1.1 | dcc[i].nick, dcc[i].host); |
989 | if (dcc[i].status & STAT_CHAT) { | ||
990 | struct chat_info *ci; | ||
991 | |||
992 | ci = dcc[i].u.file->chat; | ||
993 | tothwolf | 1.70 | free(dcc[i].u.file); |
994 | segfault | 1.1 | dcc[i].u.chat = ci; |
995 | dcc[i].status &= (~STAT_CHAT); | ||
996 | dcc[i].type = &DCC_CHAT; | ||
997 | if (dcc[i].u.chat->channel >= 0) { | ||
998 | chanout_but(-1, dcc[i].u.chat->channel, | ||
999 | "*** %s has returned.\n", dcc[i].nick); | ||
1000 | } | ||
1001 | } else { | ||
1002 | killsock(dcc[i].sock); | ||
1003 | fabian | 1.16 | lostdcc(i); |
1004 | segfault | 1.1 | } |
1005 | } | ||
1006 | } | ||
1007 | } | ||
1008 | return u->flags; | ||
1009 | } | ||
1010 | |||
1011 | stdarg | 1.108 | int check_dcc_chanattrs(user_t *u, char *chname, int chflags, |
1012 | segfault | 1.1 | int ochatr) |
1013 | { | ||
1014 | int i, found = 0, atr = u ? u->flags : 0; | ||
1015 | struct chanset_t *chan; | ||
1016 | |||
1017 | if (!u) | ||
1018 | return 0; | ||
1019 | for (i = 0; i < dcc_total; i++) { | ||
1020 | stdarg | 1.99 | if (dcc[i].type && (dcc[i].type->flags & DCT_MASTER) && |
1021 | tothwolf | 1.74 | !strcasecmp(u->handle, dcc[i].nick)) { |
1022 | segfault | 1.1 | if ((ochatr & USER_MASTER) && !(chflags & USER_MASTER)) { |
1023 | if (!(atr & USER_MASTER)) | ||
1024 | dcc[i].u.chat->con_flags &= ~(LOG_MISC | LOG_CMDS); | ||
1025 | dprintf(i, "*** POOF! ***\n"); | ||
1026 | ite | 1.89 | dprintf(i, _("You are no longer a master on %s.\n"), chname); |
1027 | segfault | 1.1 | } |
1028 | if (!(ochatr & USER_MASTER) && (chflags & USER_MASTER)) { | ||
1029 | dcc[i].u.chat->con_flags |= conmask; | ||
1030 | if (!(atr & USER_MASTER)) | ||
1031 | dcc[i].u.chat->con_flags &= | ||
1032 | ~(LOG_LEV1 | LOG_LEV2 | LOG_LEV3 | LOG_LEV4 | | ||
1033 | LOG_LEV5 | LOG_LEV6 | LOG_LEV7 | LOG_LEV8 | | ||
1034 | LOG_RAW | LOG_DEBUG | LOG_WALL | LOG_FILES | LOG_SRVOUT); | ||
1035 | dprintf(i, "*** POOF! ***\n"); | ||
1036 | ite | 1.89 | dprintf(i, _("You are now a master on %s.\n"), chname); |
1037 | segfault | 1.1 | } |
1038 | if (!(ochatr & USER_OWNER) && (chflags & USER_OWNER)) { | ||
1039 | dprintf(i, "@@@ POOF! @@@\n"); | ||
1040 | ite | 1.89 | dprintf(i, _("You are now an OWNER of %s.\n"), chname); |
1041 | segfault | 1.1 | } |
1042 | if ((ochatr & USER_OWNER) && !(chflags & USER_OWNER)) { | ||
1043 | dprintf(i, "@@@ POOF! @@@\n"); | ||
1044 | ite | 1.89 | dprintf(i, _("You are no longer an owner of %s.\n"), chname); |
1045 | segfault | 1.1 | } |
1046 | if (((ochatr & (USER_OP | USER_MASTER | USER_OWNER)) && | ||
1047 | (!(chflags & (USER_OP | USER_MASTER | USER_OWNER)))) || | ||
1048 | ((chflags & (USER_OP | USER_MASTER | USER_OWNER)) && | ||
1049 | (!(ochatr & (USER_OP | USER_MASTER | USER_OWNER))))) { | ||
1050 | fabian | 1.11 | struct flag_record fr = {FR_CHAN, 0, 0, 0, 0, 0}; |
1051 | segfault | 1.1 | |
1052 | guppy | 1.56 | for (chan = chanset; chan && !found; chan = chan->next) { |
1053 | fabian | 1.8 | get_user_flagrec(u, &fr, chan->dname); |
1054 | segfault | 1.1 | if (fr.chan & (USER_OP | USER_MASTER | USER_OWNER)) |
1055 | found = 1; | ||
1056 | } | ||
1057 | if (!chan) | ||
1058 | chan = chanset; | ||
1059 | if (chan) | ||
1060 | fabian | 1.8 | strcpy(dcc[i].u.chat->con_chan, chan->dname); |
1061 | segfault | 1.1 | else |
1062 | strcpy(dcc[i].u.chat->con_chan, "*"); | ||
1063 | } | ||
1064 | } | ||
1065 | } | ||
1066 | return chflags; | ||
1067 | } | ||
1068 | |||
1069 | stdarg | 1.108 | static int cmd_chattr(user_t *u, int idx, char *par) |
1070 | segfault | 1.1 | { |
1071 | fabian | 1.6 | char *hand, *arg = NULL, *tmpchg = NULL, *chg = NULL, work[1024]; |
1072 | segfault | 1.1 | struct chanset_t *chan = NULL; |
1073 | stdarg | 1.108 | user_t *u2; |
1074 | fabian | 1.2 | struct flag_record pls = {0, 0, 0, 0, 0, 0}, |
1075 | mns = {0, 0, 0, 0, 0, 0}, | ||
1076 | user = {0, 0, 0, 0, 0, 0}; | ||
1077 | segfault | 1.1 | module_entry *me; |
1078 | int fl = -1, of = 0, ocf = 0; | ||
1079 | |||
1080 | if (!par[0]) { | ||
1081 | dprintf(idx, "Usage: chattr <handle> [changes] [channel]\n"); | ||
1082 | stdarg | 1.103 | return(0); |
1083 | segfault | 1.1 | } |
1084 | hand = newsplit(&par); | ||
1085 | u2 = get_user_by_handle(userlist, hand); | ||
1086 | fabian | 1.6 | if (!u2) { |
1087 | ite | 1.89 | dprintf(idx, _("No such user!\n")); |
1088 | stdarg | 1.103 | return(0); |
1089 | segfault | 1.1 | } |
1090 | fabian | 1.6 | |
1091 | /* Parse args */ | ||
1092 | if (par[0]) { | ||
1093 | fabian | 1.8 | arg = newsplit(&par); |
1094 | fabian | 1.6 | if (par[0]) { |
1095 | /* .chattr <handle> <changes> <channel> */ | ||
1096 | chg = arg; | ||
1097 | fabian | 1.8 | arg = newsplit(&par); |
1098 | chan = findchan_by_dname(arg); | ||
1099 | fabian | 1.6 | } else { |
1100 | fabian | 1.8 | chan = findchan_by_dname(arg); |
1101 | fabian | 1.22 | /* Consider modeless channels, starting with '+' */ |
1102 | fabian | 1.6 | if (!(arg[0] == '+' && chan) && |
1103 | !(arg[0] != '+' && strchr (CHANMETA, arg[0]))) { | ||
1104 | /* .chattr <handle> <changes> */ | ||
1105 | chg = arg; | ||
1106 | chan = NULL; /* uh, !strchr (CHANMETA, channel[0]) && channel found?? */ | ||
1107 | arg = NULL; | ||
1108 | } | ||
1109 | /* .chattr <handle> <channel>: nothing to do... */ | ||
1110 | } | ||
1111 | } | ||
1112 | /* arg: pointer to channel name, NULL if none specified | ||
1113 | * chan: pointer to channel structure, NULL if none found or none specified | ||
1114 | * chg: pointer to changes, NULL if none specified | ||
1115 | */ | ||
1116 | tothwolf | 1.72 | assert(!(!arg && chan)); |
1117 | fabian | 1.6 | if (arg && !chan) { |
1118 | ite | 1.89 | dprintf(idx, _("No channel record for %s.\n"), arg); |
1119 | stdarg | 1.103 | return(0); |
1120 | segfault | 1.1 | } |
1121 | fabian | 1.6 | if (chg) { |
1122 | if (!arg && strpbrk(chg, "&|")) { | ||
1123 | /* .chattr <handle> *[&|]*: use console channel if found... */ | ||
1124 | if (!strcmp ((arg = dcc[idx].u.chat->con_chan), "*")) | ||
1125 | arg = NULL; | ||
1126 | else | ||
1127 | fabian | 1.8 | chan = findchan_by_dname(arg); |
1128 | fabian | 1.6 | if (arg && !chan) { |
1129 | ite | 1.89 | dprintf (idx, _("Invalid console channel %s.\n"), arg); |
1130 | stdarg | 1.103 | return(0); |
1131 | fabian | 1.6 | } |
1132 | } else if (arg && !strpbrk(chg, "&|")) { | ||
1133 | tothwolf | 1.70 | tmpchg = malloc(strlen(chg) + 2); |
1134 | fabian | 1.11 | strcpy(tmpchg, "|"); |
1135 | strcat(tmpchg, chg); | ||
1136 | fabian | 1.6 | chg = tmpchg; |
1137 | segfault | 1.1 | } |
1138 | } | ||
1139 | fabian | 1.6 | par = arg; |
1140 | segfault | 1.1 | user.match = FR_GLOBAL; |
1141 | if (chan) | ||
1142 | user.match |= FR_CHAN; | ||
1143 | fabian | 1.8 | get_user_flagrec(u, &user, chan ? chan->dname : 0); |
1144 | segfault | 1.1 | if (!chan && !glob_botmast(user)) { |
1145 | ite | 1.89 | dprintf(idx, _("You do not have Bot Master privileges.\n")); |
1146 | fabian | 1.6 | if (tmpchg) |
1147 | tothwolf | 1.70 | free(tmpchg); |
1148 | stdarg | 1.103 | return(0); |
1149 | segfault | 1.1 | } |
1150 | if (chan && !glob_master(user) && !chan_master(user)) { | ||
1151 | ite | 1.89 | dprintf(idx, |
1152 | wcc | 1.92 | _("You do not have channel master privileges for channel %s.\n"), |
1153 | segfault | 1.1 | par); |
1154 | fabian | 1.6 | if (tmpchg) |
1155 | tothwolf | 1.70 | free(tmpchg); |
1156 | stdarg | 1.103 | return(0); |
1157 | segfault | 1.1 | } |
1158 | user.match &= fl; | ||
1159 | if (chg) { | ||
1160 | pls.match = user.match; | ||
1161 | break_down_flags(chg, &pls, &mns); | ||
1162 | fabian | 1.22 | /* No-one can change these flags on-the-fly */ |
1163 | fabian | 1.6 | pls.global &= ~(USER_BOT); |
1164 | mns.global &= ~(USER_BOT); | ||
1165 | segfault | 1.1 | |
1166 | if (chan) { | ||
1167 | pls.chan &= ~(BOT_SHARE); | ||
1168 | mns.chan &= ~(BOT_SHARE); | ||
1169 | } | ||
1170 | if (!glob_owner(user)) { | ||
1171 | fabian | 1.6 | pls.global &= ~(USER_OWNER | USER_MASTER | USER_BOTMAST | USER_UNSHARED); |
1172 | mns.global &= ~(USER_OWNER | USER_MASTER | USER_BOTMAST | USER_UNSHARED); | ||
1173 | segfault | 1.1 | |
1174 | if (chan) { | ||
1175 | pls.chan &= ~USER_OWNER; | ||
1176 | mns.chan &= ~USER_OWNER; | ||
1177 | } | ||
1178 | if (!glob_master(user)) { | ||
1179 | fabian | 1.6 | pls.global &= USER_PARTY | USER_XFER; |
1180 | mns.global &= USER_PARTY | USER_XFER; | ||
1181 | segfault | 1.1 | |
1182 | if (!glob_botmast(user)) { | ||
1183 | pls.global = 0; | ||
1184 | mns.global = 0; | ||
1185 | } | ||
1186 | } | ||
1187 | } | ||
1188 | if (chan && !chan_owner(user) && !glob_owner(user)) { | ||
1189 | pls.chan &= ~USER_MASTER; | ||
1190 | mns.chan &= ~USER_MASTER; | ||
1191 | if (!chan_master(user) && !glob_master(user)) { | ||
1192 | pls.chan = 0; | ||
1193 | mns.chan = 0; | ||
1194 | } | ||
1195 | } | ||
1196 | get_user_flagrec(u2, &user, par); | ||
1197 | if (user.match & FR_GLOBAL) { | ||
1198 | of = user.global; | ||
1199 | user.global = sanity_check((user.global |pls.global) &~mns.global); | ||
1200 | |||
1201 | user.udef_global = (user.udef_global | pls.udef_global) | ||
1202 | & ~mns.udef_global; | ||
1203 | } | ||
1204 | if (chan) { | ||
1205 | ocf = user.chan; | ||
1206 | user.chan = chan_sanity_check((user.chan | pls.chan) & ~mns.chan, | ||
1207 | user.global); | ||
1208 | |||
1209 | user.udef_chan = (user.udef_chan | pls.udef_chan) & ~mns.udef_chan; | ||
1210 | } | ||
1211 | set_user_flagrec(u2, &user, par); | ||
1212 | } | ||
1213 | fabian | 1.22 | /* Get current flags and display them */ |
1214 | segfault | 1.1 | if (user.match & FR_GLOBAL) { |
1215 | user.match = FR_GLOBAL; | ||
1216 | if (chg) | ||
1217 | check_dcc_attrs(u2, of); | ||
1218 | get_user_flagrec(u2, &user, NULL); | ||
1219 | build_flags(work, &user, NULL); | ||
1220 | if (work[0] != '-') | ||
1221 | wcc | 1.92 | dprintf(idx, _("Global flags for %1$s are now +%2$s.\n"), hand, work); |
1222 | segfault | 1.1 | else |
1223 | ite | 1.89 | dprintf(idx, _("No global flags for %s.\n"), hand); |
1224 | segfault | 1.1 | } |
1225 | if (chan) { | ||
1226 | user.match = FR_CHAN; | ||
1227 | get_user_flagrec(u2, &user, par); | ||
1228 | user.chan &= ~BOT_SHARE; | ||
1229 | if (chg) | ||
1230 | fabian | 1.8 | check_dcc_chanattrs(u2, chan->dname, user.chan, ocf); |
1231 | segfault | 1.1 | build_flags(work, &user, NULL); |
1232 | if (work[0] != '-') | ||
1233 | wcc | 1.92 | dprintf(idx, _("Channel flags for %1$s on %2$s are now +%3$s.\n"), hand, |
1234 | fabian | 1.8 | chan->dname, work); |
1235 | segfault | 1.1 | else |
1236 | ite | 1.89 | dprintf(idx, _("No flags for %1$s on %2$s.\n"), hand, chan->dname); |
1237 | ite | 1.79 | } |
1238 | if (chg && (me = module_find("irc", 0, 0))) { | ||
1239 | Function *func = me->funcs; | ||
1240 | |||
1241 | guppy | 1.82 | (func[IRC_CHECK_THIS_USER]) (hand, 0, NULL); |
1242 | segfault | 1.1 | } |
1243 | fabian | 1.6 | if (tmpchg) |
1244 | tothwolf | 1.70 | free(tmpchg); |
1245 | stdarg | 1.103 | return(1); |
1246 | segfault | 1.1 | } |
1247 | |||
1248 | stdarg | 1.108 | static int cmd_botattr(user_t *u, int idx, char *par) |
1249 | segfault | 1.1 | { |
1250 | fabian | 1.6 | char *hand, *chg = NULL, *arg = NULL, *tmpchg = NULL, work[1024]; |
1251 | segfault | 1.1 | struct chanset_t *chan = NULL; |
1252 | stdarg | 1.108 | user_t *u2; |
1253 | fabian | 1.8 | struct flag_record pls = {0, 0, 0, 0, 0, 0}, |
1254 | mns = {0, 0, 0, 0, 0, 0}, | ||
1255 | user = {0, 0, 0, 0, 0, 0}; | ||
1256 | segfault | 1.1 | int idx2; |
1257 | |||
1258 | if (!par[0]) { | ||
1259 | dprintf(idx, "Usage: botattr <handle> [changes] [channel]\n"); | ||
1260 | stdarg | 1.103 | return(0); |
1261 | segfault | 1.1 | } |
1262 | hand = newsplit(&par); | ||
1263 | u2 = get_user_by_handle(userlist, hand); | ||
1264 | fabian | 1.6 | if (!u2 || !(u2->flags & USER_BOT)) { |
1265 | ite | 1.89 | dprintf(idx, _("No such bot!\n")); |
1266 | stdarg | 1.103 | return(0); |
1267 | segfault | 1.1 | } |
1268 | for (idx2 = 0; idx2 < dcc_total; idx2++) | ||
1269 | stdarg | 1.107 | if (dcc[idx2].type && !strcasecmp(dcc[idx2].nick, hand)) |
1270 | segfault | 1.1 | break; |
1271 | if (idx2 != dcc_total) { | ||
1272 | ite | 1.89 | dprintf(idx, |
1273 | _("You may not change the attributes of a directly linked bot.\n")); | ||
1274 | stdarg | 1.103 | return(0); |
1275 | segfault | 1.1 | } |
1276 | fabian | 1.6 | /* Parse args */ |
1277 | if (par[0]) { | ||
1278 | fabian | 1.10 | arg = newsplit(&par); |
1279 | fabian | 1.6 | if (par[0]) { |
1280 | /* .botattr <handle> <changes> <channel> */ | ||
1281 | chg = arg; | ||
1282 | fabian | 1.10 | arg = newsplit(&par); |
1283 | fabian | 1.8 | chan = findchan_by_dname(arg); |
1284 | fabian | 1.6 | } else { |
1285 | fabian | 1.8 | chan = findchan_by_dname(arg); |
1286 | fabian | 1.22 | /* Consider modeless channels, starting with '+' */ |
1287 | fabian | 1.6 | if (!(arg[0] == '+' && chan) && |
1288 | !(arg[0] != '+' && strchr (CHANMETA, arg[0]))) { | ||
1289 | /* .botattr <handle> <changes> */ | ||
1290 | chg = arg; | ||
1291 | chan = NULL; /* uh, !strchr (CHANMETA, channel[0]) && channel found?? */ | ||
1292 | arg = NULL; | ||
1293 | } | ||
1294 | /* .botattr <handle> <channel>: nothing to do... */ | ||
1295 | } | ||
1296 | } | ||
1297 | /* arg: pointer to channel name, NULL if none specified | ||
1298 | * chan: pointer to channel structure, NULL if none found or none specified | ||
1299 | * chg: pointer to changes, NULL if none specified | ||
1300 | */ | ||
1301 | tothwolf | 1.72 | assert(!(!arg && chan)); |
1302 | fabian | 1.6 | if (arg && !chan) { |
1303 | ite | 1.89 | dprintf(idx, _("No channel record for %s.\n"), arg); |
1304 | stdarg | 1.103 | return(0); |
1305 | segfault | 1.1 | } |
1306 | fabian | 1.6 | if (chg) { |
1307 | if (!arg && strpbrk(chg, "&|")) { | ||
1308 | /* botattr <handle> *[&|]*: use console channel if found... */ | ||
1309 | if (!strcmp ((arg = dcc[idx].u.chat->con_chan), "*")) | ||
1310 | arg = NULL; | ||
1311 | else | ||
1312 | fabian | 1.8 | chan = findchan_by_dname(arg); |
1313 | fabian | 1.6 | if (arg && !chan) { |
1314 | ite | 1.89 | dprintf (idx, _("Invalid console channel %s.\n"), arg); |
1315 | stdarg | 1.103 | return(0); |
1316 | fabian | 1.6 | } |
1317 | } else if (arg && !strpbrk(chg, "&|")) { | ||
1318 | tothwolf | 1.70 | tmpchg = malloc(strlen(chg) + 2); |
1319 | strcpy(tmpchg, "|"); | ||
1320 | strcat(tmpchg, chg); | ||
1321 | fabian | 1.6 | chg = tmpchg; |
1322 | } | ||
1323 | segfault | 1.1 | } |
1324 | fabian | 1.6 | par = arg; |
1325 | guppy | 1.49 | |
1326 | segfault | 1.1 | user.match = FR_GLOBAL; |
1327 | fabian | 1.8 | get_user_flagrec(u, &user, chan ? chan->dname : 0); |
1328 | segfault | 1.1 | if (!glob_botmast(user)) { |
1329 | ite | 1.89 | dprintf(idx, _("You do not have Bot Master privileges.\n")); |
1330 | fabian | 1.6 | if (tmpchg) |
1331 | tothwolf | 1.70 | free(tmpchg); |
1332 | stdarg | 1.103 | return(0); |
1333 | segfault | 1.1 | } |
1334 | if (chg) { | ||
1335 | user.match = FR_BOT | (chan ? FR_CHAN : 0); | ||
1336 | pls.match = user.match; | ||
1337 | break_down_flags(chg, &pls, &mns); | ||
1338 | fabian | 1.22 | /* No-one can change these flags on-the-fly */ |
1339 | segfault | 1.1 | pls.global &=~BOT_BOT; |
1340 | mns.global &=~BOT_BOT; | ||
1341 | |||
1342 | if (chan && glob_owner(user)) { | ||
1343 | pls.chan &= BOT_SHARE; | ||
1344 | mns.chan &= BOT_SHARE; | ||
1345 | } else { | ||
1346 | pls.chan = 0; | ||
1347 | mns.chan = 0; | ||
1348 | } | ||
1349 | if (!glob_owner(user)) { | ||
1350 | pls.bot &= ~(BOT_SHARE | BOT_GLOBAL); | ||
1351 | mns.bot &= ~(BOT_SHARE | BOT_GLOBAL); | ||
1352 | } | ||
1353 | user.match = FR_BOT | (chan ? FR_CHAN : 0); | ||
1354 | get_user_flagrec(u2, &user, par); | ||
1355 | user.bot = (user.bot | pls.bot) & ~mns.bot; | ||
1356 | if ((user.bot & BOT_SHARE) == BOT_SHARE) | ||
1357 | user.bot &= ~BOT_SHARE; | ||
1358 | if (chan) | ||
1359 | user.chan = (user.chan | pls.chan) & ~mns.chan; | ||
1360 | set_user_flagrec(u2, &user, par); | ||
1361 | } | ||
1362 | /* get current flags and display them */ | ||
1363 | if (!chan || pls.bot || mns.bot) { | ||
1364 | user.match = FR_BOT; | ||
1365 | get_user_flagrec(u2, &user, NULL); | ||
1366 | build_flags(work, &user, NULL); | ||
1367 | if (work[0] != '-') | ||
1368 | wcc | 1.92 | dprintf(idx, _("Bot flags for %1$s are now +%2$s.\n"), hand, work); |
1369 | segfault | 1.1 | else |
1370 | ite | 1.89 | dprintf(idx, _("No bot flags for %s.\n"), hand); |
1371 | segfault | 1.1 | } |
1372 | if (chan) { | ||
1373 | user.match = FR_CHAN; | ||
1374 | get_user_flagrec(u2, &user, par); | ||
1375 | user.chan &= BOT_SHARE; | ||
1376 | build_flags(work, &user, NULL); | ||
1377 | if (work[0] != '-') | ||
1378 | wcc | 1.92 | dprintf(idx, _("Bot flags for %1$s on %2$s are now +%3$s.\n"), hand, |
1379 | fabian | 1.8 | chan->dname, work); |
1380 | segfault | 1.1 | else |
1381 | ite | 1.89 | dprintf(idx, _("No bot flags for %1$s on %2$s.\n"), hand, chan->dname); |
1382 | segfault | 1.1 | } |
1383 | fabian | 1.6 | if (tmpchg) |
1384 | tothwolf | 1.70 | free(tmpchg); |
1385 | stdarg | 1.103 | return(1); |
1386 | segfault | 1.1 | } |
1387 | |||
1388 | stdarg | 1.108 | static int cmd_su(user_t *u, int idx, char *par) |
1389 | segfault | 1.1 | { |
1390 | int atr = u ? u->flags : 0; | ||
1391 | fabian | 1.4 | struct flag_record fr = {FR_ANYWH | FR_CHAN | FR_GLOBAL, 0, 0, 0, 0, 0}; |
1392 | segfault | 1.1 | |
1393 | u = get_user_by_handle(userlist, par); | ||
1394 | |||
1395 | if (!par[0]) | ||
1396 | dprintf(idx, "Usage: su <user>\n"); | ||
1397 | else if (!u) | ||
1398 | ite | 1.89 | dprintf(idx, _("No such user.\n")); |
1399 | segfault | 1.1 | else if (u->flags & USER_BOT) |
1400 | ite | 1.89 | dprintf(idx, _("Can't su to a bot... then again, why would you wanna?\n")); |
1401 | segfault | 1.1 | else if (dcc[idx].u.chat->su_nick) |
1402 | ite | 1.89 | dprintf(idx, _("You cannot currently double .su, try .su'ing directly\n")); |
1403 | segfault | 1.1 | else { |
1404 | get_user_flagrec(u, &fr, NULL); | ||
1405 | guppy | 1.81 | if (!glob_party(fr) && !(atr & USER_BOTMAST)) |
1406 | ite | 1.89 | dprintf(idx, _("No party line access permitted for %s.\n"), par); |
1407 | segfault | 1.1 | else { |
1408 | correct_handle(par); | ||
1409 | if (!(atr & USER_OWNER) || | ||
1410 | fabian | 1.31 | ((u->flags & USER_OWNER) && (isowner(par)) && |
1411 | !(isowner(dcc[idx].nick)))) { | ||
1412 | fabian | 1.4 | /* This check is only important for non-owners */ |
1413 | if (u_pass_match(u, "-")) { | ||
1414 | ite | 1.89 | dprintf(idx, |
1415 | wcc | 1.92 | _("No password set for user. You may not .su to them.\n")); |
1416 | stdarg | 1.103 | return(0); |
1417 | fabian | 1.4 | } |
1418 | segfault | 1.1 | chanout_but(-1, dcc[idx].u.chat->channel, |
1419 | "*** %s left the party line.\n", dcc[idx].nick); | ||
1420 | fabian | 1.22 | /* Store the old nick in the away section, for weenies who can't get |
1421 | * their password right ;) | ||
1422 | */ | ||
1423 | segfault | 1.1 | if (dcc[idx].u.chat->away != NULL) |
1424 | tothwolf | 1.70 | free(dcc[idx].u.chat->away); |
1425 | tothwolf | 1.71 | dcc[idx].u.chat->away = calloc(1, strlen(dcc[idx].nick) + 1); |
1426 | segfault | 1.1 | strcpy(dcc[idx].u.chat->away, dcc[idx].nick); |
1427 | tothwolf | 1.71 | dcc[idx].u.chat->su_nick = calloc(1, strlen(dcc[idx].nick) + 1); |
1428 | segfault | 1.1 | strcpy(dcc[idx].u.chat->su_nick, dcc[idx].nick); |
1429 | dcc[idx].user = u; | ||
1430 | strcpy(dcc[idx].nick, par); | ||
1431 | fabian | 1.33 | /* Display password prompt and turn off echo (send IAC WILL ECHO). */ |
1432 | segfault | 1.1 | dprintf(idx, "Enter password for %s%s\n", par, |
1433 | fabian | 1.33 | (dcc[idx].status & STAT_TELNET) ? TLN_IAC_C TLN_WILL_C |
1434 | TLN_ECHO_C : ""); | ||
1435 | segfault | 1.1 | dcc[idx].type = &DCC_CHAT_PASS; |
1436 | } else if (atr & USER_OWNER) { | ||
1437 | chanout_but(-1, dcc[idx].u.chat->channel, | ||
1438 | "*** %s left the party line.\n", dcc[idx].nick); | ||
1439 | ite | 1.89 | dprintf(idx, _("Setting your username to %s.\n"), par); |
1440 | segfault | 1.1 | if (atr & USER_MASTER) |
1441 | dcc[idx].u.chat->con_flags = conmask; | ||
1442 | tothwolf | 1.71 | dcc[idx].u.chat->su_nick = calloc(1, strlen(dcc[idx].nick) + 1); |
1443 | segfault | 1.1 | strcpy(dcc[idx].u.chat->su_nick, dcc[idx].nick); |
1444 | dcc[idx].user = u; | ||
1445 | strcpy(dcc[idx].nick, par); | ||
1446 | dcc_chatter(idx); | ||
1447 | } | ||
1448 | } | ||
1449 | } | ||
1450 | stdarg | 1.103 | return(1); |
1451 | segfault | 1.1 | } |
1452 | |||
1453 | stdarg | 1.108 | static int cmd_fixcodes(user_t *u, int idx, char *par) |
1454 | segfault | 1.1 | { |
1455 | if (dcc[idx].status & STAT_ECHO) { | ||
1456 | dcc[idx].status |= STAT_TELNET; | ||
1457 | dcc[idx].status &= ~STAT_ECHO; | ||
1458 | ite | 1.89 | dprintf(idx, _("Turned on telnet codes\n")); |
1459 | segfault | 1.1 | putlog(LOG_CMDS, "*", "#%s# fixcodes (telnet on)", dcc[idx].nick); |
1460 | stdarg | 1.103 | return(0); |
1461 | segfault | 1.1 | } |
1462 | if (dcc[idx].status & STAT_TELNET) { | ||
1463 | dcc[idx].status |= STAT_ECHO; | ||
1464 | dcc[idx].status &= ~STAT_TELNET; | ||
1465 | ite | 1.89 | dprintf(idx, _("Turned off telnet codes\n")); |
1466 | segfault | 1.1 | putlog(LOG_CMDS, "*", "#%s# fixcodes (telnet off)", dcc[idx].nick); |
1467 | stdarg | 1.103 | return(0); |
1468 | segfault | 1.1 | } |
1469 | stdarg | 1.103 | return(1); |
1470 | segfault | 1.1 | } |
1471 | |||
1472 | stdarg | 1.108 | static int cmd_page(user_t *u, int idx, char *par) |
1473 | segfault | 1.1 | { |
1474 | int a; | ||
1475 | fabian | 1.2 | module_entry *me; |
1476 | segfault | 1.1 | |
1477 | if (!par[0]) { | ||
1478 | if (dcc[idx].status & STAT_PAGE) { | ||
1479 | ite | 1.89 | dprintf(idx, _("Currently paging outputs to %d lines.\n"), |
1480 | segfault | 1.1 | dcc[idx].u.chat->max_line); |
1481 | } else | ||
1482 | ite | 1.89 | dprintf(idx, _("You don't have paging on.\n")); |
1483 | stdarg | 1.103 | return(0); |
1484 | segfault | 1.1 | } |
1485 | a = atoi(par); | ||
1486 | tothwolf | 1.74 | if ((!a && !par[0]) || !strcasecmp(par, "off")) { |
1487 | segfault | 1.1 | dcc[idx].status &= ~STAT_PAGE; |
1488 | dcc[idx].u.chat->max_line = 0x7ffffff; /* flush_lines needs this */ | ||
1489 | while (dcc[idx].u.chat->buffer) | ||
1490 | flush_lines(idx, dcc[idx].u.chat); | ||
1491 | ite | 1.89 | dprintf(idx, _("Paging turned off.\n")); |
1492 | segfault | 1.1 | putlog(LOG_CMDS, "*", "#%s# page off", dcc[idx].nick); |
1493 | fabian | 1.2 | } else if (a > 0) { |
1494 | ite | 1.98 | dprintf(idx, P_("Paging turned on, stopping every %d line.\n", |
1495 | "Paging turned on, stopping every %d lines.\n", a), a); | ||
1496 | segfault | 1.1 | dcc[idx].status |= STAT_PAGE; |
1497 | dcc[idx].u.chat->max_line = a; | ||
1498 | dcc[idx].u.chat->line_count = 0; | ||
1499 | dcc[idx].u.chat->current_lines = 0; | ||
1500 | putlog(LOG_CMDS, "*", "#%s# page %d", dcc[idx].nick, a); | ||
1501 | fabian | 1.2 | } else { |
1502 | dprintf(idx, "Usage: page <off or #>\n"); | ||
1503 | stdarg | 1.103 | return(0); |
1504 | fabian | 1.2 | } |
1505 | fabian | 1.22 | /* New style autosave here too -- rtc, 09/28/1999*/ |
1506 | fabian | 1.2 | if ((me = module_find("console", 1, 1))) { |
1507 | Function *func = me->funcs; | ||
1508 | (func[CONSOLE_DOSTORE]) (idx); | ||
1509 | segfault | 1.1 | } |
1510 | stdarg | 1.103 | return(1); |
1511 | segfault | 1.1 | } |
1512 | |||
1513 | stdarg | 1.108 | static int cmd_module(user_t *u, int idx, char *par) |
1514 | segfault | 1.1 | { |
1515 | do_module_report(idx, 2, par[0] ? par : NULL); | ||
1516 | stdarg | 1.103 | return(1); |
1517 | segfault | 1.1 | } |
1518 | |||
1519 | stdarg | 1.108 | static int cmd_loadmod(user_t *u, int idx, char *par) |
1520 | segfault | 1.1 | { |
1521 | const char *p; | ||
1522 | |||
1523 | guppy | 1.80 | if (!isowner(dcc[idx].nick)) { |
1524 | ite | 1.63 | dprintf(idx, _("What? You need .help\n")); |
1525 | stdarg | 1.103 | return(0); |
1526 | segfault | 1.1 | } |
1527 | if (!par[0]) { | ||
1528 | ite | 1.63 | dprintf(idx, "%s: loadmod <module>\n", _("Usage")); |
1529 | segfault | 1.1 | } else { |
1530 | p = module_load(par); | ||
1531 | if (p) | ||
1532 | ite | 1.63 | dprintf(idx, "%s: %s %s\n", par, _("Error loading module:"), p); |
1533 | segfault | 1.1 | else { |
1534 | ite | 1.63 | dprintf(idx, _("Module loaded: %-16s"), par); |
1535 | fabian | 1.28 | dprintf(idx, "\n"); |
1536 | segfault | 1.1 | } |
1537 | } | ||
1538 | stdarg | 1.103 | return(1); |
1539 | segfault | 1.1 | } |
1540 | |||
1541 | stdarg | 1.108 | static int cmd_unloadmod(user_t *u, int idx, char *par) |
1542 | segfault | 1.1 | { |
1543 | char *p; | ||
1544 | |||
1545 | guppy | 1.80 | if (!isowner(dcc[idx].nick)) { |
1546 | ite | 1.63 | dprintf(idx, _("What? You need .help\n")); |
1547 | stdarg | 1.103 | return(0); |
1548 | segfault | 1.1 | } |
1549 | if (!par[0]) { | ||
1550 | ite | 1.63 | dprintf(idx, "%s: unloadmod <module>\n", _("Usage")); |
1551 | segfault | 1.1 | } else { |
1552 | p = module_unload(par, dcc[idx].nick); | ||
1553 | if (p) | ||
1554 | ite | 1.63 | dprintf(idx, "%s %s: %s\n", _("Error unloading module:"), par, p); |
1555 | segfault | 1.1 | else { |
1556 | ite | 1.63 | dprintf(idx, "%s %s\n", _("Module unloaded:"), par); |
1557 | segfault | 1.1 | } |
1558 | } | ||
1559 | stdarg | 1.103 | return(1); |
1560 | segfault | 1.1 | } |
1561 | |||
1562 | stdarg | 1.108 | static int cmd_pls_ignore(user_t *u, int idx, char *par) |
1563 | segfault | 1.1 | { |
1564 | fabian | 1.38 | char *who; |
1565 | char s[UHOSTLEN]; | ||
1566 | unsigned long int expire_time = 0; | ||
1567 | segfault | 1.1 | |
1568 | if (!par[0]) { | ||
1569 | fabian | 1.38 | dprintf(idx, |
1570 | guppy | 1.55 | "Usage: +ignore <hostmask> [%%<XdXhXm>] [comment]\n"); |
1571 | stdarg | 1.103 | return(0); |
1572 | segfault | 1.1 | } |
1573 | fabian | 1.38 | |
1574 | segfault | 1.1 | who = newsplit(&par); |
1575 | fabian | 1.38 | if (par[0] == '%') { |
1576 | char *p, *p_expire; | ||
1577 | unsigned long int expire_foo; | ||
1578 | |||
1579 | p = newsplit(&par); | ||
1580 | p_expire = p + 1; | ||
1581 | while (*(++p) != 0) { | ||
1582 | switch (tolower(*p)) { | ||
1583 | case 'd': | ||
1584 | *p = 0; | ||
1585 | expire_foo = strtol(p_expire, NULL, 10); | ||
1586 | if (expire_foo > 365) | ||
1587 | expire_foo = 365; | ||
1588 | expire_time += 86400 * expire_foo; | ||
1589 | p_expire = p + 1; | ||
1590 | break; | ||
1591 | case 'h': | ||
1592 | *p = 0; | ||
1593 | expire_foo = strtol(p_expire, NULL, 10); | ||
1594 | if (expire_foo > 8760) | ||
1595 | expire_foo = 8760; | ||
1596 | expire_time += 3600 * expire_foo; | ||
1597 | p_expire = p + 1; | ||
1598 | break; | ||
1599 | case 'm': | ||
1600 | *p = 0; | ||
1601 | expire_foo = strtol(p_expire, NULL, 10); | ||
1602 | if (expire_foo > 525600) | ||
1603 | expire_foo = 525600; | ||
1604 | expire_time += 60 * expire_foo; | ||
1605 | p_expire = p + 1; | ||
1606 | } | ||
1607 | } | ||
1608 | } | ||
1609 | segfault | 1.1 | if (!par[0]) |
1610 | par = "requested"; | ||
1611 | else if (strlen(par) > 65) | ||
1612 | par[65] = 0; | ||
1613 | fabian | 1.6 | if (strlen(who) > UHOSTMAX - 4) |
1614 | who[UHOSTMAX - 4] = 0; | ||
1615 | fabian | 1.38 | |
1616 | /* Fix missing ! or @ BEFORE continuing */ | ||
1617 | segfault | 1.1 | if (!strchr(who, '!')) { |
1618 | if (!strchr(who, '@')) | ||
1619 | simple_sprintf(s, "%s!*@*", who); | ||
1620 | else | ||
1621 | simple_sprintf(s, "*!%s", who); | ||
1622 | } else if (!strchr(who, '@')) | ||
1623 | simple_sprintf(s, "%s@*", who); | ||
1624 | else | ||
1625 | strcpy(s, who); | ||
1626 | fabian | 1.38 | |
1627 | if (match_ignore(s)) | ||
1628 | ite | 1.89 | dprintf(idx, _("That already matches an existing ignore.\n")); |
1629 | fabian | 1.38 | else { |
1630 | dprintf(idx, "Now ignoring: %s (%s)\n", s, par); | ||
1631 | addignore(s, dcc[idx].nick, par, expire_time ? now + expire_time : 0L); | ||
1632 | segfault | 1.1 | } |
1633 | stdarg | 1.103 | return(1); |
1634 | segfault | 1.1 | } |
1635 | |||
1636 | stdarg | 1.108 |