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 }