unrealircd

- supernets unrealircd source & configuration
git clone git://git.acid.vegas/unrealircd.git
Log | Files | Refs | Archive | README | LICENSE

part.c (5644B)

      1 /*
      2  *   IRC - Internet Relay Chat, src/modules/part.c
      3  *   (C) 2005 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_part);
     26 
     27 #define MSG_PART 	"PART"	
     28 
     29 ModuleHeader MOD_HEADER
     30   = {
     31 	"part",
     32 	"5.0",
     33 	"command /part", 
     34 	"UnrealIRCd Team",
     35 	"unrealircd-6",
     36     };
     37 
     38 MOD_INIT()
     39 {
     40 	CommandAdd(modinfo->handle, MSG_PART, cmd_part, 2, CMD_USER);
     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_part
     57 **	parv[1] = channel
     58 **	parv[2] = comment (added by Lefler)
     59 */
     60 CMD_FUNC(cmd_part)
     61 {
     62 	char request[BUFSIZE];
     63 	Channel *channel;
     64 	Membership *lp;
     65 	char *p = NULL, *name;
     66 	const char *commentx = (parc > 2 && parv[2]) ? parv[2] : NULL;
     67 	const char *comment;
     68 	int n;
     69 	int ntargets = 0;
     70 	int maxtargets = max_targets_for_command("PART");
     71 	
     72 	if (parc < 2 || parv[1][0] == '\0')
     73 	{
     74 		sendnumeric(client, ERR_NEEDMOREPARAMS, "PART");
     75 		return;
     76 	}
     77 
     78 	if (MyUser(client))
     79 	{
     80 		if (IsShunned(client))
     81 			commentx = NULL;
     82 		if (STATIC_PART)
     83 		{
     84 			if (!strcasecmp(STATIC_PART, "yes") || !strcmp(STATIC_PART, "1"))
     85 				commentx = NULL;
     86 			else if (!strcasecmp(STATIC_PART, "no") || !strcmp(STATIC_PART, "0"))
     87 				; /* keep original reason */
     88 			else
     89 				commentx = STATIC_PART;
     90 		}
     91 		if (commentx)
     92 		{
     93 			if (match_spamfilter(client, commentx, SPAMF_PART, "PART", parv[1], 0, NULL))
     94 				commentx = NULL;
     95 			if (IsDead(client))
     96 				return;
     97 		}
     98 	}
     99 
    100 	strlcpy(request, parv[1], sizeof(request));
    101 	for (name = strtoken(&p, request, ","); name; name = strtoken(&p, NULL, ","))
    102 	{
    103 		MessageTag *mtags = NULL;
    104 
    105 		if (MyUser(client) && (++ntargets > maxtargets))
    106 		{
    107 			sendnumeric(client, ERR_TOOMANYTARGETS, name, maxtargets, "PART");
    108 			break;
    109 		}
    110 
    111 		channel = find_channel(name);
    112 		if (!channel)
    113 		{
    114 			sendnumeric(client, ERR_NOSUCHCHANNEL, name);
    115 			continue;
    116 		}
    117 
    118 		/* 'commentx' is the general part msg, but it can be changed
    119 		 * per-channel (eg some chans block badwords, strip colors, etc)
    120 		 * so we copy it to 'comment' and use that in this for loop :)
    121 		 */
    122 		comment = commentx;
    123 
    124 		if (!(lp = find_membership_link(client->user->channel, channel)))
    125 		{
    126 			/* Normal to get get when our client did a kick
    127 			   ** for a remote client (who sends back a PART),
    128 			   ** so check for remote client or not --Run
    129 			 */
    130 			if (MyUser(client))
    131 				sendnumeric(client, ERR_NOTONCHANNEL, name);
    132 			continue;
    133 		}
    134 
    135 		if (!ValidatePermissionsForPath("channel:override:banpartmsg",client,NULL,channel,NULL) && !check_channel_access(client, channel, "oaq")) {
    136 			/* Banned? No comment allowed ;) */
    137 			if (comment && is_banned(client, channel, BANCHK_MSG, &comment, NULL))
    138 				comment = NULL;
    139 			if (comment && is_banned(client, channel, BANCHK_LEAVE_MSG, &comment, NULL))
    140 				comment = NULL;
    141 		}
    142 
    143 		if (MyConnect(client))
    144 		{
    145 			Hook *tmphook;
    146 			for (tmphook = Hooks[HOOKTYPE_PRE_LOCAL_PART]; tmphook; tmphook = tmphook->next) {
    147 				comment = (*(tmphook->func.stringfunc))(client, channel, comment);
    148 				if (!comment)
    149 					break;
    150 			}
    151 		}
    152 
    153 		/* Create a new message, this one is actually used by 8 calls (though at most 4 max) */
    154 		new_message_special(client, recv_mtags, &mtags, ":%s PART %s", client->name, channel->name);
    155 
    156 		/* Send to other servers... */
    157 		sendto_server(client, 0, 0, mtags, ":%s PART %s :%s",
    158 			client->id, channel->name, comment ? comment : "");
    159 
    160 		if (invisible_user_in_channel(client, channel))
    161 		{
    162 			/* Show PART only to chanops and self */
    163 			if (!comment)
    164 			{
    165 				sendto_channel(channel, client, client,
    166 					       "ho", 0,
    167 					       SEND_LOCAL, mtags,
    168 					       ":%s PART %s",
    169 					       client->name, channel->name);
    170 				if (MyUser(client))
    171 				{
    172 					sendto_one(client, mtags, ":%s!%s@%s PART %s",
    173 						client->name, client->user->username, GetHost(client), channel->name);
    174 				}
    175 			}
    176 			else
    177 			{
    178 				sendto_channel(channel, client, client,
    179 					       "ho", 0,
    180 					       SEND_LOCAL, mtags,
    181 					       ":%s PART %s %s",
    182 					       client->name, channel->name, comment);
    183 				if (MyUser(client))
    184 				{
    185 					sendto_one(client, mtags,
    186 						":%s!%s@%s PART %s %s",
    187 						client->name, client->user->username, GetHost(client),
    188 						channel->name, comment);
    189 				}
    190 			}
    191 		}
    192 		else
    193 		{
    194 			/* Show PART to all users in channel */
    195 			if (!comment)
    196 			{
    197 				sendto_channel(channel, client, NULL, 0, 0, SEND_LOCAL, mtags,
    198 				               ":%s PART %s",
    199 				               client->name, channel->name);
    200 			} else {
    201 				sendto_channel(channel, client, NULL, 0, 0, SEND_LOCAL, mtags,
    202 				               ":%s PART %s :%s",
    203 				               client->name, channel->name, comment);
    204 			}
    205 		}
    206 
    207 		if (MyUser(client))
    208 			RunHook(HOOKTYPE_LOCAL_PART, client, channel, mtags, comment);
    209 		else
    210 			RunHook(HOOKTYPE_REMOTE_PART, client, channel, mtags, comment);
    211 
    212 		free_message_tags(mtags);
    213 
    214 		remove_user_from_channel(client, channel, 0);
    215 	}
    216 }