Commit 1658f171 authored by Ed "oddsock" Zaleski's avatar Ed "oddsock" Zaleski

added parsing of new icy-audio-info header which will be used to

communicate things like samplerate/quality/number of channels to
icecast2. This info will be then forwarded to the yp servers for
better stream info.

also factored out some logic in source_main into common functions

added a few new routines into util.c (taken from Brendan's
updates to libshout)

svn path=/trunk/icecast/; revision=4379
parent 680e56bf
This diff is collapsed.
......@@ -3,6 +3,7 @@
#include "config.h"
#include "yp.h"
#include "util.h"
#include "format.h"
typedef struct source_tag
......@@ -27,6 +28,7 @@ typedef struct source_tag
rwlock_t *shutdown_rwlock;
ypdata_t *ypdata[MAX_YP_DIRECTORIES];
util_dict *audio_info;
int num_yp_directories;
long listeners;
long max_listeners;
......
......@@ -385,3 +385,139 @@ char *util_base64_decode(unsigned char *input)
return result;
}
util_dict *util_dict_new(void)
{
return (util_dict *)calloc(1, sizeof(util_dict));
}
void util_dict_free(util_dict *dict)
{
util_dict *next;
while (dict) {
next = dict->next;
if (dict->key)
free (dict->key);
if (dict->val)
free (dict->val);
free (dict);
dict = next;
}
}
const char *util_dict_get(util_dict *dict, const char *key)
{
while (dict) {
if (!strcmp(key, dict->key))
return dict->val;
dict = dict->next;
}
}
int util_dict_set(util_dict *dict, const char *key, const char *val)
{
util_dict *prev;
if (!dict || !key) {
ERROR0("NULL values passed to util_dict_set()");
return 0;
}
prev = NULL;
while (dict) {
if (!dict->key || !strcmp(dict->key, key))
break;
prev = dict;
dict = dict->next;
}
if (!dict) {
dict = util_dict_new();
if (!dict) {
ERROR0("unable to allocate new dictionary");
return 0;
}
if (prev)
prev->next = dict;
}
if (dict->key)
free (dict->val);
else if (!(dict->key = strdup(key))) {
if (prev)
prev->next = NULL;
util_dict_free (dict);
ERROR0("unable to allocate new dictionary key");
return 0;
}
dict->val = strdup(val);
if (!dict->val) {
ERROR0("unable to allocate new dictionary value");
return 0;
}
return 1;
}
/* given a dictionary, URL-encode each key and val and
stringify them in order as key=val&key=val... if val
is set, or just key&key if val is NULL.
TODO: Memory management needs overhaul. */
char *util_dict_urlencode(util_dict *dict, char delim)
{
char *res, *tmp;
char *enc;
int start = 1;
for (res = NULL; dict; dict = dict->next) {
/* encode key */
if (!dict->key)
continue;
if (!(enc = util_url_escape(dict->key))) {
if (res)
free(res);
return NULL;
}
if (start) {
if (!(res = malloc(strlen(enc) + 1))) {
free(enc);
return NULL;
}
sprintf(res, "%s", enc);
free(enc);
start = 0;
} else {
if (!(tmp = realloc(res, strlen(res) + strlen(enc) + 2))) {
free(enc);
free(res);
return NULL;
} else
res = tmp;
sprintf(res + strlen(res), "%c%s", delim, enc);
free(enc);
}
/* encode value */
if (!dict->val)
continue;
if (!(enc = util_url_escape(dict->val))) {
free(res);
return NULL;
}
if (!(tmp = realloc(res, strlen(res) + strlen(enc) + 2))) {
free(enc);
free(res);
return NULL;
} else
res = tmp;
sprintf(res + strlen(res), "=%s", enc);
free(enc);
}
return res;
}
......@@ -16,4 +16,18 @@ char *util_base64_decode(unsigned char *input);
char *util_url_escape(char *src);
/* String dictionary type, without support for NULL keys, or multiple
* instances of the same key */
typedef struct _util_dict {
char *key;
char *val;
struct _util_dict *next;
} util_dict;
util_dict *util_dict_new(void);
void util_dict_free(util_dict *dict);
/* dict, key must not be NULL. */
int util_dict_set(util_dict *dict, const char *key, const char *val);
const char *util_dict_get(util_dict *dict, const char *key);
char *util_dict_urlencode(util_dict *dict, char delim);
#endif /* __UTIL_H__ */
......@@ -196,8 +196,9 @@ int yp_add(source_t *source, int which)
if (ok) {
if (source->ypdata[i]) {
url_size = strlen("action=add&sn=&genre=&cpswd=&desc=&url="
"&listenurl=&type=&b=") + 1;
url_size = strlen("action=add&sn=&genre=&cpswd="
"&desc=&url=&listenurl=&type=&b=&")
+ 1;
if (source->ypdata[i]->server_name) {
url_size += strlen(source->ypdata[i]->server_name);
}
......@@ -261,10 +262,18 @@ int yp_add(source_t *source, int which)
source->ypdata[i]->current_song = (char *)malloc(1);
source->ypdata[i]->current_song[0] = 0;
}
if (source->ypdata[i]->audio_info) {
url_size += strlen(source->ypdata[i]->audio_info);
}
else {
source->ypdata[i]->audio_info = (char *)malloc(1);
source->ypdata[i]->audio_info[0] = 0;
}
url_size += 1024;
url = malloc(url_size);
sprintf(url, "action=add&sn=%s&genre=%s&cpswd=%s&desc=%s&url=%s"
"&listenurl=%s&type=%s&b=%s",
sprintf(url, "action=add&sn=%s&genre=%s&cpswd=%s&desc="
"%s&url=%s&listenurl=%s&type=%s&b=%s&%s",
source->ypdata[i]->server_name,
source->ypdata[i]->server_genre,
source->ypdata[i]->cluster_password,
......@@ -272,7 +281,8 @@ int yp_add(source_t *source, int which)
source->ypdata[i]->server_url,
source->ypdata[i]->listen_url,
source->ypdata[i]->server_type,
source->ypdata[i]->bitrate);
source->ypdata[i]->bitrate,
source->ypdata[i]->audio_info);
curl_con = curl_get_connection();
if (curl_con < 0) {
......@@ -350,6 +360,9 @@ void yp_destroy_ypdata(ypdata_t *ypdata)
if (ypdata->server_type) {
free(ypdata->server_type);
}
if (ypdata->audio_info) {
free(ypdata->audio_info);
}
free(ypdata);
}
}
......
......@@ -16,6 +16,7 @@ typedef struct ypdata_tag
char *server_url;
char *listen_url;
char *bitrate;
char *audio_info;
char *server_type;
char *current_song;
char *yp_url;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment