unrealircd- supernets unrealircd source & configuration |
git clone git://git.acid.vegas/unrealircd.git |
Log | Files | Refs | Archive | README | LICENSE |
squit.c (4471B)
1 /* 2 * IRC - Internet Relay Chat, src/modules/squit.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_squit); 26 27 #define MSG_SQUIT "SQUIT" 28 29 ModuleHeader MOD_HEADER 30 = { 31 "squit", 32 "5.0", 33 "command /squit", 34 "UnrealIRCd Team", 35 "unrealircd-6", 36 }; 37 38 MOD_INIT() 39 { 40 CommandAdd(modinfo->handle, MSG_SQUIT, cmd_squit, 2, CMD_USER|CMD_SERVER); 41 MARK_AS_OFFICIAL_MODULE(modinfo); 42 return MOD_SUCCESS; 43 } 44 45 MOD_LOAD() 46 { 47 return MOD_SUCCESS; 48 } 49 50 MOD_UNLOAD() 51 { 52 return MOD_SUCCESS; 53 } 54 55 /* 56 ** cmd_squit 57 ** parv[1] = server name 58 ** parv[parc-1] = comment 59 */ 60 CMD_FUNC(cmd_squit) 61 { 62 const char *server; 63 Client *target; 64 const char *comment = (parc > 2 && parv[parc - 1]) ? parv[parc - 1] : client->name; 65 66 // FIXME: this function is way too confusing, and full of old shit? 67 68 if (!ValidatePermissionsForPath("route:local",client,NULL,NULL,NULL)) 69 { 70 sendnumeric(client, ERR_NOPRIVILEGES); 71 return; 72 } 73 74 if ((parc < 2) || BadPtr(parv[1])) 75 { 76 sendnumeric(client, ERR_NEEDMOREPARAMS, "SQUIT"); 77 return; 78 } 79 80 server = parv[1]; 81 82 target = find_server_quick(server); 83 if (target && IsMe(target)) 84 { 85 target = client->direction; 86 server = client->direction->local->sockhost; 87 } 88 89 /* 90 ** SQUIT semantics is tricky, be careful... 91 ** 92 ** The old (irc2.2PL1 and earlier) code just cleans away the 93 ** server client from the links (because it is never true 94 ** "client->direction == target". 95 ** 96 ** This logic here works the same way until "SQUIT host" hits 97 ** the server having the target "host" as local link. Then it 98 ** will do a real cleanup spewing SQUIT's and QUIT's to all 99 ** directions, also to the link from which the orinal SQUIT 100 ** came, generating one unnecessary "SQUIT host" back to that 101 ** link. 102 ** 103 ** One may think that this could be implemented like 104 ** "hunt_server" (e.g. just pass on "SQUIT" without doing 105 ** nothing until the server having the link as local is 106 ** reached). Unfortunately this wouldn't work in the real life, 107 ** because either target may be unreachable or may not comply 108 ** with the request. In either case it would leave target in 109 ** links--no command to clear it away. So, it's better just 110 ** clean out while going forward, just to be sure. 111 ** 112 ** ...of course, even better cleanout would be to QUIT/SQUIT 113 ** dependant users/servers already on the way out, but 114 ** currently there is not enough information about remote 115 ** clients to do this... --msa 116 */ 117 if (!target) 118 { 119 sendnumeric(client, ERR_NOSUCHSERVER, server); 120 return; 121 } 122 if (MyUser(client) && ((!ValidatePermissionsForPath("route:global",client,NULL,NULL,NULL) && !MyConnect(target)) || 123 (!ValidatePermissionsForPath("route:local",client,NULL,NULL,NULL) && MyConnect(target)))) 124 { 125 sendnumeric(client, ERR_NOPRIVILEGES); 126 return; 127 } 128 /* 129 ** Notify all opers, if my local link is remotely squitted 130 */ 131 if (MyConnect(target) && !MyUser(client)) 132 { 133 unreal_log(ULOG_INFO, "link", "SQUIT", client, 134 "SQUIT: Forced server disconnect of $target by $client ($reason)", 135 log_data_client("target", target), 136 log_data_string("reason", comment)); 137 } 138 else if (MyConnect(target)) 139 { 140 if (target->user) 141 { 142 sendnotice(client, "ERROR: You're connected to %s, we cannot SQUIT ourselves", 143 me.name); 144 return; 145 } 146 unreal_log(ULOG_INFO, "link", "SQUIT", client, 147 "SQUIT: Forced server disconnect of $target by $client ($reason)", 148 log_data_client("target", target), 149 log_data_string("reason", comment)); 150 } 151 152 exit_client_ex(target, client->direction, recv_mtags, comment); 153 }