⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 account.c

📁 打魔兽战网的都知道他是什么
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * 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. */#define ACCOUNT_INTERNAL_ACCESS#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>#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#include "compat/pdir.h"#include "common/list.h"#include "common/elist.h"#include "common/eventlog.h"#include "prefs.h"#include "common/util.h"#include "common/field_sizes.h"#include "common/bnethash.h"#include "common/introtate.h"#include "account.h"#include "account_wrap.h"#include "common/hashtable.h"#include "connection.h"#include "watch.h"#include "friends.h"#include "team.h"#include "common/tag.h"#include "ladder.h"#include "clan.h"#include "server.h"#include "attrgroup.h"#include "attrlayer.h"#include "storage.h"#include "common/flags.h"#include "common/xalloc.h"#ifdef HAVE_ASSERT_H# include <assert.h>#endif#include "common/setup_after.h"static t_hashtable * accountlist_head=NULL;static t_hashtable * accountlist_uid_head=NULL;unsigned int maxuserid=0;/* This is to force the creation of all accounts when we initially load the accountlist. */static int force_account_add=0;static unsigned int account_hash(char const * username);static t_account * account_load(t_attrgroup *);static int account_load_friends(t_account * account);static int account_unload_friends(t_account * account);static void account_destroy(t_account * account);static t_account * accountlist_add_account(t_account * account);static unsigned int account_hash(char const *username){    register unsigned int h;    register unsigned int len = strlen(username);    for (h = 5381; len > 0; --len, ++username) {        h += h << 5;	if (isupper((int) *username) == 0)	    h ^= *username;	else	    h ^= tolower((int) *username);    }    return h;}static t_account * account_create(char const * username, char const * passhash1){    t_account * account;        if (username && !passhash1) {	eventlog(eventlog_level_error,__FUNCTION__,"got NULL passhash1");	return NULL;    }    if (username && account_check_name(username)) {	eventlog(eventlog_level_error,__FUNCTION__,"got invalid chars in username");	return NULL;    }    account = xmalloc(sizeof(t_account));    account->name     = NULL;    account->clanmember = NULL;    account->attrgroup   = NULL;    account->friends  = NULL;    account->teams    = NULL;    account->conn = NULL;    FLAG_ZERO(&account->flags);    account->namehash = 0; /* hash it later before inserting */    account->uid      = 0; /* hash it later before inserting */    if (username) { /* actually making a new account */	/* first check if such a username already owns an account.	 * we search in the memory hash mainly for non-indexed storage types.	 * indexed storage types check themselves if the username exists already 	 * in the storage (see storage_sql.c) */	if (accountlist_find_account(username)) {		eventlog(eventlog_level_debug,__FUNCTION__,"user \"%s\" already has an account",username);		goto err;	}	account->attrgroup =  attrgroup_create_newuser(username);	if(!account->attrgroup) {	    eventlog(eventlog_level_error,__FUNCTION__,"failed to add user");	    goto err;	}	account->name = xstrdup(username);        if (account_set_strattr(account,"BNET\\acct\\username",username)<0) {            eventlog(eventlog_level_error,__FUNCTION__,"could not set username");            goto err;        }        if (account_set_numattr(account,"BNET\\acct\\userid",maxuserid+1)<0) {            eventlog(eventlog_level_error,__FUNCTION__,"could not set userid");            goto err;        }	if (account_set_strattr(account,"BNET\\acct\\passhash1",passhash1)<0) {            eventlog(eventlog_level_error,__FUNCTION__,"could not set passhash1");            goto err;        }        if (account_set_numattr(account,"BNET\\acct\\ctime",(unsigned int)now)) {            eventlog(eventlog_level_error,__FUNCTION__,"could not set ctime");            goto err;        }    }    return account;err:    account_destroy(account);    return NULL;}static void account_destroy(t_account * account){    assert(account);    friendlist_close(account->friends);    teams_destroy(account->teams);    if (account->attrgroup)    	attrgroup_destroy(account->attrgroup);    if (account->name)        xfree(account->name);    xfree(account);}extern unsigned int account_get_uid(t_account const * account){    if (!account) {	eventlog(eventlog_level_error,__FUNCTION__,"got NULL account");	return 0;    }    return account->uid;}extern int account_match(t_account * account, char const * username){    unsigned int userid=0;    unsigned int namehash;    char const * tname;        if (!account)    {	eventlog(eventlog_level_error,__FUNCTION__,"got NULL account");	return -1;    }    if (!username)    {	eventlog(eventlog_level_error,__FUNCTION__,"got NULL username");	return -1;    }        if (username[0]=='#')        if (str_to_uint(&username[1],&userid)<0)            userid = 0;        if (userid)    {        if (account->uid==userid)            return 1;    }    else    {	namehash = account_hash(username);        if (account->namehash==namehash &&	    (tname = account_get_name(account)))	{	    if (strcasecmp(tname,username)==0)		return 1;	}    }        return 0;}extern int account_save(t_account * account, unsigned flags){    assert(account);    return attrgroup_save(account->attrgroup, flags);}extern int account_flush(t_account * account, unsigned flags){    int res;    assert(account);    res = attrgroup_flush(account->attrgroup, flags);    if (res<0) return res;    account_unload_friends(account);    return res;}extern char const * account_get_strattr_real(t_account * account, char const * key, char const * fn, unsigned int ln){    if (!account) {	eventlog(eventlog_level_error,__FUNCTION__,"got NULL account (from %s:%u)",fn,ln);	return NULL;    }    if (!key) {	eventlog(eventlog_level_error,__FUNCTION__,"got NULL key (from %s:%u)",fn,ln);	return NULL;    }    return attrgroup_get_attr(account->attrgroup, key);}extern int account_set_strattr(t_account * account, char const * key, char const * val){    if (!account) {	eventlog(eventlog_level_error,__FUNCTION__,"got NULL account");	return -1;    }    if (!key) {	eventlog(eventlog_level_error,__FUNCTION__,"got NULL key");	return -1;    }    return attrgroup_set_attr(account->attrgroup, key, val);}static t_account * account_load(t_attrgroup *attrgroup){    t_account * account;    assert(attrgroup);    if (!(account = account_create(NULL,NULL))) {	eventlog(eventlog_level_error,__FUNCTION__,"could not create account");	return NULL;    }    account->attrgroup = attrgroup;    return account;}static t_account * account_load_new(char const * name, unsigned uid){    t_account *account;    t_attrgroup *attrgroup;    if (name && account_check_name(name)) return NULL;    force_account_add = 1; /* disable the protection */    attrgroup = attrgroup_create_nameuid(name, uid);    if (!attrgroup) {	force_account_add = 0;	return NULL;    }    if (!(account = account_load(attrgroup))) {        eventlog(eventlog_level_error, __FUNCTION__,"could not load account");        attrgroup_destroy(attrgroup);	force_account_add = 0;        return NULL;    }    if (!accountlist_add_account(account)) {        eventlog(eventlog_level_error, __FUNCTION__,"could not add account to list");        account_destroy(account);	force_account_add = 0;        return NULL;    }    force_account_add = 0;    return account;}static int _cb_read_accounts(t_attrgroup *attrgroup, void *data){    unsigned int *count = (unsigned int *)data;    t_account *account;    if (!(account = account_load(attrgroup))) {        eventlog(eventlog_level_error, __FUNCTION__,"could not load account");	attrgroup_destroy(attrgroup);        return -1;    }    if (!accountlist_add_account(account)) {        eventlog(eventlog_level_error, __FUNCTION__,"could not add account to list");        account_destroy(account);        return -1;    }    /* might as well free up the memory since we probably won't need it */    account_flush(account,FS_FORCE); /* force unload */    (*count)++;    return 0;}extern int accountlist_load_all(int flag){    unsigned int count;    int starttime = time(NULL);    static int loaded = 0; /* all accounts already loaded ? */    int res;    if (loaded) return 0;    count = 0;    res = 0;    force_account_add = 1; /* disable the protection */    switch(attrgroup_read_accounts(flag, _cb_read_accounts, &count))    {	case -1:    	    eventlog(eventlog_level_error, __FUNCTION__,"got error reading users");    	    res = -1;	    break;	case 0: 	    loaded = 1;	    eventlog(eventlog_level_info, __FUNCTION__, "loaded %u user accounts in %ld seconds",count,time(NULL) - starttime);	    break;	default:	    break;    }    force_account_add = 0; /* enable the protection */    return res;}extern int accountlist_create(void){    eventlog(eventlog_level_info, __FUNCTION__, "started creating accountlist");        if (!(accountlist_head = hashtable_create(prefs_get_hashtable_size())))    {        eventlog(eventlog_level_error, __FUNCTION__, "could not create accountlist_head");	return -1;    }        if (!(accountlist_uid_head = hashtable_create(prefs_get_hashtable_size())))    {        eventlog(eventlog_level_error, __FUNCTION__, "could not create accountlist_uid_head");	return -1;    }    /* load accounts without force, indexed storage types wont be loading */    accountlist_load_all(ST_NONE);    maxuserid = storage->read_maxuserid();    return 0;}extern int accountlist_destroy(void){    t_entry *   curr;    t_account * account;    HASHTABLE_TRAVERSE(accountlist_head,curr)    {	if (!(account = entry_get_data(curr)))	    eventlog(eventlog_level_error,__FUNCTION__,"found NULL account in list");	else	{	    if (account_flush(account, FS_FORCE)<0)		eventlog(eventlog_level_error,__FUNCTION__,"could not save account");	    account_destroy(account);	}	hashtable_remove_entry(accountlist_head,curr);    }    HASHTABLE_TRAVERSE(accountlist_uid_head,curr)    {	    hashtable_remove_entry(accountlist_head,curr);    }    if (hashtable_destroy(accountlist_head)<0)	return -1;    accountlist_head = NULL;    if (hashtable_destroy(accountlist_uid_head)<0)	return -1;    accountlist_uid_head = NULL;    return 0;}extern t_hashtable * accountlist(void){    return accountlist_head;}extern t_hashtable * accountlist_uid(void){    return accountlist_uid_head;}extern unsigned int accountlist_get_length(void){    return hashtable_get_length(accountlist_head);}extern int accountlist_save(unsigned flags){    return attrlayer_save(flags);}extern int accountlist_flush(unsigned flags){    return attrlayer_flush(flags);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -