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

📄 databasefs.c

📁 Save you music Database in MySQL
💻 C
📖 第 1 页 / 共 2 页
字号:
/***************************************************************************** * DatabaseFS - Copyright Eric Lorimer (5/02) * * DatabaseFS is a samba VFS module connecting to a MySQL database and allowing * dynamic database browsing * * see the file README for some explanation of how it works. *   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 "config.h"#include <stdio.h>#include <sys/stat.h>#include <utime.h>#include <dirent.h>#include <fcntl.h>#include <errno.h>#include <string.h>#include <includes.h>#include <vfs.h>#include "mysql.h"#include "shortcut.h"#include "musicdb.h"//static struct vfs_ops default_vfs_ops;   /* For passthrough operation *///static struct smb_vfs_handle_struct *musicdb_handle;extern userdom_struct current_user_info;MYSQL mysql;/*************************************************************************** * int musicdb_connect * * connect to the mysql database mp3 as user samba * *************************************************************************///static int musicdb_connect(struct connection_struct *conn, const char *service,//	const char *user)    static int musicdb_connect(struct vfs_handle_struct *musicdb_handle,	struct connection_struct *conn, const char *service, const char *user)    {	char *username, *password;	int entries, i = 0;	struct musicdb_ctx *mydata;	report_mem_usage("connect");	/* start out by initializing our private data */	mydata = (struct musicdb_ctx *)MALLOC(sizeof(struct musicdb_ctx));	mydata->memory = talloc_init("musicdb");	mydata->dtable = talloc(mydata->memory, sizeof(struct dirtbl));	musicdb_handle->data = mydata;	parse_config(lp_parm_const_string(SNUM(conn), musicdb_handle->param, "config_file", "databasefs.conf"));	username = get_string_option("user");	password = get_string_option("password");	if ( !(mydata->sock = mysql_connect(&mysql, NULL, username, password)) ) {		DEBUG(1, ("mysql_connect failed for user %s.\n", username));		return -1;	}	if ( mysql_select_db(mydata->sock, get_string_option("database")) ) {		DEBUG(1, ("mysql_select_db failed.\n"));		return -1;	}	/* load dirtbl into memory */	mydata->dtable->rows = (struct dirtbl_row *)				talloc(mydata->memory, sizeof(struct dirtbl_row) * DIRTBL_ROWS);	mydata->dtable->size = DIRTBL_ROWS;	entries = load_dirtbl(mydata->sock, mydata->dtable);	/* hmm... apparently the last mysql_select_db call does not execute fast	 * enough. There must be a better way to check the status of the database	 * before executing the query, but this works for now. big hack */	while ( entries == 0 && i < 5 ) {		entries = load_dirtbl(mydata->sock, mydata->dtable);		i++;	}	/* check that this host name is allowed */	/*	if ( check_black_list(get_remote_machine_name(), mydata->sock) )		smb_panic("User blacklisted.");	*/	/* now initialize the cache */	mydata->cache = (ubi_cacheRoot *)						talloc(mydata->memory, sizeof(ubi_cacheRoot));	if ( mydata->cache == 0 ) {		DEBUG(1, ("musicdb: mydata->cache initialization failed!\n"));		return -1;	}	ubi_cacheInit(mydata->cache, compare_nodes, killnode, CACHE_ENTRIES,			CACHE_ROWS);	/* we set the entry_size as the number of rows */	if ( !module_init() )		smb_panic("FATAL error. unable to initialize module\n");	return 0;}/************************************************************************** * void musicdb_disconnect * * closes the mysql database socket * ************************************************************************/static void musicdb_disconnect(struct vfs_handle_struct *musicdb_handle, struct connection_struct *conn){	struct musicdb_ctx *mydata = (struct musicdb_ctx *)musicdb_handle->data;	ubi_cacheClear(mydata->cache);	mysql_close(mydata->sock);	talloc_destroy(mydata->memory);	cleanup_config();//	SAFE_FREE(mydata);	FREE(mydata);	report_mem_usage("disconnect");	return;}/************************************************************************** * DIR *musicdb_opendir * * open the directory given by fname by executing a SQL statement * ************************************************************************/static DIR *musicdb_opendir(struct vfs_handle_struct *musicdb_handle, struct connection_struct *conn, const char *fname){	struct directory *dirptr =			(struct directory *)MALLOC(sizeof(struct directory));	struct dirtbl_row *drow;	struct strstack stack;	char newfname[128];	struct cache_node *cache_entry;	struct musicdb_ctx *mydata = (struct musicdb_ctx *)musicdb_handle->data;	stack.stackptr = 0;	/* if it doesn't end in a slash, tack one on */	strncpy(newfname, fname, 128);	if ( newfname[strlen(fname)-1] != '/' ) {		newfname[strlen(fname)] = '/';		newfname[strlen(fname)+1] = '\0';	}	if ( !search(1, newfname, &drow, &stack, mydata->dtable) )		return NULL;	if ( drow->subptr != -1 ) {		dirptr->dtable_ptr = dirtbl_search(drow->subptr, mydata->dtable);		dirptr->sdirid = drow->subptr;	} else		dirptr->dtable_ptr = -1;	if ( drow->fileqry[0] == '\0' )		dirptr->filequery = NULL;	else {		pstring filledqry;		replace(drow->fileqry, &stack, filledqry, mydata->sock);		cache_entry = (struct cache_node *)ubi_cacheGet(mydata->cache, filledqry);		if ( cache_entry == NULL ) {			/* couldn't find it in the cache. we have to load it */			dirptr->filequery = (struct song_entry *)					cache_load(SONG, filledqry, mydata->sock, mydata->cache);		} else {			/* found in the cache */			dirptr->filequery = (struct song_entry *)				ubi_slFirst((ubi_slListPtr)cache_entry->data);		}	}	if ( drow->dirqry[0] == '\0' )		dirptr->dirquery = NULL;	else {		pstring filledqry;		replace(drow->dirqry, &stack, filledqry, mydata->sock);		cache_entry = (struct cache_node *)ubi_cacheGet(mydata->cache, filledqry);		if ( cache_entry == NULL ) {			/* couldn't find it in the cache. we have to load it */			dirptr->dirquery = (struct dir_entry *)					cache_load(DDIR, filledqry, mydata->sock, mydata->cache);		} else {			/* found in the cache */			dirptr->dirquery = (struct dir_entry *)				ubi_slFirst((ubi_slListPtr)cache_entry->data);		}	}	return (DIR *)dirptr;}/************************************************************************** * struct dirent *musicdb_readdir * * read and return the directory contents from the mysql result pointer * ************************************************************************/static struct dirent *musicdb_readdir(struct vfs_handle_struct *musicdb_handle, struct connection_struct *conn, DIR *dirp){	struct directory *dirptr = (struct directory *)dirp;	struct musicdb_ctx *mydata = (struct musicdb_ctx *)musicdb_handle->data;	static struct dirent dirbuf; 	struct song_entry *filerow;	int ptr;		memset(&dirbuf, 0, sizeof(struct dirent));		// zero the struct	if ( (filerow = dirptr->filequery) ) {		strncpy(dirbuf.d_name, filerow->fname, 255);		dirptr->filequery = (struct song_entry *)ubi_slNext(dirptr->filequery);		return &dirbuf;	}	if ( dirptr->dirquery ) {		snprintf(dirbuf.d_name, 255, "%s", dirptr->dirquery->template);		dirptr->dirquery = (struct dir_entry *)ubi_slNext(dirptr->dirquery);		return &dirbuf;	}	ptr = dirptr->dtable_ptr;	if ( ptr > -1 && ptr < mydata->dtable->size &&			mydata->dtable->rows[ptr].dirid == dirptr->sdirid) {		snprintf(dirbuf.d_name, 255, "%s", mydata->dtable->rows[ptr].template);		dirbuf.d_name[strlen(dirbuf.d_name) - 1] = '\0';		/* chop the trailing / */		dirptr->dtable_ptr++;		return &dirbuf;	}	return NULL;			// no more data}/************************************************************************** * int musicdb_closedir * * free the mysql result handle for this directory. * ************************************************************************/static int musicdb_closedir(struct vfs_handle_struct *musicdb_handle, struct connection_struct *conn, DIR *dirp){//	SAFE_FREE(dirp);	FREE(dirp);	return 0;}/************************************************************************** * int musicdb_open * * search the directory for the file and then pass it on to the module * ************************************************************************/static int musicdb_open(struct vfs_handle_struct *musicdb_handle, struct connection_struct *conn, const char *fname, int flags, mode_t mode){	char base[512], leaf[128], *ptr;	struct musicdb_ctx *mydata = (struct musicdb_ctx *)musicdb_handle->data;	struct dirtbl_row *drow;	struct strstack sstack;	pstring filledqry;	struct cache_node *cache_entry;	struct song_entry *songs;	sstack.stackptr = 0;	strncpy(base, fname, 512);	if ( (ptr = strrchr(base, '/')) != NULL ) {		strncpy(leaf, ptr+1, 128);		*(ptr+1) = '\0';	} else {		/* is this correct? can we get a stat request for a file with no /? */		strncpy(leaf, base, 128);		strncpy(base, "./", 512);	}	if ( !search(1, base, &drow, &sstack, mydata->dtable)  ) {		errno = ENOENT;		return -1;

⌨️ 快捷键说明

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