1 // UserCommands.C -*- C++ -*-
2 // Copyright (c) 1997, 1998 Etienne BERNARD
3 // Copyright (C) 2002,2005 Clinton Ebadi
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
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.
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
17 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
28 #include <sys/types.h>
29 #include <sys/socket.h>
30 #include <netinet/in.h>
31 #include <arpa/inet.h>
34 #ifndef _X_OPEN_SOURCE
35 #define _X_OPEN_SOURCE
37 #ifndef _X_OPEN_SOURCE_EXTENDED
38 #define _X_OPEN_SOURCE_EXTENDED 1
46 #include "UserCommands.H"
47 #include "DCCConnection.H"
48 #include "DCCManager.H"
51 #include "StringTokenizer.H"
53 #include "ServerList.H"
57 char * crypt(const char *p, const char *s) { return p; }
61 UserCommands::Action(ServerConnection *cnx, Person *from,
62 String channel, String rest)
64 Message m = Commands::Action(cnx->bot, channel, rest);
66 from->sendNotice(m.getMessage());
70 UserCommands::AddUser(ServerConnection *cnx, Person *from,
71 String channel, String rest)
73 StringTokenizer st(rest);
74 String mask, who, maskChannel, level, prot,
75 aop, expiration, passwd;
77 mask = who = st.next_token();
78 maskChannel = st.next_token();
79 level = st.next_token();
80 prot = st.next_token();
81 aop = st.next_token();
82 expiration = st.next_token();
83 passwd = st.next_token();
85 if (mask == "" || maskChannel == "" || level == "" ||
86 prot == "" || aop == "") {
87 from->sendNotice("\002Invalid syntax for this command.\002");
91 // if (!Utils::wildcard_p(mask)) {
92 // mask = cnx->bot->getUserhost(channel, who);
94 // from->sendNotice(String("\002I can not find\002 ") + who);
97 // mask = Utils::make_wildcard(mask);
100 // if (cnx->bot->userList->isInUserList(mask, maskChannel)) {
101 // from->sendNotice(who + " \002is already in userlist on channel(s)\002 " +
110 l = atoi((const char *)level);
111 if (l < 0 || l > User::FRIEND)
113 if (l > Utils::get_level(cnx->bot, from->getAddress())) {
114 from->sendNotice("\002You can not give a level greater than yours.\002");
117 p = atoi((const char *)prot);
118 if (p < 0 || p > User::NO_DEOP)
120 a = (bool)atoi((const char *)aop);
121 if (a != 0 && a != 1)
124 e = Utils::str2time(expiration);
129 // cnx->bot->userList->addUser(mask, maskChannel, l, p, a, e, passwd);
132 Commands::AddUser (cnx->bot, who, maskChannel, l, p, a, e, passwd);
135 from->sendNotice(String("\002Added\002 ") + mask +
136 " \002on channels\002 " + maskChannel);
137 from->sendNotice(String("\002Level:\002 ") +
138 Utils::level2str(l) +
139 " \002Protection:\002 " +
141 " \002Auto-op:\002 " +
145 from->sendNotice(m.getMessage ());
147 // cnx->bot->rehash();
151 UserCommands::AddServer(ServerConnection *cnx, Person *from,
152 String channel, String rest)
154 if (rest.length() == 0) {
155 from->sendNotice("\002You must supply a server name.\002");
159 StringTokenizer st(rest);
160 String serverName = st.next_token();
163 if (st.more_tokens_p()) {
164 String temp = st.next_token();
165 port = atoi((const char *)temp);
168 Message m = Commands::AddServer(cnx->bot, serverName, port);
169 if (m.getCode() != 0)
170 from->sendNotice(m.getMessage());
172 from->sendNotice(String("\002Server\002 ") +
173 serverName + " \002on port\002 " +
174 String((long)port) + " \002has been added "
175 "to the server list.\002");
178 // FIXME: does this work now
180 UserCommands::AddShit(ServerConnection *cnx, Person *from,
181 String channel, String rest)
183 StringTokenizer st(rest);
184 String mask, who, maskChannel, level, expiration, reason;
186 mask = who = st.next_token();
187 maskChannel = st.next_token();
188 level = st.next_token();
189 expiration = st.next_token();
190 reason = Utils::trim_str (st.rest());
192 /* if (mask == "" || maskChannel == "" || level == "") {
193 from->sendNotice("\002Invalid syntax for this command.\002");
200 reason = "You're on my shitlist, lamer";
204 if (!Utils::wildcard_p(mask)) {
205 mask = cnx->bot->getUserhost(channel, who);
207 from->sendNotice(String("\002I can not find\002 ") + who);
210 mask = Utils::make_wildcard(mask);
211 if (cnx->bot->shitList->getShit(mask, maskChannel)) {
212 from->sendNotice(mask + " \002is already in shitlist on channel(s)\002 " +
221 l = atoi((const char *)level);
222 if (l < 0 || l > ShitEntry::SHIT_NODEBAN)
225 e = Utils::str2time(expiration);
231 if (cnx->bot->userList->getMaxProt(mask, maskChannel) > 0) {
232 from->sendNotice(String("\002I can not add\002 ") + who +
233 " \002into the shitlist (protection).");
237 cnx->bot->shitList->addShit(mask, maskChannel, l, e, reason);
240 Message M = Commands::AddShit (cnx->bot, mask, maskChannel, l, e, reason);
242 from->sendNotice(String("\002Added\002 ") + mask +
243 " \002on channels\002 " + maskChannel +
244 " \002into the shitlist.\002");
246 from->sendNotice (M.getMessage ());
249 // FIXME: Convert (and change ?)
251 UserCommands::Alias(ServerConnection *cnx, Person *from,
252 String channel, String rest)
254 StringTokenizer st(rest);
255 String newF = Utils::to_upper (st.next_token());
256 String oldF = Utils::to_upper (st.next_token());
258 if (newF == "" || oldF == "") {
259 from->sendNotice("\002Invalid syntax for this command.\002");
263 // First, we check that the "new" function does not exist
264 if (cnx->bot->userFunctions[newF]) {
265 from->sendNotice(newF + " \002is already an alias.\002");
269 // Next, we check that the "old" function exist
270 if (!cnx->bot->userFunctions[oldF])
272 from->sendNotice(String("\002I don't know the\002 ") + oldF +
277 // Fine, we do the binding
278 cnx->bot->userFunctions[newF] =
279 new userFunction (*cnx->bot->userFunctions[oldF]);
281 from->sendNotice("\002Alias added.\002");
285 UserCommands::Ban(ServerConnection *cnx, Person *from,
286 String channel, String rest)
288 if (rest.length() == 0) {
290 from->sendNotice("\002No nick/mask specified.\002");
294 Message m = Commands::Ban(cnx->bot, channel, rest);
295 if (m.getCode() != 0 && from)
296 from->sendNotice(m.getMessage());
300 UserCommands::BanList(ServerConnection *cnx, Person *from,
301 String channel, String rest)
303 time_t current = time(0);
304 Channel *c = cnx->bot->channelList->getChannel(channel);
305 from->sendNotice(String("\002Banlist for channel\002 ") +
306 channel + "\002:\002");
307 from->sendNotice("\002Mask Expires (seconds)\002");
308 for (std::vector<BanEntry *>::iterator it = c->channelBanlist.begin();
309 it != c->channelBanlist.end(); ++it)
310 if ((*it)->getExpirationDate() == -1)
311 from->sendNotice((*it)->getMask().pad(30) + " -1");
313 from->sendNotice((*it)->getMask().pad(30) + " " +
314 String((long)((*it)->getExpirationDate()-current)));
315 from->sendNotice("\002End of banlist.\002");
319 // UserCommands::ChangeLevel(ServerConnection *cnx, Person *from,
320 // String channel, String rest)
322 // StringTokenizer st(rest);
325 // String mask = who = st.next_token();
326 // String maskChannel = st.next_token();
327 // String level = st.next_token();
329 // if (mask == "" || maskChannel == "" || level == "") {
330 // from->sendNotice("\002Invalid syntax for this command.\002");
334 // if (!Utils::wildcard_p(mask)) {
335 // mask = cnx->bot->getUserhost(channel, who);
337 // from->sendNotice(String("\002I can not find\002 ") + who);
340 // mask = from->getNick() + "!" + mask;
343 // UserListItem *uli = cnx->bot->userList->getUserListItem(mask, maskChannel);
346 // from->sendNotice(String("\002I can not find\002 ") + who +
347 // " \002on channel(s)\002 " + maskChannel +
348 // " \002in my userlist.\002");
352 // int l = atoi((const char *)level);
354 // if (l < User::NONE || l > User::MASTER) {
355 // from->sendNotice("\002This is not a valid level.\002");
359 // if (l > Utils::get_level(cnx->bot, from->getAddress())) {
360 // from->sendNotice("\002You can not give a level greater than yours.\002");
364 // if (Utils::get_level(cnx->bot, from->getAddress()) < uli->level) {
365 // from->sendNotice("\002You can not change the level for a person "
366 // "whose level is greater than yours.\002");
371 // from->sendNotice("\002Level changed.\002");
372 // cnx->bot->rehash();
376 UserCommands::Channels(ServerConnection *cnx, Person *from,
377 String channel, String rest)
381 for (std::map<String, Channel *, std::less<String> >::iterator it =
382 cnx->bot->channelList->begin();
383 it != cnx->bot->channelList->end(); ++it)
384 result = result + (*it).first + " ";
387 from->sendNotice("\002I am not on any channel.\002");
389 from->sendNotice(String("\002I am currently on channel(s):\002 ") +
394 UserCommands::Cycle(ServerConnection *cnx, Person *from,
395 String channel, String rest)
397 Message m = Commands::Cycle(cnx->bot, channel);
398 if (m.getCode() != 0)
399 from->sendNotice(m.getMessage());
403 UserCommands::DCCList(ServerConnection *cnx, Person *from,
404 String channel, String rest)
406 time_t current_time = time(0);
408 from->sendNotice("\002DCClist:\002");
409 from->sendNotice("\002Hostname Last used\002");
411 for (DCC_MAP::iterator it =
412 cnx->bot->dccConnections->dcc_map.begin ();
413 it != cnx->bot->dccConnections->dcc_map.end();
415 from->sendNotice(String(it->second->dcc->get_nuh()).pad(32) + " " +
416 String((long)(current_time -
417 it->second->dcc->get_lastSpoken())));
420 from->sendNotice("\002End of dcclist.\002");
424 UserCommands::Deban(ServerConnection *cnx, Person *from,
425 String channel, String rest)
427 if (rest.length() == 0) {
428 from->sendNotice("\002No nick/mask specified.\002");
432 Message m = Commands::Deban(cnx->bot, channel, rest);
433 if (m.getCode() != 0)
434 from->sendNotice(m.getMessage());
438 UserCommands::DelServer(ServerConnection *cnx, Person *from,
439 String channel, String rest)
441 if (rest.length() == 0) {
442 from->sendNotice("\002You need to supply a server number"
443 " for this command.\002");
447 int serverNumber = atoi(rest);
449 Message m = Commands::DelServer(cnx->bot, serverNumber);
450 if (m.getCode() != 0)
451 from->sendNotice(m.getMessage());
453 from->sendNotice(String("Deleted server ") +
454 cnx->bot->serverList->get(serverNumber)->getHostName() +
455 " (" + String((long)cnx->bot->serverList->get(serverNumber)->getPort()) +
461 UserCommands::DelUser(ServerConnection *cnx, Person *from,
462 String channel, String rest)
464 StringTokenizer st(rest);
467 String mask = who = st.next_token();
468 String maskChannel = st.next_token();
470 if (mask == "" || maskChannel == "") {
471 from->sendNotice("\002Invalid syntax for this command.\002");
475 if (!Utils::wildcard_p(mask)) {
476 mask = cnx->bot->getUserhost(channel, who);
478 from->sendNotice(String("\002I can not find\002 ") + who);
481 mask = Utils::make_wildcard(mask);
484 if (!cnx->bot->userList->isInUserList(mask, maskChannel)) {
485 from->sendNotice(mask + " \002is not in userlist on channel(s)\002 " +
490 cnx->bot->userList->removeUser(mask, maskChannel);
491 from->sendNotice(who + " \002has been removed from the userlist.\002");
497 UserCommands::DelShit(ServerConnection *cnx, Person *from,
498 String channel, String rest)
500 StringTokenizer st(rest);
503 String mask = who = st.next_token();
504 String maskChannel = st.next_token();
506 if (mask == "" || maskChannel == "") {
507 from->sendNotice("\002Invalid syntax for this command.\002");
511 if (!Utils::wildcard_p(mask)) {
512 mask = cnx->bot->getUserhost(channel, who);
514 from->sendNotice(String("\002I can not find\002 ") + who);
517 mask = Utils::make_wildcard(mask);
520 if (!cnx->bot->shitList->getShit(mask, maskChannel)) {
521 from->sendNotice(mask + " \002is not in shitlist on channel(s)\002 " +
526 cnx->bot->shitList->delShit(mask, maskChannel);
527 from->sendNotice(who + " \002has been removed from the shitlist.\002");
531 UserCommands::Deop(ServerConnection *cnx, Person *from,
532 String channel, String rest)
534 String target = rest;
536 if (target.length() == 0)
537 target = from->getNick();
539 Message m = Commands::Deop(cnx->bot, channel, target);
540 if (m.getCode() != 0)
541 from->sendNotice(m.getMessage());
545 UserCommands::Die(ServerConnection *cnx, Person *from,
546 String channel, String rest)
550 if (rest.length() == 0)
555 Commands::Die(cnx->bot, reason);
559 UserCommands::Do(ServerConnection *cnx, Person *from,
560 String channel, String rest)
562 if (rest.length() != 0)
563 Commands::Do(cnx->bot, rest);
568 UserCommands::Execute(ServerConnection *cnx, Person *from,
569 String channel, String rest)
571 if (rest.length() != 0)
572 Interp::Execute(cnx->bot, rest);
577 UserCommands::Help(ServerConnection *cnx, Person *from,
578 String channel, String rest)
580 if (rest.length() == 0) {
581 from->sendNotice("\002Available topics for you are:\002");
582 int level = Utils::get_level(cnx->bot, from->getAddress());
585 std::map<std::string, class userFunction*, std::less<std::string> >::iterator it;
586 for (it = cnx->bot->userFunctions.begin(); it != cnx->bot->userFunctions.end(); ++it)
587 if ((*it).second->minLevel <= level) {
588 result = result + (*it).first + " ";
589 length += (*it).first.length() + 1;
591 from->sendNotice(result);
592 result = ""; length = 0;
596 from->sendNotice(result);
597 from->sendNotice("\002Use\002 HELP <command> \002for"
598 " help about\002 <command>");
602 StringTokenizer st(rest);
603 String command = Utils::to_upper (st.next_token());
604 std::ifstream helpFile(cnx->bot->helpFileName);
607 from->sendNotice(String("\002Error: I can not find the "
609 cnx->bot->helpFileName);
614 while (!helpFile.eof()) {
616 if (buf.subString(0, command.length()) == String(":") + command) {
617 buf = buf.subString(1);
618 from->sendNotice(String("\002Help for\002 ") + command +
621 from->sendNotice(buf);
624 from->sendNotice("\002End of help.\002");
629 from->sendNotice(String("\002No such topic (\002") +
630 command + "\002).\002");
634 UserCommands::Ident(ServerConnection *cnx, Person *from,
635 String channel, String rest)
637 Channel *c = cnx->bot->channelList->getChannel(channel);
639 if (rest.length() <= 2) {
640 from->sendNotice("\002No password specified or password "
645 User * u = c->getUser(from->getNick());
647 from->sendNotice(String("\002You can identify yourself on"
648 " channel\002 ") + channel +
649 " \002only if you are on the channel.\002");
653 if (u->userListItem && u->userListItem->identified) {
654 from->sendNotice(String("\002You are already identified on"
655 " channel\002 ") + channel);
659 if (!u->userListItem) {
660 from->sendNotice("\002You are not in my userlist.\002");
664 if (u->userListItem->passwd ==
665 crypt((const char *)rest, (const char *)u->userListItem->passwd)) {
666 // For each channel, we increment identification counter
667 for (std::map<String, Channel *, std::less<String> >::iterator it =
668 cnx->bot->channelList->begin();
669 it != cnx->bot->channelList->end(); ++it)
670 u->userListItem->identified++;
672 from->sendNotice("\002You are now identified.\002");
674 from->sendNotice("\002This is a wrong password.\002");
678 UserCommands::Invite(ServerConnection *cnx, Person *from,
679 String channel, String rest)
681 Message m = Commands::Invite(cnx->bot, channel, rest);
683 from->sendNotice(m.getMessage());
684 from->sendNotice(String("\002Inviting\002 ") + rest + " \002on channel\002 " + channel);
689 UserCommands::Join(ServerConnection *cnx, Person *from,
690 String channel, String rest)
692 StringTokenizer st(rest);
693 channel = st.next_token();
695 if (!Utils::valid_channel_name_p(channel)) {
696 from->sendNotice(String("\002") + channel +
697 " is not a valid channel name\002");
701 // We change the key only if we are not on the channel. We don't trust
703 if (!cnx->bot->channelList->getChannel(channel)) {
704 if (cnx->bot->wantedChannels[channel])
705 cnx->bot->wantedChannels[channel]->key = st.rest();
707 cnx->bot->wantedChannels[channel] = new wantedChannel("", "", st.rest());
710 cnx->queue->sendJoin(channel, cnx->bot->wantedChannels[channel]->key);
715 UserCommands::Keep(ServerConnection *cnx, Person *from,
716 String channel, String rest)
718 String nick = from->getNick();
720 if (rest.length() == 0) {
721 from->sendNotice("\002No channel modes specified.\002");
725 cnx->bot->channelList->getChannel(channel)->keepModes = rest;
726 from->sendNotice(String("\002Keeping modes\002 ") +
727 rest + " \002on channel\002 " +
733 UserCommands::Kick(ServerConnection *cnx, Person *from,
734 String channel, String rest)
736 String nick = from->getNick();
738 Channel * c = cnx->bot->channelList->getChannel(channel);
740 if (rest.length() == 0) {
741 from->sendNotice("\002No nick specified.\002");
745 StringTokenizer st(rest);
746 String who = st.next_token();
748 if (Utils::wildcard_p(who)) {
749 User * u = c->getUser(nick);
752 if (u->getLevel() < User::TRUSTED_USER) {
753 from->sendNotice("\002You need an higher level to "
754 "use wildcards.\002");
759 if (!cnx->bot->iAmOp(channel)) {
760 from->sendNotice(String("\002I am not channel op on\002 ") +
765 if (Utils::wildcard_p(who)) {
767 for (std::map<String, User *, std::less<String> >::iterator it =
768 c->channelMemory.begin();
769 it != c->channelMemory.end();
771 if (m.matches((*it).second->nick + "!" +
772 (*it).second->userhost) &&
773 (*it).second->getProt() < User::NO_KICK)
774 cnx->queue->sendKick(channel, (*it).second->nick, st.rest());
776 User * u = c->getUser(who);
778 from->sendNotice(String("\002I can not find\002 ") +
779 who + " \002on\002 " + channel);
782 if (u->getProt() < User::NO_KICK)
783 cnx->queue->sendKick(channel, who, st.rest());
785 from->sendNotice(String("\002I can not kick\002 ") +
786 who + " \002on\002 " + channel +
787 " \002(protected).\002");
793 UserCommands::KickBan(ServerConnection *cnx, Person *from,
794 String channel, String rest)
796 StringTokenizer st(rest);
798 Ban(cnx, 0, channel, st.next_token());
799 Kick(cnx, from, channel, rest);
803 UserCommands::Load(ServerConnection *cnx, Person *from,
804 String channel, String rest)
806 cnx->bot->shitList->read();
807 cnx->bot->userList->read();
808 cnx->bot->userList->addUserFirst(cnx->bot->nickName + "!" + cnx->bot->userHost, "*", 0, 3, true, -1, "");
810 from->sendNotice("\002Userlist and shitlist loaded.\002");
815 UserCommands::LoadScript(ServerConnection *cnx, Person *from,
816 String channel, String rest)
818 if (rest.length() != 0)
819 Interp::LoadScript(cnx->bot, rest);
825 UserCommands::Lock(ServerConnection *cnx, Person *from,
826 String channel, String rest)
828 cnx->bot->channelList->getChannel(channel)->lockedTopic = true;
829 from->sendNotice(String("\002Locking topic for channel\002 ") +
835 UserCommands::Mode(ServerConnection *cnx, Person *from,
836 String channel, String rest)
838 String nick = from->getNick();
840 if (rest.length() == 0) {
841 from->sendNotice("\002I need a parameter for this command.\002");
845 if (!cnx->bot->iAmOp(channel)) {
846 from->sendNotice(String("\002I am not channel op on\002 ") +
851 cnx->queue->sendChannelMode(String("MODE ") + channel + " " + rest);
855 UserCommands::Msg(ServerConnection *cnx, Person *from,
856 String channel, String rest)
858 StringTokenizer st(rest);
859 String who = st.next_token();
860 String message = st.rest();
862 Message m = Commands::Msg(cnx->bot, who, message);
863 if (m.getCode() != 0)
864 from->sendNotice(m.getMessage());
868 UserCommands::Names(ServerConnection *cnx, Person *from,
869 String channel, String rest)
871 String nick = from->getNick();
874 Channel *c = cnx->bot->channelList->getChannel(channel);
875 std::map<String, User *, std::less<String> >::iterator it;
877 from->sendNotice(String("\002Names on ") +
880 for (it = c->channelMemory.begin();
881 it != c->channelMemory.end(); ++it) {
883 ((*it).second->mode & User::OP_MODE ? "@" :
884 ((*it).second->mode & User::VOICE_MODE ? "+" : "")) +
885 (*it).second->nick + " ";
886 length += (*it).first.length() + 1;
888 from->sendNotice(result);
889 result = ""; length = 0;
894 from->sendNotice(result);
896 from->sendNotice("\002End of names.\002");
901 UserCommands::NextServer(ServerConnection *cnx, Person *from,
902 String channel, String rest)
904 if (cnx->bot->serverList->size() == 0) {
905 from->sendNotice("\002Server list is empty !\002");
909 if (cnx->bot->serverList->size() == 1) {
910 from->sendNotice("\002Server list has only one item. Use"
911 " \"reconnect\" to force reconnection.\002");
915 if (cnx->bot->canChangeServer()) {
916 cnx->queue->sendQuit("Changing server");
917 cnx->bot->nextServer();
920 from->sendNotice("\002I can not change server without"
921 " losing op on a channel I am on.\002");
926 UserCommands::Nick(ServerConnection *cnx, Person *from,
927 String channel, String rest)
929 // We parse the parameters
930 StringTokenizer st(rest);
931 String nick = st.next_token();
934 from->sendNotice(String("\002No nickname given.\002"));
938 if (!Utils::valid_nickname_p (cnx->bot, nick)) {
939 from->sendNotice(String("\002") + nick +
940 " is not a valid nickname\002");
944 cnx->bot->wantedNickName = nick;
945 cnx->queue->sendNick(nick);
949 UserCommands::NsLookup(ServerConnection *cnx, Person *from,
950 String channel, String rest)
954 if (rest.length() == 0) {
955 from->sendNotice("\002You need to supply a nick or an "
956 "host for this command.\002");
960 if (rest.find('.') == -1) {
961 StringTokenizer st(cnx->bot->getUserhost("", rest));
964 if (target.length() == 0) {
965 from->sendNotice(String("\002I could not find\002 ") +
972 struct hostent * host;
973 struct in_addr iaddr;
975 if (isdigit(target[0])) { // An IP ?
976 iaddr.s_addr = inet_addr((const char *)target);
977 host = gethostbyaddr((char *)(&iaddr),
978 sizeof(struct in_addr),
981 from->sendNotice(target +
982 " \002is the IP address of\002 " +
987 host = gethostbyname((const char *)target);
989 memcpy((char *)&iaddr, (char *)host->h_addr,
991 from->sendNotice(target + " \002has\002 " +
992 inet_ntoa(iaddr) + " \002for IP address.\002");
997 from->sendNotice(String("\002I could not find host\002 ") +
1003 UserCommands::Op(ServerConnection *cnx, Person *from,
1004 String channel, String rest)
1006 String nick = from->getNick();
1008 if (!cnx->bot->iAmOp(channel)) {
1009 from->sendNotice(String("\002I am not channel op on\002 ") +
1014 if (Utils::wildcard_p(rest)) {
1015 from->sendNotice("\002Mass op is not allowed.\002");
1021 if (rest.length() == 0)
1026 User *u = cnx->bot->channelList->getChannel(channel)->getUser(target);
1028 from->sendNotice(String("\002I cannot find\002 ") + target + " \002on channel\002 " + channel);
1032 ShitEntry *se = cnx->bot->shitList->getShit(target, channel);
1033 if (se && se->isStillValid() && se->getShitLevel() >= ShitEntry::SHIT_NOOP) {
1034 from->sendNotice(String("\002I can not op\002 ")+target+" \002on channel\002 "+channel+" \002(shitlist).\002");
1038 if (!(u->mode & User::OP_MODE))
1039 cnx->queue->sendChannelMode(channel, "+o", target);
1042 from->sendNotice(String("\002You are already channel "
1043 "operator on\002 ") + channel);
1045 from->sendNotice(target + " \002is already channel "
1046 "operator on\002 " + channel);
1052 UserCommands::Part(ServerConnection *cnx, Person *from,
1053 String channel, String rest)
1055 wantedChannel *w = cnx->bot->wantedChannels[channel];
1056 cnx->bot->wantedChannels.erase(channel);
1058 cnx->queue->sendPart(channel);
1062 UserCommands::Password(ServerConnection *cnx, Person *from,
1063 String channel, String rest)
1065 Channel *c = cnx->bot->channelList->getChannel(channel);
1067 if (rest.length() == 0) {
1068 from->sendNotice("\002No password.\002");
1072 User * u = c->getUser(from->getNick());
1074 from->sendNotice(String("\002To change your password for\002") +
1075 channel + "\002, you need to be on the "
1080 if (!u->userListItem) {
1081 from->sendNotice("\002You are not in my userlist.\002");
1085 if (rest.toLower() == "none") {
1086 u->userListItem->passwd = "";
1087 from->sendNotice("\002Password cleared.\002");
1091 static char saltChars[] = "abcdefghijklmnopqrstuvwxyz"
1092 "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789./";
1095 salt[0] = saltChars[rand() % 64];
1096 salt[1] = saltChars[rand() % 64];
1099 u->userListItem->passwd = crypt((const char *)rest, salt);
1100 from->sendNotice("\002Password changed.\002");
1104 UserCommands::Save(ServerConnection *cnx, Person *from,
1105 String channel, String rest)
1107 cnx->bot->userList->save();
1108 cnx->bot->shitList->save();
1109 from->sendNotice("\002Userlist and shitlist saved.\002");
1114 UserCommands::Say(ServerConnection *cnx, Person *from,
1115 String channel, String rest)
1117 if (rest.length() != 0)
1118 cnx->queue->sendPrivmsg(channel, rest);
1123 UserCommands::Server(ServerConnection *cnx, Person *from,
1124 String channel, String rest)
1127 String nick = from->getNick();
1129 if (rest.length() == 0) {
1130 from->sendNotice("\002You need to supply a server number for this command.\002");
1134 serverNumber = atoi(rest);
1136 if (serverNumber < 0 || serverNumber >= cnx->bot->serverList->size()) {
1137 from->sendNotice(String((long)serverNumber) +
1138 " \002is an invalid server number (see the serverlist).\002");
1142 if (cnx->bot->canChangeServer()) {
1143 cnx->queue->sendQuit("Changing server");
1144 cnx->queue->flush();
1145 cnx->bot->connect(serverNumber);
1148 from->sendNotice("\002I can not change server without losing op on a channel I am on.\002");
1152 UserCommands::ServerList(ServerConnection *cnx, Person *from,
1153 String channel, String rest)
1155 String nick = from->getNick();
1157 from->sendNotice("\002Server list:\002");
1160 for (std::vector<class Server *>::iterator it =
1161 cnx->bot->serverList->v.begin();
1162 it != cnx->bot->serverList->v.end();
1164 s = (*it) == cnx->server ? "\026" : "";
1165 from->sendNotice(s + String(l++) + s + " " +
1166 (*it)->getHostName() +
1167 " (" + String((long)((*it)->getPort())) +
1170 from->sendNotice("\002End of server list.\002");
1175 UserCommands::SetFloodRate(ServerConnection *cnx, Person *from,
1176 String channel, String rest)
1178 Message m = Commands::SetFloodRate (cnx->bot, std::atoi (rest));
1180 from->sendNotice (m.getMessage ());
1182 from->sendNotice ("Flood Rate set to:" + String(std::atol(rest)));
1186 UserCommands::SetVersion(ServerConnection *cnx, Person *from,
1187 String channel, String rest)
1189 Message m = Commands::SetVersion(cnx->bot, rest);
1191 if (m.getCode() < 0)
1193 Commands::Notice (cnx->bot, from->getNick (), m.getMessage());
1198 UserCommands::ShitList(ServerConnection *cnx, Person *from,
1199 String channel, String rest)
1201 from->sendNotice("\002Shitlist:\002");
1202 from->sendNotice("\002Mask Channel Level Expires Reason\002");
1204 for (std::list<ShitEntry *>::iterator it = cnx->bot->shitList->l.begin();
1205 it != cnx->bot->shitList->l.end();
1207 from->sendNotice((*it)->shitMask.getMask().pad(25) + " " +
1208 (*it)->shitChannelMask.getMask().pad(10) + " " +
1209 String((long)(*it)->shitLevel).pad(9) + " " +
1210 String((long)(*it)->expirationDate).pad(9) + " " +
1213 from->sendNotice("\002End of shitlist.\002");
1217 UserCommands::SpyList(ServerConnection *cnx, Person *from,
1218 String channel, String rest)
1220 String nick = from->getNick();
1222 from->sendNotice("\002Spy list:\002");
1224 for (std::map<String, Person *, std::less<String> >::iterator it =
1225 cnx->bot->spyList.begin(); it != cnx->bot->spyList.end(); ++it)
1226 from->sendNotice((*it).first);
1228 from->sendNotice("\002End of spy list.\002");
1232 UserCommands::SpyMessage(ServerConnection *cnx, Person *from,
1233 String channel, String rest)
1235 String nick = from->getNick();
1237 if (cnx->bot->spyList.find(nick) != cnx->bot->spyList.end()) {
1238 from->sendNotice("\002You are already spying messages.\002");
1242 Person *f = from->copy();
1244 cnx->bot->spyList[nick.toLower()] = f;
1245 from->sendNotice("\002You have been added to the spy list.\002");
1250 UserCommands::Reconnect(ServerConnection *cnx, Person *from,
1251 String channel, String rest)
1253 String nick = from->getNick();
1255 if (cnx->bot->canChangeServer()) {
1256 cnx->queue->sendQuit("Reconnecting");
1257 cnx->bot->reconnect();
1260 from->sendNotice("\002I can not change server without losing op on a channel I am on.\002");
1264 UserCommands::RSpyMessage(ServerConnection *cnx, Person *from,
1265 String channel, String rest)
1267 String nick = from->getNick().toLower();
1269 if (cnx->bot->spyList.find(nick) == cnx->bot->spyList.end()) {
1270 from->sendNotice("\002You are not in the spy list.\002");
1274 delete cnx->bot->spyList[nick];
1275 cnx->bot->spyList.erase(nick);
1276 from->sendNotice("\002You have been removed from the "
1282 UserCommands::Unlock(ServerConnection *cnx, Person *from,
1283 String channel, String rest)
1285 cnx->bot->channelList->getChannel(channel)->lockedTopic = false;
1286 from->sendNotice(String("\002Unlocking topic for channel\002 ") +
1291 UserCommands::Stats(ServerConnection *cnx, Person *from,
1292 String channel, String rest)
1294 String nick = from->getNick();
1296 from->sendNotice(String("\002Keeping modes\002 ") +
1297 cnx->bot->channelList->getChannel(channel)->keepModes + " \002on channel\002 " +
1303 UserCommands::TBan(ServerConnection *cnx, Person *from,
1304 String channel, String rest)
1306 Channel * c = cnx->bot->channelList->getChannel(channel);
1308 StringTokenizer st(rest);
1309 String who = st.next_token();
1310 String t = st.next_token();
1313 if (who == "" || t == "") {
1315 from->sendNotice("\002Invalid syntax for this command.\002");
1319 if (Utils::wildcard_p(who) && from) {
1320 User * u = c->getUser(from->getNick());
1321 if (u && u->getLevel() < User::TRUSTED_USER) {
1323 from->sendNotice("\002You need an higher level to use"
1329 if (!cnx->bot->iAmOp(channel)) {
1331 from->sendNotice(String("\002I am not channel op on\002 ") +
1336 if (!Utils::wildcard_p(who))
1337 dest = cnx->bot->getUserhost(channel, who);
1343 from->sendNotice(String("\002I can not find\002 ") + who);
1349 if ((w = Utils::str2time(t)) == 0) {
1351 from->sendNotice(t + " \002is an invalid time.\002");
1355 dest = Utils::make_wildcard(dest);
1358 for (std::list<UserListItem *>::iterator it = cnx->bot->userList->l.begin();
1359 it != cnx->bot->userList->l.end();
1361 if (m.matches((*it)->mask) &&
1362 (*it)->channelMask.matches(channel) &&
1363 (*it)->prot >= User::NO_BAN) {
1365 from->sendNotice(String("\002I can not ban\002 ") +
1366 who + " \002on channel\002 " +
1367 channel + " \002(protection).\002");
1371 for (std::vector<BanEntry *>::iterator it = c->channelBanlist.begin();
1372 it != c->channelBanlist.end(); ++it)
1373 if (m.matches((*it)->banMask))
1374 cnx->queue->sendChannelMode(channel, "-b", (*it)->banMask.getMask());
1376 cnx->bot->channelList->getChannel(channel)->addBan(dest, w);
1377 cnx->queue->sendChannelMode(channel, "+b", dest);
1378 cnx->bot->todoList->addDeban(channel, dest, (time_t)w);
1383 UserCommands::TKBan(ServerConnection *cnx, Person *from,
1384 String channel, String rest)
1386 StringTokenizer st(rest);
1387 String who = st.next_token();
1388 String t = st.next_token();
1390 TBan(cnx, 0, channel, who + " " + t);
1391 Kick(cnx, from, channel, who + " " + st.rest());
1396 UserCommands::Topic(ServerConnection *cnx, Person *from,
1397 String channel, String rest)
1399 String nick = from->getNick();
1401 if (rest.length() == 0) {
1402 if (cnx->bot->channelList->getChannel(channel)->channelTopic == "")
1403 from->sendNotice(String("\002No topic is set for channel\002 ") +
1404 channel + "\002.\002");
1406 from->sendNotice(String("\002Topic for\002 ") +
1407 channel + " \002is:\002 " +
1408 cnx->bot->channelList->getChannel(channel)->channelTopic);
1410 if (cnx->bot->channelList->getChannel(channel)->lockedTopic)
1411 from->sendNotice(String("\002Topic is locked on channel\002 ") +
1414 cnx->queue->sendTopic(channel, rest);
1419 UserCommands::UserList(ServerConnection *cnx, Person *from,
1420 String channel, String rest)
1422 from->sendNotice("\002Userlist:\002");
1423 from->sendNotice("\002Mask Channel Level Prot Aop Expires\002");
1425 for (std::list<UserListItem *>::iterator it = cnx->bot->userList->l.begin();
1426 it != cnx->bot->userList->l.end();
1428 from->sendNotice((*it)->mask.getMask().pad(25)
1430 + (*it)->channelMask.getMask().pad(10)
1432 String(Utils::level2str((*it)->level)).pad(12)
1434 String(Utils::prot2str((*it)->prot)).pad(7)
1436 String(Utils::bool2str((*it)->aop)).pad(5)
1438 String(Utils::long2str ((*it)->expirationDate)));
1440 from->sendNotice("\002End of userlist.\002");
1444 UserCommands::Who(ServerConnection *cnx, Person *from,
1445 String channel, String rest)
1447 String nick = from->getNick();
1448 User * u = cnx->bot->channelList->getChannel(channel)->getUser(nick);
1452 uli = u->userListItem;
1454 uli = cnx->bot->userList->getUserListItem(from->getAddress(),
1458 from->sendNotice(String("\002You are\002 ") +
1459 uli->mask.getMask() + " \002on\002 " +
1460 uli->channelMask.getMask());
1461 from->sendNotice(String("\002Lvl:\002 ") +
1462 Utils::level2str(uli->level) +
1464 Utils::prot2str(uli->prot) +
1466 Utils::bool2str(uli->aop) +
1467 " \002Expired:\002 " +
1468 Utils::bool2str(!uli->isStillValid()) +
1469 " \002Ident:\002 " +
1470 (uli && !uli->identified ? "\026" : "") +
1471 Utils::bool2str(uli && uli->identified) +
1472 (uli && !uli->identified ? "\026" : ""));
1474 from->sendNotice(String("\002You are not in the userlist for\002 ") +
1479 UserCommands::Whois(ServerConnection *cnx, Person *from,
1480 String channel, String rest)
1482 String nick = from->getNick();
1484 if (!rest.length()) {
1485 from->sendNotice("\002No nick specified.\002");
1489 StringTokenizer st(rest);
1490 String otherNick = st.next_token();
1492 User * u = cnx->bot->channelList->getChannel(channel)->getUser(otherNick);
1496 uli = u->userListItem;
1498 uli = cnx->bot->userList->getUserListItem(otherNick + "!" +
1499 cnx->bot->getUserhost(channel,
1504 from->sendNotice(otherNick +
1505 " \002is\002 " + uli->mask.getMask() +
1506 " \002on\002 " + uli->channelMask.getMask());
1507 from->sendNotice(String("\002Lvl:\002 ") +
1508 Utils::level2str(uli->level) +
1510 Utils::prot2str(uli->prot) +
1512 Utils::bool2str(uli->aop) +
1513 " \002Expired:\002 " +
1514 Utils::bool2str(!uli->isStillValid()) +
1515 " \002Ident:\002 " +
1516 Utils::bool2str(uli && uli->identified));
1518 from->sendNotice(otherNick +
1519 " \002is not in the userlist for\002 " +