?? storage_file.c
字號:
/* * Copyright (C) 1998,1999,2000,2001 Ross Combs (rocombs@cs.nmsu.edu) * Copyright (C) 2000,2001 Marco Ziech (mmz@gmx.net) * Copyright (C) 2002,2003,2004 Dizzy * * 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 2 * 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, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */#include "common/setup_before.h"#include <stdio.h>#ifdef HAVE_STDDEF_H# include <stddef.h>#else# ifndef NULL# define NULL ((void *)0)# endif#endif#ifdef STDC_HEADERS# include <stdlib.h>#else# ifdef HAVE_MALLOC_H# include <malloc.h># endif#endif#ifdef HAVE_STRING_H# include <string.h>#else# ifdef HAVE_STRINGS_H# include <strings.h># endif#endif#include "compat/strchr.h"#include "compat/strdup.h"#include "compat/strcasecmp.h"#include "compat/strncasecmp.h"#include <ctype.h>#ifdef HAVE_LIMITS_H# include <limits.h>#endif#include "compat/char_bit.h"#ifdef TIME_WITH_SYS_TIME# include <sys/time.h># include <time.h>#else# ifdef HAVE_SYS_TIME_H# include <sys/time.h># else# include <time.h># endif#endif#include <errno.h>#include "compat/strerror.h"#ifdef HAVE_SYS_TYPES_H# include <sys/types.h>#endif#ifdef HAVE_UNISTD_H# include <unistd.h>#endif#include "compat/access.h"#include "compat/rename.h"#include "compat/pdir.h"#include "common/eventlog.h"#include "prefs.h"#include "common/util.h"#include "common/field_sizes.h"#include "common/bnethash.h"#define CLAN_INTERNAL_ACCESS#define TEAM_INTERNAL_ACCESS#include "common/introtate.h"#include "team.h"#include "account.h"#include "common/hashtable.h"#include "storage.h"#include "storage_file.h"#include "file_plain.h"#include "file_cdb.h"#include "common/list.h"#include "connection.h"#include "watch.h"#include "clan.h"#undef ACCOUNT_INTERNAL_ACCESS#undef TEAM_INTERNAL_ACCESS#undef CLAN_INTERNAL_ACCESS#include "common/tag.h"#include "common/xalloc.h"#include "common/elist.h"#include "common/setup_after.h"/* file storage API functions */static int file_init(const char *);static int file_close(void);static unsigned file_read_maxuserid(void);static t_storage_info *file_create_account(char const *);static t_storage_info *file_get_defacct(void);static int file_free_info(t_storage_info *);static int file_read_attrs(t_storage_info *, t_read_attr_func, void *);static t_attr *file_read_attr(t_storage_info *, const char *);static int file_write_attrs(t_storage_info *, const t_hlist *);static int file_read_accounts(int,t_read_accounts_func, void *);static t_storage_info *file_read_account(const char *, unsigned);static int file_cmp_info(t_storage_info *, t_storage_info *);static const char *file_escape_key(const char *);static int file_load_clans(t_load_clans_func);static int file_write_clan(void *);static int file_remove_clan(int);static int file_remove_clanmember(int);static int file_load_teams(t_load_teams_func);static int file_write_team(void *);static int file_remove_team(unsigned int);/* storage struct populated with the functions above */t_storage storage_file = { file_init, file_close, file_read_maxuserid, file_create_account, file_get_defacct, file_free_info, file_read_attrs, file_write_attrs, file_read_attr, file_read_accounts, file_read_account, file_cmp_info, file_escape_key, file_load_clans, file_write_clan, file_remove_clan, file_remove_clanmember, file_load_teams, file_write_team, file_remove_team};/* start of actual file storage code */static const char *accountsdir = NULL;static const char *clansdir = NULL;static const char *teamsdir = NULL;static const char *defacct = NULL;static t_file_engine *file = NULL;static unsigned file_read_maxuserid(void){ return maxuserid;}static int file_init(const char *path){ char *tok, *copy, *tmp, *p; const char *dir = NULL; const char *clan = NULL; const char *team = NULL; const char *def = NULL; const char *driver = NULL; if (path == NULL || path[0] == '\0') { eventlog(eventlog_level_error, __FUNCTION__, "got NULL or empty path"); return -1; } copy = xstrdup(path); tmp = copy; while ((tok = strtok(tmp, ";")) != NULL) { tmp = NULL; if ((p = strchr(tok, '=')) == NULL) { eventlog(eventlog_level_error, __FUNCTION__, "invalid storage_path, no '=' present in token"); xfree((void *) copy); return -1; } *p = '\0'; if (strcasecmp(tok, "dir") == 0) dir = p + 1; else if (strcasecmp(tok, "clan") == 0) clan = p + 1; else if (strcasecmp(tok, "team") == 0) team = p + 1; else if (strcasecmp(tok, "default") == 0) def = p + 1; else if (strcasecmp(tok, "mode") == 0) driver = p + 1; else eventlog(eventlog_level_warn, __FUNCTION__, "unknown token in storage_path : '%s'", tok); } if (def == NULL || clan == NULL || team == NULL || dir == NULL || driver == NULL) { eventlog(eventlog_level_error, __FUNCTION__, "invalid storage_path line for file module (doesnt have a 'dir', a 'clan', a 'team', a 'default' token and a 'mode' token)"); xfree((void *) copy); return -1; } if (!strcasecmp(driver, "plain")) file = &file_plain; else if (!strcasecmp(driver, "cdb")) file = &file_cdb; else { eventlog(eventlog_level_error, __FUNCTION__, "unknown mode '%s' must be either plain or cdb", driver); xfree((void *) copy); return -1; } if (accountsdir) file_close(); accountsdir = xstrdup(dir); clansdir = xstrdup(clan); teamsdir = xstrdup(team); defacct = xstrdup(def); xfree((void *) copy); return 0;}static int file_close(void){ if (accountsdir) xfree((void *) accountsdir); accountsdir = NULL; if (clansdir) xfree((void *) clansdir); clansdir = NULL; if (teamsdir) xfree((void *) teamsdir); teamsdir = NULL; if (defacct) xfree((void *) defacct); defacct = NULL; file = NULL; return 0;}static t_storage_info *file_create_account(const char *username){ char *temp; if (accountsdir == NULL || file == NULL) { eventlog(eventlog_level_error, __FUNCTION__, "file storage not initilized"); return NULL; } if (prefs_get_savebyname()) { char const *safename; if (!strcmp(username, defacct)) { eventlog(eventlog_level_error, __FUNCTION__, "username as defacct not allowed"); return NULL; } if (!(safename = escape_fs_chars(username, strlen(username)))) { eventlog(eventlog_level_error, __FUNCTION__, "could not escape username"); return NULL; } temp = xmalloc(strlen(accountsdir) + 1 + strlen(safename) + 1); /* dir + / + name + NUL */ sprintf(temp, "%s/%s", accountsdir, safename); xfree((void *) safename); /* avoid warning */ } else { temp = xmalloc(strlen(accountsdir) + 1 + 8 + 1); /* dir + / + uid + NUL */ sprintf(temp, "%s/%06u", accountsdir, maxuserid + 1); /* FIXME: hmm, maybe up the %06 to %08... */ } return temp;}static int file_write_attrs(t_storage_info * info, const t_hlist *attributes){ char *tempname; if (accountsdir == NULL || file == NULL) { eventlog(eventlog_level_error, __FUNCTION__, "file storage not initilized"); return -1; } if (info == NULL) { eventlog(eventlog_level_error, __FUNCTION__, "got NULL info storage"); return -1; } if (attributes == NULL) { eventlog(eventlog_level_error, __FUNCTION__, "got NULL attributes"); return -1; } tempname = xmalloc(strlen(accountsdir) + 1 + strlen(BNETD_ACCOUNT_TMP) + 1); sprintf(tempname, "%s/%s", accountsdir, BNETD_ACCOUNT_TMP); if (file->write_attrs(tempname, attributes)) { /* no eventlog here, it should be reported from the file layer */ xfree(tempname); return -1; } if (p_rename(tempname, (const char *) info) < 0) { eventlog(eventlog_level_error, __FUNCTION__, "could not rename account file to \"%s\" (rename: %s)", (char *) info, pstrerror(errno)); xfree(tempname); return -1; } xfree(tempname); return 0;}static int file_read_attrs(t_storage_info * info, t_read_attr_func cb, void *data){ if (accountsdir == NULL || file == NULL) { eventlog(eventlog_level_error, __FUNCTION__, "file storage not initilized"); return -1; } if (info == NULL) { eventlog(eventlog_level_error, __FUNCTION__, "got NULL info storage"); return -1; } if (cb == NULL) { eventlog(eventlog_level_error, __FUNCTION__, "got NULL callback"); return -1; } eventlog(eventlog_level_debug, __FUNCTION__, "loading \"%s\"", (char *) info); if (file->read_attrs((const char *) info, cb, data)) { /* no eventlog, error reported earlier */ return -1; } return 0;}static t_attr *file_read_attr(t_storage_info * info, const char *key){ if (accountsdir == NULL || file == NULL) { eventlog(eventlog_level_error, __FUNCTION__, "file storage not initilized"); return NULL; } if (info == NULL) { eventlog(eventlog_level_error, __FUNCTION__, "got NULL info storage"); return NULL; } if (key == NULL) { eventlog(eventlog_level_error, __FUNCTION__, "got NULL key"); return NULL; } return file->read_attr((const char *) info, key);}static int file_free_info(t_storage_info * info){ if (info) xfree((void *) info); return 0;}static t_storage_info *file_get_defacct(void){ t_storage_info *info; if (defacct == NULL) { eventlog(eventlog_level_error, __FUNCTION__, "file storage not initilized"); return NULL; } info = xstrdup(defacct); return info;}static int file_read_accounts(int flag,t_read_accounts_func cb, void *data){ char const *dentry; char *pathname; t_pdir *accountdir; if (accountsdir == NULL) { eventlog(eventlog_level_error, __FUNCTION__, "file storage not initilized"); return -1; } if (cb == NULL) { eventlog(eventlog_level_error, __FUNCTION__, "got NULL callback"); return -1; } if (!(accountdir = p_opendir(accountsdir))) { eventlog(eventlog_level_error, __FUNCTION__, "unable to open user directory \"%s\" for reading (p_opendir: %s)", accountsdir, pstrerror(errno)); return -1; } while ((dentry = p_readdir(accountdir))) { if (dentry[0] == '.') continue; pathname = xmalloc(strlen(accountsdir) + 1 + strlen(dentry) + 1); /* dir + / + file + NUL */ sprintf(pathname, "%s/%s", accountsdir, dentry); cb(pathname, data); } if (p_closedir(accountdir) < 0) eventlog(eventlog_level_error, __FUNCTION__, "unable to close user directory \"%s\" (p_closedir: %s)", accountsdir, pstrerror(errno)); return 0;}static t_storage_info *file_read_account(const char *accname, unsigned uid){ char *pathname; if (accountsdir == NULL) {
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -