unrealircd

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

away.c (4605B)

      1 /*
      2  *   IRC - Internet Relay Chat, src/modules/away.c
      3  *   (C) 2001 The UnrealIRCd Team
      4  *
      5  *   away command
      6  *
      7  *   See file AUTHORS in IRC package for additional names of
      8  *   the programmers.
      9  *
     10  *   This program is free software; you can redistribute it and/or modify
     11  *   it under the terms of the GNU General Public License as published by
     12  *   the Free Software Foundation; either version 1, or (at your option)
     13  *   any later version.
     14  *
     15  *   This program is distributed in the hope that it will be useful,
     16  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
     17  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     18  *   GNU General Public License for more details.
     19  *
     20  *   You should have received a copy of the GNU General Public License
     21  *   along with this program; if not, write to the Free Software
     22  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
     23  */
     24 
     25 #include "unrealircd.h"
     26 
     27 CMD_FUNC(cmd_away);
     28 int away_join(Client *client, Channel *channel, MessageTag *mtags);
     29 
     30 long CAP_AWAY_NOTIFY = 0L;
     31 
     32 #define MSG_AWAY 	"AWAY"	
     33 
     34 ModuleHeader MOD_HEADER
     35   = {
     36 	"away",
     37 	"5.0",
     38 	"command /away", 
     39 	"UnrealIRCd Team",
     40 	"unrealircd-6",
     41     };
     42 
     43 MOD_INIT()
     44 {
     45 	ClientCapabilityInfo c;
     46 	memset(&c, 0, sizeof(c));
     47 	c.name = "away-notify";
     48 	ClientCapabilityAdd(modinfo->handle, &c, &CAP_AWAY_NOTIFY);
     49 	CommandAdd(modinfo->handle, MSG_AWAY, cmd_away, 1, CMD_USER);
     50 	HookAdd(modinfo->handle, HOOKTYPE_LOCAL_JOIN, 0, away_join);
     51 	HookAdd(modinfo->handle, HOOKTYPE_REMOTE_JOIN, 0, away_join);
     52 
     53 	MARK_AS_OFFICIAL_MODULE(modinfo);
     54 	return MOD_SUCCESS;
     55 }
     56 
     57 MOD_LOAD()
     58 {
     59 	return MOD_SUCCESS;
     60 }
     61 
     62 MOD_UNLOAD()
     63 {
     64 	return MOD_SUCCESS;
     65 }
     66 
     67 int away_join(Client *client, Channel *channel, MessageTag *mtags)
     68 {
     69 	Member *lp;
     70 	Client *acptr;
     71 	int invisible = invisible_user_in_channel(client, channel);
     72 	for (lp = channel->members; lp; lp = lp->next)
     73 	{
     74 		acptr = lp->client;
     75 
     76 		if (!MyConnect(acptr))
     77 			continue; /* only locally connected clients */
     78 
     79 		if (invisible && !check_channel_access_member(lp, "hoaq") && (client != acptr))
     80 			continue; /* skip non-ops if requested to (used for mode +D), but always send to 'client' */
     81 
     82 		if (client->user->away && HasCapabilityFast(acptr, CAP_AWAY_NOTIFY))
     83 		{
     84 			MessageTag *mtags_away = NULL;
     85 			new_message(client, NULL, &mtags_away);
     86 			sendto_one(acptr, mtags_away, ":%s!%s@%s AWAY :%s",
     87 			           client->name, client->user->username, GetHost(client), client->user->away);
     88 			free_message_tags(mtags_away);
     89 		}
     90 	}
     91 	return 0;
     92 }
     93 
     94 /** Mark client as AWAY or mark them as back (in case of empty reason) */
     95 CMD_FUNC(cmd_away)
     96 {
     97 	char reason[512];
     98 	int n, already_as_away = 0;
     99 	MessageTag *mtags = NULL;
    100 
    101 	if (IsServer(client))
    102 		return;
    103 
    104 	if (parc < 2 || BadPtr(parv[1]))
    105 	{
    106 		/* Marking as not away */
    107 		if (client->user->away)
    108 		{
    109 			safe_free(client->user->away);
    110 
    111 			new_message(client, recv_mtags, &mtags);
    112 			sendto_server(client, 0, 0, mtags, ":%s AWAY", client->name);
    113 			sendto_local_common_channels(client, client, CAP_AWAY_NOTIFY, mtags,
    114 			                             ":%s AWAY", client->name);
    115 			RunHook(HOOKTYPE_AWAY, client, mtags, NULL, 0);
    116 			free_message_tags(mtags);
    117 		}
    118 
    119 		if (MyConnect(client))
    120 			sendnumeric(client, RPL_UNAWAY);
    121 		return;
    122 	}
    123 
    124 	/* Obey set::away-length */
    125 	strlncpy(reason, parv[1], sizeof(reason), iConf.away_length);
    126 
    127 	/* Check spamfilters */
    128 	if (MyUser(client) && match_spamfilter(client, reason, SPAMF_AWAY, "AWAY", NULL, 0, NULL))
    129 		return;
    130 
    131 	/* Check away-flood */
    132 	if (MyUser(client) &&
    133 	    !ValidatePermissionsForPath("immune:away-flood",client,NULL,NULL,NULL) &&
    134 	    flood_limit_exceeded(client, FLD_AWAY))
    135 	{
    136 		sendnumeric(client, ERR_TOOMANYAWAY);
    137 		return;
    138 	}
    139 
    140 	/* Check if the new away reason is the same as the current reason - if so then return (no change) */
    141 	if ((client->user->away) && !strcmp(client->user->away, reason))
    142 		return;
    143 
    144 	/* All tests passed. Now marking as away (or still away but changing the away reason) */
    145 
    146 	client->user->away_since = TStime();
    147 	
    148 	new_message(client, recv_mtags, &mtags);
    149 
    150 	sendto_server(client, 0, 0, mtags, ":%s AWAY :%s", client->id, reason);
    151 
    152 	if (client->user->away)
    153 	{
    154 		safe_free(client->user->away);
    155 		already_as_away = 1;
    156 	}
    157 	
    158 	safe_strdup(client->user->away, reason);
    159 
    160 	if (MyConnect(client))
    161 		sendnumeric(client, RPL_NOWAWAY);
    162 
    163 	sendto_local_common_channels(client, client,
    164 	                             CAP_AWAY_NOTIFY, mtags,
    165 	                             ":%s AWAY :%s", client->name, client->user->away);
    166 
    167 	RunHook(HOOKTYPE_AWAY, client, mtags, client->user->away, already_as_away);
    168 
    169 	free_message_tags(mtags);
    170 
    171 	return;
    172 }