#ifdef HAVE_CONFIG_H # include "config.h" #endif #include #include #include #include #include #include "cddbp.h" #include "main_window_handler.h" #include "misc_utils.h" int cddbp_query_proxy( FILE*, const char *disk_id, int tracknum, long int offsets[], int duration, int *matches, char ***category_buffer, char ***title_buffer, char ***id_buffer ); int cddbp_stat( FILE*, char **result ); int http_stat( const char *server, int port, const char *URL, char **result, const char *client, const char *version ); int cddbp_signon( FILE *socket ) { char * buffer; int code; buffer = get_string_piece( socket, '\n' ); if (buffer == NULL) return -1; #ifdef DEBUG printf( "<= %s\n", buffer ); #endif /* convert the answer code to int */ code = ( ( buffer[ 0 ] - 0x30 ) * 10 + ( buffer[ 1 ] - 0x30 ) ) * 10 + ( buffer[ 2 ] - 0x30 ); free( buffer ); return code; } int cddbp_handshake( FILE *socket, const char *clientname, const char *version ) { char * buffer; int code; /* Greetings! */ /* - no need to disclose user and hostname */ #ifdef DEBUG printf( "=> cddb hello %s %s %s %s\n", "anonymous", "localhost", clientname, version ); #endif fprintf( socket, "cddb hello %s %s %s %s\n", "anonymous", "localhost", clientname, version ); buffer = get_string_piece( socket, '\n' ); if (buffer == NULL) return -1; #ifdef DEBUG printf( "<= %s\n", buffer ); #endif code = ( ( buffer[ 0 ] - 0x30 ) * 10 + ( buffer[ 1 ] - 0x30 ) ) * 10 + ( buffer[ 2 ] - 0x30 ); free( buffer ); return code; } int cddbp_query( FILE *socket, const char *disk_id, int tracknum, long int offset[], int duration, int *matches, char ***category_buffer, char ***title_buffer, char ***id_buffer ) { char * buffer, *tmp; int code, i; buffer = ( char* ) malloc( strlen( "cddb query " ) + strlen( disk_id ) + 1 + 3 + tracknum * 10 + 6 + 1 ); sprintf( buffer, "cddb query %s %d ", disk_id, tracknum ); tmp = ( char* ) malloc( 10 ); for ( i = 0; i < tracknum; i++ ) { sprintf( tmp, "%ld ", offset[ i ] ); strcat( buffer, tmp ); } sprintf( tmp, "%d\n", duration ); strcat( buffer, tmp ); free( tmp ); #ifdef DEBUG printf( "=> %s\n", buffer ); #endif fprintf( socket, buffer ); free( buffer ); tmp = buffer = get_string_piece( socket, '\n' ); if (buffer == NULL) return -1; #ifdef DEBUG printf( "<= %s\n", buffer ); #endif code = ( ( buffer[ 0 ] - 0x30 ) * 10 + ( buffer[ 1 ] - 0x30 ) ) * 10 + ( buffer[ 2 ] - 0x30 ); *matches = 0; if ( code == 200 ) { buffer = tmp + 4; } else if ( code == 211 ) { free( buffer ); tmp = buffer = get_string_piece( socket, '\n' ); } else return code; /* get the alternavtives */ *title_buffer = ( char** ) malloc( sizeof( char* ) * 1000 ); *category_buffer = ( char** ) malloc( sizeof( char* ) * 1000 ); *id_buffer = ( char** ) malloc( sizeof( char* ) * 1000 ); do { if ( strcmp( buffer, ".\r\n" ) == 0 ) break; /* if we get more than 1000 matches, the char*[] will be full, and we will skip the remaining few million matches */ if ( *matches == 999 ) { free( tmp ); continue; } i = strcspn( buffer, " " ); ( *category_buffer ) [ *matches ] = ( char* ) malloc( i + 1 ); strncpy( ( *category_buffer ) [ *matches ], buffer, i ); ( *category_buffer ) [ *matches ][ i ] = 0; /*terminate the string*/ buffer += i + 1; /* skip to the disk id */ ( *id_buffer ) [ *matches ] = ( char* ) malloc( 9 ); /* the disk id is always 8 char long */ strncpy( ( *id_buffer ) [ *matches ], buffer, 8 ); ( *id_buffer ) [ *matches ][ 8 ] = 0; /*terminate the string */ buffer += 9; i = strlen( buffer ) - 2; /*strip the remaining '\r\n' from the end of the line*/ ( *title_buffer ) [ *matches ] = ( char* ) malloc( i + 1 ); strncpy( ( *title_buffer ) [ *matches ], buffer, i ); ( *title_buffer ) [ *matches ][ i ] = 0; /*terminate the string */ ( *matches ) ++; free( tmp ); } while ( code != 200 && ( tmp = buffer = get_string_piece( socket, '\n' ) ) != NULL ); return code; } int cddbp_read( FILE* socket, const char* category, const char* disk_id, char **result_buffer ) { char * buffer; int code; int count; char status_buf[ 36 ]; #ifdef DEBUG printf( "=> cddb read %s %s\n", category, disk_id ); #endif fprintf( socket, "cddb read %s %s\n", category, disk_id ); buffer = get_string_piece( socket, '\n' ); if (buffer == NULL) return -1; #ifdef DEBUG printf( "<= %s\n", buffer ); #endif code = ( ( buffer[ 0 ] - 0x30 ) * 10 + ( buffer[ 1 ] - 0x30 ) ) * 10 + ( buffer[ 2 ] - 0x30 ); free( buffer ); if ( code > 210 ) return code; /* skip the first row, and copy the data that follows into the result buffer*/ *result_buffer = ( char* ) malloc( 1 ); strcpy( *result_buffer, "" ); count = 1; do { buffer = get_string_piece( socket, '\n' ); if ( strncmp( buffer, "TTITLE", 6 ) == 0 ) { sprintf( status_buf, _("Reading Information about track %2d"), count ); main_window_handler( MW_UPDATE_STATUSBAR, status_buf, NULL ); while ( gtk_events_pending() ) gtk_main_iteration(); count++; } #ifdef DEBUG printf( "<= %s", buffer ); #endif string_append( result_buffer, buffer ); free( buffer ); } while ( strstr( *result_buffer, "\r\n.\r\n" ) == NULL ); main_window_handler( MW_UPDATE_STATUSBAR, _("Done..."), NULL ); while ( gtk_events_pending() ) gtk_main_iteration(); return code; } int cddbp_stat( FILE *socket, char **result ) { int code; char *buffer; #ifdef DEBUG printf( "=> stat\n" ); #endif fprintf( socket, "stat\n" ); buffer = get_string_piece( socket, '\n' ); if (buffer == NULL) return -1; #ifdef DEBUG printf( "<= %s\n", buffer ); #endif code = ( ( buffer[ 0 ] - 0x30 ) * 10 + ( buffer[ 1 ] - 0x30 ) ) * 10 + ( buffer[ 2 ] - 0x30 ); free( buffer ); if ( code > 210 ) return code; do { buffer = get_string_piece( socket, '\n' ); #ifdef DEBUG printf( "<= %s", buffer ); #endif string_append( result, buffer ); free( buffer ); } while ( strstr( *result, "\r\n.\r\n" ) == NULL ); return code; } void cddbp_signoff( FILE *socket ) { char * buffer; fprintf( socket, "quit\n" ); buffer = get_string_piece( socket, '\n' ); free( buffer ); fclose( socket ); #ifdef DEBUG printf( "Signing off\n" ); #endif } int http_query( const char *server, int port, const char *URL, const char *cd_id, int tracknum, long int offset[], int duration, int *matches, char ***category_buffer, char ***title_buffer, char ***id_buffer, const char *client, const char *version ) { char * buffer = ( char* ) malloc( 1024 ), *tmp = ( char* ) malloc( 1024 ); int i, code; FILE *sock; sprintf( buffer, "GET /%s?cmd=cddb+query+%s+%d", URL, cd_id, tracknum ); for ( i = 0; i < tracknum; i++ ) { sprintf( tmp, "+%ld", offset[ i ] ); strcat( buffer, tmp ); strcpy( tmp, "" ); } sprintf( tmp, "+%d&hello=%s+%s+%s+%s&proto=1 HTTP/1.0\r\n\r\n", duration, "anonymous", "localhost", client, version ); strcat( buffer, tmp ); free( tmp ); #ifdef DEBUG printf( "=> %s\n", buffer ); #endif sock = socket_init( server, port ); if ( !sock ) return 999; fprintf( sock, "%s", buffer ); free( buffer ); buffer = get_ascii_file( sock ); #ifdef DEBUG printf( "<= %s\n", buffer ); #endif /* strip the http header of the answer */ tmp = strstr( buffer, "\r\n\r\n" ); if ( tmp == NULL ) { /* uhoh, no empty row anywhere.... */ free( buffer ); return -1; } tmp += 4; tmp = strdup( tmp ); free( buffer ); buffer = tmp; *matches = 0; code = ( ( tmp[ 0 ] - 0x30 ) * 10 + ( tmp[ 1 ] - 0x30 ) ) * 10 + ( tmp[ 2 ] - 0x30 ); if ( code == 200 ) { buffer += 4; } else if ( code == 211 ) { buffer = strchr( buffer, '\n' ); } else { free( tmp ); return code; } *title_buffer = ( char** ) malloc( sizeof( char* ) * 1000 ); *category_buffer = ( char** ) malloc( sizeof( char* ) * 1000 ); *id_buffer = ( char** ) malloc( sizeof( char* ) * 1000 ); do { if ( strcmp( buffer, ".\r\n" ) == 0 ) break; /* if we get more than 1000 matches, the char*[] will be full, and we will skip the remaining few million matches */ if ( *matches == 999 ) { continue; } i = strcspn( buffer, " " ); if ( buffer[ 0 ] == '\n' ) /* skip the \n only if it is there */ { buffer++; i--; } ( *category_buffer ) [ *matches ] = ( char* ) malloc( i + 1 ); strncpy( ( *category_buffer ) [ *matches ], buffer, i ); ( *category_buffer ) [ *matches ][ i ] = 0; /*terminate the string*/ buffer += i + 1; /* skip to the disk id */ ( *id_buffer ) [ *matches ] = ( char* ) malloc( 9 ); /* the disk id is always 8 char long */ strncpy( ( *id_buffer ) [ *matches ], buffer, 8 ); ( *id_buffer ) [ *matches ][ 8 ] = 0; /*terminate the string */ buffer += 9; i = strcspn( buffer, "\r\n" ); ( *title_buffer ) [ *matches ] = ( char* ) malloc( i + 1 ); strncpy( ( *title_buffer ) [ *matches ], buffer, i ); ( *title_buffer ) [ *matches ][ i ] = 0; /*terminate the string */ ( *matches ) ++; buffer += i + 2; /* skip the \r\n */ } while ( ( buffer = strchr( buffer, '\n' ) ) != NULL ); #ifdef DEBUG printf( "category: %s, title: %s", ( *category_buffer ) [ 0 ], ( *title_buffer ) [ 0 ] ); #endif free( tmp ); return code; } int http_query_proxy( const char *server, int port, const char *proxy_server, int proxy_port, const char *URL, const char *cd_id, int tracknum, long int offset[], int duration, int *matches, char ***category_buffer, char ***title_buffer, char ***id_buffer, const char *client, const char *version ) { char * buffer = ( char* ) malloc( 1024 ), *tmp = ( char* ) malloc( 1024 ); int i, code; FILE *sock; sprintf( buffer, "GET http://%s:%i/%s?cmd=cddb+query+%s+%d", server, port, URL, cd_id, tracknum ); for ( i = 0; i < tracknum; i++ ) { sprintf( tmp, "+%ld", offset[ i ] ); strcat( buffer, tmp ); strcpy( tmp, "" ); } sprintf( tmp, "+%d&hello=%s+%s+%s+%s&proto=1 HTTP/1.0\r\n\r\n", duration, "anonymous", "localhost", client, version ); strcat( buffer, tmp ); free( tmp ); #ifdef DEBUG printf( "=> %s\n", buffer ); #endif sock = socket_init( proxy_server, proxy_port ); if ( !sock ) return 999; fprintf( sock, "%s", buffer ); free( buffer ); buffer = get_ascii_file( sock ); #ifdef DEBUG printf( "<= %s\n", buffer ); #endif /* strip the http header of the answer */ tmp = strstr( buffer, "\r\n\r\n" ); if ( tmp == NULL ) { /* uhoh, no empty row anywhere.... */ free( buffer ); return - 1; } tmp += 4; tmp = strdup( tmp ); free( buffer ); buffer = tmp; *matches = 0; code = ( ( tmp[ 0 ] - 0x30 ) * 10 + ( tmp[ 1 ] - 0x30 ) ) * 10 + ( tmp[ 2 ] - 0x30 ); if ( code == 200 ) { buffer += 4; } else if ( code == 211 ) { buffer = strchr( buffer, '\n' ); } else { free( tmp ); return code; } *title_buffer = ( char** ) malloc( sizeof( char* ) * 1000 ); *category_buffer = ( char** ) malloc( sizeof( char* ) * 1000 ); *id_buffer = ( char** ) malloc( sizeof( char* ) * 1000 ); do { if ( strcmp( buffer, ".\r\n" ) == 0 ) break; /* if we get more than 1000 matches, the char*[] will be full, and we will skip the remaining few million matches */ if ( *matches == 999 ) { continue; } i = strcspn( buffer, " " ); if ( buffer[ 0 ] == '\n' ) /* skip the \n only if it is there */ { buffer++; i--; } ( *category_buffer ) [ *matches ] = ( char* ) malloc( i + 1 ); strncpy( ( *category_buffer ) [ *matches ], buffer, i ); ( *category_buffer ) [ *matches ][ i ] = 0; /*terminate the string*/ buffer += i + 1; /* skip to the disk id */ ( *id_buffer ) [ *matches ] = ( char* ) malloc( 9 ); /* the disk id is always 8 char long */ strncpy( ( *id_buffer ) [ *matches ], buffer, 8 ); ( *id_buffer ) [ *matches ][ 8 ] = 0; /*terminate the string */ buffer += 9; i = strcspn( buffer, "\r\n" ); ( *title_buffer ) [ *matches ] = ( char* ) malloc( i + 1 ); strncpy( ( *title_buffer ) [ *matches ], buffer, i ); ( *title_buffer ) [ *matches ][ i ] = 0; /*terminate the string */ ( *matches ) ++; buffer += i + 2; /* skip the \r\n */ } while ( ( buffer = strchr( buffer, '\n' ) ) != NULL ); #ifdef DEBUG printf( "category: %s, title: %s", ( *category_buffer ) [ 0 ], ( *title_buffer ) [ 0 ] ); #endif free( tmp ); return code; } int http_read( const char *server, int port, const char *URL, const char *category, const char *disk_id, char **result, const char *client, const char *version ) { int code; char *buffer, *tmp; FILE *sock; #ifdef DEBUG printf( "=> GET /%s?cmd=cddb+read+%s+%s&hello=%s+%s+%s+%s&proto=1 HTTP/1.0\r\n\r\n", URL, category, disk_id, "anonymouse", "localhost", client, version ); #endif sock = socket_init( server, port ); if ( !sock ) return 999; fprintf( sock, "GET /%s?cmd=cddb+read+%s+%s&hello=%s+%s+%s+%s&proto=5 HTTP/1.0\r\n\r\n", URL, category, disk_id, "anonymous", "localhost", client, version ); buffer = get_ascii_file( sock ); #ifdef DEBUG printf( "<= %s\n", buffer ); #endif /* strip the http header of the answer */ tmp = strstr( buffer, "\r\n\r\n" ); if ( tmp == NULL ) { /* uhoh, no empty row anywhere.... */ free( buffer ); return - 1; } tmp += 4; tmp = strdup( tmp ); free( buffer ); buffer = tmp; code = ( ( buffer[ 0 ] - 0x30 ) * 10 + ( buffer[ 1 ] - 0x30 ) ) * 10 + ( buffer[ 2 ] - 0x30 ); if ( code > 210 ) { free( buffer ); return code; } /* skip the first row, and copy the data that follows into the result buffer*/ tmp = strchr( buffer, '\n' ) + 1; *result = strdup( tmp ); free( buffer ); return code; } int http_read_proxy( const char *server, int port, const char *proxy_server, int proxy_port, const char *URL, const char *category, const char *disk_id, char **result, const char *client, const char *version ) { int code; char *buffer, *tmp; FILE *sock; #ifdef DEBUG printf( "=> GET http://%s:%i/%s?cmd=cddb+read+%s+%s&hello=%s+%s+%s+%s&proto=1 HTTP/1.0\r\n\r\n", server, port, URL, category, disk_id, "anonymous", "localhost", client, version ); #endif sock = socket_init( proxy_server, proxy_port ); if ( !sock ) return 999; fprintf( sock, "GET http://%s:%i/%s?cmd=cddb+read+%s+%s&hello=%s+%s+%s+%s&proto=5 HTTP/1.0\r\n\r\n", server, port, URL, category, disk_id, "anonymous", "localhost", client, version ); buffer = get_ascii_file( sock ); #ifdef DEBUG printf( "<= %s\n", buffer ); #endif /* strip the http header of the answer */ tmp = strstr( buffer, "\r\n\r\n" ); if ( tmp == NULL ) { /* uhoh, no empty row anywhere.... */ free( buffer ); return - 1; } tmp += 4; tmp = strdup( tmp ); free( buffer ); buffer = tmp; code = ( ( buffer[ 0 ] - 0x30 ) * 10 + ( buffer[ 1 ] - 0x30 ) ) * 10 + ( buffer[ 2 ] - 0x30 ); if ( code > 210 ) { free( buffer ); return code; } /* skip the first row, and copy the data that follows into the result buffer*/ tmp = strchr( buffer, '\n' ) + 1; *result = strdup( tmp ); free( buffer ); return code; } int http_stat( const char *server, int port, const char *URL, char **result, const char *client, const char *version ) { int code; char *buffer, *tmp; FILE *sock; #ifdef DEBUG printf( "=> GET /%s?cmd=stat&hello=%s+%s+%s+%s&proto=1 HTTP/1.0\r\n\r\n", URL, "anonymous", "localhost", client, version ); #endif sock = socket_init( server, port ); if ( !sock ) return 999; fprintf( sock, "GET /%s?cmd=stat&hello=%s+%s+%s+%s&proto=1 HTTP/1.0\r\n\r\n", URL, "anonymous", "localhost", client, version ); buffer = get_ascii_file( sock ); #ifdef DEBUG printf( "<= %s\n", buffer ); #endif /* strip the http header of the answer */ tmp = strstr( buffer, "\r\n\r\n" ); if ( tmp == NULL ) { /* uhoh, no empty row anywhere.... */ free( buffer ); return - 1; } tmp += 4; tmp = strdup( tmp ); free( buffer ); buffer = tmp; code = ( ( buffer[ 0 ] - 0x30 ) * 10 + ( buffer[ 1 ] - 0x30 ) ) * 10 + ( buffer[ 2 ] - 0x30 ); if ( code > 210 ) { free( buffer ); return code; } /* skip the first row, and copy the data that follows into the result buffer*/ tmp = strchr( buffer, '\n' ) + 1; *result = strdup( tmp ); free( buffer ); return code; }