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

📄 accessory.c

📁 Save you music Database in MySQL
💻 C
字号:
/************************************************************************* * MusicDB - Copyright Eric Lorimer (5/02) * * This file hold accessory functions related to MusicDB. *   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"#include "ubi_sLinkList.h"#define DIRTBL_SQL		"SELECT * FROM dirtbl WHERE uname=\"%s\" ORDER BY dirid, priority"extern userdom_struct current_user_info;/*************************************************************************** * int replace * * fill in the template given by source using the stack and return it into * dest * *************************************************************************/int replace(const char *source, struct strstack *stack, pstring dest, MYSQL *mysql){	char *uname = current_user_info.smb_name;	const char *remote;	enum { COPY, PARAM } state = COPY;	char buffer[6];	int i, cur_parm, bindex = 0;	fstring replaced;	char replaced2[512];	for (i=0; i < strlen(source); i++) {		switch (state) {			case COPY:				if ( source[i] != '$' )					*dest++ = source[i];				else state = PARAM;				break;			case PARAM:				if ( source[i] > '9' || source[i] < '0' ) {					buffer[bindex] = '\0';					if ( buffer[0] == '\0' ) {						switch (source[i]) {							case 'U':		/* user name */								pstrcpy(dest, uname);								dest += strlen(uname);								break;							case 'I':		/* remote host ip address */								pstrcpy(dest, client_name());								dest += strlen(client_name());								break;							case 'N':		/* host name */								remote = get_remote_machine_name();								pstrcpy(dest, remote);								dest += strlen(remote);								break;							default:								*dest++ = source[i];								break;						}					} else {						cur_parm = atoi(buffer);						stack_get(stack, cur_parm, replaced);						mysql_real_escape_string(mysql, replaced2, replaced,								strlen(replaced));						pstrcpy(dest, replaced2);						dest += strlen(replaced2);						*dest++ = source[i];					}					bindex = 0;					state = COPY;				} else					buffer[bindex++] = source[i];				break;		}	}	*dest = '\0';	return 1;}/************************************************************************** * int template_match * * try to match a directory path against a template. * ************************************************************************/int template_match(const char *template, const char *dpath, fstring buffer){	int i;	int len = (strlen(dpath) > 256) ? 256 : strlen(dpath);	for (i=0; i < len && template[i] == dpath[i]; i++)		*buffer++ = dpath[i];	if ( template[i] == '%' ) {		char stopch = template[i+1];		for (; i < len && dpath[i] != stopch; i++)			*buffer++ = dpath[i];		if ( dpath[i] == stopch ) i++;	} else		buffer--;	*buffer = '\0';	return i;}/************************************************************************** * int search * * recursive function to search for a directory. uses the global dtable * ************************************************************************/int search(int dirid, const char *dpath, struct dirtbl_row **drow, struct strstack *stack, struct dirtbl *dtable){	fstring matchstr;	int matched = 0, i;	i = dirtbl_search(dirid, dtable);	if ( i == -1 )		return 0;	while ( i < dtable->size && dtable->rows[i].dirid == dirid ) {		int nmatched = template_match(dtable->rows[i].template, dpath,				matchstr);		if ( nmatched >= strlen(dtable->rows[i].template) ) {		// FIX			stack_push(stack, matchstr);			matched = 1;			if ( dtable->rows[i].subptr != -1 ) {				dpath += nmatched;				if ( *dpath )					return search(dtable->rows[i].subptr, dpath, drow, stack, dtable);				*drow = &dtable->rows[i];				return 1;			} else {				if ( nmatched == strlen(dpath) ) {					*drow = &dtable->rows[i];					return 1;				}				return 0;			}		}		i++;	}	return 0;}/************************************************************************** * int load_dirtbl * * load the entire dirtbl into memory to speed up searches * ************************************************************************/int load_dirtbl(MYSQL *sock, struct dirtbl *dtable){	MYSQL_RES *res;	MYSQL_ROW myrow;	int i = 0;	struct dirtbl_row *dirtbl = dtable->rows;	char SQL[256];		snprintf(SQL, 256, DIRTBL_SQL, current_user_info.smb_name);	if ( MYSQL_QUERY(sock, SQL) ) {		DEBUG(3, ("MYSQL_QUERY failed loading dirtbl: %s\n", SQL));		return 0;	}	res = mysql_store_result(sock);	if ( !res || (mysql_num_rows(res) == 0) ) {		/* no such user; fall back to the defaults */		snprintf(SQL, 256, DIRTBL_SQL, "*");		if ( MYSQL_QUERY(sock, SQL) ) {			DEBUG(3, ("MYSQL_QUERY failed loading dirtbl: %s\n", SQL));			return 0;		}		res = mysql_store_result(sock);	}	if ( ! res ) {		DEBUG(3, ("musicdb could not load dirtbl defaults.\n"));		return 0;	}	while ( (myrow = mysql_fetch_row(res)) && i < dtable->size ) {		dirtbl[i].dirid = atoi(myrow[1]);		if ( myrow[2] ) strncpy(dirtbl[i].template, myrow[2], 128);			else dirtbl[i].template[0] = '\0';		if ( myrow[3] ) dirtbl[i].subptr = atoi(myrow[3]);			else dirtbl[i].subptr = -1;		if ( myrow[4] ) strncpy(dirtbl[i].fileqry, myrow[4], 1024);			else dirtbl[i].fileqry[0] = '\0';		if ( myrow[5] ) strncpy(dirtbl[i].dirqry, myrow[5], 1024);			else dirtbl[i].dirqry[0] = '\0';		if ( myrow[7] ) dirtbl[i].visible = myrow[7][0];			else dirtbl[i].visible = 'F';		i++;	}	mysql_free_result(res);	return i;}/************************************************************************** * int dirtbl_search * * search for the given dirid from the dtable. Linear search. Easy to make * binary search for better performance, but we don't have enough directory * entries to make it worth it. * ************************************************************************/int dirtbl_search(int dirid, struct dirtbl *dtable){	/* for now we'll do a linear search. Implement binary search later */	int i;	for (i=0; i < dtable->size; i++)		if ( dtable->rows[i].dirid == dirid )			return i;	return -1;}/************************************************************************** * int MYSQL_QUERY * * wrapper around mysql_query to do some basic profiling * ************************************************************************/int MYSQL_QUERY(MYSQL *sock, const char *query){	char SQL[1024];	char *uname = current_user_info.smb_name;	DEBUG(3, ("MYSQL_QUERY: %s\n", query));	snprintf(SQL, 1024, "INSERT INTO logs VALUES ('%s', NOW(), '%s')", uname,			query);	mysql_query(sock, SQL);	return mysql_query(sock, query);}/************************************************************************** * int compare_nodes * * function used by the cache to compare items and keys in nodes * ************************************************************************/int compare_nodes(ubi_btItemPtr item, ubi_btNodePtr node){	return strcmp((char *)item, ((struct cache_node *)node)->key);}/************************************************************************** * void killnode * * function used by the cache to cleanup cache nodes. Goes through the * linked list and deletes each entry. * ************************************************************************/void killnode(ubi_trNodePtr thenode){	struct cache_node *node = (struct cache_node *)thenode;	struct dir_entry *dnode;	struct song_entry *snode;	int i;		/* go through the linked list and free all memory */	switch (node->type) {		case DDIR:			while ( (dnode = (struct dir_entry *)ubi_slRemHead(node->data)) ) {				FREE(dnode->template);				FREE(dnode);			}			break;		case SONG:			while ( (snode = (struct song_entry *)ubi_slRemHead(node->data)) ) {				for (i=0; i < snode->nfields; i++)					FREE(snode->fields[i]);				FREE(snode);			}			break;	}	FREE(node->data);	FREE(node->key);	FREE(node);	return;}/************************************************************************** * ubi_slNodePtr cache_load * * load the specified query and add it to the cache. return a pointer to * the linked-list of data * ************************************************************************/ubi_slNodePtr cache_load(cachetype type, char *query, MYSQL *sock,	ubi_cacheRoot *cache){	int count;	ubi_slListPtr newlist;	struct cache_node *cache_entry;	newlist = (ubi_slListPtr)MALLOC(sizeof(ubi_slList));	switch (type) {		case SONG:			count = load_song_query(newlist, query, sock);			break;		default:			count = load_dir_query(newlist, query, sock);	}	if ( count == 0 ) {		FREE(newlist);		return NULL;	}	/* and add it to the cache */	cache_entry = (struct cache_node *)MALLOC(sizeof(struct cache_node));	cache_entry->type = type;	cache_entry->key = strdup(query);	STRDUP();	cache_entry->data = newlist;	ubi_cachePut(cache, count, (ubi_cacheEntryPtr)cache_entry,		(ubi_trItemPtr)cache_entry->key);	return ubi_slFirst(newlist);}

⌨️ 快捷键说明

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