unrealircd

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

dccallow.c (6089B)

      1 /*
      2  *   IRC - Internet Relay Chat, src/modules/m_dccallow
      3  *   (C) 2004 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_dccallow);
     26 
     27 #define MSG_DCCALLOW 	"DCCALLOW"
     28 
     29 ModuleHeader MOD_HEADER
     30   = {
     31 	"dccallow",
     32 	"5.0",
     33 	"command /dccallow", 
     34 	"UnrealIRCd Team",
     35 	"unrealircd-6",
     36     };
     37 
     38 MOD_INIT()
     39 {
     40 	CommandAdd(modinfo->handle, MSG_DCCALLOW, cmd_dccallow, 1, CMD_USER);
     41 	ISupportAdd(modinfo->handle, "USERIP", NULL);
     42 	MARK_AS_OFFICIAL_MODULE(modinfo);
     43 	return MOD_SUCCESS;
     44 }
     45 
     46 MOD_LOAD()
     47 {
     48 	return MOD_SUCCESS;
     49 }
     50 
     51 MOD_UNLOAD()
     52 {
     53 	return MOD_SUCCESS;
     54 }
     55 
     56 /* cmd_dccallow:
     57  * HISTORY:
     58  * Taken from bahamut 1.8.1
     59  */
     60 CMD_FUNC(cmd_dccallow)
     61 {
     62 	char request[BUFSIZE];
     63 	Link *lp;
     64 	char *p, *s;
     65 	Client *friend;
     66 	int didlist = 0, didhelp = 0, didanything = 0;
     67 	char **ptr;
     68 	int ntargets = 0;
     69 	int maxtargets = max_targets_for_command("WHOIS");
     70 	static char *dcc_help[] =
     71 	{
     72 		"/DCCALLOW [<+|->nick[,<+|->nick, ...]] [list] [help]",
     73 		"You may allow DCCs of files which are otherwise blocked by the IRC server",
     74 		"by specifying a DCC allow for the user you want to recieve files from.",
     75 		"For instance, to allow the user Bob to send you file.exe, you would type:",
     76 		"/DCCALLOW +bob",
     77 		"and Bob would then be able to send you files. Bob will have to resend the file",
     78 		"if the server gave him an error message before you added him to your allow list.",
     79 		"/DCCALLOW -bob",
     80 		"Will do the exact opposite, removing him from your dcc allow list.",
     81 		"/dccallow list",
     82 		"Will list the users currently on your dcc allow list.",
     83 		NULL
     84 	};
     85 
     86 	if (!MyUser(client))
     87 		return;
     88 	
     89 	if (parc < 2)
     90 	{
     91 		sendnotice(client, "No command specified for DCCALLOW. "
     92 			"Type '/DCCALLOW HELP' for more information.");
     93 		return;
     94 	}
     95 
     96 	strlcpy(request, parv[1], sizeof(request));
     97 	for (p = NULL, s = strtoken(&p, request, ", "); s; s = strtoken(&p, NULL, ", "))
     98 	{
     99 		if (MyUser(client) && (++ntargets > maxtargets))
    100 		{
    101 			sendnumeric(client, ERR_TOOMANYTARGETS, s, maxtargets, "DCCALLOW");
    102 			break;
    103 		}
    104 		if (*s == '+')
    105 		{
    106 			didanything = 1;
    107 			if (!*++s)
    108 				continue;
    109 			
    110 			friend = find_user(s, NULL);
    111 			
    112 			if (friend == client)
    113 				continue;
    114 			
    115 			if (!friend)
    116 			{
    117 				sendnumeric(client, ERR_NOSUCHNICK, s);
    118 				continue;
    119 			}
    120 			add_dccallow(client, friend);
    121 		} else
    122 		if (*s == '-')
    123 		{
    124 			didanything = 1;
    125 			if (!*++s)
    126 				continue;
    127 			
    128 			friend = find_user(s, NULL);
    129 			if (friend == client)
    130 				continue;
    131 			if (!friend)
    132 			{
    133 				sendnumeric(client, ERR_NOSUCHNICK, s);
    134 				continue;
    135 			}
    136 			del_dccallow(client, friend);
    137 		} else
    138 		if (!didlist && !strncasecmp(s, "list", 4))
    139 		{
    140 			didanything = didlist = 1;
    141 			sendnumeric(client, RPL_DCCINFO, "The following users are on your dcc allow list:");
    142 			for(lp = client->user->dccallow; lp; lp = lp->next)
    143 			{
    144 				if (lp->flags == DCC_LINK_REMOTE)
    145 					continue;
    146 				sendnumericfmt(client, RPL_DCCLIST, ":%s (%s@%s)", lp->value.client->name,
    147 					lp->value.client->user->username,
    148 					GetHost(lp->value.client));
    149 			}
    150 			sendnumeric(client, RPL_ENDOFDCCLIST, s);
    151 		} else
    152 		if (!didhelp && !strncasecmp(s, "help", 4))
    153 		{
    154 			didanything = didhelp = 1;
    155 			for(ptr = dcc_help; *ptr; ptr++)
    156 				sendnumeric(client, RPL_DCCINFO, *ptr);
    157 			sendnumeric(client, RPL_ENDOFDCCLIST, s);
    158 		}
    159 	}
    160 	if (!didanything)
    161 	{
    162 		sendnotice(client, "Invalid syntax for DCCALLOW. Type '/DCCALLOW HELP' for more information.");
    163 		return;
    164 	}
    165 }
    166 
    167 /* The dccallow functions below are all taken from bahamut (1.8.1).
    168  * Well, with some small modifications of course. -- Syzop
    169  */
    170 
    171 /** Adds 'optr' to the DCCALLOW list of 'client' */
    172 int add_dccallow(Client *client, Client *optr)
    173 {
    174 	Link *lp;
    175 	int cnt = 0;
    176 
    177 	for (lp = client->user->dccallow; lp; lp = lp->next)
    178 	{
    179 		if (lp->flags != DCC_LINK_ME)
    180 			continue;
    181 		cnt++;
    182 		if (lp->value.client == optr)
    183 			return 0;
    184 	}
    185 
    186 	if (cnt >= MAXDCCALLOW)
    187 	{
    188 		sendnumeric(client, ERR_TOOMANYDCC,
    189 			optr->name, MAXDCCALLOW);
    190 		return 0;
    191 	}
    192 
    193 	lp = make_link();
    194 	lp->value.client = optr;
    195 	lp->flags = DCC_LINK_ME;
    196 	lp->next = client->user->dccallow;
    197 	client->user->dccallow = lp;
    198 
    199 	lp = make_link();
    200 	lp->value.client = client;
    201 	lp->flags = DCC_LINK_REMOTE;
    202 	lp->next = optr->user->dccallow;
    203 	optr->user->dccallow = lp;
    204 
    205 	sendnumeric(client, RPL_DCCSTATUS, optr->name, "added to");
    206 	return 0;
    207 }
    208 
    209 /** Removes 'optr' from the DCCALLOW list of 'client' */
    210 int del_dccallow(Client *client, Client *optr)
    211 {
    212 	Link **lpp, *lp;
    213 	int found = 0;
    214 
    215 	for (lpp = &(client->user->dccallow); *lpp; lpp=&((*lpp)->next))
    216 	{
    217 		if ((*lpp)->flags != DCC_LINK_ME)
    218 			continue;
    219 		if ((*lpp)->value.client == optr)
    220 		{
    221 			lp = *lpp;
    222 			*lpp = lp->next;
    223 			free_link(lp);
    224 			found++;
    225 			break;
    226 		}
    227 	}
    228 	if (!found)
    229 	{
    230 		sendnumericfmt(client, RPL_DCCINFO, ":%s is not in your DCC allow list", optr->name);
    231 		return 0;
    232 	}
    233 
    234 	for (found = 0, lpp = &(optr->user->dccallow); *lpp; lpp=&((*lpp)->next))
    235 	{
    236 		if ((*lpp)->flags != DCC_LINK_REMOTE)
    237 			continue;
    238 		if ((*lpp)->value.client == client)
    239 		{
    240 			lp = *lpp;
    241 			*lpp = lp->next;
    242 			free_link(lp);
    243 			found++;
    244 			break;
    245 		}
    246 	}
    247 	if (!found)
    248 	{
    249 		unreal_log(ULOG_WARNING, "dccallow", "BUG_DCCALLOW", client,
    250 		           "[BUG] DCCALLOW list for $client did not contain $target",
    251 		           log_data_client("target", optr));
    252 	}
    253 
    254 	sendnumeric(client, RPL_DCCSTATUS, optr->name, "removed from");
    255 
    256 	return 0;
    257 }