/[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.107 - (hide annotations) (download) (as text)
Fri Sep 20 21:41:49 2002 UTC (17 years, 2 months ago) by stdarg
Branch: MAIN
Changes since 1.106: +14 -482 lines
File MIME type: text/x-chdr
* Mo-Ize removed the botnet code, thanks

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