/[cvs]/eggdrop1.9/src/cmds.c
ViewVC logotype

Annotation of /eggdrop1.9/src/cmds.c

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.112 - (hide annotations) (download) (as text)
Mon Feb 3 11:41:34 2003 UTC (16 years, 10 months ago) by wcc
Branch: MAIN
Changes since 1.111: +10 -12 lines
File MIME type: text/x-chdr
* More botnet removal.

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