unrealircd- supernets unrealircd source & configuration |
git clone git://git.acid.vegas/unrealircd.git |
Log | Files | Refs | Archive | README | LICENSE |
knock.c (3970B)
1 /* 2 * IRC - Internet Relay Chat, src/modules/knock.c 3 * (C) 2004 The UnrealIRCd Team 4 * 5 * See file AUTHORS in IRC package for additional names of 6 * the programmers. 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License as published by 10 * the Free Software Foundation; either version 1, or (at your option) 11 * any later version. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with this program; if not, write to the Free Software 20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 21 */ 22 23 #include "unrealircd.h" 24 25 CMD_FUNC(cmd_knock); 26 27 #define MSG_KNOCK "KNOCK" 28 29 ModuleHeader MOD_HEADER 30 = { 31 "knock", 32 "5.0", 33 "command /knock", 34 "UnrealIRCd Team", 35 "unrealircd-6", 36 }; 37 38 MOD_INIT() 39 { 40 CommandAdd(modinfo->handle, MSG_KNOCK, cmd_knock, 2, CMD_USER); 41 ISupportAdd(modinfo->handle, "KNOCK", NULL); 42 MARK_AS_OFFICIAL_MODULE(modinfo); 43 return MOD_SUCCESS; 44 } 45 46 MOD_LOAD() 47 { 48 return MOD_SUCCESS; 49 } 50 51 MOD_UNLOAD() 52 { 53 return MOD_SUCCESS; 54 } 55 56 /* 57 ** cmd_knock 58 ** parv[1] - channel 59 ** parv[2] - reason 60 ** 61 ** Coded by Stskeeps 62 ** Additional bugfixes/ideas by codemastr 63 ** (C) codemastr & Stskeeps 64 ** 65 ** 2019-11-27: Behavior change. We now send the KNOCK 66 ** across servers and only deliver the channel notice 67 ** to local channel members. The reason for this is that 68 ** otherwise we cannot count KNOCKs network-wide which 69 ** caused knock-floods per-channel to be per-server 70 ** rather than global, which undesirable. 71 ** Unfortunately, this means that if you have a mixed 72 ** U4 and U5 network you will see KNOCK notices twice 73 ** for every attempt. 74 */ 75 CMD_FUNC(cmd_knock) 76 { 77 Channel *channel; 78 Hook *h; 79 int i = 0; 80 MessageTag *mtags = NULL; 81 const char *reason; 82 83 if (IsServer(client)) 84 return; 85 86 if (parc < 2 || *parv[1] == '\0') 87 { 88 sendnumeric(client, ERR_NEEDMOREPARAMS, "KNOCK"); 89 return; 90 } 91 92 reason = parv[2] ? parv[2] : "no reason specified"; 93 94 if (MyConnect(client) && !valid_channelname(parv[1])) 95 { 96 sendnumeric(client, ERR_NOSUCHCHANNEL, parv[1]); 97 return; 98 } 99 100 if (!(channel = find_channel(parv[1]))) 101 { 102 sendnumeric(client, ERR_CANNOTKNOCK, parv[1], "Channel does not exist!"); 103 return; 104 } 105 106 /* IsMember bugfix by codemastr */ 107 if (IsMember(client, channel) == 1) 108 { 109 sendnumeric(client, ERR_CANNOTKNOCK, channel->name, "You're already there!"); 110 return; 111 } 112 113 if (!has_channel_mode(channel, 'i')) 114 { 115 sendnumeric(client, ERR_CANNOTKNOCK, channel->name, "Channel is not invite only!"); 116 return; 117 } 118 119 if (is_banned(client, channel, BANCHK_JOIN, NULL, NULL)) 120 { 121 sendnumeric(client, ERR_CANNOTKNOCK, channel->name, "You're banned!"); 122 return; 123 } 124 125 for (h = Hooks[HOOKTYPE_PRE_KNOCK]; h; h = h->next) 126 { 127 i = (*(h->func.intfunc))(client, channel, &reason); 128 if (i == HOOK_DENY || i == HOOK_ALLOW) 129 break; 130 } 131 132 if (i == HOOK_DENY) 133 return; 134 135 if (MyUser(client) && 136 !ValidatePermissionsForPath("immune:knock-flood",client,NULL,NULL,NULL) && 137 flood_limit_exceeded(client, FLD_KNOCK)) 138 { 139 sendnumeric(client, ERR_CANNOTKNOCK, parv[1], "You are KNOCK flooding"); 140 return; 141 } 142 143 new_message(&me, NULL, &mtags); 144 145 sendto_channel(channel, &me, NULL, "o", 146 0, SEND_LOCAL, mtags, 147 ":%s NOTICE @%s :[Knock] by %s!%s@%s (%s)", 148 me.name, channel->name, 149 client->name, client->user->username, GetHost(client), 150 reason); 151 152 sendto_server(client, 0, 0, mtags, ":%s KNOCK %s :%s", client->id, channel->name, reason); 153 154 if (MyUser(client)) 155 sendnotice(client, "Knocked on %s", channel->name); 156 157 RunHook(HOOKTYPE_KNOCK, client, channel, mtags, parv[2]); 158 159 free_message_tags(mtags); 160 }