Atrinik Server 2.5
server/ban.c
Go to the documentation of this file.
00001 /************************************************************************
00002 *            Atrinik, a Multiplayer Online Role Playing Game            *
00003 *                                                                       *
00004 *    Copyright (C) 2009-2011 Alex Tokar and Atrinik Development Team    *
00005 *                                                                       *
00006 * Fork from Daimonin (Massive Multiplayer Online Role Playing Game)     *
00007 * and Crossfire (Multiplayer game for X-windows).                       *
00008 *                                                                       *
00009 * This program is free software; you can redistribute it and/or modify  *
00010 * it under the terms of the GNU General Public License as published by  *
00011 * the Free Software Foundation; either version 2 of the License, or     *
00012 * (at your option) any later version.                                   *
00013 *                                                                       *
00014 * This program is distributed in the hope that it will be useful,       *
00015 * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00017 * GNU General Public License for more details.                          *
00018 *                                                                       *
00019 * You should have received a copy of the GNU General Public License     *
00020 * along with this program; if not, write to the Free Software           *
00021 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.             *
00022 *                                                                       *
00023 * The author can be reached at admin@atrinik.org                        *
00024 ************************************************************************/
00025 
00039 #include <global.h>
00040 
00042 static objectlink *ban_list = NULL;
00043 
00048 static void add_ban_entry(char *name, char *ip)
00049 {
00050     objectlink *ol = get_objectlink();
00051     _ban_struct *gptr = (_ban_struct *) get_poolchunk(pool_bans);
00052 
00053     memset(gptr, 0, sizeof(_ban_struct));
00054     ol->objlink.ban = gptr;
00055 
00056     ol->objlink.ban->ip = strdup_local(ip);
00057     FREE_AND_COPY_HASH(ol->objlink.ban->name, name);
00058     objectlink_link(&ban_list, NULL, NULL, ban_list, ol);
00059 }
00060 
00064 static void remove_ban_entry(objectlink *ol)
00065 {
00066     free(ol->objlink.ban->ip);
00067     FREE_AND_CLEAR_HASH(ol->objlink.ban->name);
00068     objectlink_unlink(&ban_list, NULL, ol);
00069     return_poolchunk(ol->objlink.ban, pool_bans);
00070     return_poolchunk(ol, pool_objectlink);
00071 }
00072 
00075 void load_bans_file()
00076 {
00077     char filename[MAX_BUF], buf[MAX_BUF], name[64], ip[64];
00078     FILE *fp;
00079 
00080     snprintf(filename, sizeof(filename), "%s/%s", settings.localdir, BANFILE);
00081 
00082     if (!(fp = fopen(filename, "r")))
00083     {
00084         return;
00085     }
00086 
00087     while (fgets(buf, sizeof(buf), fp))
00088     {
00089         /* Skip comments and blank lines. */
00090         if (buf[0] == '#' || buf[0] == '\n')
00091         {
00092             continue;
00093         }
00094 
00095         if (sscanf(buf, "%s %s", name, ip) == 2)
00096         {
00097             add_ban_entry(name, ip);
00098         }
00099         else
00100         {
00101             LOG(llevBug, "Malformed line in bans file: %s\n", buf);
00102         }
00103     }
00104 
00105     fclose(fp);
00106 }
00107 
00110 void save_bans_file()
00111 {
00112     char filename[MAX_BUF];
00113     FILE *fp;
00114     objectlink *ol;
00115 
00116     snprintf(filename, sizeof(filename), "%s/%s", settings.localdir, BANFILE);
00117 
00118     if (!(fp = fopen(filename, "w")))
00119     {
00120         LOG(llevBug, "Cannot open %s for writing.\n", filename);
00121         return;
00122     }
00123 
00124     for (ol = ban_list; ol; ol = ol->next)
00125     {
00126         fprintf(fp, "%s %s\n", ol->objlink.ban->name, ol->objlink.ban->ip);
00127     }
00128 
00129     fclose(fp);
00130 }
00131 
00137 int checkbanned(const char *name, char *ip)
00138 {
00139     objectlink *ol;
00140 
00141     for (ol = ban_list; ol; ol = ol->next)
00142     {
00143         int name_matches = name && (ol->objlink.ban->name[0] == '*' || ol->objlink.ban->name == name);
00144 
00145         if ((name_matches || ol->objlink.ban->name[0] == '*') && (ol->objlink.ban->ip[0] == '*' || strstr(ip, ol->objlink.ban->ip) || !strcmp(ip, ol->objlink.ban->ip)))
00146         {
00147             return 1;
00148         }
00149     }
00150 
00151     return 0;
00152 }
00153 
00159 int add_ban(char *input)
00160 {
00161     char *tmp[2];
00162 
00163     if (split_string(input, tmp, sizeof(tmp) / sizeof(*tmp), ':') != 2 || *tmp[1] == '\0')
00164     {
00165         return 0;
00166     }
00167 
00168     /* IPs with ':' in them will be impossible to remove once added. */
00169     if (strstr(tmp[1], ":"))
00170     {
00171         return 0;
00172     }
00173 
00174     add_ban_entry(tmp[0], tmp[1]);
00175     save_bans_file();
00176     return 1;
00177 }
00178 
00184 int remove_ban(char *input)
00185 {
00186     char *tmp[2];
00187     objectlink *ol;
00188 
00189     if (split_string(input, tmp, sizeof(tmp) / sizeof(*tmp), ':') != 2 || *tmp[1] == '\0')
00190     {
00191         return 0;
00192     }
00193 
00194     for (ol = ban_list; ol; ol = ol->next)
00195     {
00196         if (!strcmp(ol->objlink.ban->name, tmp[0]) && !strcmp(ol->objlink.ban->ip, tmp[1]))
00197         {
00198             remove_ban_entry(ol);
00199             save_bans_file();
00200             return 1;
00201         }
00202     }
00203 
00204     return 0;
00205 }
00206 
00211 void list_bans(object *op)
00212 {
00213     objectlink *ol;
00214 
00215     if (op)
00216     {
00217         new_draw_info(0, COLOR_WHITE, op, "List of bans:");
00218     }
00219     else
00220     {
00221         LOG(llevInfo, "List of bans:\n");
00222     }
00223 
00224     for (ol = ban_list; ol; ol = ol->next)
00225     {
00226         if (op)
00227         {
00228             new_draw_info_format(0, COLOR_WHITE, op, "%s:%s", ol->objlink.ban->name, ol->objlink.ban->ip);
00229         }
00230         else
00231         {
00232             LOG(llevInfo, "%s:%s\n", ol->objlink.ban->name, ol->objlink.ban->ip);
00233         }
00234     }
00235 }