diff options
Diffstat (limited to 'libmpdemux/cddb.c')
-rw-r--r-- | libmpdemux/cddb.c | 878 |
1 files changed, 0 insertions, 878 deletions
diff --git a/libmpdemux/cddb.c b/libmpdemux/cddb.c deleted file mode 100644 index 2bc127029e..0000000000 --- a/libmpdemux/cddb.c +++ /dev/null @@ -1,878 +0,0 @@ -/* - * 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 <stdio.h> -#include <stdlib.h> -#include <fcntl.h> -#include <stdarg.h> -#include <errno.h> -#include <unistd.h> -#include <string.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(__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; - -#if defined(__linux__) || defined(__bsdi__) -int -read_toc(const char *dev) { - int drive; - struct cdrom_tochdr tochdr; - struct cdrom_tocentry tocentry; - int i; - - drive = open(dev, O_RDONLY | O_NONBLOCK); - if( drive<0 ) { - return drive; - } - - ioctl(drive, CDROMREADTOCHDR, &tochdr); - for (i = tochdr.cdth_trk0; i <= tochdr.cdth_trk1; i++) { - tocentry.cdte_track = i; - tocentry.cdte_format = CDROM_MSF; - ioctl(drive, CDROMREADTOCENTRY, &tocentry); - cdtoc[i-1].min = tocentry.cdte_addr.msf.minute; - cdtoc[i-1].sec = tocentry.cdte_addr.msf.second; - cdtoc[i-1].frame = tocentry.cdte_addr.msf.frame; - cdtoc[i-1].frame += cdtoc[i-1].min*60*75; - cdtoc[i-1].frame += cdtoc[i-1].sec*75; - } - tocentry.cdte_track = 0xAA; - tocentry.cdte_format = CDROM_MSF; - ioctl(drive, CDROMREADTOCENTRY, &tocentry); - cdtoc[tochdr.cdth_trk1].min = tocentry.cdte_addr.msf.minute; - cdtoc[tochdr.cdth_trk1].sec = tocentry.cdte_addr.msf.second; - cdtoc[tochdr.cdth_trk1].frame = tocentry.cdte_addr.msf.frame; - cdtoc[tochdr.cdth_trk1].frame += cdtoc[tochdr.cdth_trk1].min*60*75; - cdtoc[tochdr.cdth_trk1].frame += cdtoc[tochdr.cdth_trk1].sec*75; - close(drive); - return tochdr.cdth_trk1; -} - -#elif defined(WIN32) -int -read_toc(const char *dev) { - HANDLE drive; - DWORD r; - CDROM_TOC toc; - char device[10]; - int i; - - 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; - } - - for (i = toc.FirstTrack; i <= toc.LastTrack; i++) { - toc.FirstTrack = i; - cdtoc[i-1].min = toc.TrackData[i - 1].Address[1]; - cdtoc[i-1].sec = toc.TrackData[i - 1].Address[2]; - cdtoc[i-1].frame = toc.TrackData[i - 1].Address[3]; - cdtoc[i-1].frame += cdtoc[i-1].min*60*75; - cdtoc[i-1].frame += cdtoc[i-1].sec*75; - } - toc.FirstTrack = 0xAA; - cdtoc[toc.LastTrack].min = toc.TrackData[toc.LastTrack].Address[1]; - cdtoc[toc.LastTrack].sec = toc.TrackData[toc.LastTrack].Address[2]; - cdtoc[toc.LastTrack].frame = toc.TrackData[toc.LastTrack].Address[3]; - cdtoc[toc.LastTrack].frame += cdtoc[toc.LastTrack].min*60*75; - cdtoc[toc.LastTrack].frame += cdtoc[toc.LastTrack].sec*75; - CloseHandle(drive); - return toc.LastTrack; -} - -#elif defined(__FreeBSD__) || defined(__DragonFly__) -int -read_toc(const char *dev) { - int drive; - struct ioc_toc_header tochdr; - struct ioc_read_toc_single_entry tocentry; - int i; - - drive = open(dev, O_RDONLY | O_NONBLOCK); - if( drive<0 ) { - return drive; - } - - ioctl(drive, CDIOREADTOCHEADER, &tochdr); - for (i = tochdr.starting_track; i <= tochdr.ending_track; i++) { - tocentry.track = i; - tocentry.address_format = CD_MSF_FORMAT; - ioctl(drive, CDIOREADTOCENTRY, &tocentry); - cdtoc[i-1].min = tocentry.entry.addr.msf.minute; - cdtoc[i-1].sec = tocentry.entry.addr.msf.second; - cdtoc[i-1].frame = tocentry.entry.addr.msf.frame; - cdtoc[i-1].frame += cdtoc[i-1].min*60*75; - cdtoc[i-1].frame += cdtoc[i-1].sec*75; - } - tocentry.track = 0xAA; - tocentry.address_format = CD_MSF_FORMAT; - ioctl(drive, CDIOREADTOCENTRY, &tocentry); - cdtoc[tochdr.ending_track].min = tocentry.entry.addr.msf.minute; - cdtoc[tochdr.ending_track].sec = tocentry.entry.addr.msf.second; - cdtoc[tochdr.ending_track].frame = tocentry.entry.addr.msf.frame; - cdtoc[tochdr.ending_track].frame += cdtoc[tochdr.ending_track].min*60*75; - cdtoc[tochdr.ending_track].frame += cdtoc[tochdr.ending_track].sec*75; - close(drive); - return tochdr.ending_track; -} - -#elif defined(__NetBSD__) || defined(__OpenBSD__) -int -read_toc(const char *dev) { - int drive; - struct ioc_toc_header tochdr; - struct ioc_read_toc_entry tocentry; - int i; - struct cd_toc_entry toc_buffer; - - drive = open(dev, O_RDONLY | O_NONBLOCK); - if( drive<0 ) { - return drive; - } - - ioctl(drive, CDIOREADTOCHEADER, &tochdr); - for (i = tochdr.starting_track; i <= tochdr.ending_track; i++) { - tocentry.starting_track = i; - tocentry.address_format = CD_MSF_FORMAT; - tocentry.data = &toc_buffer; - tocentry.data_len = sizeof(toc_buffer); - ioctl(drive, CDIOREADTOCENTRYS, &tocentry); - cdtoc[i-1].min = toc_buffer.addr.msf.minute; - cdtoc[i-1].sec = toc_buffer.addr.msf.second; - cdtoc[i-1].frame = toc_buffer.addr.msf.frame; - cdtoc[i-1].frame += cdtoc[i-1].min*60*75; - cdtoc[i-1].frame += cdtoc[i-1].sec*75; - } - tocentry.starting_track = 0xAA; - tocentry.address_format = CD_MSF_FORMAT; - ioctl(drive, CDIOREADTOCENTRYS, &tocentry); - cdtoc[tochdr.ending_track].min = toc_buffer.addr.msf.minute; - cdtoc[tochdr.ending_track].sec = toc_buffer.addr.msf.second; - cdtoc[tochdr.ending_track].frame = toc_buffer.addr.msf.frame; - cdtoc[tochdr.ending_track].frame += cdtoc[tochdr.ending_track].min*60*75; - cdtoc[tochdr.ending_track].frame += cdtoc[tochdr.ending_track].sec*75; - close(drive); - return tochdr.ending_track; -} -#endif - -/** -\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); -} - - - -int -cddb_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; -} - -int -cddb_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; -} - -int -cddb_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; -} - -int -cddb_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 %s %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; - http_hdr->body_size = 0; - return cddb_write_cache(cddb_data); - default: - mp_msg(MSGT_DEMUX, MSGL_FIXME, MSGTR_MPDEMUX_CDDB_UnhandledCode); - } - return 0; -} - -int -cddb_request_titles(cddb_data_t *cddb_data) { - char command[1024]; - sprintf( command, "cddb+read+%s+%08lx", cddb_data->category, cddb_data->disc_id); - return cddb_http_request(command, cddb_read_parse, cddb_data); -} - -int -cddb_parse_matches_list(HTTP_header_t *http_hdr, cddb_data_t *cddb_data) { - char album_title[100]; - char *ptr = NULL; - int ret; - - ptr = strstr(http_hdr->body, "\n"); - if( ptr==NULL ) { - mp_msg(MSGT_DEMUX, MSGL_ERR, MSGTR_MPDEMUX_CDDB_UnableToFindEOL); - return -1; - } - ptr++; - // We have a list of exact/inexact matches, so which one do we use? - // So let's take the first one. - ret = sscanf(ptr, "%s %08lx %s", cddb_data->category, &(cddb_data->disc_id), album_title); - if( ret!=3 ) { - mp_msg(MSGT_DEMUX, MSGL_ERR, MSGTR_ParseError); - return -1; - } - ptr = strstr(http_hdr->body, album_title); - if( ptr!=NULL ) { - char *ptr2; - int len; - ptr2 = strstr(ptr, "\n"); - if( ptr2==NULL ) { - len = (http_hdr->body_size)-(ptr-(http_hdr->body)); - } else { - len = ptr2-ptr+1; - } - strncpy(album_title, ptr, len); - album_title[len-2]='\0'; - } - mp_msg(MSGT_DEMUX, MSGL_STATUS, MSGTR_MPDEMUX_CDDB_ParseOKFoundAlbumTitle, album_title); - return 0; -} - -int -cddb_query_parse(HTTP_header_t *http_hdr, cddb_data_t *cddb_data) { - char album_title[100]; - char *ptr = NULL; - int ret, status; - - ret = sscanf( http_hdr->body, "%d ", &status); - if( ret!=1 ) { - mp_msg(MSGT_DEMUX, MSGL_ERR, MSGTR_ParseError); - return -1; - } - - switch(status) { - case 200: - // Found exact match - ret = sscanf(http_hdr->body, "%d %s %08lx %s", &status, cddb_data->category, &(cddb_data->disc_id), album_title); - if( ret!=4 ) { - mp_msg(MSGT_DEMUX, MSGL_ERR, MSGTR_ParseError); - return -1; - } - ptr = strstr(http_hdr->body, album_title); - if( ptr!=NULL ) { - char *ptr2; - int len; - ptr2 = strstr(ptr, "\n"); - if( ptr2==NULL ) { - len = (http_hdr->body_size)-(ptr-(http_hdr->body)); - } else { - len = ptr2-ptr+1; - } - strncpy(album_title, ptr, len); - album_title[len-2]='\0'; - } - mp_msg(MSGT_DEMUX, MSGL_STATUS, MSGTR_MPDEMUX_CDDB_ParseOKFoundAlbumTitle, album_title); - return cddb_request_titles(cddb_data); - case 202: - // No match found - mp_msg(MSGT_DEMUX, MSGL_WARN, MSGTR_MPDEMUX_CDDB_AlbumNotFound); - break; - case 210: - // Found exact matches, list follows - cddb_parse_matches_list(http_hdr, cddb_data); - return cddb_request_titles(cddb_data); -/* -body=[210 Found exact matches, list follows (until terminating `.') -misc c711930d Santana / Supernatural -rock c711930d Santana / Supernatural -blues c711930d Santana / Supernatural -.] -*/ - case 211: - // Found inexact matches, list follows - cddb_parse_matches_list(http_hdr, cddb_data); - return cddb_request_titles(cddb_data); - case 500: - mp_msg(MSGT_DEMUX, MSGL_FIXME, MSGTR_MPDEMUX_CDDB_ServerReturnsCommandSyntaxErr); - break; - default: - mp_msg(MSGT_DEMUX, MSGL_FIXME, MSGTR_MPDEMUX_CDDB_UnhandledCode); - } - return -1; -} - -int -cddb_proto_level_parse(HTTP_header_t *http_hdr, cddb_data_t *cddb_data) { - int max; - int ret, status; - char *ptr; - - ret = sscanf( http_hdr->body, "%d ", &status); - if( ret!=1 ) { - mp_msg(MSGT_DEMUX, MSGL_ERR, MSGTR_ParseError); - return -1; - } - - switch(status) { - case 210: - ptr = strstr(http_hdr->body, "max proto:"); - if( ptr==NULL ) { - mp_msg(MSGT_DEMUX, MSGL_ERR, MSGTR_ParseError); - return -1; - } - ret = sscanf(ptr, "max proto: %d", &max); - if( ret!=1 ) { - mp_msg(MSGT_DEMUX, MSGL_ERR, MSGTR_ParseError); - return -1; - } - cddb_data->freedb_proto_level = max; - return 0; - default: - mp_msg(MSGT_DEMUX, MSGL_FIXME, MSGTR_MPDEMUX_CDDB_UnhandledCode); - } - return -1; -} - -int -cddb_get_proto_level(cddb_data_t *cddb_data) { - return cddb_http_request("stat", cddb_proto_level_parse, cddb_data); -} - -int -cddb_freedb_sites_parse(HTTP_header_t *http_hdr, cddb_data_t *cddb_data) { - int ret, status; - - ret = sscanf( http_hdr->body, "%d ", &status); - if( ret!=1 ) { - mp_msg(MSGT_DEMUX, MSGL_ERR, MSGTR_ParseError); - return -1; - } - - switch(status) { - case 210: - // TODO: Parse the sites - ret = cddb_data->anonymous; // For gcc complaining about unused parameter. - return 0; - case 401: - mp_msg(MSGT_DEMUX, MSGL_FIXME, MSGTR_MPDEMUX_CDDB_NoSitesInfoAvailable); - break; - default: - mp_msg(MSGT_DEMUX, MSGL_FIXME, MSGTR_MPDEMUX_CDDB_UnhandledCode); - } - return -1; -} - -int -cddb_get_freedb_sites(cddb_data_t *cddb_data) { - return cddb_http_request("sites", cddb_freedb_sites_parse, cddb_data); -} - -void -cddb_create_hello(cddb_data_t *cddb_data) { - char host_name[51]; - char *user_name; - - if( cddb_data->anonymous ) { // Default is anonymous - /* Note from Eduardo Pérez Ureta <eperez@it.uc3m.es> : - * We don't send current user/host name in hello to prevent spam. - * Software that sends this is considered spyware - * that most people don't like. - */ - user_name = "anonymous"; - strcpy(host_name, "localhost"); - } else { - if( gethostname(host_name, 50)<0 ) { - strcpy(host_name, "localhost"); - } - user_name = getenv("LOGNAME"); - } - sprintf( cddb_data->cddb_hello, "&hello=%s+%s+%s+%s", user_name, host_name, "MPlayer", VERSION ); -} - -int -cddb_retrieve(cddb_data_t *cddb_data) { - char offsets[1024], command[1024]; - char *ptr; - unsigned int i, time_len; - int ret; - - ptr = offsets; - for( i=0; i<cddb_data->tracks ; i++ ) { - ptr += sprintf(ptr, "%d+", cdtoc[i].frame ); - if (ptr-offsets > sizeof offsets - 40) break; - } - ptr[0]=0; - time_len = (cdtoc[cddb_data->tracks].frame)/75; - - cddb_data->freedb_server = DEFAULT_FREEDB_SERVER; - cddb_data->freedb_proto_level = 1; - cddb_data->xmcd_file = NULL; - - cddb_create_hello(cddb_data); - if( cddb_get_proto_level(cddb_data)<0 ) { - mp_msg(MSGT_DEMUX, MSGL_ERR, MSGTR_MPDEMUX_CDDB_FailedToGetProtocolLevel); - return -1; - } - - //cddb_get_freedb_sites(&cddb_data); - - sprintf(command, "cddb+query+%08lx+%d+%s%d", cddb_data->disc_id, cddb_data->tracks, offsets, time_len ); - ret = cddb_http_request(command, cddb_query_parse, cddb_data); - if( ret<0 ) return -1; - - if( cddb_data->cache_dir!=NULL ) { - free(cddb_data->cache_dir); - } - return 0; -} - -int -cddb_resolve(const char *dev, char **xmcd_file) { - char cddb_cache_dir[] = DEFAULT_CACHE_DIR; - char *home_dir = NULL; - cddb_data_t cddb_data; - - if (cdtoc_last_track <= 0) - { - cdtoc_last_track = read_toc(dev); - if (cdtoc_last_track < 0) { - mp_msg(MSGT_OPEN, MSGL_ERR, MSGTR_MPDEMUX_CDDB_FailedToOpenDevice, dev); - return -1; - } - } - cddb_data.tracks = cdtoc_last_track; - cddb_data.disc_id = cddb_discid(cddb_data.tracks); - cddb_data.anonymous = 1; // Don't send user info by default - - // Check if there is a CD in the drive - // FIXME: That's not really a good way to check - if( cddb_data.disc_id==0 ) { - mp_msg(MSGT_DEMUX, MSGL_ERR, MSGTR_MPDEMUX_CDDB_NoCDInDrive); - return -1; - } - - home_dir = getenv("HOME"); -#ifdef __MINGW32__ - if( home_dir==NULL ) home_dir = getenv("USERPROFILE"); - if( home_dir==NULL ) home_dir = getenv("HOMEPATH"); - // Last resort, store the cddb cache in the mplayer directory - if( home_dir==NULL ) home_dir = (char *)get_path(""); -#endif - if( home_dir==NULL ) { - cddb_data.cache_dir = NULL; - } else { - cddb_data.cache_dir = malloc(strlen(home_dir)+strlen(cddb_cache_dir)+1); - if( cddb_data.cache_dir==NULL ) { - mp_msg(MSGT_DEMUX, MSGL_ERR, MSGTR_MemAllocFailed); - return -1; - } - sprintf(cddb_data.cache_dir, "%s%s", home_dir, cddb_cache_dir ); - } - - // Check for a cached file - if( cddb_read_cache(&cddb_data)<0 ) { - // No Cache found - if( cddb_retrieve(&cddb_data)<0 ) { - return -1; - } - } - - if( cddb_data.xmcd_file!=NULL ) { -// printf("%s\n", cddb_data.xmcd_file ); - *xmcd_file = cddb_data.xmcd_file; - return 0; - } - - return -1; -} - -/******************************************************************************************************************* - * - * xmcd parser - * - *******************************************************************************************************************/ -char* -xmcd_parse_dtitle(cd_info_t *cd_info, char *line) { - char *ptr, *album; - ptr = strstr(line, "DTITLE="); - if( ptr!=NULL ) { - ptr += 7; - album = strstr(ptr, "/"); - if( album==NULL ) return NULL; - cd_info->album = malloc(strlen(album+2)+1); - if( cd_info->album==NULL ) { - return NULL; - } - strcpy( cd_info->album, album+2 ); - album--; - album[0] = '\0'; - cd_info->artist = malloc(strlen(ptr)+1); - if( cd_info->artist==NULL ) { - return NULL; - } - strcpy( cd_info->artist, ptr ); - } - return ptr; -} - -char* -xmcd_parse_dgenre(cd_info_t *cd_info, char *line) { - char *ptr; - ptr = strstr(line, "DGENRE="); - if( ptr!=NULL ) { - ptr += 7; - cd_info->genre = malloc(strlen(ptr)+1); - if( cd_info->genre==NULL ) { - return NULL; - } - strcpy( cd_info->genre, ptr ); - } - return ptr; -} - -char* -xmcd_parse_ttitle(cd_info_t *cd_info, char *line) { - unsigned int track_nb; - unsigned long sec, off; - char *ptr; - ptr = strstr(line, "TTITLE"); - if( ptr!=NULL ) { - ptr += 6; - // Here we point to the track number - track_nb = atoi(ptr); - ptr = strstr(ptr, "="); - if( ptr==NULL ) return NULL; - ptr++; - - sec = cdtoc[track_nb].frame; - off = cdtoc[track_nb+1].frame-sec+1; - - cd_info_add_track( cd_info, ptr, track_nb+1, (unsigned int)(off/(60*75)), (unsigned int)((off/75)%60), (unsigned int)(off%75), sec, off ); - } - return ptr; -} - -cd_info_t* -cddb_parse_xmcd(char *xmcd_file) { - cd_info_t *cd_info = NULL; - int length, pos = 0; - char *ptr, *ptr2; - unsigned int audiolen; - if( xmcd_file==NULL ) return NULL; - - cd_info = cd_info_new(); - if( cd_info==NULL ) { - return NULL; - } - - length = strlen(xmcd_file); - ptr = xmcd_file; - while( ptr!=NULL && pos<length ) { - // Read a line - ptr2 = ptr; - while( ptr2[0]!='\0' && ptr2[0]!='\r' && ptr2[0]!='\n' ) ptr2++; - if( ptr2[0]=='\0' ) { - break; - } - ptr2[0] = '\0'; - // Ignore comments - if( ptr[0]!='#' ) { - // Search for the album title - if( xmcd_parse_dtitle(cd_info, ptr) ); - // Search for the genre - else if( xmcd_parse_dgenre(cd_info, ptr) ); - // Search for a track title - else if( xmcd_parse_ttitle(cd_info, ptr) ) audiolen++; // <-- audiolen++ to shut up gcc warning - } - if( ptr2[1]=='\n' ) ptr2++; - pos = (ptr2+1)-ptr; - ptr = ptr2+1; - } - - audiolen = cdtoc[cd_info->nb_tracks].frame-cdtoc[0].frame; - cd_info->min = (unsigned int)(audiolen/(60*75)); - cd_info->sec = (unsigned int)((audiolen/75)%60); - cd_info->msec = (unsigned int)(audiolen%75); - - return cd_info; -} |