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

📄 stream_cddb.c

📁 君正早期ucos系统(只有早期的才不没有打包成库),MPLAYER,文件系统,图片解码,浏览,电子书,录音,想学ucos,识货的人就下吧 russblock fmradio explore set
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * CDDB HTTP protocol  * by Bertrand Baudet <bertrand_baudet@yahoo.com> * (C) 2002, MPlayer team. * * Implementation follow the freedb.howto1.06.txt specification * from http://freedb.freedb.org *  * discid computation by Jeremy D. Zawodny *	 Copyright (c) 1998-2000 Jeremy D. Zawodny <Jeremy@Zawodny.com> *	 Code release under GPL * */#include "config.h"#include <mplaylib.h>#include <mplaylib.h>#include <fcntl.h>#include <stdarg.h>#include <errno.h>#include <mplaylib.h>#include <mplaylib.h>#ifdef WIN32#ifdef __MINGW32__#define mkdir(a,b) mkdir(a)#endif#include <windows.h>#ifdef HAVE_WINSOCK2#include <winsock2.h>#endif#else#include <netdb.h>#include <sys/ioctl.h>#endif#include <sys/types.h>#include <sys/stat.h>#include "mp_msg.h"#include "help_mp.h"#if defined(__linux__)	#include <linux/cdrom.h>#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__)	#include <sys/cdio.h>#elif defined(WIN32)        #include <ddk/ntddcdrm.h>#elif (__bsdi__)        #include <dvd.h>#endif#include "cdd.h"#include "version.h"#include "stream.h"#include "network.h"#define DEFAULT_FREEDB_SERVER	"freedb.freedb.org"#define DEFAULT_CACHE_DIR	"/.cddb/"stream_t* open_cdda(char *dev, char *track);static cd_toc_t cdtoc[100];static int cdtoc_last_track;int read_toc(const char *dev) {	int first, last;	int i;#ifdef WIN32        HANDLE drive;        DWORD r;        CDROM_TOC toc;        char device[10];        sprintf(device, "\\\\.\\%s", dev);        drive = CreateFile(device, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);        if(!DeviceIoControl(drive, IOCTL_CDROM_READ_TOC, NULL, 0, &toc, sizeof(CDROM_TOC), &r, 0)) {                mp_msg(MSGT_OPEN, MSGL_ERR, MSGTR_MPDEMUX_CDDB_FailedToReadTOC);                return 0;        }        first = toc.FirstTrack - 1; last = toc.LastTrack;        for (i = first; i <= last; i++) {		cdtoc[i].min = toc.TrackData[i].Address[1];		cdtoc[i].sec = toc.TrackData[i].Address[2];		cdtoc[i].frame = toc.TrackData[i].Address[3];        }        CloseHandle(drive);#else	int drive;	drive = open(dev, O_RDONLY | O_NONBLOCK);	if( drive<0 ) {		return drive;	}	#if defined(__linux__) || defined(__bsdi__)	{	struct cdrom_tochdr tochdr;	ioctl(drive, CDROMREADTOCHDR, &tochdr);	first = tochdr.cdth_trk0 - 1; last = tochdr.cdth_trk1;	}	for (i = first; i <= last; i++) {		struct cdrom_tocentry tocentry;		tocentry.cdte_track = (i == last) ? 0xAA : i + 1;		tocentry.cdte_format = CDROM_MSF;		ioctl(drive, CDROMREADTOCENTRY, &tocentry);		cdtoc[i].min = tocentry.cdte_addr.msf.minute;		cdtoc[i].sec = tocentry.cdte_addr.msf.second;		cdtoc[i].frame = tocentry.cdte_addr.msf.frame;	}#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)	{	struct ioc_toc_header tochdr;	ioctl(drive, CDIOREADTOCHEADER, &tochdr);	first = tochdr.starting_track - 1; last = tochdr.ending_track;	}	for (i = first; i <= last; i++) {		struct ioc_read_toc_single_entry tocentry;		tocentry.track = (i == last) ? 0xAA : i + 1;		tocentry.address_format = CD_MSF_FORMAT;		ioctl(drive, CDIOREADTOCENTRY, &tocentry);		cdtoc[i].min = tocentry.entry.addr.msf.minute;		cdtoc[i].sec = tocentry.entry.addr.msf.second;		cdtoc[i].frame = tocentry.entry.addr.msf.frame;	}#elif defined(__NetBSD__) || defined(__OpenBSD__)	{	struct ioc_toc_header tochdr;	ioctl(drive, CDIOREADTOCHEADER, &tochdr);	first = tochdr.starting_track - 1; last = tochdr.ending_track;	}	for (i = first; i <= last; i++) {		struct ioc_read_toc_entry tocentry;		struct cd_toc_entry toc_buffer;		tocentry.starting_track = (i == last) ? 0xAA : i + 1;		tocentry.address_format = CD_MSF_FORMAT;		tocentry.data = &toc_buffer;		tocentry.data_len = sizeof(toc_buffer);		ioctl(drive, CDIOREADTOCENTRYS, &tocentry);		cdtoc[i].min = toc_buffer.addr.msf.minute;		cdtoc[i].sec = toc_buffer.addr.msf.second;		cdtoc[i].frame = toc_buffer.addr.msf.frame;	}#endif	close(drive);#endif	for (i = first; i <= last; i++)	  cdtoc[i].frame += (cdtoc[i].min * 60 + cdtoc[i].sec) * 75;	return last;}/** \brief Reads TOC from CD in the given device and prints the number of tracks       and the length of each track in minute:second:frame format.\param *dev the device to analyse\return if the command line -identify is given, returns the last track of        the TOC or -1 if the TOC can't be read,        otherwise just returns 0 and let cddb_resolve the TOC*/int cdd_identify(const char *dev){	cdtoc_last_track = 0;	if (mp_msg_test(MSGT_IDENTIFY, MSGL_INFO))	{		int i, min, sec, frame;		cdtoc_last_track = read_toc(dev);		if (cdtoc_last_track < 0) {			mp_msg(MSGT_OPEN, MSGL_ERR, MSGTR_MPDEMUX_CDDB_FailedToOpenDevice, dev);			return -1;		}		mp_msg(MSGT_GLOBAL, MSGL_INFO, "ID_CDDA_TRACKS=%d\n", cdtoc_last_track);		for (i = 1; i <= cdtoc_last_track; i++)		{			frame = cdtoc[i].frame - cdtoc[i-1].frame;			sec = frame / 75;			frame -= sec * 75;			min = sec / 60;			sec -= min * 60;			mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_CDDA_TRACK_%d_MSF=%02d:%02d:%02d\n", i, min, sec, frame);		}	}	return cdtoc_last_track;}unsigned int cddb_sum(int n) {	unsigned int ret;	ret = 0;	while (n > 0) {		ret += (n % 10);		n /= 10;	}	return ret;}unsigned long cddb_discid(int tot_trks) {	unsigned int i, t = 0, n = 0;	i = 0;	while (i < (unsigned int)tot_trks) {		n = n + cddb_sum((cdtoc[i].min * 60) + cdtoc[i].sec);		i++;	}	t = ((cdtoc[tot_trks].min * 60) + cdtoc[tot_trks].sec) -		((cdtoc[0].min * 60) + cdtoc[0].sec);	return ((n % 0xff) << 24 | t << 8 | tot_trks);}intcddb_http_request(char *command, int (*reply_parser)(HTTP_header_t*,cddb_data_t*), cddb_data_t *cddb_data) {	char request[4096];	int fd, ret = 0;	URL_t *url;	HTTP_header_t *http_hdr;		if( reply_parser==NULL || command==NULL || cddb_data==NULL ) return -1;		sprintf( request, "http://%s/~cddb/cddb.cgi?cmd=%s%s&proto=%d", cddb_data->freedb_server, command, cddb_data->cddb_hello, cddb_data->freedb_proto_level );	mp_msg(MSGT_OPEN, MSGL_INFO,"Request[%s]\n", request );	url = url_new(request);	if( url==NULL ) {		mp_msg(MSGT_DEMUX, MSGL_ERR, MSGTR_MPDEMUX_CDDB_NotAValidURL);		return -1;	}		fd = http_send_request(url,0);	if( fd<0 ) {		mp_msg(MSGT_DEMUX, MSGL_ERR, MSGTR_MPDEMUX_CDDB_FailedToSendHTTPRequest);		return -1;	}	http_hdr = http_read_response( fd );	if( http_hdr==NULL ) {		mp_msg(MSGT_DEMUX, MSGL_ERR, MSGTR_MPDEMUX_CDDB_FailedToReadHTTPResponse);		return -1;	}	http_debug_hdr(http_hdr);	mp_msg(MSGT_OPEN, MSGL_INFO,"body=[%s]\n", http_hdr->body );	switch(http_hdr->status_code) {		case 200:			ret = reply_parser(http_hdr, cddb_data);			break;		case 400:			mp_msg(MSGT_DEMUX, MSGL_ERR, MSGTR_MPDEMUX_CDDB_HTTPErrorNOTFOUND);			break;		default:			mp_msg(MSGT_DEMUX, MSGL_ERR, MSGTR_MPDEMUX_CDDB_HTTPErrorUnknown);	}	http_free( http_hdr );	url_free( url );		return ret;}intcddb_read_cache(cddb_data_t *cddb_data) {	char file_name[100];	struct stat stats;	int file_fd, ret;	size_t file_size;	if( cddb_data==NULL || cddb_data->cache_dir==NULL ) return -1;		sprintf( file_name, "%s%08lx", cddb_data->cache_dir, cddb_data->disc_id);		file_fd = open(file_name, O_RDONLY#ifdef WIN32	| O_BINARY#endif	);	if( file_fd<0 ) {		mp_msg(MSGT_DEMUX, MSGL_ERR, MSGTR_MPDEMUX_CDDB_NoCacheFound);		return -1;	}	ret = fstat( file_fd, &stats );	if( ret<0 ) {		perror("fstat");		file_size = 4096;	} else {		file_size = stats.st_size;	}		cddb_data->xmcd_file = malloc(file_size);	if( cddb_data->xmcd_file==NULL ) {		mp_msg(MSGT_DEMUX, MSGL_ERR, MSGTR_MemAllocFailed);		close(file_fd);		return -1;	}	cddb_data->xmcd_file_size = read(file_fd, cddb_data->xmcd_file, file_size);	if( cddb_data->xmcd_file_size!=file_size ) {		mp_msg(MSGT_DEMUX, MSGL_WARN, MSGTR_MPDEMUX_CDDB_NotAllXMCDFileHasBeenRead);		close(file_fd);		return -1;	}		close(file_fd);		return 0;}intcddb_write_cache(cddb_data_t *cddb_data) {	// We have the file, save it for cache.	struct stat file_stat;	char file_name[100];	int file_fd, ret;	int wrote=0;	if( cddb_data==NULL || cddb_data->cache_dir==NULL ) return -1;	// Check if the CDDB cache dir exist	ret = stat( cddb_data->cache_dir, &file_stat );	if( ret<0 ) {		// Directory not present, create it.		ret = mkdir( cddb_data->cache_dir, 0755 );#ifdef __MINGW32__		if( ret<0 && errno != EEXIST ) {#else		if( ret<0 ) {#endif			perror("mkdir");			mp_msg(MSGT_DEMUX, MSGL_ERR, MSGTR_MPDEMUX_CDDB_FailedToCreateDirectory, cddb_data->cache_dir);			return -1;		}	}		sprintf( file_name, "%s%08lx", cddb_data->cache_dir, cddb_data->disc_id );		file_fd = creat(file_name, S_IREAD|S_IWRITE);	if( file_fd<0 ) {		perror("create");		return -1;	}		wrote = write(file_fd, cddb_data->xmcd_file, cddb_data->xmcd_file_size);	if( wrote<0 ) {		perror("write");		close(file_fd);		return -1;	}	if( (unsigned int)wrote!=cddb_data->xmcd_file_size ) {		mp_msg(MSGT_DEMUX, MSGL_WARN, MSGTR_MPDEMUX_CDDB_NotAllXMCDFileHasBeenWritten);		close(file_fd);		return -1;	}		close(file_fd);	return 0;}intcddb_read_parse(HTTP_header_t *http_hdr, cddb_data_t *cddb_data) {	unsigned long disc_id;	char category[100];	char *ptr=NULL, *ptr2=NULL;	int ret, status;	if( http_hdr==NULL || cddb_data==NULL ) return -1;		ret = sscanf( http_hdr->body, "%d ", &status);	if( ret!=1 ) {		mp_msg(MSGT_DEMUX, MSGL_ERR, MSGTR_ParseError);		return -1;	}	switch(status) {		case 210:			ret = sscanf( http_hdr->body, "%d %99s %08lx", &status, category, &disc_id);			if( ret!=3 ) {				mp_msg(MSGT_DEMUX, MSGL_ERR, MSGTR_ParseError);				return -1;			}			// Check if it's a xmcd database file			ptr = strstr(http_hdr->body, "# xmcd");			if( ptr==NULL ) {				mp_msg(MSGT_DEMUX, MSGL_ERR, MSGTR_MPDEMUX_CDDB_InvalidXMCDDatabaseReturned);				return -1;			}			// Ok found the beginning of the file			// look for the end			ptr2 = strstr(ptr, "\r\n.\r\n");			if( ptr2==NULL ) {				ptr2 = strstr(ptr, "\n.\n");				if( ptr2==NULL ) {					mp_msg(MSGT_DEMUX, MSGL_FIXME, "Unable to find '.'\n");					ptr2=ptr+strlen(ptr); //return -1;				}			}			// Ok found the end			// do a sanity check			if( http_hdr->body_size<(unsigned int)(ptr2-ptr) ) {				mp_msg(MSGT_DEMUX, MSGL_ERR, MSGTR_MPDEMUX_CDDB_UnexpectedFIXME);				return -1;			}			cddb_data->xmcd_file = ptr;			cddb_data->xmcd_file_size = ptr2-ptr+2;			cddb_data->xmcd_file[cddb_data->xmcd_file_size] = '\0';			// Avoid the http_free function to free the xmcd file...save a mempcy...			http_hdr->body = NULL;

⌨️ 快捷键说明

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