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 }