mirror of
http://mpg123.de/trunk/.git
synced 2025-08-06 10:02:38 +03:00
Essential part of ICY support. It's in reader and http_open.
Missing is only proper output - and, that it actually works:-/ There is something fishy in the reader... git-svn-id: svn://scm.orgis.org/mpg123/trunk@536 35dc7657-300d-0410-a2e5-dc2837fedb53
This commit is contained in:
@@ -57,7 +57,7 @@ sub printdefs
|
|||||||
unshift(@args, '') if(@args);
|
unshift(@args, '') if(@args);
|
||||||
print ' #define '.$type.($i > 1 ? ($i-1) : '').'(s';
|
print ' #define '.$type.($i > 1 ? ($i-1) : '').'(s';
|
||||||
print join(', ', @args).') ';
|
print join(', ', @args).') ';
|
||||||
if($forreal){ print 'fprintf(stderr, "[" __FILE__ ":%i] '.$type.': " s "\n", __LINE__'.join(', ', @args).")\n"; }
|
if($forreal){ print 'fprintf(stderr, "[" __FILE__ ":%i] '.$type.': " s "\n", __LINE__'.join(', ', @args).");\n"; }
|
||||||
else{ print "{}\n"; }
|
else{ print "{}\n"; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -32,6 +32,8 @@ mpg123_SOURCES = \
|
|||||||
getlopt.h \
|
getlopt.h \
|
||||||
httpget.c \
|
httpget.c \
|
||||||
huffman.h \
|
huffman.h \
|
||||||
|
icy.c \
|
||||||
|
icy.h \
|
||||||
id3.c \
|
id3.c \
|
||||||
id3.h \
|
id3.h \
|
||||||
genre.h \
|
genre.h \
|
||||||
|
@@ -610,12 +610,12 @@ generic:
|
|||||||
mpg123-make:
|
mpg123-make:
|
||||||
@ $(MAKE) BINNAME=mpg123 mpg123
|
@ $(MAKE) BINNAME=mpg123 mpg123
|
||||||
|
|
||||||
mpg123: mpg123.o playlist.o stringbuf.o common.o id3.o $(OBJECTS) decode_2to1.o decode_4to1.o \
|
mpg123: mpg123.o playlist.o stringbuf.o common.o id3.o icy.o $(OBJECTS) decode_2to1.o decode_4to1.o \
|
||||||
tabinit.o audio.o layer1.o layer2.o layer3.o buffer.o \
|
tabinit.o audio.o layer1.o layer2.o layer3.o buffer.o \
|
||||||
getlopt.o httpget.o xfermem.o equalizer.o \
|
getlopt.o httpget.o xfermem.o equalizer.o \
|
||||||
decode_ntom.o $(MAKEFILE) wav.o readers.o getbits.o \
|
decode_ntom.o $(MAKEFILE) wav.o readers.o getbits.o \
|
||||||
control_generic.o
|
control_generic.o
|
||||||
$(CC) $(CFLAGS) $(LDFLAGS) mpg123.o playlist.o stringbuf.o tabinit.o common.o id3.o layer1.o \
|
$(CC) $(CFLAGS) $(LDFLAGS) mpg123.o playlist.o stringbuf.o tabinit.o common.o id3.o icy.o layer1.o \
|
||||||
layer2.o layer3.o audio.o buffer.o decode_2to1.o equalizer.o \
|
layer2.o layer3.o audio.o buffer.o decode_2to1.o equalizer.o \
|
||||||
decode_4to1.o getlopt.o httpget.o xfermem.o decode_ntom.o \
|
decode_4to1.o getlopt.o httpget.o xfermem.o decode_ntom.o \
|
||||||
wav.o readers.o getbits.o control_generic.o \
|
wav.o readers.o getbits.o control_generic.o \
|
||||||
@@ -653,7 +653,7 @@ buffer.o: mpg123.h xfermem.h buffer.h debug.h config.h
|
|||||||
getbits.o: common.h mpg123.h debug.h config.h
|
getbits.o: common.h mpg123.h debug.h config.h
|
||||||
tabinit.o: mpg123.h audio.h debug.h config.h
|
tabinit.o: mpg123.h audio.h debug.h config.h
|
||||||
getlopt.o: getlopt.h debug.h config.h
|
getlopt.o: getlopt.h debug.h config.h
|
||||||
httpget.o: mpg123.h debug.h config.h
|
httpget.o: mpg123.h debug.h config.h icy.h stringbuf.h
|
||||||
dct64.o: mpg123.h debug.h config.h
|
dct64.o: mpg123.h debug.h config.h
|
||||||
dct64_i386.o: mpg123.h debug.h config.h
|
dct64_i386.o: mpg123.h debug.h config.h
|
||||||
xfermem.o: xfermem.h debug.h config.h
|
xfermem.o: xfermem.h debug.h config.h
|
||||||
@@ -664,6 +664,7 @@ term.o: mpg123.h buffer.h term.h common.h debug.h config.h
|
|||||||
playlist.o: mpg123.h term.h getlopt.h debug.h config.h stringbuf.h
|
playlist.o: mpg123.h term.h getlopt.h debug.h config.h stringbuf.h
|
||||||
stringbuf.o: stringbuf.h config.h debug.h
|
stringbuf.o: stringbuf.h config.h debug.h
|
||||||
id3.o: config.h mpg123.h stringbuf.h genre.h id3.h debug.h common.h
|
id3.o: config.h mpg123.h stringbuf.h genre.h id3.h debug.h common.h
|
||||||
|
icy.o: icy.h stringbuf.h
|
||||||
control_generic.o: config.h mpg123.h common.h debug.h layer3.h
|
control_generic.o: config.h mpg123.h common.h debug.h layer3.h
|
||||||
|
|
||||||
|
|
||||||
|
66
src/debug.h
66
src/debug.h
@@ -26,17 +26,17 @@
|
|||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#define debug(s) fprintf(stderr, "[" __FILE__ ":%i] debug: " s "\n", __LINE__)
|
#define debug(s) fprintf(stderr, "[" __FILE__ ":%i] debug: " s "\n", __LINE__);
|
||||||
#define debug1(s, a) fprintf(stderr, "[" __FILE__ ":%i] debug: " s "\n", __LINE__, a)
|
#define debug1(s, a) fprintf(stderr, "[" __FILE__ ":%i] debug: " s "\n", __LINE__, a);
|
||||||
#define debug2(s, a, b) fprintf(stderr, "[" __FILE__ ":%i] debug: " s "\n", __LINE__, a, b)
|
#define debug2(s, a, b) fprintf(stderr, "[" __FILE__ ":%i] debug: " s "\n", __LINE__, a, b);
|
||||||
#define debug3(s, a, b, c) fprintf(stderr, "[" __FILE__ ":%i] debug: " s "\n", __LINE__, a, b, c)
|
#define debug3(s, a, b, c) fprintf(stderr, "[" __FILE__ ":%i] debug: " s "\n", __LINE__, a, b, c);
|
||||||
#define debug4(s, a, b, c, d) fprintf(stderr, "[" __FILE__ ":%i] debug: " s "\n", __LINE__, a, b, c, d)
|
#define debug4(s, a, b, c, d) fprintf(stderr, "[" __FILE__ ":%i] debug: " s "\n", __LINE__, a, b, c, d);
|
||||||
#define debug5(s, a, b, c, d, e) fprintf(stderr, "[" __FILE__ ":%i] debug: " s "\n", __LINE__, a, b, c, d, e)
|
#define debug5(s, a, b, c, d, e) fprintf(stderr, "[" __FILE__ ":%i] debug: " s "\n", __LINE__, a, b, c, d, e);
|
||||||
#define debug6(s, a, b, c, d, e, f) fprintf(stderr, "[" __FILE__ ":%i] debug: " s "\n", __LINE__, a, b, c, d, e, f)
|
#define debug6(s, a, b, c, d, e, f) fprintf(stderr, "[" __FILE__ ":%i] debug: " s "\n", __LINE__, a, b, c, d, e, f);
|
||||||
#define debug7(s, a, b, c, d, e, f, g) fprintf(stderr, "[" __FILE__ ":%i] debug: " s "\n", __LINE__, a, b, c, d, e, f, g)
|
#define debug7(s, a, b, c, d, e, f, g) fprintf(stderr, "[" __FILE__ ":%i] debug: " s "\n", __LINE__, a, b, c, d, e, f, g);
|
||||||
#define debug8(s, a, b, c, d, e, f, g, h) fprintf(stderr, "[" __FILE__ ":%i] debug: " s "\n", __LINE__, a, b, c, d, e, f, g, h)
|
#define debug8(s, a, b, c, d, e, f, g, h) fprintf(stderr, "[" __FILE__ ":%i] debug: " s "\n", __LINE__, a, b, c, d, e, f, g, h);
|
||||||
#define debug9(s, a, b, c, d, e, f, g, h, i) fprintf(stderr, "[" __FILE__ ":%i] debug: " s "\n", __LINE__, a, b, c, d, e, f, g, h, i)
|
#define debug9(s, a, b, c, d, e, f, g, h, i) fprintf(stderr, "[" __FILE__ ":%i] debug: " s "\n", __LINE__, a, b, c, d, e, f, g, h, i);
|
||||||
#define debug10(s, a, b, c, d, e, f, g, h, i, j) fprintf(stderr, "[" __FILE__ ":%i] debug: " s "\n", __LINE__, a, b, c, d, e, f, g, h, i, j)
|
#define debug10(s, a, b, c, d, e, f, g, h, i, j) fprintf(stderr, "[" __FILE__ ":%i] debug: " s "\n", __LINE__, a, b, c, d, e, f, g, h, i, j);
|
||||||
#else
|
#else
|
||||||
#define debug(s) {}
|
#define debug(s) {}
|
||||||
#define debug1(s, a) {}
|
#define debug1(s, a) {}
|
||||||
@@ -52,27 +52,27 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* warning macros also here... */
|
/* warning macros also here... */
|
||||||
#define warning(s) fprintf(stderr, "[" __FILE__ ":%i] warning: " s "\n", __LINE__)
|
#define warning(s) fprintf(stderr, "[" __FILE__ ":%i] warning: " s "\n", __LINE__);
|
||||||
#define warning1(s, a) fprintf(stderr, "[" __FILE__ ":%i] warning: " s "\n", __LINE__, a)
|
#define warning1(s, a) fprintf(stderr, "[" __FILE__ ":%i] warning: " s "\n", __LINE__, a);
|
||||||
#define warning2(s, a, b) fprintf(stderr, "[" __FILE__ ":%i] warning: " s "\n", __LINE__, a, b)
|
#define warning2(s, a, b) fprintf(stderr, "[" __FILE__ ":%i] warning: " s "\n", __LINE__, a, b);
|
||||||
#define warning3(s, a, b, c) fprintf(stderr, "[" __FILE__ ":%i] warning: " s "\n", __LINE__, a, b, c)
|
#define warning3(s, a, b, c) fprintf(stderr, "[" __FILE__ ":%i] warning: " s "\n", __LINE__, a, b, c);
|
||||||
#define warning4(s, a, b, c, d) fprintf(stderr, "[" __FILE__ ":%i] warning: " s "\n", __LINE__, a, b, c, d)
|
#define warning4(s, a, b, c, d) fprintf(stderr, "[" __FILE__ ":%i] warning: " s "\n", __LINE__, a, b, c, d);
|
||||||
#define warning5(s, a, b, c, d, e) fprintf(stderr, "[" __FILE__ ":%i] warning: " s "\n", __LINE__, a, b, c, d, e)
|
#define warning5(s, a, b, c, d, e) fprintf(stderr, "[" __FILE__ ":%i] warning: " s "\n", __LINE__, a, b, c, d, e);
|
||||||
#define warning6(s, a, b, c, d, e, f) fprintf(stderr, "[" __FILE__ ":%i] warning: " s "\n", __LINE__, a, b, c, d, e, f)
|
#define warning6(s, a, b, c, d, e, f) fprintf(stderr, "[" __FILE__ ":%i] warning: " s "\n", __LINE__, a, b, c, d, e, f);
|
||||||
#define warning7(s, a, b, c, d, e, f, g) fprintf(stderr, "[" __FILE__ ":%i] warning: " s "\n", __LINE__, a, b, c, d, e, f, g)
|
#define warning7(s, a, b, c, d, e, f, g) fprintf(stderr, "[" __FILE__ ":%i] warning: " s "\n", __LINE__, a, b, c, d, e, f, g);
|
||||||
#define warning8(s, a, b, c, d, e, f, g, h) fprintf(stderr, "[" __FILE__ ":%i] warning: " s "\n", __LINE__, a, b, c, d, e, f, g, h)
|
#define warning8(s, a, b, c, d, e, f, g, h) fprintf(stderr, "[" __FILE__ ":%i] warning: " s "\n", __LINE__, a, b, c, d, e, f, g, h);
|
||||||
#define warning9(s, a, b, c, d, e, f, g, h, i) fprintf(stderr, "[" __FILE__ ":%i] warning: " s "\n", __LINE__, a, b, c, d, e, f, g, h, i)
|
#define warning9(s, a, b, c, d, e, f, g, h, i) fprintf(stderr, "[" __FILE__ ":%i] warning: " s "\n", __LINE__, a, b, c, d, e, f, g, h, i);
|
||||||
#define warning10(s, a, b, c, d, e, f, g, h, i, j) fprintf(stderr, "[" __FILE__ ":%i] warning: " s "\n", __LINE__, a, b, c, d, e, f, g, h, i, j)
|
#define warning10(s, a, b, c, d, e, f, g, h, i, j) fprintf(stderr, "[" __FILE__ ":%i] warning: " s "\n", __LINE__, a, b, c, d, e, f, g, h, i, j);
|
||||||
|
|
||||||
/* error macros also here... */
|
/* error macros also here... */
|
||||||
#define error(s) fprintf(stderr, "[" __FILE__ ":%i] error: " s "\n", __LINE__)
|
#define error(s) fprintf(stderr, "[" __FILE__ ":%i] error: " s "\n", __LINE__);
|
||||||
#define error1(s, a) fprintf(stderr, "[" __FILE__ ":%i] error: " s "\n", __LINE__, a)
|
#define error1(s, a) fprintf(stderr, "[" __FILE__ ":%i] error: " s "\n", __LINE__, a);
|
||||||
#define error2(s, a, b) fprintf(stderr, "[" __FILE__ ":%i] error: " s "\n", __LINE__, a, b)
|
#define error2(s, a, b) fprintf(stderr, "[" __FILE__ ":%i] error: " s "\n", __LINE__, a, b);
|
||||||
#define error3(s, a, b, c) fprintf(stderr, "[" __FILE__ ":%i] error: " s "\n", __LINE__, a, b, c)
|
#define error3(s, a, b, c) fprintf(stderr, "[" __FILE__ ":%i] error: " s "\n", __LINE__, a, b, c);
|
||||||
#define error4(s, a, b, c, d) fprintf(stderr, "[" __FILE__ ":%i] error: " s "\n", __LINE__, a, b, c, d)
|
#define error4(s, a, b, c, d) fprintf(stderr, "[" __FILE__ ":%i] error: " s "\n", __LINE__, a, b, c, d);
|
||||||
#define error5(s, a, b, c, d, e) fprintf(stderr, "[" __FILE__ ":%i] error: " s "\n", __LINE__, a, b, c, d, e)
|
#define error5(s, a, b, c, d, e) fprintf(stderr, "[" __FILE__ ":%i] error: " s "\n", __LINE__, a, b, c, d, e);
|
||||||
#define error6(s, a, b, c, d, e, f) fprintf(stderr, "[" __FILE__ ":%i] error: " s "\n", __LINE__, a, b, c, d, e, f)
|
#define error6(s, a, b, c, d, e, f) fprintf(stderr, "[" __FILE__ ":%i] error: " s "\n", __LINE__, a, b, c, d, e, f);
|
||||||
#define error7(s, a, b, c, d, e, f, g) fprintf(stderr, "[" __FILE__ ":%i] error: " s "\n", __LINE__, a, b, c, d, e, f, g)
|
#define error7(s, a, b, c, d, e, f, g) fprintf(stderr, "[" __FILE__ ":%i] error: " s "\n", __LINE__, a, b, c, d, e, f, g);
|
||||||
#define error8(s, a, b, c, d, e, f, g, h) fprintf(stderr, "[" __FILE__ ":%i] error: " s "\n", __LINE__, a, b, c, d, e, f, g, h)
|
#define error8(s, a, b, c, d, e, f, g, h) fprintf(stderr, "[" __FILE__ ":%i] error: " s "\n", __LINE__, a, b, c, d, e, f, g, h);
|
||||||
#define error9(s, a, b, c, d, e, f, g, h, i) fprintf(stderr, "[" __FILE__ ":%i] error: " s "\n", __LINE__, a, b, c, d, e, f, g, h, i)
|
#define error9(s, a, b, c, d, e, f, g, h, i) fprintf(stderr, "[" __FILE__ ":%i] error: " s "\n", __LINE__, a, b, c, d, e, f, g, h, i);
|
||||||
#define error10(s, a, b, c, d, e, f, g, h, i, j) fprintf(stderr, "[" __FILE__ ":%i] error: " s "\n", __LINE__, a, b, c, d, e, f, g, h, i, j)
|
#define error10(s, a, b, c, d, e, f, g, h, i, j) fprintf(stderr, "[" __FILE__ ":%i] error: " s "\n", __LINE__, a, b, c, d, e, f, g, h, i, j);
|
||||||
|
@@ -58,6 +58,8 @@
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "mpg123.h"
|
#include "mpg123.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
#include "stringbuf.h"
|
||||||
|
#include "icy.h"
|
||||||
|
|
||||||
#ifndef INADDR_NONE
|
#ifndef INADDR_NONE
|
||||||
#define INADDR_NONE 0xffffffff
|
#define INADDR_NONE 0xffffffff
|
||||||
@@ -207,6 +209,29 @@ char *url2hostport (char *url, char **hname, unsigned long *hip, unsigned int *p
|
|||||||
return (cptr);
|
return (cptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char* get_header_val(const char *hname, char* response, size_t *length)
|
||||||
|
{
|
||||||
|
char *tmp = NULL;
|
||||||
|
size_t len = 0;
|
||||||
|
size_t prelen = strlen(hname);
|
||||||
|
/* if header name found, next char is at least something, so just check for : */
|
||||||
|
if(!strncasecmp(hname, response, prelen) && (response[prelen] == ':'))
|
||||||
|
{
|
||||||
|
++prelen;
|
||||||
|
if((tmp = strchr(response, '\r')) != NULL ) tmp[0] = 0;
|
||||||
|
if((tmp = strchr(response, '\n')) != NULL ) tmp[0] = 0;
|
||||||
|
len = strlen(response)-prelen;
|
||||||
|
tmp = response+prelen;
|
||||||
|
while(len && ((tmp[0] == ' ') || (tmp[0] == '\t')))
|
||||||
|
{
|
||||||
|
++tmp;
|
||||||
|
--len;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*length = len;
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
|
||||||
char *proxyurl = NULL;
|
char *proxyurl = NULL;
|
||||||
unsigned long proxyip = 0;
|
unsigned long proxyip = 0;
|
||||||
unsigned int proxyport;
|
unsigned int proxyport;
|
||||||
@@ -215,6 +240,9 @@ unsigned int proxyport;
|
|||||||
/* #define CONN_HEAD "Connection: close\r\n" */
|
/* #define CONN_HEAD "Connection: close\r\n" */
|
||||||
#define CONN_HEAD ""
|
#define CONN_HEAD ""
|
||||||
|
|
||||||
|
/* shoutcsast meta data: 1=on, 0=off */
|
||||||
|
#define ACCEPT_ICY_META "Icy-MetaData: 0\r\n"
|
||||||
|
|
||||||
char *httpauth = NULL;
|
char *httpauth = NULL;
|
||||||
char *httpauth1 = NULL;
|
char *httpauth1 = NULL;
|
||||||
|
|
||||||
@@ -320,9 +348,10 @@ int http_open (char* url, char** content_type)
|
|||||||
* ACCEPT_HEAD strlen(ACCEPT_HEAD)
|
* ACCEPT_HEAD strlen(ACCEPT_HEAD)
|
||||||
* "Authorization: Basic \r\n" 23
|
* "Authorization: Basic \r\n" 23
|
||||||
* "\r\n" 2
|
* "\r\n" 2
|
||||||
|
* ... plus the other predefined header lines
|
||||||
*/
|
*/
|
||||||
linelengthbase = 62 + strlen(PACKAGE_NAME) + strlen(PACKAGE_VERSION)
|
linelengthbase = 62 + strlen(PACKAGE_NAME) + strlen(PACKAGE_VERSION)
|
||||||
+ strlen(ACCEPT_HEAD) + strlen(CONN_HEAD);
|
+ strlen(ACCEPT_HEAD) + strlen(CONN_HEAD) + strlen(ACCEPT_ICY_META);
|
||||||
|
|
||||||
if(httpauth) {
|
if(httpauth) {
|
||||||
tmp = (strlen(httpauth) + 1) * 4;
|
tmp = (strlen(httpauth) + 1) * 4;
|
||||||
@@ -482,6 +511,7 @@ int http_open (char* url, char** content_type)
|
|||||||
} */
|
} */
|
||||||
strcat (request, ACCEPT_HEAD);
|
strcat (request, ACCEPT_HEAD);
|
||||||
strcat (request, CONN_HEAD);
|
strcat (request, CONN_HEAD);
|
||||||
|
strcat (request, ACCEPT_ICY_META);
|
||||||
server.sin_family = AF_INET;
|
server.sin_family = AF_INET;
|
||||||
server.sin_port = htons(myport);
|
server.sin_port = htons(myport);
|
||||||
server.sin_addr.s_addr = myip;
|
server.sin_addr.s_addr = myip;
|
||||||
@@ -622,24 +652,14 @@ int http_open (char* url, char** content_type)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
char *tmp;
|
||||||
|
size_t len;
|
||||||
/* watch out for content type */
|
/* watch out for content type */
|
||||||
debug1("searching for content-type... %s", response);
|
debug1("searching for header values... %s", response);
|
||||||
if(!strncasecmp("content-type:", response, 13))
|
if((tmp = get_header_val("content-type", response, &len)))
|
||||||
{
|
{
|
||||||
if(content_type != NULL)
|
if(content_type != NULL)
|
||||||
{
|
{
|
||||||
char *tmp = NULL;
|
|
||||||
size_t len = 0;
|
|
||||||
|
|
||||||
if((tmp = strchr(response, '\r')) != NULL ) tmp[0] = 0;
|
|
||||||
if((tmp = strchr(response, '\n')) != NULL ) tmp[0] = 0;
|
|
||||||
len = strlen(response)-13;
|
|
||||||
tmp = response+13;
|
|
||||||
while(len && ((tmp[0] == ' ') || (tmp[0] == '\t')))
|
|
||||||
{
|
|
||||||
++tmp;
|
|
||||||
--len;
|
|
||||||
}
|
|
||||||
if(len)
|
if(len)
|
||||||
{
|
{
|
||||||
if(*content_type != NULL) free(*content_type);
|
if(*content_type != NULL) free(*content_type);
|
||||||
@@ -650,10 +670,28 @@ int http_open (char* url, char** content_type)
|
|||||||
(*content_type)[len] = 0;
|
(*content_type)[len] = 0;
|
||||||
debug1("got type %s", *content_type);
|
debug1("got type %s", *content_type);
|
||||||
}
|
}
|
||||||
else fprintf(stderr, "Error: canno allocate memory for content type!\n");
|
else error("cannot allocate memory for content type!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/* watch out for icy-name */
|
||||||
|
else if((tmp = get_header_val("icy-name", response, &len)))
|
||||||
|
{
|
||||||
|
if(set_stringbuf(&icy.name, tmp)) debug1("got icy-name %s", icy.name.p)
|
||||||
|
else error1("unable to set icy name to %s!", tmp)
|
||||||
|
}
|
||||||
|
/* watch out for icy-url */
|
||||||
|
else if((tmp = get_header_val("icy-url", response, &len)))
|
||||||
|
{
|
||||||
|
if(set_stringbuf(&icy.url, tmp)) debug1("got icy-url %s", icy.name.p)
|
||||||
|
else error1("unable to set icy url to %s!", tmp)
|
||||||
|
}
|
||||||
|
/* watch out for icy-metaint */
|
||||||
|
else if((tmp = get_header_val("icy-metaint", response, &len)))
|
||||||
|
{
|
||||||
|
icy.interval = atoi(tmp);
|
||||||
|
debug1("got icy-metaint %li", (long int)icy.interval);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} while (response[0] != '\r' && response[0] != '\n');
|
} while (response[0] != '\r' && response[0] != '\n');
|
||||||
} while (relocate && purl[0] && numrelocs++ < HTTP_MAX_RELOCATIONS);
|
} while (relocate && purl[0] && numrelocs++ < HTTP_MAX_RELOCATIONS);
|
||||||
|
30
src/icy.c
Normal file
30
src/icy.c
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
#include "icy.h"
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
struct icy_meta icy;
|
||||||
|
|
||||||
|
void init_icy()
|
||||||
|
{
|
||||||
|
init_stringbuf(&icy.name);
|
||||||
|
init_stringbuf(&icy.url);
|
||||||
|
icy.data = NULL;
|
||||||
|
icy.interval = 0;
|
||||||
|
icy.next = 0;
|
||||||
|
icy.changed = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void clear_icy()
|
||||||
|
{
|
||||||
|
/* if pointers are non-null, they have some memory */
|
||||||
|
free_stringbuf(&icy.name);
|
||||||
|
free_stringbuf(&icy.url);
|
||||||
|
free(icy.data);
|
||||||
|
init_icy();
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_data(char* new_data)
|
||||||
|
{
|
||||||
|
if(icy.data) free(icy.data);
|
||||||
|
icy.data = new_data;
|
||||||
|
icy.changed = 1;
|
||||||
|
}
|
26
src/icy.h
Normal file
26
src/icy.h
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
/*
|
||||||
|
icy: support for SHOUTcast ICY meta info, an attempt to keep it organized
|
||||||
|
|
||||||
|
copyright 2006 by the mpg123 project - free software under the terms of the LGPL 2.1
|
||||||
|
see COPYING and AUTHORS files in distribution or http://mpg123.de
|
||||||
|
initially written by Thomas Orgis and modelled after patch by Honza
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include "stringbuf.h"
|
||||||
|
|
||||||
|
struct icy_meta
|
||||||
|
{
|
||||||
|
struct stringbuf name;
|
||||||
|
struct stringbuf url;
|
||||||
|
char* data;
|
||||||
|
off_t interval;
|
||||||
|
off_t next;
|
||||||
|
int changed;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* bah, just make it global... why bother with all that poiner passing to "methods" when there will be only one? */
|
||||||
|
extern struct icy_meta icy;
|
||||||
|
|
||||||
|
void init_icy();
|
||||||
|
void clear_icy();
|
@@ -36,6 +36,7 @@
|
|||||||
#endif
|
#endif
|
||||||
#include "playlist.h"
|
#include "playlist.h"
|
||||||
#include "id3.h"
|
#include "id3.h"
|
||||||
|
#include "icy.h"
|
||||||
|
|
||||||
static void usage(int err);
|
static void usage(int err);
|
||||||
static void want_usage(char* arg);
|
static void want_usage(char* arg);
|
||||||
@@ -814,12 +815,15 @@ int main(int argc, char *argv[])
|
|||||||
if(param.remote) {
|
if(param.remote) {
|
||||||
int ret;
|
int ret;
|
||||||
init_id3();
|
init_id3();
|
||||||
|
init_icy();
|
||||||
ret = control_generic(&fr);
|
ret = control_generic(&fr);
|
||||||
|
clear_icy();
|
||||||
exit_id3();
|
exit_id3();
|
||||||
safe_exit(ret);
|
safe_exit(ret);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
init_icy();
|
||||||
init_id3(); /* prepare id3 memory */
|
init_id3(); /* prepare id3 memory */
|
||||||
while ((fname = get_next_file())) {
|
while ((fname = get_next_file())) {
|
||||||
char *dirname, *filename;
|
char *dirname, *filename;
|
||||||
@@ -1025,6 +1029,7 @@ tc_hack:
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
} /* end of loop over input files */
|
} /* end of loop over input files */
|
||||||
|
clear_icy();
|
||||||
exit_id3(); /* free id3 memory */
|
exit_id3(); /* free id3 memory */
|
||||||
#ifndef NOXFERMEM
|
#ifndef NOXFERMEM
|
||||||
if (param.usebuffer) {
|
if (param.usebuffer) {
|
||||||
|
@@ -17,11 +17,87 @@
|
|||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include "buffer.h"
|
#include "buffer.h"
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
#include "icy.h"
|
||||||
|
|
||||||
static off_t get_fileinfo(struct reader *,char *buf);
|
static off_t get_fileinfo(struct reader *,char *buf);
|
||||||
|
|
||||||
|
static ssize_t icy_fullread(struct reader *rds,unsigned char *buf, ssize_t count);
|
||||||
|
static ssize_t plain_fullread(struct reader *rds,unsigned char *buf, ssize_t count);
|
||||||
|
ssize_t (*fullread)(struct reader *,unsigned char *, ssize_t) = plain_fullread;
|
||||||
|
|
||||||
|
/* stream based operation with icy meta data*/
|
||||||
|
static ssize_t icy_fullread(struct reader *rds,unsigned char *buf, ssize_t count)
|
||||||
|
{
|
||||||
|
ssize_t ret,cnt;
|
||||||
|
cnt = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
We check against READER_ID3TAG instead of rds->filelen >= 0 because if we got the ID3 TAG we know we have the end of the file.
|
||||||
|
If we don't have an ID3 TAG, then it is possible the file has grown since we started playing, so we want to keep reading from it if possible.
|
||||||
|
*/
|
||||||
|
if((rds->flags & READER_ID3TAG) && rds->filepos + count > rds->filelen) count = rds->filelen - rds->filepos;
|
||||||
|
|
||||||
|
while(cnt < count)
|
||||||
|
{
|
||||||
|
/* all icy code is inside this if block, everything else is the plain fullread we know */
|
||||||
|
if(icy.interval && (rds->filepos+count > icy.next))
|
||||||
|
{
|
||||||
|
char temp_buff;
|
||||||
|
int meta_size;
|
||||||
|
ssize_t cut_pos;
|
||||||
|
|
||||||
|
/* we are near icy-metaint boundary, read up to the boundary */
|
||||||
|
cut_pos = icy.next-rds->filepos;
|
||||||
|
ret = read(rds->filept,buf,cut_pos);
|
||||||
|
if(ret < 0) return ret;
|
||||||
|
|
||||||
|
rds->filepos += ret;
|
||||||
|
cnt += ret;
|
||||||
|
|
||||||
|
/* now off to read icy data */
|
||||||
|
|
||||||
|
/* one byte icy-meta size (must be multiplied by 16 to get icy-meta length) */
|
||||||
|
ret = read(rds->filept,&temp_buff,1);
|
||||||
|
if(ret < 0) return ret;
|
||||||
|
if(ret == 0) break;
|
||||||
|
|
||||||
|
rds->filepos += ret; /* 1... */
|
||||||
|
|
||||||
|
if((meta_size = (unsigned int) temp_buff * 16))
|
||||||
|
{
|
||||||
|
/* we have got some metadata */
|
||||||
|
char *meta_buff;
|
||||||
|
meta_buff = (char*) malloc(meta_size+1);
|
||||||
|
meta_buff[meta_size] = 0; /* string paranoia */
|
||||||
|
if(meta_buff != NULL)
|
||||||
|
{
|
||||||
|
ret = read(rds->filept,meta_buff,meta_size);
|
||||||
|
if(ret < 0) return ret;
|
||||||
|
|
||||||
|
rds->filepos += ret;
|
||||||
|
|
||||||
|
if(icy.data) free(icy.data);
|
||||||
|
icy.data = meta_buff;
|
||||||
|
icy.changed = 1;
|
||||||
|
debug2("icy-meta: %s size: %d bytes", icy.data, meta_size);
|
||||||
|
}
|
||||||
|
else error("cannot allocate memory for meta_buff!");
|
||||||
|
}
|
||||||
|
icy.next = rds->filepos+icy.interval;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = read(rds->filept,buf+cnt,count-cnt);
|
||||||
|
if(ret < 0) return ret;
|
||||||
|
if(ret == 0) break;
|
||||||
|
|
||||||
|
rds->filepos += ret;
|
||||||
|
cnt += ret;
|
||||||
|
}
|
||||||
|
return cnt;
|
||||||
|
}
|
||||||
|
|
||||||
/* stream based operation */
|
/* stream based operation */
|
||||||
static ssize_t fullread(struct reader *rds,unsigned char *buf, ssize_t count)
|
static ssize_t plain_fullread(struct reader *rds,unsigned char *buf, ssize_t count)
|
||||||
{
|
{
|
||||||
ssize_t ret,cnt=0;
|
ssize_t ret,cnt=0;
|
||||||
|
|
||||||
@@ -275,6 +351,7 @@ int open_stream(char *bs_filenam,int fd)
|
|||||||
int filept_opened = 1;
|
int filept_opened = 1;
|
||||||
int filept; /* descriptor of opened file/stream */
|
int filept; /* descriptor of opened file/stream */
|
||||||
|
|
||||||
|
clear_icy();
|
||||||
if(!bs_filenam) /* no file to open, got a descriptor (stdin) */
|
if(!bs_filenam) /* no file to open, got a descriptor (stdin) */
|
||||||
{
|
{
|
||||||
if(fd < 0) /* special: read from stdin */
|
if(fd < 0) /* special: read from stdin */
|
||||||
@@ -328,6 +405,8 @@ int open_stream(char *bs_filenam,int fd)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(icy.interval) fullread = icy_fullread;
|
||||||
|
fullread = icy_fullread;
|
||||||
/* id3tag printing moved to read_frame */
|
/* id3tag printing moved to read_frame */
|
||||||
return filept;
|
return filept;
|
||||||
}
|
}
|
||||||
|
@@ -82,3 +82,9 @@ int add_to_stringbuf(struct stringbuf* sb, char* stuff)
|
|||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int set_stringbuf(struct stringbuf* sb, char* stuff)
|
||||||
|
{
|
||||||
|
sb->fill = 0;
|
||||||
|
return add_to_stringbuf(sb, stuff);
|
||||||
|
}
|
||||||
|
@@ -23,5 +23,6 @@ void free_stringbuf(struct stringbuf* sb);
|
|||||||
int resize_stringbuf(struct stringbuf* sb, size_t new);
|
int resize_stringbuf(struct stringbuf* sb, size_t new);
|
||||||
int copy_stringbuf(struct stringbuf* from, struct stringbuf* to);
|
int copy_stringbuf(struct stringbuf* from, struct stringbuf* to);
|
||||||
int add_to_stringbuf(struct stringbuf* sb, char* stuff);
|
int add_to_stringbuf(struct stringbuf* sb, char* stuff);
|
||||||
|
int set_stringbuf(struct stringbuf* sb, char* stuff);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Reference in New Issue
Block a user