unrealircd

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

quit.c (4332B)

      1 /*
      2  *   Unreal Internet Relay Chat Daemon, src/modules/quit.c
      3  *   (C) 2000-2001 Carsten V. Munk and the UnrealIRCd Team
      4  *   Moved to modules by Fish (Justin Hammond)
      5  *
      6  *   This program is free software; you can redistribute it and/or modify
      7  *   it under the terms of the GNU General Public License as published by
      8  *   the Free Software Foundation; either version 1, or (at your option)
      9  *   any later version.
     10  *
     11  *   This program is distributed in the hope that it will be useful,
     12  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
     13  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     14  *   GNU General Public License for more details.
     15  *
     16  *   You should have received a copy of the GNU General Public License
     17  *   along with this program; if not, write to the Free Software
     18  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
     19  */
     20 
     21 #include "unrealircd.h"
     22 
     23 CMD_FUNC(cmd_quit);
     24 
     25 #define MSG_QUIT        "QUIT"  /* QUIT */
     26 
     27 ModuleHeader MOD_HEADER
     28   = {
     29 	"quit",	/* Name of module */
     30 	"5.0", /* Version */
     31 	"command /quit", /* Short description of module */
     32 	"UnrealIRCd Team",
     33 	"unrealircd-6",
     34     };
     35 
     36 /* This is called on module init, before Server Ready */
     37 MOD_INIT()
     38 {
     39 	CommandAdd(modinfo->handle, MSG_QUIT, cmd_quit, 1, CMD_UNREGISTERED|CMD_USER|CMD_VIRUS);
     40 	MARK_AS_OFFICIAL_MODULE(modinfo);
     41 	return MOD_SUCCESS;
     42 }
     43 
     44 /* Is first run when server is 100% ready */
     45 MOD_LOAD()
     46 {
     47 	return MOD_SUCCESS;
     48 }
     49 
     50 /* Called when module is unloaded */
     51 MOD_UNLOAD()
     52 {
     53 	return MOD_SUCCESS;
     54 }
     55 
     56 /*
     57 ** cmd_quit
     58 **	parv[1] = comment
     59 */
     60 CMD_FUNC(cmd_quit)
     61 {
     62 	const char *comment = (parc > 1 && parv[1]) ? parv[1] : client->name;
     63 	char commentbuf[MAXQUITLEN + 1];
     64 	char commentbuf2[MAXQUITLEN + 1];
     65 
     66 	if (parc > 1 && parv[1])
     67 	{
     68 		strlncpy(commentbuf, parv[1], sizeof(commentbuf), iConf.quit_length);
     69 		comment = commentbuf;
     70 	} else {
     71 		comment = client->name;
     72 	}
     73 
     74 	if (MyUser(client))
     75 	{
     76 		int n;
     77 		Hook *tmphook;
     78 
     79 		if (STATIC_QUIT)
     80 		{
     81 			exit_client(client, recv_mtags, STATIC_QUIT);
     82 			return;
     83 		}
     84 
     85 		if (IsVirus(client))
     86 		{
     87 			exit_client(client, recv_mtags, "Client exited");
     88 			return;
     89 		}
     90 
     91 		if (match_spamfilter(client, comment, SPAMF_QUIT, "QUIT", NULL, 0, NULL))
     92 		{
     93 			comment = client->name;
     94 			if (IsDead(client))
     95 				return;
     96 		}
     97 		
     98 		if (!ValidatePermissionsForPath("immune:anti-spam-quit-message-time",client,NULL,NULL,NULL) && ANTI_SPAM_QUIT_MSG_TIME)
     99 		{
    100 			if (client->local->creationtime+ANTI_SPAM_QUIT_MSG_TIME > TStime())
    101 				comment = client->name;
    102 		}
    103 
    104 		if (iConf.part_instead_of_quit_on_comment_change && MyUser(client))
    105 		{
    106 			Membership *lp, *lp_next;
    107 			const char *newcomment;
    108 			Channel *channel;
    109 
    110 			for (lp = client->user->channel; lp; lp = lp_next)
    111 			{
    112 				channel = lp->channel;
    113 				newcomment = comment;
    114 				lp_next = lp->next;
    115 
    116 				for (tmphook = Hooks[HOOKTYPE_PRE_LOCAL_QUIT_CHAN]; tmphook; tmphook = tmphook->next)
    117 				{
    118 					newcomment = (*(tmphook->func.stringfunc))(client, channel, comment);
    119 					if (!newcomment)
    120 						break;
    121 				}
    122 
    123 				if (newcomment && is_banned(client, channel, BANCHK_LEAVE_MSG, &newcomment, NULL))
    124 					newcomment = NULL;
    125 
    126 				/* Comment changed? Then PART the user before we do the QUIT. */
    127 				if (comment != newcomment)
    128 				{
    129 					const char *parx[4];
    130 					char tmp[512];
    131 					int ret;
    132 
    133 
    134 					parx[0] = NULL;
    135 					parx[1] = channel->name;
    136 					if (newcomment)
    137 					{
    138 						strlcpy(tmp, newcomment, sizeof(tmp));
    139 						parx[2] = tmp;
    140 						parx[3] = NULL;
    141 					} else {
    142 						parx[2] = NULL;
    143 					}
    144 
    145 					do_cmd(client, recv_mtags, "PART", newcomment ? 3 : 2, parx);
    146 					/* This would be unusual, but possible (somewhere in the future perhaps): */
    147 					if (IsDead(client))
    148 						return;
    149 				}
    150 			}
    151 		}
    152 
    153 		for (tmphook = Hooks[HOOKTYPE_PRE_LOCAL_QUIT]; tmphook; tmphook = tmphook->next)
    154 		{
    155 			comment = (*(tmphook->func.stringfunc))(client, comment);
    156 			if (!comment)
    157 			{			
    158 				comment = client->name;
    159 				break;
    160 			}
    161 		}
    162 
    163 		if (PREFIX_QUIT)
    164 			snprintf(commentbuf2, sizeof(commentbuf2), "%s: %s", PREFIX_QUIT, comment);
    165 		else
    166 			strlcpy(commentbuf2, comment, sizeof(commentbuf2));
    167 
    168 		exit_client(client, recv_mtags, commentbuf2);
    169 	}
    170 	else
    171 	{
    172 		/* Remote quits and non-person quits always use their original comment.
    173 		 * Also pass recv_mtags so to keep the msgid and such.
    174 		 */
    175 		exit_client(client, recv_mtags, comment);
    176 	}
    177 }