diff --git a/src/plugins/LastFRipper/Makefile b/src/plugins/LastFRipper/Makefile deleted file mode 100644 index e7c51ad..0000000 --- a/src/plugins/LastFRipper/Makefile +++ /dev/null @@ -1 +0,0 @@ -include Makefile.var diff --git a/src/plugins/LastFRipper/Makefile.inc b/src/plugins/LastFRipper/Makefile.inc deleted file mode 100644 index 962f012..0000000 --- a/src/plugins/LastFRipper/Makefile.inc +++ /dev/null @@ -1,7 +0,0 @@ -all: $(BUILDDIR)lastFripper$(DLSUFFICS) - -lastFripper$(OBJSUFFICS): lastFripper.c - $(CC) $(DCFLAGS) $(CFLAGS) lastFripper.c - -$(BUILDDIR)lastFripper$(DLSUFFICS): lastFripper$(OBJSUFFICS) - $(LN) $(LNOUT)../../$(BUILDDIR)lastFripper$(DLSUFFICS) $(LDFLAGS) $(DLFLAGS) lastFripper$(OBJSUFFICS) diff --git a/src/plugins/LastFRipper/lastFripper.c b/src/plugins/LastFRipper/lastFripper.c deleted file mode 100644 index b1299f2..0000000 --- a/src/plugins/LastFRipper/lastFripper.c +++ /dev/null @@ -1,709 +0,0 @@ -/* - released as a public domain - std.denis, 2009 -*/ -#include "../../structures.h" -#include "lastFripper.h" - -#define strdup _strdup -#define strnicmp _strnicmp -#define ltoa _ltoa - -#define mkdir _mkdir - -#define PART_SUFFIX "_partial" - -void my_mkdir( char* name ) -{ - char* pdir = name; - - while( 1 ) { - char ch; - char* pnext = pdir; - while( *pnext && *pnext != '\\' && *pnext != '/' ) - pnext++; - if( *pnext == 0 ) - break; - - ch = *pnext; - *pnext = 0; - mkdir( name ); - *pnext = ch; - - pdir = pnext + 1; - } - mkdir( name ); -} - - -__inline void myOutputDebugStringA1( char* str ) -{ -/* char fname[128]; - ltoa( GetCurrentThreadId(), fname, 10 ); - FILE* fp = fopen( fname, "ab" ); - fputs( str, fp ); - fputs( "\r\n", fp ); - fflush( fp ); - fclose( fp ); -*/ -} - -__inline void myOutputDebugStringA( void* buf, int len ) -{ -/* char fname[128]; - ltoa( GetCurrentThreadId(), fname, 10 ); - FILE* fp = fopen( fname, "ab" ); - fwrite( buf, len, 1, fp ); - fputs( "\r\n", fp ); - fflush( fp ); - fclose( fp ); */ -} - -#ifndef isnumber -#define isnumber(i_n_arg) ((i_n_arg>='0')&&(i_n_arg<='9')) -#endif - -#define sizearr(x) (sizeof(x)/sizeof(x[0])) -#define xmalloc( type, len ) ((type*)malloc( (len) * sizeof(type) ) ) -#define xcalloc( type, len ) ((type*)calloc( (len), sizeof(type) ) ) - -int clean_filename( char* filename ) -{ - int i; - for( i = 0; filename[i]; i++ ) - switch( filename[i] ) { - case '*': - case '?': - case '<': - case '>': - case '\\': - case '/': - case ':': - case '"': - filename[i] = '_'; - break; - } - return i; -} - - -static struct pluginlink * pl; -static int lfm_loaded = 0; -static char* g_folder = 0; -static char* g_format = 0; - -static int lfm_format_filename( struct playlist_item* p_item, char* p_filename, int n_filename ) -{ - int i = 0, j; - char ch; - char* fmt; - char *ff = NULL; - - if( g_folder && *g_folder ) { - strncpy( p_filename, g_folder, n_filename ); - i = strlen( p_filename ); - if( i < n_filename-1 && p_filename[i-1] != '\\' ) - p_filename[i++] = '\\'; - } - - fmt = g_format; - if( fmt == NULL ) fmt = "%a\\%t.mp3"; - while( ( ch = *fmt++ ) != 0 ) { - if( ch == '%' ) { - char* p_sz = NULL; - char a_sz[32]; - ch = *fmt++; - switch( ch ) { - case 0: - fmt--; break; - case '%': - p_sz = "%"; - break; - case 'n': { - static unsigned ndx = 0; - ltoa( ndx++, a_sz, 10 ); - p_sz = a_sz; - break; - } - case 'a': - p_sz = p_item->artist; - break; - case 't': - p_sz = p_item->title; - break; - case 'l': - p_sz = p_item->album; - break; - } - if( p_sz ) { - strncpy( p_filename+i, p_sz, n_filename-i ); - p_filename[n_filename-1] = 0; - i += clean_filename( p_filename+i ); - } - } else - if( i < n_filename ) p_filename[i++] = ch; - } - - for( j = i-1; j >= 0; j-- ) - if( p_filename[j] == '\\' || p_filename[j] == '/' ) { - ff = p_filename + j; - break; - } - if( ff ) { - char ch = *ff; - *ff = 0; - my_mkdir( p_filename ); - *ff = ch; - } - - return i; -} - -static void lfm_close_request( struct lfm_client_data* p_client ) -{ - struct lfm_filter_data* p_data; - if( p_client == NULL ) return; - p_data = p_client->p_data; - if( p_data == NULL ) return; - - if( p_client->req_type == LFM_PLAYLIST ) { - free( p_client->pl_xml ); - } else if( p_client->req_type == LFM_GET && p_client->fp ) { - struct playlist_item* p_item = p_client->pl_item; - if( p_item ) { - char id3v1[128]; - memset( id3v1, 0, 128 ); - strcpy( id3v1, "TAG" ); - strncpy( id3v1+3, p_item->title, 30 ); - strncpy( id3v1+33, p_item->artist, 30 ); - strncpy( id3v1+63, p_item->album, 30 ); - id3v1[127] = -1; - fwrite( id3v1, 128, 1, p_client->fp ); - } - fclose( p_client->fp ); -/* - if( p_item ) { - char filename_part[512], filename[512]; - int i = lfm_format_filename( p_item, filename_part, sizearr(filename_part) ); - memcpy( filename, filename_part, sizeof(filename) ); - strncpy( filename_part+i, PART_SUFFIX, sizearr(filename_part)-i ); - rename( filename_part, filename ); - } -*/ - pthread_mutex_lock( &p_data->mutex ); - if( p_data->playlist != NULL && p_item != NULL ) { - if( p_data->playlist == p_item ) - p_data->playlist = p_item->next; - else { - struct playlist_item *p_last = p_data->playlist; - - while( p_last->next != NULL && p_last->next != p_item ) - p_last = p_last->next; - - if( p_last->next ) - p_last->next = p_item->next; - } - if( p_item->artist ) free( p_item->artist ); - if( p_item->title ) free( p_item->title ); - if( p_item->album ) free( p_item->album ); - if( p_item->url ) free( p_item->url ); - free( p_item ); - } - pthread_mutex_unlock( &p_data->mutex ); - } - p_client->req_type = LFM_NONE; -} - -static void* lfm_filter_open( void * idata, struct srvparam * param ){ - struct lfm_filter_data* pdata = (struct lfm_filter_data*)idata; - if( pdata ){ - pthread_mutex_lock( &pdata->mutex ); - pdata->refs++; - pthread_mutex_unlock( &pdata->mutex ); - } else { - if( ( pdata = xcalloc( struct lfm_filter_data, 1 ) ) != NULL ) { - pthread_mutex_init( &pdata->mutex, NULL ); - pdata->playlist = NULL; - pdata->refs++; - } - } - return pdata; -} - -static FILTER_ACTION lfm_filter_client( void *fo, struct clientparam* param, void** fc ) -{ - struct lfm_filter_data* p_data; - struct lfm_client_data* p_client; - *fc = NULL; - if( fo == NULL ) return PASS; - - p_data = (struct lfm_filter_data*)fo; - p_client = xcalloc( struct lfm_client_data, 1 ); - if( p_client == NULL ) return PASS; - - p_client->p_data = p_data; - p_client->req_type = LFM_NONE; - - *fc = p_client; - return CONTINUE; -} - -static void lfm_filter_clear( void *fc ) -{ - struct lfm_client_data* p_client; - - p_client = (struct lfm_client_data*)fc; - if( p_client == NULL ) return; - - lfm_close_request( p_client ); - - free( p_client ); -} - -static void lfm_filter_close(void *fo){ - struct lfm_filter_data* p_data; - struct playlist_item* p_item; - - p_data = (struct lfm_filter_data*)fo; - if( p_data == NULL ) return; - - if( --p_data->refs > 0 ) return; - - pthread_mutex_destroy( &p_data->mutex ); - p_item = p_data->playlist; - while( p_item ) { - struct playlist_item* p_old = p_item; - p_item = p_item->next; - - if( p_old->artist ) free( p_old->artist ); - if( p_old->title ) free( p_old->title ); - if( p_old->album ) free( p_old->album ); - if( p_old->url ) free( p_old->url ); - free( p_old ); - } - - free( p_data ); -} - -static FILTER_ACTION lfm_filter_request( void *fc, struct clientparam *param, unsigned char** buf_p, int* bufsize_p, int offset, int* length_p ) -{ - char* p_buf = (char*)( *buf_p + offset ); - int n_buf = *length_p - offset; - struct lfm_client_data* p_client; - struct lfm_filter_data* p_data; - - if( p_buf == NULL || n_buf < 5 ) return CONTINUE; - - p_client = (struct lfm_client_data*)fc; - if( p_client == NULL ) return CONTINUE; - p_data = p_client->p_data; - if( p_data == NULL ) return CONTINUE; - - pl->conf->filtermaxsize = 0; - - lfm_close_request( p_client ); - - p_client->req_type = LFM_NONE; - p_client->fp = NULL; - - if( strncasecmp( p_buf, "GET ", 4 ) != 0 ) return CONTINUE; - - p_buf += 4; - - if( strncasecmp( p_buf, "http://ws.audioscrobbler.com/radio/xspf.php?", 44 ) == 0 ) { - myOutputDebugStringA1( "getting a playlist" ); - p_client->req_type = LFM_PLAYLIST; - } else { - char zzz[256]; - int i; - struct playlist_item* p_item; - for( i = 0; i < n_buf && i < 256; i++ ) { - if( p_buf[i] == '\r' ) break; - zzz[i] = p_buf[i]; - } - zzz[i] = 0; - myOutputDebugStringA1( zzz ); - pthread_mutex_lock( &p_data->mutex ); - p_item = p_data->playlist; - while( p_item ) { - if( strncasecmp( p_buf, p_item->url, p_item->url_len ) == 0 ) - break; - p_item = p_item->next; - } - pthread_mutex_unlock( &p_data->mutex ); - if( p_item ) { - myOutputDebugStringA1( "getting a known url: " ); - myOutputDebugStringA1( p_item->title ); - p_client->req_type = LFM_GET; - p_client->pl_item = p_item; - } - } - - return CONTINUE; -} - -static FILTER_ACTION lfm_filter_header_srv( void *fc, struct clientparam *param, unsigned char** buf_p, int* bufsize_p, int offset, int* length_p ) -{ - char* p_buf = (char*)( *buf_p + offset ); - struct lfm_client_data* p_client; - int n_buf = *length_p - offset; - struct lfm_filter_data* p_data; - char zzz[100]; - int code; - - if( p_buf == NULL || n_buf < 9 ) return CONTINUE; - - p_client = (struct lfm_client_data*)fc; - if( p_client == NULL ) return CONTINUE; - p_data = p_client->p_data; - if( p_data == NULL ) return CONTINUE; - - code = atoi( p_buf + 9 ); - sprintf( zzz, "http code: %d", code ); - myOutputDebugStringA1( zzz ); - myOutputDebugStringA( p_buf, n_buf ); - if( p_client->req_type == LFM_GET && ( code > 300 && code < 304 || code == 307 ) ) { - p_client->req_type = LFM_REDIR; - do { - char* p_line = p_buf; - int n_line; - - for(; n_buf > 0 && *p_buf != '\r'; p_buf++, n_buf-- ) {}; - n_line = p_buf - p_line; - if( n_line <= 0 ) break; - if( n_line > 10 && strncasecmp( p_line, "location: ", 10 ) == 0 ) { - myOutputDebugStringA1( "redir/location: " ); - myOutputDebugStringA( p_line + 10, n_line - 10 ); - if( p_client->pl_item ) { - char* p_url = p_line + 10; - int n_url = n_line - 10; - pthread_mutex_lock( &p_data->mutex ); - if( p_client->pl_item->url ) free( p_client->pl_item->url ); - p_client->pl_item->url = xmalloc( char, n_url + 1 + 1 ); - memcpy( p_client->pl_item->url, p_url, n_url ); - p_client->pl_item->url[n_url] = ' '; - p_client->pl_item->url[n_url+1] = 0; - p_client->pl_item->url_len = n_url + 1; - myOutputDebugStringA1( "got a url: " ); - myOutputDebugStringA1( p_client->pl_item->url ); - pthread_mutex_unlock( &p_data->mutex ); - } - p_client->req_type = LFM_NONE; - } - for(; n_buf > 0 && ( *p_buf == '\n' || *p_buf == '\r' ); p_buf++, n_buf-- ) {}; - } while( n_buf > 0 ); - } - - if( code == 200 && p_client->req_type == LFM_GET ) { - struct playlist_item* p_item = p_client->pl_item; - char filename[512]; - int i = lfm_format_filename( p_item, filename, sizearr(filename) ); - /* - strncpy( filename + i, PART_SUFFIX, sizearr(filename)-i ); - */ - p_client->fp = fopen( filename, "wb" ); - } - else if( code == 200 && p_client->req_type == LFM_PLAYLIST ) { - p_client->pl_xml = xcalloc( struct xml_state, 1 ); - } - - return CONTINUE; -} - -void playlist_analyze( struct lfm_client_data* p_client, const char* p_buf, int len ); -static FILTER_ACTION lfm_filter_data_srv( void *fc, struct clientparam *param, unsigned char** buf_p, int* bufsize_p, int offset, int* length_p ) -{ - char* p_buf = (char*)( *buf_p + offset ); - int n_buf = *length_p - offset; - struct lfm_client_data* p_client; - struct lfm_filter_data* p_data; - - - myOutputDebugStringA1( "filter_data_srv" ); - myOutputDebugStringA( p_buf, n_buf ); - - if( p_buf == NULL || n_buf < 1 ) return CONTINUE; - - p_client = (struct lfm_client_data*)fc; - if( p_client == NULL ) return CONTINUE; - p_data = p_client->p_data; - if( p_data == NULL ) return CONTINUE; - - if( p_client->req_type == LFM_PLAYLIST ) - myOutputDebugStringA1( "filter_data_srv: playlist" ); - else if( p_client->req_type == LFM_GET ) { - myOutputDebugStringA1( "filter_data_srv: retrieving" ); - if( p_client->fp == NULL ) - myOutputDebugStringA1( "but no file allocated" ); - } - - if( p_client->req_type == LFM_PLAYLIST ) - playlist_analyze( p_client, p_buf, n_buf ); - if( p_client->fp ) - fwrite( p_buf, n_buf, 1, p_client->fp ); - - return CONTINUE; -} - -enum XmlState -{ - XML_TEXT, - XML_TAGNAME, - XML_ATTRNAME_W, - XML_ATTRNAME, - XML_ATTRVALUE_W, - XML_ATTRVALUE, - XML_TAGCLOSE, - XML_TAGOPENCLOSE, -}; - -int xml_get_token_id( char** table, char* token ) -{ - int i; - char* psz; - for( psz = token; *psz; psz++ ) - *psz = tolower( *psz ); - for( i = 0; *table; i++, table++ ) - if( strcmp( *table, token ) == 0 ) return i; - - return -1; -} - -enum { - XT_PLAYLIST, - XT_TRACK_LIST, - XT_TRACK, - XT_LOCATION, - XT_CREATOR, - XT_ALBUM, - XT_TITLE -}; - -char* xt_list[] = { - "playlist", - "tracklist", - "track", - "location", - "creator", - "album", - "title", - NULL -}; - -void playlist_analyze( struct lfm_client_data* p_client, const char* p_buf, int len ) -{ - struct xml_state* xs = p_client->pl_xml; - int n_buf = len; - - if( xs == NULL ) return; - - while( n_buf > 0 ) { - enum { - XMS_NONE, - XMS_TAG, - XMS_ATTR_NAME, - XMS_ATTR_VALUE, - XMS_TEXT - } gotta = XMS_NONE; - char ch = *p_buf++; - n_buf--; -lbl_retry: - switch( xs->state ) { - case XML_TAGNAME: - if( ch == '>' ) { - xs->state = XML_TEXT; - gotta = XMS_TAG; - break; - } else if( ch == '/' ) { - if( xs->n_token == 0 ) - xs->closing = 1; - else { - xs->state = XML_ATTRNAME_W; - gotta = XMS_TAG; - xs->n_token--; - } - break; - } else if( isspace( ch ) ) { - xs->state = XML_ATTRNAME_W; - gotta = XMS_TAG; - break; - } - if( xs->n_token < TOKEN_MAXLEN ) xs->p_token[xs->n_token++] = ch; - break; - case XML_ATTRNAME_W: - if( ch == '>' ) { - xs->state = XML_TEXT; - break; - } else if( ch == '/' ) { - xs->closing = 1; - xs->state = XML_TEXT; - gotta = XMS_TAG; - break; - } else if( !isspace( ch ) ) { - xs->state = XML_ATTRNAME; - goto lbl_retry; - } - break; - case XML_ATTRNAME: - if( ch == '=' ) { - xs->state = XML_ATTRVALUE_W; - gotta = XMS_ATTR_NAME; - break; - } - if( xs->n_token < TOKEN_MAXLEN ) xs->p_token[xs->n_token++] = ch; - break; - case XML_ATTRVALUE_W: - if( ch == '"' || ch == '\'' ) { - xs->sep = ch; - xs->state = XML_ATTRVALUE; - break; - } - break; - case XML_ATTRVALUE: - if( ch == xs->sep ) { - xs->state = XML_ATTRNAME_W; - gotta = XMS_ATTR_VALUE; - break; - } - if( xs->n_token < TOKEN_MAXLEN ) xs->p_token[xs->n_token++] = ch; - break; - case XML_TEXT: - if( ch == '<' ) { - xs->state = XML_TAGNAME; - gotta = XMS_TEXT; - break; - } - if( xs->n_token < TOKEN_MAXLEN ) xs->p_token[xs->n_token++] = ch; - break; - } - - if( gotta != XMS_NONE ) { - xs->p_token[xs->n_token] = 0; - - switch( gotta ) { - case XMS_TAG: { - int id = xml_get_token_id( xt_list, xs->p_token ); - if( !xs->closing ) { - if( xs->level < sizeof(xs->tree) ) xs->tree[xs->level] = id; - xs->level++; - - if( id == XT_TRACK && xs->level == 3 && xs->tree[1] == XT_TRACK_LIST ) - xs->p_item = xcalloc( struct playlist_item, 1 ); - } else { - if( xs->level > 0 ) xs->level--; - if( id == XT_TRACK && xs->level == 2 && xs->tree[1] == XT_TRACK_LIST ) { - char zzz[1024]; - _snprintf( zzz, 1024, "artist: <%s>, title: <%s>, url: <%s>", - xs->p_item->artist, xs->p_item->title, xs->p_item->url ); - myOutputDebugStringA1( zzz ); - pthread_mutex_lock( &p_client->p_data->mutex ); - xs->p_item->next = p_client->p_data->playlist; - p_client->p_data->playlist = xs->p_item; - pthread_mutex_unlock( &p_client->p_data->mutex ); - } - xs->closing = 0; - } - - break; - } - case XMS_ATTR_NAME: - break; - case XMS_ATTR_VALUE: - break; - case XMS_TEXT: - if( xs->level == 4 && xs->tree[1] == XT_TRACK_LIST && xs->tree[2] == XT_TRACK ) { - struct playlist_item* item = xs->p_item; - if( item ) - switch( xs->tree[3] ) { - case XT_LOCATION: - item->url_len = xs->n_token; - item->url = xmalloc( char, item->url_len + 1 + 1); - memcpy( item->url, xs->p_token, item->url_len ); - item->url[item->url_len++] = ' '; - item->url[item->url_len] = 0; - break; - case XT_CREATOR: - item->artist = strdup( xs->p_token ); - break; - case XT_ALBUM: - item->album = strdup( xs->p_token ); - break; - case XT_TITLE: - item->title = strdup( xs->p_token ); - break; - } - } - break; - } - xs->n_token = 0; - } - } -} - - -static struct filter lfm_filter = { - NULL, - "last.fm spy", - NULL, - - lfm_filter_open, - lfm_filter_client, - lfm_filter_request, - NULL, - lfm_filter_header_srv, - NULL, - NULL, - lfm_filter_data_srv, - lfm_filter_clear, - lfm_filter_close -}; - -static int h_lfm_folder( int argc, unsigned char **argv ) -{ - if( g_folder ) free( g_folder ); - g_folder = strdup( (char*)argv[1] ); - return 0; -} - -static int h_lfm_format( int argc, unsigned char **argv ) -{ - if( g_format ) free( g_format ); - g_format = strdup( (char*)argv[1] ); - return 0; -} - -static struct commands lfm_commandhandlers[] = { - {lfm_commandhandlers+1, "lfm_folder", h_lfm_folder, 2, 2}, - {NULL, "lfm_format", h_lfm_format, 2, 2} -}; - - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef WATCOM -#pragma aux lfm_plugin "*" parm caller [ ] value struct float struct routine [eax] modify [eax ecx edx] -#undef PLUGINCALL -#define PLUGINCALL -#endif - -PLUGINAPI int PLUGINCALL lfm_plugin( struct pluginlink * pluginlink, int argc, char** argv ) -{ - pl = pluginlink; - myOutputDebugStringA1( "lfm_plugin" ); - if( !lfm_loaded ) { - lfm_loaded = 1; - - lfm_filter.next = pl->conf->filters; - pl->conf->filters = &lfm_filter; - - lfm_commandhandlers[1].next = pl->commandhandlers->next; - pl->commandhandlers->next = lfm_commandhandlers; - } - return 0; -} - -#ifdef __cplusplus -} -#endif diff --git a/src/plugins/LastFRipper/lastFripper.h b/src/plugins/LastFRipper/lastFripper.h deleted file mode 100644 index cd1e88b..0000000 --- a/src/plugins/LastFRipper/lastFripper.h +++ /dev/null @@ -1,66 +0,0 @@ -// -// released as a public domain -// std.denis, 2009 -// -/* - #include "direct.h" -*/ - -#ifdef _WIN32 -#define strcasecmp stricmp -#define strncasecmp strnicmp -#else -#define closesocket close -extern pthread_attr_t pa; -#endif - -#ifndef SOCKET_ERROR -#define SOCKET_ERROR -1 -#endif - - -typedef enum { - LFM_NONE, - LFM_PLAYLIST, // GET http://ws.audioscrobbler.com/radio/adjust.php(...) - LFM_REDIR, // GET http://play.last.fm/user/(...) - LFM_GET -} LFM_CLASS; - -struct playlist_item { - struct playlist_item* next; - - char* artist; - char* title; - char* album; - char* url; - int url_len; -}; - -#define TOKEN_MAXLEN 1024 -struct xml_state { - int state; - int closing; - char sep; - - int level; - char tree[128]; // 128 levels nesting - - int n_token; - char p_token[TOKEN_MAXLEN]; - - struct playlist_item* p_item; -}; - -struct lfm_filter_data { - pthread_mutex_t mutex; - struct playlist_item* playlist; - int refs; -}; -struct lfm_client_data { - struct lfm_filter_data* p_data; - - int req_type; - struct xml_state* pl_xml; - struct playlist_item* pl_item; - FILE* fp; -};