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

📄 tdbutil.c

📁 samba-3.0.22.tar.gz 编译smb服务器的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*    Unix SMB/CIFS implementation.   tdb utility functions   Copyright (C) Andrew Tridgell   1992-1998   Copyright (C) Rafal Szczesniak  2002      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., 675 Mass Ave, Cambridge, MA 02139, USA.*/#include "includes.h"#include <fnmatch.h>/* these are little tdb utility functions that are meant to make   dealing with a tdb database a little less cumbersome in Samba */static SIG_ATOMIC_T gotalarm;/*************************************************************** Signal function to tell us we timed out.****************************************************************/static void gotalarm_sig(void){	gotalarm = 1;}/*************************************************************** Make a TDB_DATA and keep the const warning in one place****************************************************************/TDB_DATA make_tdb_data(const char *dptr, size_t dsize){	TDB_DATA ret;	ret.dptr = CONST_DISCARD(char *, dptr);	ret.dsize = dsize;	return ret;}TDB_DATA string_tdb_data(const char *string){	return make_tdb_data(string, strlen(string));}/**************************************************************************** Lock a chain with timeout (in seconds).****************************************************************************/static int tdb_chainlock_with_timeout_internal( TDB_CONTEXT *tdb, TDB_DATA key, unsigned int timeout, int rw_type){	/* Allow tdb_chainlock to be interrupted by an alarm. */	int ret;	gotalarm = 0;	tdb_set_lock_alarm(CONST_DISCARD(sig_atomic_t *, &gotalarm));	if (timeout) {		CatchSignal(SIGALRM, SIGNAL_CAST gotalarm_sig);		alarm(timeout);	}	if (rw_type == F_RDLCK)		ret = tdb_chainlock_read(tdb, key);	else		ret = tdb_chainlock(tdb, key);	if (timeout) {		alarm(0);		CatchSignal(SIGALRM, SIGNAL_CAST SIG_IGN);		if (gotalarm) {			DEBUG(0,("tdb_chainlock_with_timeout_internal: alarm (%u) timed out for key %s in tdb %s\n",				timeout, key.dptr, tdb->name ));			/* TODO: If we time out waiting for a lock, it might			 * be nice to use F_GETLK to get the pid of the			 * process currently holding the lock and print that			 * as part of the debugging message. -- mbp */			return -1;		}	}	return ret;}/**************************************************************************** Write lock a chain. Return -1 if timeout or lock failed.****************************************************************************/int tdb_chainlock_with_timeout( TDB_CONTEXT *tdb, TDB_DATA key, unsigned int timeout){	return tdb_chainlock_with_timeout_internal(tdb, key, timeout, F_WRLCK);}/**************************************************************************** Lock a chain by string. Return -1 if timeout or lock failed.****************************************************************************/int tdb_lock_bystring(TDB_CONTEXT *tdb, const char *keyval, unsigned int timeout){	TDB_DATA key = make_tdb_data(keyval, strlen(keyval)+1);		return tdb_chainlock_with_timeout_internal(tdb, key, timeout, F_WRLCK);}/**************************************************************************** Unlock a chain by string.****************************************************************************/void tdb_unlock_bystring(TDB_CONTEXT *tdb, const char *keyval){	TDB_DATA key = make_tdb_data(keyval, strlen(keyval)+1);	tdb_chainunlock(tdb, key);}/**************************************************************************** Read lock a chain by string. Return -1 if timeout or lock failed.****************************************************************************/int tdb_read_lock_bystring(TDB_CONTEXT *tdb, const char *keyval, unsigned int timeout){	TDB_DATA key = make_tdb_data(keyval, strlen(keyval)+1);		return tdb_chainlock_with_timeout_internal(tdb, key, timeout, F_RDLCK);}/**************************************************************************** Read unlock a chain by string.****************************************************************************/void tdb_read_unlock_bystring(TDB_CONTEXT *tdb, const char *keyval){	TDB_DATA key = make_tdb_data(keyval, strlen(keyval)+1);		tdb_chainunlock_read(tdb, key);}/**************************************************************************** Fetch a int32 value by a arbitrary blob key, return -1 if not found. Output is int32 in native byte order.****************************************************************************/int32 tdb_fetch_int32_byblob(TDB_CONTEXT *tdb, const char *keyval, size_t len){	TDB_DATA key = make_tdb_data(keyval, len);	TDB_DATA data;	int32 ret;	data = tdb_fetch(tdb, key);	if (!data.dptr || data.dsize != sizeof(int32)) {		SAFE_FREE(data.dptr);		return -1;	}	ret = IVAL(data.dptr,0);	SAFE_FREE(data.dptr);	return ret;}/**************************************************************************** Fetch a int32 value by string key, return -1 if not found. Output is int32 in native byte order.****************************************************************************/int32 tdb_fetch_int32(TDB_CONTEXT *tdb, const char *keystr){	return tdb_fetch_int32_byblob(tdb, keystr, strlen(keystr) + 1);}/**************************************************************************** Store a int32 value by an arbitary blob key, return 0 on success, -1 on failure. Input is int32 in native byte order. Output in tdb is in little-endian.****************************************************************************/int tdb_store_int32_byblob(TDB_CONTEXT *tdb, const char *keystr, size_t len, int32 v){	TDB_DATA key = make_tdb_data(keystr, len);	TDB_DATA data;	int32 v_store;	SIVAL(&v_store,0,v);	data.dptr = (void *)&v_store;	data.dsize = sizeof(int32);	return tdb_store(tdb, key, data, TDB_REPLACE);}/**************************************************************************** Store a int32 value by string key, return 0 on success, -1 on failure. Input is int32 in native byte order. Output in tdb is in little-endian.****************************************************************************/int tdb_store_int32(TDB_CONTEXT *tdb, const char *keystr, int32 v){	return tdb_store_int32_byblob(tdb, keystr, strlen(keystr) + 1, v);}/**************************************************************************** Fetch a uint32 value by a arbitrary blob key, return -1 if not found. Output is uint32 in native byte order.****************************************************************************/BOOL tdb_fetch_uint32_byblob(TDB_CONTEXT *tdb, const char *keyval, size_t len, uint32 *value){	TDB_DATA key = make_tdb_data(keyval, len);	TDB_DATA data;	data = tdb_fetch(tdb, key);	if (!data.dptr || data.dsize != sizeof(uint32)) {		SAFE_FREE(data.dptr);		return False;	}	*value = IVAL(data.dptr,0);	SAFE_FREE(data.dptr);	return True;}/**************************************************************************** Fetch a uint32 value by string key, return -1 if not found. Output is uint32 in native byte order.****************************************************************************/BOOL tdb_fetch_uint32(TDB_CONTEXT *tdb, const char *keystr, uint32 *value){	return tdb_fetch_uint32_byblob(tdb, keystr, strlen(keystr) + 1, value);}/**************************************************************************** Store a uint32 value by an arbitary blob key, return 0 on success, -1 on failure. Input is uint32 in native byte order. Output in tdb is in little-endian.****************************************************************************/BOOL tdb_store_uint32_byblob(TDB_CONTEXT *tdb, const char *keystr, size_t len, uint32 value){	TDB_DATA key = make_tdb_data(keystr, len);	TDB_DATA data;	uint32 v_store;	BOOL ret = True;	SIVAL(&v_store, 0, value);	data.dptr = (void *)&v_store;	data.dsize = sizeof(uint32);	if (tdb_store(tdb, key, data, TDB_REPLACE) == -1)		ret = False;	return ret;}/**************************************************************************** Store a uint32 value by string key, return 0 on success, -1 on failure. Input is uint32 in native byte order. Output in tdb is in little-endian.****************************************************************************/BOOL tdb_store_uint32(TDB_CONTEXT *tdb, const char *keystr, uint32 value){	return tdb_store_uint32_byblob(tdb, keystr, strlen(keystr) + 1, value);}/**************************************************************************** Store a buffer by a null terminated string key.  Return 0 on success, -1 on failure.****************************************************************************/int tdb_store_bystring(TDB_CONTEXT *tdb, const char *keystr, TDB_DATA data, int flags){	TDB_DATA key = make_tdb_data(keystr, strlen(keystr)+1);		return tdb_store(tdb, key, data, flags);}/**************************************************************************** Fetch a buffer using a null terminated string key.  Don't forget to call free() on the result dptr.****************************************************************************/TDB_DATA tdb_fetch_bystring(TDB_CONTEXT *tdb, const char *keystr){	TDB_DATA key = make_tdb_data(keystr, strlen(keystr)+1);	return tdb_fetch(tdb, key);}/**************************************************************************** Delete an entry using a null terminated string key. ****************************************************************************/int tdb_delete_bystring(TDB_CONTEXT *tdb, const char *keystr){	TDB_DATA key = make_tdb_data(keystr, strlen(keystr)+1);	return tdb_delete(tdb, key);}/**************************************************************************** Atomic integer change. Returns old value. To create, set initial value in *oldval. ****************************************************************************/int32 tdb_change_int32_atomic(TDB_CONTEXT *tdb, const char *keystr, int32 *oldval, int32 change_val){	int32 val;	int32 ret = -1;	if (tdb_lock_bystring(tdb, keystr,0) == -1)		return -1;	if ((val = tdb_fetch_int32(tdb, keystr)) == -1) {		/* The lookup failed */		if (tdb_error(tdb) != TDB_ERR_NOEXIST) {			/* but not because it didn't exist */			goto err_out;		}				/* Start with 'old' value */		val = *oldval;	} else {		/* It worked, set return value (oldval) to tdb data */		*oldval = val;	}	/* Increment value for storage and return next time */	val += change_val;			if (tdb_store_int32(tdb, keystr, val) == -1)		goto err_out;	ret = 0;  err_out:	tdb_unlock_bystring(tdb, keystr);	return ret;}/**************************************************************************** Atomic unsigned integer change. Returns old value. To create, set initial value in *oldval. ****************************************************************************/BOOL tdb_change_uint32_atomic(TDB_CONTEXT *tdb, const char *keystr, uint32 *oldval, uint32 change_val){	uint32 val;	BOOL ret = False;	if (tdb_lock_bystring(tdb, keystr,0) == -1)		return False;	if (!tdb_fetch_uint32(tdb, keystr, &val)) {		/* It failed */		if (tdb_error(tdb) != TDB_ERR_NOEXIST) { 			/* and not because it didn't exist */			goto err_out;		}		/* Start with 'old' value */		val = *oldval;	} else {		/* it worked, set return value (oldval) to tdb data */		*oldval = val;	}	/* get a new value to store */	val += change_val;			if (!tdb_store_uint32(tdb, keystr, val))		goto err_out;	ret = True;  err_out:	tdb_unlock_bystring(tdb, keystr);	return ret;}/**************************************************************************** Useful pair of routines for packing/unpacking data consisting of integers and strings.****************************************************************************/size_t tdb_pack_va(char *buf, int bufsize, const char *fmt, va_list ap){	uint8 bt;	uint16 w;	uint32 d;	int i;	void *p;	int len;	char *s;	char c;	char *buf0 = buf;	const char *fmt0 = fmt;	int bufsize0 = bufsize;	while (*fmt) {		switch ((c = *fmt++)) {		case 'b': /* unsigned 8-bit integer */			len = 1;			bt = (uint8)va_arg(ap, int);			if (bufsize && bufsize >= len)				SSVAL(buf, 0, bt);			break;		case 'w': /* unsigned 16-bit integer */			len = 2;			w = (uint16)va_arg(ap, int);			if (bufsize && bufsize >= len)				SSVAL(buf, 0, w);			break;		case 'd': /* signed 32-bit integer (standard int in most systems) */			len = 4;			d = va_arg(ap, uint32);			if (bufsize && bufsize >= len)				SIVAL(buf, 0, d);			break;		case 'p': /* pointer */			len = 4;			p = va_arg(ap, void *);			d = p?1:0;			if (bufsize && bufsize >= len)				SIVAL(buf, 0, d);			break;		case 'P': /* null-terminated string */			s = va_arg(ap,char *);			w = strlen(s);			len = w + 1;			if (bufsize && bufsize >= len)				memcpy(buf, s, len);

⌨️ 快捷键说明

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