unrealircd

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

aliases.c (8698B)

      1 /*
      2  *   Unreal Internet Relay Chat Daemon, src/aliases.c
      3  *   (C) 2000-2001 Carsten V. Munk and the UnrealIRCd Team
      4  *
      5  *   This program is free software; you can redistribute it and/or modify
      6  *   it under the terms of the GNU General Public License as published by
      7  *   the Free Software Foundation; either version 1, or (at your option)
      8  *   any later version.
      9  *
     10  *   This program is distributed in the hope that it will be useful,
     11  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
     12  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     13  *   GNU General Public License for more details.
     14  *
     15  *   You should have received a copy of the GNU General Public License
     16  *   along with this program; if not, write to the Free Software
     17  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
     18  */
     19 
     20 #include "unrealircd.h"
     21 
     22 /* Function to return a group of tokens -- codemastr */
     23 void strrangetok(char *in, char *out, char tok, short first, short last) {
     24 	int i = 0, tokcount = 0, j = 0;
     25 	first--;
     26 	last--;
     27 	while(in[i]) {
     28 		if (in[i] == tok) {
     29 			tokcount++;
     30 			if (tokcount == first)
     31 				i++;
     32 		}
     33 		if (tokcount >= first && (tokcount <= last || last == -1)) {
     34 			out[j] = in[i];
     35 			j++;
     36 		}
     37 		i++;
     38 	}
     39 	out[j] = 0;
     40 }			
     41 
     42 /* cmd_alias is a special type of command, it has an extra argument 'cmd'. */
     43 static int recursive_alias = 0;
     44 
     45 void cmd_alias(Client *client, MessageTag *mtags, int parc, const char *parv[], const char *cmd)
     46 {
     47 	ConfigItem_alias *alias;
     48 	Client *acptr;
     49 	int ret;
     50 	char request[BUFSIZE];
     51 
     52 	if (!(alias = find_alias(cmd))) 
     53 	{
     54 		sendto_one(client, NULL, ":%s %d %s %s :Unknown command",
     55 			me.name, ERR_UNKNOWNCOMMAND, client->name, cmd);
     56 		return;
     57 	}
     58 	
     59 	/* If it isn't an ALIAS_COMMAND, we require a paramter ... We check ALIAS_COMMAND LATER */
     60 	if (alias->type != ALIAS_COMMAND && (parc < 2 || *parv[1] == '\0'))
     61 	{
     62 		sendnumeric(client, ERR_NOTEXTTOSEND);
     63 		return;
     64 	}
     65 
     66 	if (alias->type == ALIAS_SERVICES) 
     67 	{
     68 		if (SERVICES_NAME && (acptr = find_user(alias->nick, NULL)))
     69 		{
     70 			if (alias->spamfilter && match_spamfilter(client, parv[1], SPAMF_USERMSG, cmd, alias->nick, 0, NULL))
     71 				return;
     72 			sendto_one(acptr, NULL, ":%s PRIVMSG %s@%s :%s", client->name,
     73 				alias->nick, SERVICES_NAME, parv[1]);
     74 		}
     75 		else
     76 			sendnumeric(client, ERR_SERVICESDOWN, alias->nick);
     77 	}
     78 	else if (alias->type == ALIAS_STATS) 
     79 	{
     80 		if (STATS_SERVER && (acptr = find_user(alias->nick, NULL)))
     81 		{
     82 			if (alias->spamfilter && match_spamfilter(client, parv[1], SPAMF_USERMSG, cmd, alias->nick, 0, NULL))
     83 				return;
     84 			sendto_one(acptr, NULL, ":%s PRIVMSG %s@%s :%s", client->name,
     85 				alias->nick, STATS_SERVER, parv[1]);
     86 		}
     87 		else
     88 			sendnumeric(client, ERR_SERVICESDOWN, alias->nick);
     89 	}
     90 	else if (alias->type == ALIAS_NORMAL) 
     91 	{
     92 		if ((acptr = find_user(alias->nick, NULL))) 
     93 		{
     94 			if (alias->spamfilter && match_spamfilter(client, parv[1], SPAMF_USERMSG, cmd, alias->nick, 0, NULL))
     95 				return;
     96 			if (MyUser(acptr))
     97 				sendto_one(acptr, NULL, ":%s!%s@%s PRIVMSG %s :%s", client->name, 
     98 					client->user->username, GetHost(client),
     99 					alias->nick, parv[1]);
    100 			else
    101 				sendto_one(acptr, NULL, ":%s PRIVMSG %s :%s", client->name,
    102 					alias->nick, parv[1]);
    103 		}
    104 		else
    105 			sendnumeric(client, ERR_NOSUCHNICK, alias->nick);
    106 	}
    107 	else if (alias->type == ALIAS_CHANNEL)
    108 	{
    109 		Channel *channel;
    110 		if ((channel = find_channel(alias->nick)))
    111 		{
    112 			const char *msg = parv[1];
    113 			const char *errmsg = NULL;
    114 			if (can_send_to_channel(client, channel, &msg, &errmsg, 0))
    115 			{
    116 				if (alias->spamfilter && match_spamfilter(client, parv[1], SPAMF_CHANMSG, cmd, channel->name, 0, NULL))
    117 					return;
    118 				new_message(client, NULL, &mtags);
    119 				sendto_channel(channel, client, client->direction,
    120 				               NULL, 0, SEND_ALL|SKIP_DEAF, mtags,
    121 				               ":%s PRIVMSG %s :%s",
    122 				               client->name, channel->name, parv[1]);
    123 				free_message_tags(mtags);
    124 				return;
    125 			}
    126 		}
    127 		sendnumeric(client, ERR_CANNOTDOCOMMAND,
    128 				cmd, "You may not use this command at this time");
    129 	}
    130 	else if (alias->type == ALIAS_COMMAND) 
    131 	{
    132 		ConfigItem_alias_format *format;
    133 		char *ptr = "";
    134 
    135 		if (!(parc < 2 || *parv[1] == '\0'))
    136 		{
    137 			strlcpy(request, parv[1], sizeof(request));
    138 			ptr = request;
    139 		}
    140 
    141 		for (format = alias->format; format; format = format->next)
    142 		{
    143 			if (unreal_match(format->expr, ptr))
    144 			{
    145 				/* Parse the parameters */
    146 				int i = 0, j = 0, k = 1;
    147 				char output[1024], current[1024];
    148 				char nums[4];
    149 
    150 				memset(current, 0, sizeof(current));
    151 				memset(output, 0, sizeof(output));
    152 
    153 				while(format->parameters[i] && j < 500) 
    154 				{
    155 					k = 0;
    156 					if (format->parameters[i] == '%') 
    157 					{
    158 						i++;
    159 						if (format->parameters[i] == '%') 
    160 							output[j++] = '%';
    161 						else if (isdigit(format->parameters[i])) 
    162 						{
    163 							for(; isdigit(format->parameters[i]) && k < 2; i++, k++) {
    164 								nums[k] = format->parameters[i];
    165 							}
    166 							nums[k] = 0;
    167 							i--;
    168 							if (format->parameters[i+1] == '-') {
    169 								strrangetok(ptr, current, ' ', atoi(nums),0);
    170 								i++;
    171 							}
    172 							else 
    173 								strrangetok(ptr, current, ' ', atoi(nums), atoi(nums));
    174 							if (!*current)
    175 								continue;
    176 							if (j + strlen(current)+1 >= 500)
    177 								break;
    178 							strlcat(output, current, sizeof output);
    179 							j += strlen(current);
    180 							
    181 						}
    182 						else if (format->parameters[i] == 'n' ||
    183 							 format->parameters[i] == 'N')
    184 						{
    185 							strlcat(output, client->name, sizeof output);
    186 							j += strlen(client->name);
    187 						}
    188 						else 
    189 						{
    190 							output[j++] = '%';
    191 							output[j++] = format->parameters[i];
    192 						}
    193 						i++;
    194 						continue;
    195 					}
    196 					output[j++] = format->parameters[i++];
    197 				}
    198 				output[j] = 0;
    199 				/* Now check to make sure we have something to send */
    200 				if (strlen(output) == 0)
    201 				{
    202 					sendnumeric(client, ERR_NEEDMOREPARAMS, cmd);
    203 					return;
    204 				}
    205 				
    206 				if (format->type == ALIAS_SERVICES) 
    207 				{
    208 					if (SERVICES_NAME && (acptr = find_user(format->nick, NULL)))
    209 					{
    210 						if (alias->spamfilter && match_spamfilter(client, output, SPAMF_USERMSG, cmd, format->nick, 0, NULL))
    211 							return;
    212 						sendto_one(acptr, NULL, ":%s PRIVMSG %s@%s :%s", client->name,
    213 							format->nick, SERVICES_NAME, output);
    214 					} else
    215 						sendnumeric(client, ERR_SERVICESDOWN, format->nick);
    216 				}
    217 				else if (format->type == ALIAS_STATS) 
    218 				{
    219 					if (STATS_SERVER && (acptr = find_user(format->nick, NULL)))
    220 					{
    221 						if (alias->spamfilter && match_spamfilter(client, output, SPAMF_USERMSG, cmd, format->nick, 0, NULL))
    222 							return;
    223 						sendto_one(acptr, NULL, ":%s PRIVMSG %s@%s :%s", client->name,
    224 							format->nick, STATS_SERVER, output);
    225 					} else
    226 						sendnumeric(client, ERR_SERVICESDOWN, format->nick);
    227 				}
    228 				else if (format->type == ALIAS_NORMAL) 
    229 				{
    230 					if ((acptr = find_user(format->nick, NULL))) 
    231 					{
    232 						if (alias->spamfilter && match_spamfilter(client, output, SPAMF_USERMSG, cmd, format->nick, 0, NULL))
    233 							return;
    234 						if (MyUser(acptr))
    235 							sendto_one(acptr, NULL, ":%s!%s@%s PRIVMSG %s :%s", client->name, 
    236 							client->user->username, IsHidden(client) ? client->user->virthost : client->user->realhost,
    237 							format->nick, output);
    238 						else
    239 							sendto_one(acptr, NULL, ":%s PRIVMSG %s :%s", client->name,
    240 								format->nick, output);
    241 					}
    242 					else
    243 						sendnumeric(client, ERR_NOSUCHNICK, format->nick);
    244 				}
    245 				else if (format->type == ALIAS_CHANNEL)
    246 				{
    247 					Channel *channel;
    248 					if ((channel = find_channel(format->nick)))
    249 					{
    250 						const char *msg = output;
    251 						const char *errmsg = NULL;
    252 						if (!can_send_to_channel(client, channel, &msg, &errmsg, 0))
    253 						{
    254 							if (alias->spamfilter && match_spamfilter(client, output, SPAMF_CHANMSG, cmd, channel->name, 0, NULL))
    255 								return;
    256 							new_message(client, NULL, &mtags);
    257 							sendto_channel(channel, client, client->direction,
    258 							               NULL, 0, SEND_ALL|SKIP_DEAF, mtags,
    259 							               ":%s PRIVMSG %s :%s",
    260 							               client->name, channel->name, parv[1]);
    261 							free_message_tags(mtags);
    262 							return;
    263 						}
    264 					}
    265 					sendnumeric(client, ERR_CANNOTDOCOMMAND, cmd, 
    266 						"You may not use this command at this time");
    267 				}
    268 				else if (format->type == ALIAS_REAL)
    269 				{
    270 					int ret;
    271 					char mybuf[500];
    272 					
    273 					snprintf(mybuf, sizeof(mybuf), "%s %s", format->nick, output);
    274 
    275 					if (recursive_alias)
    276 					{
    277 						sendnumeric(client, ERR_CANNOTDOCOMMAND, cmd, "You may not use this command at this time -- recursion");
    278 						return;
    279 					}
    280 
    281 					recursive_alias = 1;
    282 					parse(client, mybuf, strlen(mybuf));
    283 					recursive_alias = 0;
    284 
    285 					return;
    286 				}
    287 				break;
    288 			}
    289 		}
    290 	}
    291 }