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

📄 cddb.c

📁 xmms-1.2.10.tar.gz学习使用的就下吧
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *  cddb.c  Copyright 1999-2003 Haavard Kvaalen <havardk@xmms.org> * * *  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. */#include "cddb.h"#include "http.h"#include "cdaudio.h"#include "cdinfo.h"#include <libxmms/util.h>#include <gtk/gtk.h>#include <stdarg.h>#include <dirent.h>#include <pthread.h>#include "xmms/i18n.h"static guint32 cached_id = 0;static GtkWidget *server_dialog, *server_clist;static GtkWidget *debug_window, *debug_clist;static GList *debug_messages = NULL;static GList *temp_messages = NULL;static pthread_mutex_t list_mutex = PTHREAD_MUTEX_INITIALIZER;static guint cddb_timeout_id;void configure_set_cddb_server(gchar *server);static void cddb_log(gchar *str, ...){	static GList *end_ptr = NULL;	static gint message_num = 0;	va_list args;	char *text;	va_start(args, str);	text = g_strdup_vprintf(str, args);	va_end(args);	message_num++;	debug_messages = g_list_prepend(debug_messages, text);	if (!end_ptr)		end_ptr = debug_messages;	if (message_num > CDDB_LOG_MAX)	{		GList *temp;				temp = g_list_previous(end_ptr);		temp->next = NULL;		g_free(end_ptr->data);		g_list_free_1(end_ptr);		end_ptr = temp;		message_num--;	}	if (debug_window)	{		pthread_mutex_lock(&list_mutex);		temp_messages = g_list_append(temp_messages, g_strdup(text));		pthread_mutex_unlock(&list_mutex);	}}static gint cddb_sum(gint in){	gint retval = 0;	while (in > 0)	{		retval += in % 10;		in /= 10;	}	return retval;}guint32 cdda_cddb_compute_discid(cdda_disc_toc_t *info){	gint i;	guint high = 0, low;	for (i = info->first_track; i <= info->last_track; i++)		high += cddb_sum(info->track[i].minute * 60 + info->track[i].second);	low = (info->leadout.minute * 60 + info->leadout.second) -		(info->track[info->first_track].minute * 60 +		 info->track[info->first_track].second);	return ((high % 0xff) << 24 | low << 8 | (info->last_track - info->first_track + 1));}static char * cddb_generate_offset_string(cdda_disc_toc_t *info){	char *buffer;	int i;	buffer = g_malloc(info->last_track * 7 + 1);	sprintf(buffer, "%d", LBA(info->track[info->first_track]));	for (i = info->first_track + 1; i <= info->last_track; i++)		sprintf(buffer, "%s+%d", buffer, LBA(info->track[i]));	return buffer;}static gchar * cddb_generate_hello_string(void){	static char *buffer;	if (buffer == NULL)	{		char *env, *client = NULL, *version = NULL, **strs = NULL;		env = getenv("XMMS_CDDB_CLIENT_NAME");		if (env)		{			strs = g_strsplit(env, " ", 2);			if (strs && strs[0] && strs[1])			{				client = strs[0];				version = strs[1];			}		}		if (!client || !version)		{			client = PACKAGE;			version = VERSION;		}				buffer = g_strdup_printf("&hello=nobody+localhost+%s+%s",					 client, version);		if (strs)			g_strfreev(strs);	}	return buffer;}static gint cddb_http_open_connection(gchar * server, gint port){	gint sock;	gchar *status;		if((sock = http_open_connection(server, 80)) == 0)		status = "Failed";	else		status = "Ok";		cddb_log("Connecting to CDDB-server %s: %s", server, status);	return sock;}static gboolean cddb_query(gchar *server, cdda_disc_toc_t *info, cddb_disc_header_t *cddb_info){	/*	 * Query the cddb-server for the cd.	 * Returns the *real* diskid and category.	 */		gint sock;	gchar *offsets, *getstr;	gchar buffer[256];	gchar **response;	gint i;	if((sock = cddb_http_open_connection(server, 80)) == 0)		return FALSE;	offsets = cddb_generate_offset_string(info);	cddb_log("Sending query-command. Disc ID: %08x", cdda_cddb_compute_discid(info));	getstr = g_strdup_printf(		"GET /~cddb/cddb.cgi?cmd=cddb+query+%08x+%d+%s+%d%s&proto=%d HTTP/1.0\r\n\r\n",		cdda_cddb_compute_discid(info), info->last_track - info->first_track + 1,		offsets, (info->leadout.minute * 60 + info->leadout.second),		cddb_generate_hello_string(), cdda_cfg.cddb_protocol_level);	g_free(offsets);	write(sock, getstr, strlen(getstr));	g_free(getstr);	if (http_read_first_line(sock, buffer, 256) < 0)	{		http_close_connection(sock);		return FALSE;	}	http_close_connection(sock);	response = g_strsplit(buffer, " ", 4);	cddb_log("Query response: %s", buffer);	switch(strtol(response[0], NULL, 10))	{		case 200:			/* One exact match */			for (i = 0; i < 4; i++)			{				if (response[i] == NULL)				{					g_strfreev(response);					return FALSE;				}			}			cddb_info->category = g_strdup(response[1]);			cddb_info->discid = strtoul(response[2], NULL, 16);			break;		default: /* FIXME: Handle other 2xx */			g_strfreev(response);			return FALSE;	}	g_strfreev(response);	return TRUE;}static gint cddb_check_protocol_level(gchar *server){	int level = 0, sock, n;	char *str, buffer[256];	if((sock = cddb_http_open_connection(server, 80)) == 0)		return 0;			str = g_strdup_printf(		"GET /~cddb/cddb.cgi?cmd=stat%s&proto=1 HTTP/1.0\r\n\r\n",		cddb_generate_hello_string());			write(sock, str, strlen(str));	g_free(str);		if ((n = http_read_first_line(sock, buffer, 256)) < 0 ||	    atoi(buffer) != 210)	{		if (n > 0)			cddb_log("Getting cddb protocol level failed: %s",				 buffer);		else			cddb_log("Getting cddb protocol level failed.");					http_close_connection(sock);		return 0;	}	while (http_read_line(sock, buffer, 256) >= 0)	{		g_strstrip(buffer);		if (!strncmp(buffer, "max proto:", 10))			level = atoi(buffer + 10);		if (!strcmp(buffer, "."))			break;	}	http_close_connection(sock);	cddb_log("Getting cddb protocol level. Got level %d", level);	return (MIN(level, CDDB_MAX_PROTOCOL_LEVEL));}#define BUF2SIZE (80*3)static gboolean cddb_read(gchar *server, cddb_disc_header_t *cddb_info, cdinfo_t *cdinfo){	gint sock;	gchar *readstr;	gchar buffer[256], buffer2[BUF2SIZE];	gchar *realstr, *temp;	gint len, command, bufs;	gint num, oldnum;		if((sock = cddb_http_open_connection(server, 80)) == 0)		return FALSE;	cddb_log("Sending read-command. Disc ID: %08x. Category: %s",		 cddb_info->discid, cddb_info->category);	readstr = g_strdup_printf(		"GET /~cddb/cddb.cgi?cmd=cddb+read+%s+%08x%s&proto=%d HTTP/1.0\r\n\r\n",		cddb_info->category, cddb_info->discid, cddb_generate_hello_string(),		cdda_cfg.cddb_protocol_level);	write(sock, readstr, strlen(readstr));	g_free(readstr);	if (http_read_first_line(sock, buffer, 256) < 0)	{		http_close_connection(sock);		return FALSE;	}	cddb_log("Read response: %s", buffer);	command = 1;	bufs = 0;	oldnum = -1;	do {/*  		fprintf(stderr,"%s\n",buffer); */		realstr = strchr(buffer, '=');  		if (buffer[0] == '#' || !realstr)  			continue;		realstr++;		len = strlen(realstr);				switch (command) {			case 1:				if (!strncmp(buffer, "DISCID", 6))					break;				command++;			case 2:				if (!strncmp(buffer, "DTITLE", 6))				{					strncpy(buffer2 + bufs, realstr, BUF2SIZE - bufs);					bufs += len;					break;				}				if (bufs > 0)				{					buffer2[BUF2SIZE-1] = '\0';					if ((temp = strstr(buffer2, " / ")) != NULL)					{						cdda_cdinfo_cd_set(cdinfo, g_strdup(temp+3), g_strndup(buffer2, temp-buffer2));					}					else						cdda_cdinfo_cd_set(cdinfo, g_strdup(buffer2), g_strdup(buffer2));					bufs = 0;				}				command++;			case 3:				if (!strncmp(buffer, "TTITLE", 6))				{

⌨️ 快捷键说明

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