/[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.109 - (hide annotations) (download) (as text)
Fri Oct 11 00:49:20 2002 UTC (17 years, 1 month ago) by wcc
Branch: MAIN
Changes since 1.108: +35 -26 lines
File MIME type: text/x-chdr
* Completed 1.6<>1.7 patch synch.

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.90 * Copyright (C) 1999, 2000, 2001, 2002 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.109 static const char rcsid[] = "$Id: cmds.c,v 1.108 2002/10/07 22:36:36 stdarg 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     if (!chan_op(fr) && !(glob_op(fr) && !chan_deop(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