Cease including Bot.H in Utils.H
[clinton/bobotpp.git] / source / UserCommands.C
CommitLineData
cb21075d 1// UserCommands.C -*- C++ -*-
2// Copyright (c) 1997, 1998 Etienne BERNARD
a6339323 3// Copyright (C) 2002,2005 Clinton Ebadi
cb21075d 4
5// This program is free software; you can redistribute it and/or modify
6// it under the terms of the GNU General Public License as published by
7// the Free Software Foundation; either version 2 of the License, or
8// any later version.
9
10// This program is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13// GNU General Public License for more details.
14
15// You should have received a copy of the GNU General Public License
16// along with this program; if not, write to the Free Software
c6e7af05 17// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18// 02110-1301, USA.
cb21075d 19
20#ifdef HAVE_CONFIG_H
21#include "config.h"
22#endif
23
24#include <fstream>
e07b6b46 25#include <map>
a6339323 26#include <string>
27#include <cctype>
28#include <cstdlib>
55f2215d 29#include <cstring>
cb21075d 30#include <sys/types.h>
31#include <sys/socket.h>
32#include <netinet/in.h>
33#include <arpa/inet.h>
34#include <netdb.h>
55f2215d 35
cb21075d 36#ifndef _X_OPEN_SOURCE
37#define _X_OPEN_SOURCE
38#endif
39#ifndef _X_OPEN_SOURCE_EXTENDED
40#define _X_OPEN_SOURCE_EXTENDED 1
41#endif
42#ifndef __USE_XOPEN
43#define __USE_XOPEN
44#endif
55f2215d 45
cb21075d 46#include <unistd.h>
47
48#include "Commands.H"
49#include "UserCommands.H"
50#include "DCCConnection.H"
6530edbf 51#include "DCCManager.H"
cb21075d 52#include "Parser.H"
53#include "Macros.H"
54#include "StringTokenizer.H"
55#include "Utils.H"
56#include "ServerList.H"
57#include "Server.H"
58
59#ifdef NOCRYPT
60char * crypt(const char *p, const char *s) { return p; }
61#endif
62
63void
64UserCommands::Action(ServerConnection *cnx, Person *from,
65 String channel, String rest)
66{
67 Message m = Commands::Action(cnx->bot, channel, rest);
68 if (m.getCode() != 0)
69 from->sendNotice(m.getMessage());
70}
71
72void
73UserCommands::AddUser(ServerConnection *cnx, Person *from,
74 String channel, String rest)
75{
76 StringTokenizer st(rest);
77 String mask, who, maskChannel, level, prot,
78 aop, expiration, passwd;
79
a6339323 80 mask = who = st.next_token();
81 maskChannel = st.next_token();
82 level = st.next_token();
83 prot = st.next_token();
84 aop = st.next_token();
85 expiration = st.next_token();
86 passwd = st.next_token();
cb21075d 87
88 if (mask == "" || maskChannel == "" || level == "" ||
89 prot == "" || aop == "") {
90 from->sendNotice("\002Invalid syntax for this command.\002");
91 return;
92 }
93
a6339323 94// if (!Utils::wildcard_p(mask)) {
cb21075d 95// mask = cnx->bot->getUserhost(channel, who);
96// if (mask == "") {
97// from->sendNotice(String("\002I can not find\002 ") + who);
98// return;
99// }
a6339323 100// mask = Utils::make_wildcard(mask);
cb21075d 101// }
102
103// if (cnx->bot->userList->isInUserList(mask, maskChannel)) {
104// from->sendNotice(who + " \002is already in userlist on channel(s)\002 " +
105// maskChannel);
106// return;
107// }
108
109 int l, p;
110 bool a;
111 time_t e;
112
113 l = atoi((const char *)level);
114 if (l < 0 || l > User::FRIEND)
115 return;
a6339323 116 if (l > Utils::get_level(cnx->bot, from->getAddress())) {
cb21075d 117 from->sendNotice("\002You can not give a level greater than yours.\002");
118 return;
119 }
120 p = atoi((const char *)prot);
121 if (p < 0 || p > User::NO_DEOP)
122 return;
123 a = (bool)atoi((const char *)aop);
124 if (a != 0 && a != 1)
125 return;
126
a6339323 127 e = Utils::str2time(expiration);
cb21075d 128
129 if (!e)
130 e = -1;
131
132 // cnx->bot->userList->addUser(mask, maskChannel, l, p, a, e, passwd);
133
134 Message m =
135 Commands::AddUser (cnx->bot, who, maskChannel, l, p, a, e, passwd);
136 if (!m.getCode ())
137 {
138 from->sendNotice(String("\002Added\002 ") + mask +
139 " \002on channels\002 " + maskChannel);
140 from->sendNotice(String("\002Level:\002 ") +
a6339323 141 Utils::level2str(l) +
cb21075d 142 " \002Protection:\002 " +
a6339323 143 Utils::prot2str(p) +
cb21075d 144 " \002Auto-op:\002 " +
a6339323 145 Utils::bool2str(a));
cb21075d 146 }
147 else
148 from->sendNotice(m.getMessage ());
149
150 // cnx->bot->rehash();
151}
152
153void
154UserCommands::AddServer(ServerConnection *cnx, Person *from,
155 String channel, String rest)
156{
157 if (rest.length() == 0) {
158 from->sendNotice("\002You must supply a server name.\002");
159 return;
160 }
161
162 StringTokenizer st(rest);
a6339323 163 String serverName = st.next_token();
cb21075d 164 int port = 6667;
165
a6339323 166 if (st.more_tokens_p()) {
167 String temp = st.next_token();
cb21075d 168 port = atoi((const char *)temp);
169 }
170
171 Message m = Commands::AddServer(cnx->bot, serverName, port);
172 if (m.getCode() != 0)
173 from->sendNotice(m.getMessage());
174 else
175 from->sendNotice(String("\002Server\002 ") +
176 serverName + " \002on port\002 " +
177 String((long)port) + " \002has been added "
178 "to the server list.\002");
179}
180
181// FIXME: does this work now
182void
183UserCommands::AddShit(ServerConnection *cnx, Person *from,
184 String channel, String rest)
185{
186 StringTokenizer st(rest);
187 String mask, who, maskChannel, level, expiration, reason;
188
a6339323 189 mask = who = st.next_token();
190 maskChannel = st.next_token();
191 level = st.next_token();
192 expiration = st.next_token();
193 reason = Utils::trim_str (st.rest());
cb21075d 194
195 /* if (mask == "" || maskChannel == "" || level == "") {
196 from->sendNotice("\002Invalid syntax for this command.\002");
197 return;
198 }
199 */
200
201 /*
202 if (reason == "")
203 reason = "You're on my shitlist, lamer";
204 */
205
206 /*
a6339323 207 if (!Utils::wildcard_p(mask)) {
cb21075d 208 mask = cnx->bot->getUserhost(channel, who);
209 if (mask == "") {
210 from->sendNotice(String("\002I can not find\002 ") + who);
211 return;
212 }
a6339323 213 mask = Utils::make_wildcard(mask);
cb21075d 214 if (cnx->bot->shitList->getShit(mask, maskChannel)) {
215 from->sendNotice(mask + " \002is already in shitlist on channel(s)\002 " +
216 maskChannel);
217 return;
218 }
219 }
220 */
221 int l;
222 time_t e;
223
224 l = atoi((const char *)level);
225 if (l < 0 || l > ShitEntry::SHIT_NODEBAN)
226 return;
227
a6339323 228 e = Utils::str2time(expiration);
cb21075d 229
230 if (!e)
231 e = -1;
232
233 /*
234 if (cnx->bot->userList->getMaxProt(mask, maskChannel) > 0) {
235 from->sendNotice(String("\002I can not add\002 ") + who +
236 " \002into the shitlist (protection).");
237 return;
238 }
239
240 cnx->bot->shitList->addShit(mask, maskChannel, l, e, reason);
241 */
242
243 Message M = Commands::AddShit (cnx->bot, mask, maskChannel, l, e, reason);
244 if (!M.getCode ())
245 from->sendNotice(String("\002Added\002 ") + mask +
246 " \002on channels\002 " + maskChannel +
247 " \002into the shitlist.\002");
248 else
249 from->sendNotice (M.getMessage ());
250}
251
252// FIXME: Convert (and change ?)
253void
254UserCommands::Alias(ServerConnection *cnx, Person *from,
255 String channel, String rest)
256{
257 StringTokenizer st(rest);
a6339323 258 String newF = Utils::to_upper (st.next_token());
259 String oldF = Utils::to_upper (st.next_token());
cb21075d 260
261 if (newF == "" || oldF == "") {
262 from->sendNotice("\002Invalid syntax for this command.\002");
263 return;
264 }
265
266 // First, we check that the "new" function does not exist
e07b6b46 267 if (cnx->bot->userFunctions[newF]) {
cb21075d 268 from->sendNotice(newF + " \002is already an alias.\002");
269 return;
e07b6b46 270 }
cb21075d 271
272 // Next, we check that the "old" function exist
e07b6b46 273 if (!cnx->bot->userFunctions[oldF])
274 {
275 from->sendNotice(String("\002I don't know the\002 ") + oldF +
276 " \002command.");
277 return;
cb21075d 278 }
cb21075d 279
280 // Fine, we do the binding
e07b6b46 281 cnx->bot->userFunctions[newF] =
282 new userFunction (*cnx->bot->userFunctions[oldF]);
cb21075d 283
284 from->sendNotice("\002Alias added.\002");
285}
286
287void
288UserCommands::Ban(ServerConnection *cnx, Person *from,
289 String channel, String rest)
290{
291 if (rest.length() == 0) {
292 if (from)
293 from->sendNotice("\002No nick/mask specified.\002");
294 return;
295 }
296
297 Message m = Commands::Ban(cnx->bot, channel, rest);
298 if (m.getCode() != 0 && from)
299 from->sendNotice(m.getMessage());
300}
301
302void
303UserCommands::BanList(ServerConnection *cnx, Person *from,
304 String channel, String rest)
305{
306 time_t current = time(0);
307 Channel *c = cnx->bot->channelList->getChannel(channel);
308 from->sendNotice(String("\002Banlist for channel\002 ") +
309 channel + "\002:\002");
310 from->sendNotice("\002Mask Expires (seconds)\002");
311 for (std::vector<BanEntry *>::iterator it = c->channelBanlist.begin();
312 it != c->channelBanlist.end(); ++it)
313 if ((*it)->getExpirationDate() == -1)
314 from->sendNotice((*it)->getMask().pad(30) + " -1");
315 else
316 from->sendNotice((*it)->getMask().pad(30) + " " +
317 String((long)((*it)->getExpirationDate()-current)));
318 from->sendNotice("\002End of banlist.\002");
319}
320
321// void
322// UserCommands::ChangeLevel(ServerConnection *cnx, Person *from,
323// String channel, String rest)
324// {
325// StringTokenizer st(rest);
326
327// String who;
a6339323 328// String mask = who = st.next_token();
329// String maskChannel = st.next_token();
330// String level = st.next_token();
cb21075d 331
332// if (mask == "" || maskChannel == "" || level == "") {
333// from->sendNotice("\002Invalid syntax for this command.\002");
334// return;
335// }
336
a6339323 337// if (!Utils::wildcard_p(mask)) {
cb21075d 338// mask = cnx->bot->getUserhost(channel, who);
339// if (mask == "") {
340// from->sendNotice(String("\002I can not find\002 ") + who);
341// return;
342// }
343// mask = from->getNick() + "!" + mask;
344// }
345
346// UserListItem *uli = cnx->bot->userList->getUserListItem(mask, maskChannel);
347
348// if (!uli) {
349// from->sendNotice(String("\002I can not find\002 ") + who +
350// " \002on channel(s)\002 " + maskChannel +
351// " \002in my userlist.\002");
352// return;
353// }
354
355// int l = atoi((const char *)level);
356
357// if (l < User::NONE || l > User::MASTER) {
358// from->sendNotice("\002This is not a valid level.\002");
359// return;
360// }
361
a6339323 362// if (l > Utils::get_level(cnx->bot, from->getAddress())) {
cb21075d 363// from->sendNotice("\002You can not give a level greater than yours.\002");
364// return;
365// }
366
a6339323 367// if (Utils::get_level(cnx->bot, from->getAddress()) < uli->level) {
cb21075d 368// from->sendNotice("\002You can not change the level for a person "
369// "whose level is greater than yours.\002");
370// return;
371// }
372
373// uli->level = l;
374// from->sendNotice("\002Level changed.\002");
375// cnx->bot->rehash();
376// }
377
378void
379UserCommands::Channels(ServerConnection *cnx, Person *from,
380 String channel, String rest)
381{
382 String result = "";
383
384 for (std::map<String, Channel *, std::less<String> >::iterator it =
385 cnx->bot->channelList->begin();
386 it != cnx->bot->channelList->end(); ++it)
387 result = result + (*it).first + " ";
388
389 if (result == "")
390 from->sendNotice("\002I am not on any channel.\002");
391 else
392 from->sendNotice(String("\002I am currently on channel(s):\002 ") +
393 + result);
394}
395
396void
397UserCommands::Cycle(ServerConnection *cnx, Person *from,
398 String channel, String rest)
399{
400 Message m = Commands::Cycle(cnx->bot, channel);
401 if (m.getCode() != 0)
402 from->sendNotice(m.getMessage());
403}
404
405void
406UserCommands::DCCList(ServerConnection *cnx, Person *from,
407 String channel, String rest)
408{
409 time_t current_time = time(0);
410
411 from->sendNotice("\002DCClist:\002");
412 from->sendNotice("\002Hostname Last used\002");
413
6530edbf 414 for (DCC_MAP::iterator it =
c3ecc559 415 cnx->bot->dccConnections->dcc_map.begin ();
416 it != cnx->bot->dccConnections->dcc_map.end();
cb21075d 417 ++it) {
4edefeb6 418 from->sendNotice(String(it->second->dcc->get_nuh()).pad(32) + " " +
cb21075d 419 String((long)(current_time -
4edefeb6 420 it->second->dcc->get_lastSpoken())));
cb21075d 421 }
422
423 from->sendNotice("\002End of dcclist.\002");
424}
425
426void
427UserCommands::Deban(ServerConnection *cnx, Person *from,
428 String channel, String rest)
429{
430 if (rest.length() == 0) {
431 from->sendNotice("\002No nick/mask specified.\002");
432 return;
433 }
434
435 Message m = Commands::Deban(cnx->bot, channel, rest);
436 if (m.getCode() != 0)
437 from->sendNotice(m.getMessage());
438}
439
440void
441UserCommands::DelServer(ServerConnection *cnx, Person *from,
442 String channel, String rest)
443{
444 if (rest.length() == 0) {
445 from->sendNotice("\002You need to supply a server number"
446 " for this command.\002");
447 return;
448 }
449
450 int serverNumber = atoi(rest);
451
452 Message m = Commands::DelServer(cnx->bot, serverNumber);
453 if (m.getCode() != 0)
454 from->sendNotice(m.getMessage());
455 else
456 from->sendNotice(String("Deleted server ") +
457 cnx->bot->serverList->get(serverNumber)->getHostName() +
458 " (" + String((long)cnx->bot->serverList->get(serverNumber)->getPort()) +
459 ").");
460}
461
462// FIXME: Convert
463void
464UserCommands::DelUser(ServerConnection *cnx, Person *from,
465 String channel, String rest)
466{
467 StringTokenizer st(rest);
468
469 String who;
a6339323 470 String mask = who = st.next_token();
471 String maskChannel = st.next_token();
cb21075d 472
473 if (mask == "" || maskChannel == "") {
474 from->sendNotice("\002Invalid syntax for this command.\002");
475 return;
476 }
477
a6339323 478 if (!Utils::wildcard_p(mask)) {
cb21075d 479 mask = cnx->bot->getUserhost(channel, who);
480 if (mask == "") {
481 from->sendNotice(String("\002I can not find\002 ") + who);
482 return;
483 }
a6339323 484 mask = Utils::make_wildcard(mask);
cb21075d 485 }
486
487 if (!cnx->bot->userList->isInUserList(mask, maskChannel)) {
488 from->sendNotice(mask + " \002is not in userlist on channel(s)\002 " +
489 maskChannel);
490 return;
491 }
492
493 cnx->bot->userList->removeUser(mask, maskChannel);
494 from->sendNotice(who + " \002has been removed from the userlist.\002");
495 cnx->bot->rehash();
496}
497
498// FIXME: Convert
499void
500UserCommands::DelShit(ServerConnection *cnx, Person *from,
501 String channel, String rest)
502{
503 StringTokenizer st(rest);
504
505 String who;
a6339323 506 String mask = who = st.next_token();
507 String maskChannel = st.next_token();
cb21075d 508
509 if (mask == "" || maskChannel == "") {
510 from->sendNotice("\002Invalid syntax for this command.\002");
511 return;
512 }
513
a6339323 514 if (!Utils::wildcard_p(mask)) {
cb21075d 515 mask = cnx->bot->getUserhost(channel, who);
516 if (mask == "") {
517 from->sendNotice(String("\002I can not find\002 ") + who);
518 return;
519 }
a6339323 520 mask = Utils::make_wildcard(mask);
cb21075d 521 }
522
523 if (!cnx->bot->shitList->getShit(mask, maskChannel)) {
524 from->sendNotice(mask + " \002is not in shitlist on channel(s)\002 " +
525 maskChannel);
526 return;
527 }
528
529 cnx->bot->shitList->delShit(mask, maskChannel);
530 from->sendNotice(who + " \002has been removed from the shitlist.\002");
531}
532
533void
534UserCommands::Deop(ServerConnection *cnx, Person *from,
535 String channel, String rest)
536{
537 String target = rest;
538
539 if (target.length() == 0)
540 target = from->getNick();
541
542 Message m = Commands::Deop(cnx->bot, channel, target);
543 if (m.getCode() != 0)
544 from->sendNotice(m.getMessage());
545}
546
547void
548UserCommands::Die(ServerConnection *cnx, Person *from,
549 String channel, String rest)
550{
551 String reason;
552
553 if (rest.length() == 0)
554 reason = "Leaving";
555 else
556 reason = rest;
557
558 Commands::Die(cnx->bot, reason);
559}
560
561void
562UserCommands::Do(ServerConnection *cnx, Person *from,
563 String channel, String rest)
564{
565 if (rest.length() != 0)
566 Commands::Do(cnx->bot, rest);
567}
568
569#ifdef USESCRIPTS
570void
571UserCommands::Execute(ServerConnection *cnx, Person *from,
572 String channel, String rest)
573{
574 if (rest.length() != 0)
575 Interp::Execute(cnx->bot, rest);
576}
577#endif
578
579void
580UserCommands::Help(ServerConnection *cnx, Person *from,
581 String channel, String rest)
582{
583 if (rest.length() == 0) {
584 from->sendNotice("\002Available topics for you are:\002");
a6339323 585 int level = Utils::get_level(cnx->bot, from->getAddress());
cb21075d 586 String result = "";
587 int length = 0;
7b564711 588 std::map<std::string, class userFunction*,
589 std::less<std::string> >::iterator it;
590
591 for (it = cnx->bot->userFunctions.begin();
592 it != cnx->bot->userFunctions.end(); ++it)
593 {
594 if ((*it).second->minLevel <= level)
595 {
596 result = result + (*it).first + " ";
597 length += (*it).first.length() + 1;
598
599 if (length >= 256)
600 {
601 from->sendNotice(result);
602 result = ""; length = 0;
603 }
604 }
605 }
cb21075d 606 if (result != "")
607 from->sendNotice(result);
608 from->sendNotice("\002Use\002 HELP <command> \002for"
609 " help about\002 <command>");
610 return;
611 }
612
613 StringTokenizer st(rest);
a6339323 614 String command = Utils::to_upper (st.next_token());
cb21075d 615 std::ifstream helpFile(cnx->bot->helpFileName);
616
617 if (!helpFile) {
618 from->sendNotice(String("\002Error: I can not find the "
619 "help file\002 ") +
620 cnx->bot->helpFileName);
621 return;
622 }
623
624 String buf;
625 while (!helpFile.eof()) {
626 helpFile >> buf;
627 if (buf.subString(0, command.length()) == String(":") + command) {
628 buf = buf.subString(1);
629 from->sendNotice(String("\002Help for\002 ") + command +
630 "\002:\002");
631 while (buf != "") {
632 from->sendNotice(buf);
633 helpFile >> buf;
634 }
635 from->sendNotice("\002End of help.\002");
636 return;
637 }
638 }
639
640 from->sendNotice(String("\002No such topic (\002") +
641 command + "\002).\002");
642}
643
644void
645UserCommands::Ident(ServerConnection *cnx, Person *from,
646 String channel, String rest)
647{
648 Channel *c = cnx->bot->channelList->getChannel(channel);
649
650 if (rest.length() <= 2) {
651 from->sendNotice("\002No password specified or password "
652 "too short.\002");
653 return;
654 }
655
656 User * u = c->getUser(from->getNick());
657 if (!u) {
658 from->sendNotice(String("\002You can identify yourself on"
659 " channel\002 ") + channel +
660 " \002only if you are on the channel.\002");
661 return;
662 }
663
664 if (u->userListItem && u->userListItem->identified) {
665 from->sendNotice(String("\002You are already identified on"
666 " channel\002 ") + channel);
667 return;
668 }
669
670 if (!u->userListItem) {
671 from->sendNotice("\002You are not in my userlist.\002");
672 return;
673 }
674
675 if (u->userListItem->passwd ==
676 crypt((const char *)rest, (const char *)u->userListItem->passwd)) {
677 // For each channel, we increment identification counter
678 for (std::map<String, Channel *, std::less<String> >::iterator it =
679 cnx->bot->channelList->begin();
680 it != cnx->bot->channelList->end(); ++it)
681 u->userListItem->identified++;
682
683 from->sendNotice("\002You are now identified.\002");
684 } else
685 from->sendNotice("\002This is a wrong password.\002");
686}
687
688void
689UserCommands::Invite(ServerConnection *cnx, Person *from,
690 String channel, String rest)
691{
692 Message m = Commands::Invite(cnx->bot, channel, rest);
693 if (m.getCode() < 0)
694 from->sendNotice(m.getMessage());
695 from->sendNotice(String("\002Inviting\002 ") + rest + " \002on channel\002 " + channel);
696}
697
698// FIXME: Convert
699void
700UserCommands::Join(ServerConnection *cnx, Person *from,
701 String channel, String rest)
702{
703 StringTokenizer st(rest);
a6339323 704 channel = st.next_token();
cb21075d 705
a6339323 706 if (!Utils::valid_channel_name_p(channel)) {
cb21075d 707 from->sendNotice(String("\002") + channel +
708 " is not a valid channel name\002");
709 return;
710 }
711
712 // We change the key only if we are not on the channel. We don't trust
713 // the user...
714 if (!cnx->bot->channelList->getChannel(channel)) {
715 if (cnx->bot->wantedChannels[channel])
716 cnx->bot->wantedChannels[channel]->key = st.rest();
717 else {
718 cnx->bot->wantedChannels[channel] = new wantedChannel("", "", st.rest());
719 }
720 }
721 cnx->queue->sendJoin(channel, cnx->bot->wantedChannels[channel]->key);
722}
723
724// FIXME: Convert
725void
726UserCommands::Keep(ServerConnection *cnx, Person *from,
727 String channel, String rest)
728{
729 String nick = from->getNick();
730
731 if (rest.length() == 0) {
732 from->sendNotice("\002No channel modes specified.\002");
733 return;
734 }
735
736 cnx->bot->channelList->getChannel(channel)->keepModes = rest;
737 from->sendNotice(String("\002Keeping modes\002 ") +
738 rest + " \002on channel\002 " +
739 channel);
740}
741
742// FIXME: Convert
743void
744UserCommands::Kick(ServerConnection *cnx, Person *from,
745 String channel, String rest)
746{
747 String nick = from->getNick();
748
749 Channel * c = cnx->bot->channelList->getChannel(channel);
750
751 if (rest.length() == 0) {
752 from->sendNotice("\002No nick specified.\002");
753 return;
754 }
755
756 StringTokenizer st(rest);
a6339323 757 String who = st.next_token();
cb21075d 758
a6339323 759 if (Utils::wildcard_p(who)) {
cb21075d 760 User * u = c->getUser(nick);
761 if (!u)
762 return;
763 if (u->getLevel() < User::TRUSTED_USER) {
764 from->sendNotice("\002You need an higher level to "
765 "use wildcards.\002");
766 return;
767 }
768 }
769
770 if (!cnx->bot->iAmOp(channel)) {
771 from->sendNotice(String("\002I am not channel op on\002 ") +
772 channel);
773 return;
774 }
775
a6339323 776 if (Utils::wildcard_p(who)) {
cb21075d 777 Mask m(who);
778 for (std::map<String, User *, std::less<String> >::iterator it =
779 c->channelMemory.begin();
780 it != c->channelMemory.end();
781 ++it)
782 if (m.matches((*it).second->nick + "!" +
783 (*it).second->userhost) &&
784 (*it).second->getProt() < User::NO_KICK)
785 cnx->queue->sendKick(channel, (*it).second->nick, st.rest());
786 } else {
787 User * u = c->getUser(who);
788 if (!u) {
789 from->sendNotice(String("\002I can not find\002 ") +
790 who + " \002on\002 " + channel);
791 return;
792 }
793 if (u->getProt() < User::NO_KICK)
794 cnx->queue->sendKick(channel, who, st.rest());
795 else
796 from->sendNotice(String("\002I can not kick\002 ") +
797 who + " \002on\002 " + channel +
798 " \002(protected).\002");
799 }
800}
801
802// FIXME: Convert
803void
804UserCommands::KickBan(ServerConnection *cnx, Person *from,
805 String channel, String rest)
806{
807 StringTokenizer st(rest);
808
a6339323 809 Ban(cnx, 0, channel, st.next_token());
cb21075d 810 Kick(cnx, from, channel, rest);
811}
812
813void
814UserCommands::Load(ServerConnection *cnx, Person *from,
815 String channel, String rest)
816{
817 cnx->bot->shitList->read();
818 cnx->bot->userList->read();
819 cnx->bot->userList->addUserFirst(cnx->bot->nickName + "!" + cnx->bot->userHost, "*", 0, 3, true, -1, "");
820 cnx->bot->rehash();
821 from->sendNotice("\002Userlist and shitlist loaded.\002");
822}
823
824#ifdef USESCRIPTS
825void
826UserCommands::LoadScript(ServerConnection *cnx, Person *from,
827 String channel, String rest)
828{
829 if (rest.length() != 0)
830 Interp::LoadScript(cnx->bot, rest);
831}
832#endif
833
834// FIXME: Convert
835void
836UserCommands::Lock(ServerConnection *cnx, Person *from,
837 String channel, String rest)
838{
839 cnx->bot->channelList->getChannel(channel)->lockedTopic = true;
840 from->sendNotice(String("\002Locking topic for channel\002 ") +
841 channel);
842}
843
844// FIXME: Convert
845void
846UserCommands::Mode(ServerConnection *cnx, Person *from,
847 String channel, String rest)
848{
849 String nick = from->getNick();
850
851 if (rest.length() == 0) {
852 from->sendNotice("\002I need a parameter for this command.\002");
853 return;
854 }
855
856 if (!cnx->bot->iAmOp(channel)) {
857 from->sendNotice(String("\002I am not channel op on\002 ") +
858 channel);
859 return;
860 }
861
862 cnx->queue->sendChannelMode(String("MODE ") + channel + " " + rest);
863}
864
865void
866UserCommands::Msg(ServerConnection *cnx, Person *from,
867 String channel, String rest)
868{
869 StringTokenizer st(rest);
a6339323 870 String who = st.next_token();
cb21075d 871 String message = st.rest();
872
873 Message m = Commands::Msg(cnx->bot, who, message);
874 if (m.getCode() != 0)
875 from->sendNotice(m.getMessage());
876}
877
878void
879UserCommands::Names(ServerConnection *cnx, Person *from,
880 String channel, String rest)
881{
882 String nick = from->getNick();
883 String result = "";
884 int length = 0;
885 Channel *c = cnx->bot->channelList->getChannel(channel);
886 std::map<String, User *, std::less<String> >::iterator it;
887
888 from->sendNotice(String("\002Names on ") +
889 channel + ":\002");
890
891 for (it = c->channelMemory.begin();
892 it != c->channelMemory.end(); ++it) {
893 result = result +
894 ((*it).second->mode & User::OP_MODE ? "@" :
895 ((*it).second->mode & User::VOICE_MODE ? "+" : "")) +
896 (*it).second->nick + " ";
897 length += (*it).first.length() + 1;
898 if (length >= 256) {
899 from->sendNotice(result);
900 result = ""; length = 0;
901 }
902 }
903
904 if (result != "")
905 from->sendNotice(result);
906
907 from->sendNotice("\002End of names.\002");
908}
909
910// FIXME: Convert
911void
912UserCommands::NextServer(ServerConnection *cnx, Person *from,
913 String channel, String rest)
914{
915 if (cnx->bot->serverList->size() == 0) {
916 from->sendNotice("\002Server list is empty !\002");
917 return;
918 }
919
920 if (cnx->bot->serverList->size() == 1) {
921 from->sendNotice("\002Server list has only one item. Use"
922 " \"reconnect\" to force reconnection.\002");
923 return;
924 }
925
926 if (cnx->bot->canChangeServer()) {
927 cnx->queue->sendQuit("Changing server");
928 cnx->bot->nextServer();
929 }
930 else
931 from->sendNotice("\002I can not change server without"
932 " losing op on a channel I am on.\002");
933}
934
935// FIXME: Convert
936void
937UserCommands::Nick(ServerConnection *cnx, Person *from,
938 String channel, String rest)
939{
940 // We parse the parameters
941 StringTokenizer st(rest);
a6339323 942 String nick = st.next_token();
cb21075d 943
944 if (rest == "") {
945 from->sendNotice(String("\002No nickname given.\002"));
946 return;
947 }
948
6b7614a8 949 if (!Utils::valid_nickname_p (cnx->bot, nick)) {
cb21075d 950 from->sendNotice(String("\002") + nick +
951 " is not a valid nickname\002");
952 return;
953 }
954
955 cnx->bot->wantedNickName = nick;
956 cnx->queue->sendNick(nick);
957}
958
959void
960UserCommands::NsLookup(ServerConnection *cnx, Person *from,
961 String channel, String rest)
962{
963 String target;
964
965 if (rest.length() == 0) {
966 from->sendNotice("\002You need to supply a nick or an "
967 "host for this command.\002");
968 return;
969 }
970
971 if (rest.find('.') == -1) {
972 StringTokenizer st(cnx->bot->getUserhost("", rest));
a6339323 973 st.next_token('@');
cb21075d 974 target = st.rest();
975 if (target.length() == 0) {
976 from->sendNotice(String("\002I could not find\002 ") +
977 target);
978 return;
979 }
980 } else
981 target = rest;
982
983 struct hostent * host;
984 struct in_addr iaddr;
985
986 if (isdigit(target[0])) { // An IP ?
987 iaddr.s_addr = inet_addr((const char *)target);
988 host = gethostbyaddr((char *)(&iaddr),
989 sizeof(struct in_addr),
990 AF_INET);
991 if (host) {
992 from->sendNotice(target +
993 " \002is the IP address of\002 " +
994 host->h_name);
995 return;
996 }
997 } else {
998 host = gethostbyname((const char *)target);
999 if (host) {
55f2215d 1000 std::memcpy((char *)&iaddr, (char *)host->h_addr,
cb21075d 1001 host->h_length);
1002 from->sendNotice(target + " \002has\002 " +
1003 inet_ntoa(iaddr) + " \002for IP address.\002");
1004 return;
1005 }
1006 }
1007
1008 from->sendNotice(String("\002I could not find host\002 ") +
1009 target);
1010}
1011
1012// FIXME: Convert
1013void
1014UserCommands::Op(ServerConnection *cnx, Person *from,
1015 String channel, String rest)
1016{
1017 String nick = from->getNick();
1018
1019 if (!cnx->bot->iAmOp(channel)) {
1020 from->sendNotice(String("\002I am not channel op on\002 ") +
1021 channel);
1022 return;
1023 }
1024
a6339323 1025 if (Utils::wildcard_p(rest)) {
cb21075d 1026 from->sendNotice("\002Mass op is not allowed.\002");
1027 return;
1028 }
1029
1030 String target;
1031
1032 if (rest.length() == 0)
1033 target = nick;
1034 else
1035 target = rest;
1036
1037 User *u = cnx->bot->channelList->getChannel(channel)->getUser(target);
1038 if (!u) {
1039 from->sendNotice(String("\002I cannot find\002 ") + target + " \002on channel\002 " + channel);
1040 return;
1041 }
1042
1043 ShitEntry *se = cnx->bot->shitList->getShit(target, channel);
1044 if (se && se->isStillValid() && se->getShitLevel() >= ShitEntry::SHIT_NOOP) {
1045 from->sendNotice(String("\002I can not op\002 ")+target+" \002on channel\002 "+channel+" \002(shitlist).\002");
1046 return;
1047 }
1048
1049 if (!(u->mode & User::OP_MODE))
1050 cnx->queue->sendChannelMode(channel, "+o", target);
1051 else {
1052 if (target == nick)
1053 from->sendNotice(String("\002You are already channel "
1054 "operator on\002 ") + channel);
1055 else
1056 from->sendNotice(target + " \002is already channel "
1057 "operator on\002 " + channel);
1058 }
1059}
1060
1061// FIXME: Convert
1062void
1063UserCommands::Part(ServerConnection *cnx, Person *from,
1064 String channel, String rest)
1065{
1066 wantedChannel *w = cnx->bot->wantedChannels[channel];
1067 cnx->bot->wantedChannels.erase(channel);
1068 delete w;
1069 cnx->queue->sendPart(channel);
1070}
1071
1072void
1073UserCommands::Password(ServerConnection *cnx, Person *from,
1074 String channel, String rest)
1075{
1076 Channel *c = cnx->bot->channelList->getChannel(channel);
1077
1078 if (rest.length() == 0) {
1079 from->sendNotice("\002No password.\002");
1080 return;
1081 }
1082
1083 User * u = c->getUser(from->getNick());
1084 if (!u) {
1085 from->sendNotice(String("\002To change your password for\002") +
1086 channel + "\002, you need to be on the "
1087 "channel.\002");
1088 return;
1089 }
1090
1091 if (!u->userListItem) {
1092 from->sendNotice("\002You are not in my userlist.\002");
1093 return;
1094 }
1095
1096 if (rest.toLower() == "none") {
1097 u->userListItem->passwd = "";
1098 from->sendNotice("\002Password cleared.\002");
1099 return;
1100 }
1101
1102 static char saltChars[] = "abcdefghijklmnopqrstuvwxyz"
1103 "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789./";
1104 char salt[3];
1105 srand(time(0));
1106 salt[0] = saltChars[rand() % 64];
1107 salt[1] = saltChars[rand() % 64];
1108 salt[2] = '\0';
1109
1110 u->userListItem->passwd = crypt((const char *)rest, salt);
1111 from->sendNotice("\002Password changed.\002");
1112}
1113
1114void
1115UserCommands::Save(ServerConnection *cnx, Person *from,
1116 String channel, String rest)
1117{
1118 cnx->bot->userList->save();
1119 cnx->bot->shitList->save();
1120 from->sendNotice("\002Userlist and shitlist saved.\002");
1121}
1122
1123// FIXME: Convert
1124void
1125UserCommands::Say(ServerConnection *cnx, Person *from,
1126 String channel, String rest)
1127{
1128 if (rest.length() != 0)
1129 cnx->queue->sendPrivmsg(channel, rest);
1130}
1131
1132// FIXME: Convert
1133void
1134UserCommands::Server(ServerConnection *cnx, Person *from,
1135 String channel, String rest)
1136{
1137 int serverNumber;
1138 String nick = from->getNick();
1139
1140 if (rest.length() == 0) {
1141 from->sendNotice("\002You need to supply a server number for this command.\002");
1142 return;
1143 }
1144
1145 serverNumber = atoi(rest);
1146
1147 if (serverNumber < 0 || serverNumber >= cnx->bot->serverList->size()) {
1148 from->sendNotice(String((long)serverNumber) +
1149 " \002is an invalid server number (see the serverlist).\002");
1150 return;
1151 }
1152
1153 if (cnx->bot->canChangeServer()) {
1154 cnx->queue->sendQuit("Changing server");
1155 cnx->queue->flush();
1156 cnx->bot->connect(serverNumber);
1157 }
1158 else
1159 from->sendNotice("\002I can not change server without losing op on a channel I am on.\002");
1160}
1161
1162void
1163UserCommands::ServerList(ServerConnection *cnx, Person *from,
1164 String channel, String rest)
1165{
1166 String nick = from->getNick();
1167
1168 from->sendNotice("\002Server list:\002");
1169 long l = 0;
1170 String s;
1171 for (std::vector<class Server *>::iterator it =
1172 cnx->bot->serverList->v.begin();
1173 it != cnx->bot->serverList->v.end();
1174 ++it) {
1175 s = (*it) == cnx->server ? "\026" : "";
1176 from->sendNotice(s + String(l++) + s + " " +
1177 (*it)->getHostName() +
1178 " (" + String((long)((*it)->getPort())) +
1179 ")");
1180 }
1181 from->sendNotice("\002End of server list.\002");
1182}
1183
e171dcce 1184
1185void
1186UserCommands::SetFloodRate(ServerConnection *cnx, Person *from,
1187 String channel, String rest)
1188{
1189 Message m = Commands::SetFloodRate (cnx->bot, std::atoi (rest));
1190 if (m.getCode ())
1191 from->sendNotice (m.getMessage ());
1192 else
1193 from->sendNotice ("Flood Rate set to:" + String(std::atol(rest)));
1194}
1195
cb21075d 1196void
1197UserCommands::SetVersion(ServerConnection *cnx, Person *from,
1198 String channel, String rest)
1199{
1200 Message m = Commands::SetVersion(cnx->bot, rest);
6b7614a8 1201
cb21075d 1202 if (m.getCode() < 0)
6b7614a8 1203 {
1204 Commands::Notice (cnx->bot, from->getNick (), m.getMessage());
1205 }
cb21075d 1206}
1207
1208void
1209UserCommands::ShitList(ServerConnection *cnx, Person *from,
1210 String channel, String rest)
1211{
1212 from->sendNotice("\002Shitlist:\002");
1213 from->sendNotice("\002Mask Channel Level Expires Reason\002");
1214
1215 for (std::list<ShitEntry *>::iterator it = cnx->bot->shitList->l.begin();
1216 it != cnx->bot->shitList->l.end();
1217 it++)
1218 from->sendNotice((*it)->shitMask.getMask().pad(25) + " " +
1219 (*it)->shitChannelMask.getMask().pad(10) + " " +
1220 String((long)(*it)->shitLevel).pad(9) + " " +
1221 String((long)(*it)->expirationDate).pad(9) + " " +
1222 (*it)->shitReason);
1223
1224 from->sendNotice("\002End of shitlist.\002");
1225}
1226
1227void
1228UserCommands::SpyList(ServerConnection *cnx, Person *from,
1229 String channel, String rest)
1230{
1231 String nick = from->getNick();
1232
1233 from->sendNotice("\002Spy list:\002");
1234
1235 for (std::map<String, Person *, std::less<String> >::iterator it =
1236 cnx->bot->spyList.begin(); it != cnx->bot->spyList.end(); ++it)
1237 from->sendNotice((*it).first);
1238
1239 from->sendNotice("\002End of spy list.\002");
1240}
1241
1242void
1243UserCommands::SpyMessage(ServerConnection *cnx, Person *from,
1244 String channel, String rest)
1245{
1246 String nick = from->getNick();
1247
1248 if (cnx->bot->spyList.find(nick) != cnx->bot->spyList.end()) {
1249 from->sendNotice("\002You are already spying messages.\002");
1250 return;
1251 }
1252
1253 Person *f = from->copy();
1254 f->keepAlive();
1255 cnx->bot->spyList[nick.toLower()] = f;
1256 from->sendNotice("\002You have been added to the spy list.\002");
1257}
1258
1259// FIXME: Convert
1260void
1261UserCommands::Reconnect(ServerConnection *cnx, Person *from,
1262 String channel, String rest)
1263{
1264 String nick = from->getNick();
1265
1266 if (cnx->bot->canChangeServer()) {
1267 cnx->queue->sendQuit("Reconnecting");
1268 cnx->bot->reconnect();
1269 }
1270 else
1271 from->sendNotice("\002I can not change server without losing op on a channel I am on.\002");
1272}
1273
1274void
1275UserCommands::RSpyMessage(ServerConnection *cnx, Person *from,
1276 String channel, String rest)
1277{
1278 String nick = from->getNick().toLower();
1279
1280 if (cnx->bot->spyList.find(nick) == cnx->bot->spyList.end()) {
1281 from->sendNotice("\002You are not in the spy list.\002");
1282 return;
1283 }
1284
1285 delete cnx->bot->spyList[nick];
1286 cnx->bot->spyList.erase(nick);
1287 from->sendNotice("\002You have been removed from the "
1288 "spy list.\002");
1289}
1290
1291// FIXME: Convert
1292void
1293UserCommands::Unlock(ServerConnection *cnx, Person *from,
1294 String channel, String rest)
1295{
1296 cnx->bot->channelList->getChannel(channel)->lockedTopic = false;
1297 from->sendNotice(String("\002Unlocking topic for channel\002 ") +
1298 channel);
1299}
1300
1301void
1302UserCommands::Stats(ServerConnection *cnx, Person *from,
1303 String channel, String rest)
1304{
1305 String nick = from->getNick();
1306
1307 from->sendNotice(String("\002Keeping modes\002 ") +
1308 cnx->bot->channelList->getChannel(channel)->keepModes + " \002on channel\002 " +
1309 channel);
1310}
1311
1312// FIXME: Convert
1313void
1314UserCommands::TBan(ServerConnection *cnx, Person *from,
1315 String channel, String rest)
1316{
1317 Channel * c = cnx->bot->channelList->getChannel(channel);
1318
1319 StringTokenizer st(rest);
a6339323 1320 String who = st.next_token();
1321 String t = st.next_token();
cb21075d 1322 String dest;
1323
1324 if (who == "" || t == "") {
1325 if (from)
1326 from->sendNotice("\002Invalid syntax for this command.\002");
1327 return;
1328 }
1329
a6339323 1330 if (Utils::wildcard_p(who) && from) {
cb21075d 1331 User * u = c->getUser(from->getNick());
1332 if (u && u->getLevel() < User::TRUSTED_USER) {
1333 if (from)
1334 from->sendNotice("\002You need an higher level to use"
1335 " wildcards.\002");
1336 return;
1337 }
1338 }
1339
1340 if (!cnx->bot->iAmOp(channel)) {
1341 if (from)
1342 from->sendNotice(String("\002I am not channel op on\002 ") +
1343 channel);
1344 return;
1345 }
1346
a6339323 1347 if (!Utils::wildcard_p(who))
cb21075d 1348 dest = cnx->bot->getUserhost(channel, who);
1349 else
1350 dest = who;
1351
1352 if (dest == "") {
1353 if (from)
1354 from->sendNotice(String("\002I can not find\002 ") + who);
1355 return;
1356 }
1357
1358 time_t w;
1359
a6339323 1360 if ((w = Utils::str2time(t)) == 0) {
cb21075d 1361 if (from)
1362 from->sendNotice(t + " \002is an invalid time.\002");
1363 return;
1364 }
1365
a6339323 1366 dest = Utils::make_wildcard(dest);
cb21075d 1367 Mask m(dest);
1368
1369 for (std::list<UserListItem *>::iterator it = cnx->bot->userList->l.begin();
1370 it != cnx->bot->userList->l.end();
1371 it++)
1372 if (m.matches((*it)->mask) &&
1373 (*it)->channelMask.matches(channel) &&
1374 (*it)->prot >= User::NO_BAN) {
1375 if (from)
1376 from->sendNotice(String("\002I can not ban\002 ") +
1377 who + " \002on channel\002 " +
1378 channel + " \002(protection).\002");
1379 return;
1380 }
1381
1382 for (std::vector<BanEntry *>::iterator it = c->channelBanlist.begin();
1383 it != c->channelBanlist.end(); ++it)
1384 if (m.matches((*it)->banMask))
1385 cnx->queue->sendChannelMode(channel, "-b", (*it)->banMask.getMask());
1386
1387 cnx->bot->channelList->getChannel(channel)->addBan(dest, w);
1388 cnx->queue->sendChannelMode(channel, "+b", dest);
1389 cnx->bot->todoList->addDeban(channel, dest, (time_t)w);
1390}
1391
1392// FIXME: Convert
1393void
1394UserCommands::TKBan(ServerConnection *cnx, Person *from,
1395 String channel, String rest)
1396{
1397 StringTokenizer st(rest);
a6339323 1398 String who = st.next_token();
1399 String t = st.next_token();
cb21075d 1400
1401 TBan(cnx, 0, channel, who + " " + t);
1402 Kick(cnx, from, channel, who + " " + st.rest());
1403}
1404
1405// FIXME: Convert
1406void
1407UserCommands::Topic(ServerConnection *cnx, Person *from,
1408 String channel, String rest)
1409{
1410 String nick = from->getNick();
1411
1412 if (rest.length() == 0) {
1413 if (cnx->bot->channelList->getChannel(channel)->channelTopic == "")
1414 from->sendNotice(String("\002No topic is set for channel\002 ") +
1415 channel + "\002.\002");
1416 else
1417 from->sendNotice(String("\002Topic for\002 ") +
1418 channel + " \002is:\002 " +
1419 cnx->bot->channelList->getChannel(channel)->channelTopic);
1420 } else {
1421 if (cnx->bot->channelList->getChannel(channel)->lockedTopic)
1422 from->sendNotice(String("\002Topic is locked on channel\002 ") +
1423 channel);
1424 else
1425 cnx->queue->sendTopic(channel, rest);
1426 }
1427}
1428
1429void
1430UserCommands::UserList(ServerConnection *cnx, Person *from,
1431 String channel, String rest)
1432{
1433 from->sendNotice("\002Userlist:\002");
1434 from->sendNotice("\002Mask Channel Level Prot Aop Expires\002");
1435
1436 for (std::list<UserListItem *>::iterator it = cnx->bot->userList->l.begin();
1437 it != cnx->bot->userList->l.end();
1438 it++)
a6339323 1439 from->sendNotice((*it)->mask.getMask().pad(25)
1440 + " "
1441 + (*it)->channelMask.getMask().pad(10)
1442 + " " +
1443 String(Utils::level2str((*it)->level)).pad(12)
1444 + " " +
1445 String(Utils::prot2str((*it)->prot)).pad(7)
1446 + " " +
1447 String(Utils::bool2str((*it)->aop)).pad(5)
1448 + " " +
1449 String(Utils::long2str ((*it)->expirationDate)));
1450
cb21075d 1451 from->sendNotice("\002End of userlist.\002");
1452}
1453
1454void
1455UserCommands::Who(ServerConnection *cnx, Person *from,
c6e7af05 1456 String channel, String rest)
cb21075d 1457{
1458 String nick = from->getNick();
1459 User * u = cnx->bot->channelList->getChannel(channel)->getUser(nick);
1460 UserListItem * uli;
1461
1462 if (u)
1463 uli = u->userListItem;
1464 else
1465 uli = cnx->bot->userList->getUserListItem(from->getAddress(),
1466 channel);
1467
1468 if (uli) {
1469 from->sendNotice(String("\002You are\002 ") +
1470 uli->mask.getMask() + " \002on\002 " +
1471 uli->channelMask.getMask());
1472 from->sendNotice(String("\002Lvl:\002 ") +
a6339323 1473 Utils::level2str(uli->level) +
cb21075d 1474 " \002Prot:\002 " +
a6339323 1475 Utils::prot2str(uli->prot) +
cb21075d 1476 " \002Aop:\002 " +
a6339323 1477 Utils::bool2str(uli->aop) +
cb21075d 1478 " \002Expired:\002 " +
a6339323 1479 Utils::bool2str(!uli->isStillValid()) +
cb21075d 1480 " \002Ident:\002 " +
1481 (uli && !uli->identified ? "\026" : "") +
a6339323 1482 Utils::bool2str(uli && uli->identified) +
cb21075d 1483 (uli && !uli->identified ? "\026" : ""));
1484 } else
1485 from->sendNotice(String("\002You are not in the userlist for\002 ") +
1486 channel);
1487}
1488
1489void
1490UserCommands::Whois(ServerConnection *cnx, Person *from,
1491 String channel, String rest)
1492{
1493 String nick = from->getNick();
1494
1495 if (!rest.length()) {
1496 from->sendNotice("\002No nick specified.\002");
1497 return;
1498 }
1499
1500 StringTokenizer st(rest);
a6339323 1501 String otherNick = st.next_token();
cb21075d 1502
1503 User * u = cnx->bot->channelList->getChannel(channel)->getUser(otherNick);
1504 UserListItem * uli;
1505
1506 if (u)
1507 uli = u->userListItem;
1508 else
1509 uli = cnx->bot->userList->getUserListItem(otherNick + "!" +
1510 cnx->bot->getUserhost(channel,
1511 otherNick),
1512 channel);
1513
1514 if (uli) {
1515 from->sendNotice(otherNick +
1516 " \002is\002 " + uli->mask.getMask() +
1517 " \002on\002 " + uli->channelMask.getMask());
1518 from->sendNotice(String("\002Lvl:\002 ") +
a6339323 1519 Utils::level2str(uli->level) +
cb21075d 1520 " \002Prot:\002 " +
a6339323 1521 Utils::prot2str(uli->prot) +
cb21075d 1522 " \002Aop:\002 " +
a6339323 1523 Utils::bool2str(uli->aop) +
cb21075d 1524 " \002Expired:\002 " +
a6339323 1525 Utils::bool2str(!uli->isStillValid()) +
cb21075d 1526 " \002Ident:\002 " +
a6339323 1527 Utils::bool2str(uli && uli->identified));
cb21075d 1528 } else
1529 from->sendNotice(otherNick +
1530 " \002is not in the userlist for\002 " +
1531 channel);
1532}