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

📄 dir.c

📁 samba最新软件
💻 C
字号:
/*   Unix SMB/CIFS implementation.   Registry interface   Copyright (C) Jelmer Vernooij				  2004-2007.   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 "includes.h"#include "registry.h"#include "system/dir.h"#include "system/filesys.h"struct dir_key {	struct hive_key key;	const char *path;};static struct hive_operations reg_backend_dir;static WERROR reg_dir_add_key(TALLOC_CTX *mem_ctx,			      const struct hive_key *parent,			      const char *name, const char *classname,			      struct security_descriptor *desc,			      struct hive_key **result){	struct dir_key *dk = talloc_get_type(parent, struct dir_key);	char *path;	int ret;	path = talloc_asprintf(mem_ctx, "%s/%s", dk->path, name);	ret = mkdir(path, 0700);	if (ret == 0) {		struct dir_key *key = talloc(mem_ctx, struct dir_key);		key->key.ops = &reg_backend_dir;		key->path = talloc_steal(key, path);		*result = (struct hive_key *)key;		return WERR_OK;	}	if (errno == EEXIST)		return WERR_ALREADY_EXISTS;	printf("FAILED %s BECAUSE: %s\n", path, strerror(errno));	return WERR_GENERAL_FAILURE;}static WERROR reg_dir_delete_recursive(const char *name){	DIR *d;	struct dirent *e;	WERROR werr;	d = opendir(name);	if (d == NULL) {		DEBUG(3,("Unable to open '%s': %s\n", name,		      strerror(errno)));		return WERR_BADFILE;	}	while((e = readdir(d))) {		char *path;		struct stat stbuf;		if (ISDOT(e->d_name) || ISDOTDOT(e->d_name))			continue;		path = talloc_asprintf(name, "%s/%s", name, e->d_name);		if (!path)			return WERR_NOMEM;		stat(path, &stbuf);		if (!S_ISDIR(stbuf.st_mode)) {			if (unlink(path) < 0) {				talloc_free(path);				closedir(d);				return WERR_GENERAL_FAILURE;			}		} else {			werr = reg_dir_delete_recursive(path);			if (!W_ERROR_IS_OK(werr)) {				talloc_free(path);				closedir(d);				return werr;			}		}		talloc_free(path);	}	closedir(d);	if (rmdir(name) == 0)		return WERR_OK;	else if (errno == ENOENT)		return WERR_BADFILE;	else		return WERR_GENERAL_FAILURE;}static WERROR reg_dir_del_key(const struct hive_key *k, const char *name){	struct dir_key *dk = talloc_get_type(k, struct dir_key);	char *child = talloc_asprintf(NULL, "%s/%s", dk->path, name);	WERROR ret;	ret = reg_dir_delete_recursive(child);	talloc_free(child);	return ret;}static WERROR reg_dir_open_key(TALLOC_CTX *mem_ctx,			       const struct hive_key *parent,			       const char *name, struct hive_key **subkey){	DIR *d;	char *fullpath;	const struct dir_key *p = talloc_get_type(parent, struct dir_key);	struct dir_key *ret;	if (name == NULL) {		DEBUG(0, ("NULL pointer passed as directory name!"));		return WERR_INVALID_PARAM;	}	fullpath = talloc_asprintf(mem_ctx, "%s/%s", p->path, name);	d = opendir(fullpath);	if (d == NULL) {		DEBUG(3,("Unable to open '%s': %s\n", fullpath,			strerror(errno)));		return WERR_BADFILE;	}	closedir(d);	ret = talloc(mem_ctx, struct dir_key);	ret->key.ops = &reg_backend_dir;	ret->path = talloc_steal(ret, fullpath);	*subkey = (struct hive_key *)ret;	return WERR_OK;}static WERROR reg_dir_key_by_index(TALLOC_CTX *mem_ctx,				   const struct hive_key *k, uint32_t idx,				   const char **name,				   const char **classname,				   NTTIME *last_mod_time){	struct dirent *e;	const struct dir_key *dk = talloc_get_type(k, struct dir_key);	int i = 0;	DIR *d;	d = opendir(dk->path);	if (d == NULL)		return WERR_INVALID_PARAM;	while((e = readdir(d))) {		if(!ISDOT(e->d_name) && !ISDOTDOT(e->d_name)) {			struct stat stbuf;			char *thispath;			/* Check if file is a directory */			asprintf(&thispath, "%s/%s", dk->path, e->d_name);			stat(thispath, &stbuf);			if (!S_ISDIR(stbuf.st_mode)) {				SAFE_FREE(thispath);				continue;			}			if (i == idx) {				struct stat st;				*name = talloc_strdup(mem_ctx, e->d_name);				*classname = NULL;				stat(thispath, &st);				unix_to_nt_time(last_mod_time, st.st_mtime);				SAFE_FREE(thispath);				closedir(d);				return WERR_OK;			}			i++;			SAFE_FREE(thispath);		}	}	closedir(d);	return WERR_NO_MORE_ITEMS;}WERROR reg_open_directory(TALLOC_CTX *parent_ctx,			  const char *location, struct hive_key **key){	struct dir_key *dk;	if (location == NULL)		return WERR_INVALID_PARAM;	dk = talloc(parent_ctx, struct dir_key);	dk->key.ops = &reg_backend_dir;	dk->path = talloc_strdup(dk, location);	*key = (struct hive_key *)dk;	return WERR_OK;}WERROR reg_create_directory(TALLOC_CTX *parent_ctx,			    const char *location, struct hive_key **key){	if (mkdir(location, 0700) != 0) {		*key = NULL;		return WERR_GENERAL_FAILURE;	}	return reg_open_directory(parent_ctx, location, key);}static WERROR reg_dir_get_info(TALLOC_CTX *ctx, const struct hive_key *key,			       const char **classname,			       uint32_t *num_subkeys,			       uint32_t *num_values,			       NTTIME *lastmod,			       uint32_t *max_subkeynamelen,			       uint32_t *max_valnamelen,			       uint32_t *max_valbufsize){	DIR *d;	const struct dir_key *dk = talloc_get_type(key, struct dir_key);	struct dirent *e;	struct stat st;	SMB_ASSERT(key != NULL);	if (classname != NULL)		*classname = NULL;	d = opendir(dk->path);	if (d == NULL)		return WERR_INVALID_PARAM;	if (num_subkeys != NULL)		*num_subkeys = 0;	if (num_values != NULL)		*num_values = 0;	if (max_subkeynamelen != NULL)		*max_subkeynamelen = 0;	if (max_valnamelen != NULL)		*max_valnamelen = 0;	if (max_valbufsize != NULL)		*max_valbufsize = 0;	while((e = readdir(d))) {		if(!ISDOT(e->d_name) && !ISDOTDOT(e->d_name)) {			char *path = talloc_asprintf(ctx, "%s/%s",						     dk->path, e->d_name);			if (stat(path, &st) < 0) {				DEBUG(0, ("Error statting %s: %s\n", path,					strerror(errno)));				continue;			}			if (S_ISDIR(st.st_mode)) {				if (num_subkeys != NULL)					(*num_subkeys)++;				if (max_subkeynamelen != NULL)					*max_subkeynamelen = MAX(*max_subkeynamelen, strlen(e->d_name));			}			if (!S_ISDIR(st.st_mode)) {				if (num_values != NULL)					(*num_values)++;				if (max_valnamelen != NULL)					*max_valnamelen = MAX(*max_valnamelen, strlen(e->d_name));				if (max_valbufsize != NULL)					*max_valbufsize = MAX(*max_valbufsize, st.st_size);			}			talloc_free(path);		}	}	closedir(d);	if (lastmod != NULL)		*lastmod = 0;	return WERR_OK;}static WERROR reg_dir_set_value(struct hive_key *key, const char *name,				uint32_t type, const DATA_BLOB data){	const struct dir_key *dk = talloc_get_type(key, struct dir_key);	char *path = talloc_asprintf(dk, "%s/%s", dk->path, name);	if (!file_save(path, data.data, data.length))		return WERR_GENERAL_FAILURE;	/* FIXME: Type */	return WERR_OK;}static WERROR reg_dir_get_value(TALLOC_CTX *mem_ctx,				struct hive_key *key, const char *name,				uint32_t *type, DATA_BLOB *data){	const struct dir_key *dk = talloc_get_type(key, struct dir_key);	char *path = talloc_asprintf(mem_ctx, "%s/%s", dk->path, name);	size_t size;	char *contents;	contents = file_load(path, &size, mem_ctx);	talloc_free(path);	if (contents == NULL)		return WERR_BADFILE;	if (type != NULL)		*type = 4; /* FIXME */	data->data = (uint8_t *)contents;	data->length = size;	return WERR_OK;}static WERROR reg_dir_enum_value(TALLOC_CTX *mem_ctx,				 struct hive_key *key, int idx,				 const char **name,				 uint32_t *type, DATA_BLOB *data){	const struct dir_key *dk = talloc_get_type(key, struct dir_key);	DIR *d;	struct dirent *e;	int i;	d = opendir(dk->path);	if (d == NULL) {		DEBUG(3,("Unable to open '%s': %s\n", dk->path,			strerror(errno)));		return WERR_BADFILE;	}	i = 0;	while((e = readdir(d))) {		if (ISDOT(e->d_name) || ISDOTDOT(e->d_name))			continue;		if (i == idx) {			if (name != NULL)				*name = talloc_strdup(mem_ctx, e->d_name);			W_ERROR_NOT_OK_RETURN(reg_dir_get_value(mem_ctx, key,								*name, type,								data));			return WERR_OK;		}		i++;	}	closedir(d);	return WERR_NO_MORE_ITEMS;}static WERROR reg_dir_del_value (struct hive_key *key, const char *name){	const struct dir_key *dk = talloc_get_type(key, struct dir_key);	char *path = talloc_asprintf(key, "%s/%s", dk->path, name);	if (unlink(path) < 0) {		talloc_free(path);		if (errno == ENOENT)			return WERR_BADFILE;		return WERR_GENERAL_FAILURE;	}	talloc_free(path);	return WERR_OK;}static struct hive_operations reg_backend_dir = {	.name = "dir",	.get_key_by_name = reg_dir_open_key,	.get_key_info = reg_dir_get_info,	.add_key = reg_dir_add_key,	.del_key = reg_dir_del_key,	.enum_key = reg_dir_key_by_index,	.set_value = reg_dir_set_value,	.get_value_by_name = reg_dir_get_value,	.enum_value = reg_dir_enum_value,	.delete_value = reg_dir_del_value,};

⌨️ 快捷键说明

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