Browse Source

Remove outdated LastFRipper plugin

z3APA3A 6 năm trước cách đây
mục cha
commit
70ed1233fb

+ 0 - 1
src/plugins/LastFRipper/Makefile

@@ -1 +0,0 @@
-include Makefile.var

+ 0 - 7
src/plugins/LastFRipper/Makefile.inc

@@ -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)

+ 0 - 709
src/plugins/LastFRipper/lastFripper.c

@@ -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

+ 0 - 66
src/plugins/LastFRipper/lastFripper.h

@@ -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;
-};