305 lines
4.6 KiB
C
305 lines
4.6 KiB
C
/************************************************************************
|
|
* ban.c
|
|
* voxelands - 3d voxel world sandbox game
|
|
* Copyright (C) Lisa 'darkrose' Milne 2016 <lisa@ltmnet.com>
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful, but
|
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
* See the GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
|
************************************************************************/
|
|
|
|
#include "common.h"
|
|
#include "ban.h"
|
|
|
|
#include "file.h"
|
|
#include "thread.h"
|
|
#include "nvp.h"
|
|
#include "list.h"
|
|
#include "path.h"
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
static struct {
|
|
char* file;
|
|
mutex_t *mutex;
|
|
nvp_t *data;
|
|
char modified;
|
|
} ban = {
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
0
|
|
};
|
|
|
|
/* init ban system for the given file */
|
|
int ban_init(char* file)
|
|
{
|
|
char* path;
|
|
if (!ban.mutex) {
|
|
ban.mutex = mutex_create();
|
|
if (!ban.mutex)
|
|
return -1;
|
|
}
|
|
|
|
path = path_get("world",file,0,NULL,0);
|
|
if (!path)
|
|
return -1;
|
|
|
|
if (ban.file) {
|
|
if (!strcmp(ban.file,path)) {
|
|
free(path);
|
|
ban_load();
|
|
return 0;
|
|
}
|
|
if (ban.file)
|
|
free(ban.file);
|
|
ban.file = NULL;
|
|
|
|
nvp_free(&ban.data,1);
|
|
ban.data = NULL;
|
|
}
|
|
|
|
ban.file = path;
|
|
ban.modified = 0;
|
|
|
|
ban_load();
|
|
|
|
return 0;
|
|
}
|
|
|
|
/* free ban memory, reset ban struct */
|
|
void ban_exit()
|
|
{
|
|
if (!ban.mutex)
|
|
return;
|
|
|
|
if (ban.modified)
|
|
ban_save();
|
|
|
|
mutex_free(ban.mutex);
|
|
ban.mutex = NULL;
|
|
|
|
if (ban.file)
|
|
free(ban.file);
|
|
ban.file = NULL;
|
|
|
|
nvp_free(&ban.data,1);
|
|
ban.data = NULL;
|
|
|
|
ban.modified = 0;
|
|
}
|
|
|
|
/* load ban data from file */
|
|
void ban_load()
|
|
{
|
|
file_t *f;
|
|
char line[512];
|
|
char* n;
|
|
char* p;
|
|
|
|
mutex_lock(ban.mutex);
|
|
|
|
f = file_load(NULL,ban.file);
|
|
if (!f) {
|
|
mutex_unlock(ban.mutex);
|
|
return;
|
|
}
|
|
|
|
while (file_readline(f,line,512) > 0) {
|
|
|
|
p = line;
|
|
n = strchr(p,'|');
|
|
if (!n)
|
|
continue;
|
|
*n = 0;
|
|
n++;
|
|
|
|
if (!p[0])
|
|
continue;
|
|
|
|
nvp_set(&ban.data,p,n,NULL);
|
|
}
|
|
|
|
mutex_unlock(ban.mutex);
|
|
|
|
file_free(f);
|
|
|
|
ban.modified = 0;
|
|
}
|
|
|
|
/* save ban data to file */
|
|
void ban_save()
|
|
{
|
|
file_t *f;
|
|
nvp_t *n;
|
|
|
|
if (!ban.modified)
|
|
return;
|
|
|
|
mutex_lock(ban.mutex);
|
|
|
|
f = file_create(NULL,ban.file);
|
|
if (!f)
|
|
return;
|
|
|
|
for (n=ban.data; n; n = n->next) {
|
|
if (!n->name || !n->name[0])
|
|
continue;
|
|
file_writef(f,"%s|%s\n",n->name,n->value);
|
|
}
|
|
|
|
file_flush(f);
|
|
|
|
mutex_unlock(ban.mutex);
|
|
|
|
file_free(f);
|
|
|
|
ban.modified = 0;
|
|
}
|
|
|
|
/* check if an ip address is banned */
|
|
int ban_ipbanned(char* ip)
|
|
{
|
|
nvp_t *n;
|
|
mutex_lock(ban.mutex);
|
|
|
|
n = nvp_get(&ban.data,ip);
|
|
|
|
mutex_unlock(ban.mutex);
|
|
|
|
if (n)
|
|
return 1;
|
|
return 0;
|
|
}
|
|
|
|
/* get the discription of a ban, NULL for all */
|
|
int ban_description(char* ip_or_name, char* buff, int size)
|
|
{
|
|
nvp_t *n;
|
|
int o = 0;
|
|
if (!buff || !size)
|
|
return -1;
|
|
|
|
buff[0] = 0;
|
|
|
|
if (!ip_or_name) {
|
|
char b1[256];
|
|
int c = 0;
|
|
int k;
|
|
|
|
mutex_lock(ban.mutex);
|
|
|
|
for (n=ban.data; n; n=n->next) {
|
|
k = snprintf(b1,256,"%s|%s",n->name,n->value);
|
|
if (k >= 256)
|
|
continue;
|
|
if (k+o+3 >= size)
|
|
break;
|
|
if (c) {
|
|
buff[o++] = ',';
|
|
buff[o++] = ' ';
|
|
buff[o] = 0;
|
|
}
|
|
if (!strcpy(buff+o,b1))
|
|
break;
|
|
o += k;
|
|
c++;
|
|
}
|
|
|
|
mutex_unlock(ban.mutex);
|
|
|
|
buff[o] = 0;
|
|
|
|
return c;
|
|
}
|
|
|
|
mutex_lock(ban.mutex);
|
|
|
|
n = nvp_get(&ban.data,ip_or_name);
|
|
|
|
if (!n) {
|
|
n = ban.data;
|
|
while (n) {
|
|
if (!strcmp(n->value,ip_or_name))
|
|
break;
|
|
n = n->next;
|
|
}
|
|
}
|
|
|
|
mutex_unlock(ban.mutex);
|
|
|
|
if (!n)
|
|
return 0;
|
|
|
|
o = snprintf(buff,size,"%s|%s",n->name,n->value);
|
|
if (o >= size)
|
|
return -1;
|
|
|
|
return 1;
|
|
}
|
|
|
|
/* get the name for a given ip ban */
|
|
char* ban_ip2name(char* ip)
|
|
{
|
|
char* n;
|
|
|
|
mutex_lock(ban.mutex);
|
|
|
|
n = nvp_get_str(&ban.data,ip);
|
|
|
|
mutex_unlock(ban.mutex);
|
|
|
|
return n;
|
|
}
|
|
|
|
/* add a new ban */
|
|
void ban_add(char* ip, char* name)
|
|
{
|
|
mutex_lock(ban.mutex);
|
|
|
|
nvp_set(&ban.data,ip,name,NULL);
|
|
|
|
mutex_unlock(ban.mutex);
|
|
}
|
|
|
|
/* remove an existing ban */
|
|
void ban_remove(char* ip_or_name)
|
|
{
|
|
nvp_t *n;
|
|
mutex_lock(ban.mutex);
|
|
|
|
n = nvp_get(&ban.data,ip_or_name);
|
|
|
|
if (!n) {
|
|
for (n=ban.data; n; n=n->next) {
|
|
if (!strcmp(n->value,ip_or_name))
|
|
break;
|
|
}
|
|
if (!n) {
|
|
mutex_unlock(ban.mutex);
|
|
return;
|
|
}
|
|
}
|
|
|
|
ban.data = list_remove(&ban.data,n);
|
|
|
|
mutex_unlock(ban.mutex);
|
|
|
|
if (n->name)
|
|
free(n->name);
|
|
if (n->value)
|
|
free(n->value);
|
|
free(n);
|
|
}
|