mirror of
https://gitlab.xiph.org/xiph/icecast-server.git
synced 2024-12-04 14:46:30 -05:00
Feature: Added UUID interpolation for dump files
This commit is contained in:
parent
5cf8cb9a99
commit
43a8c04134
@ -275,6 +275,23 @@ static fallback_override_t config_str_to_fallback_override_t(ice_config_t *confi
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static interpolation_t config_str_to_interpolation_t(ice_config_t *configuration, xmlNodePtr node, const char *str)
|
||||||
|
{
|
||||||
|
if (!str || !*str || strcmp(str, "default") == 0) {
|
||||||
|
return INTERPOLATION_DEFAULT;
|
||||||
|
} else if (strcasecmp(str, "none") == 0) {
|
||||||
|
return INTERPOLATION_NONE;
|
||||||
|
} else if (strcasecmp(str, "strftime") == 0) {
|
||||||
|
return INTERPOLATION_STRFTIME;
|
||||||
|
} else if (strcasecmp(str, "uuid") == 0) {
|
||||||
|
return INTERPOLATION_UUID;
|
||||||
|
} else {
|
||||||
|
__found_bad_tag(configuration, node, BTR_INVALID, str);
|
||||||
|
ICECAST_LOG_ERROR("Unknown interpolation type \"%s\", falling back to DEFAULT.", str);
|
||||||
|
return INTERPOLATION_DEFAULT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
char * config_href_to_id(ice_config_t *configuration, xmlNodePtr node, const char *href)
|
char * config_href_to_id(ice_config_t *configuration, xmlNodePtr node, const char *href)
|
||||||
{
|
{
|
||||||
if (!href || !*href)
|
if (!href || !*href)
|
||||||
@ -1744,8 +1761,13 @@ static void _parse_mount(xmlDocPtr doc,
|
|||||||
password = (char *)xmlNodeListGetString(doc,
|
password = (char *)xmlNodeListGetString(doc,
|
||||||
node->xmlChildrenNode, 1);
|
node->xmlChildrenNode, 1);
|
||||||
} else if (xmlStrcmp(node->name, XMLSTR("dump-file")) == 0) {
|
} else if (xmlStrcmp(node->name, XMLSTR("dump-file")) == 0) {
|
||||||
|
xmlChar * interpolation = xmlGetProp(node, XMLSTR("interpolation"));
|
||||||
|
if (interpolation) {
|
||||||
|
mount->dumpfile_interpolation = config_str_to_interpolation_t(configuration, node, (const char *)interpolation);
|
||||||
|
xmlFree(interpolation);
|
||||||
|
}
|
||||||
mount->dumpfile = (char *)xmlNodeListGetString(doc,
|
mount->dumpfile = (char *)xmlNodeListGetString(doc,
|
||||||
node->xmlChildrenNode, 1);
|
node->xmlChildrenNode, 1);
|
||||||
} else if (xmlStrcmp(node->name, XMLSTR("dump-file-size-limit")) == 0) {
|
} else if (xmlStrcmp(node->name, XMLSTR("dump-file-size-limit")) == 0) {
|
||||||
unsigned int val = mount->dumpfile_size_limit;
|
unsigned int val = mount->dumpfile_size_limit;
|
||||||
__read_unsigned_int(configuration, doc, node, &val, 0, UINT_MAX);
|
__read_unsigned_int(configuration, doc, node, &val, 0, UINT_MAX);
|
||||||
@ -3008,6 +3030,8 @@ static void merge_mounts(mount_proxy * dst, mount_proxy * src)
|
|||||||
|
|
||||||
if (!dst->dumpfile)
|
if (!dst->dumpfile)
|
||||||
dst->dumpfile = (char*)xmlStrdup((xmlChar*)src->dumpfile);
|
dst->dumpfile = (char*)xmlStrdup((xmlChar*)src->dumpfile);
|
||||||
|
if (dst->dumpfile_interpolation == INTERPOLATION_DEFAULT)
|
||||||
|
dst->dumpfile_interpolation = src->dumpfile_interpolation;
|
||||||
if (!dst->dumpfile_size_limit)
|
if (!dst->dumpfile_size_limit)
|
||||||
dst->dumpfile_size_limit = src->dumpfile_size_limit;
|
dst->dumpfile_size_limit = src->dumpfile_size_limit;
|
||||||
if (!dst->dumpfile_time_limit)
|
if (!dst->dumpfile_time_limit)
|
||||||
|
@ -79,6 +79,13 @@ typedef enum {
|
|||||||
FALLBACK_OVERRIDE_OWN
|
FALLBACK_OVERRIDE_OWN
|
||||||
} fallback_override_t;
|
} fallback_override_t;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
INTERPOLATION_DEFAULT = 0,
|
||||||
|
INTERPOLATION_NONE,
|
||||||
|
INTERPOLATION_STRFTIME,
|
||||||
|
INTERPOLATION_UUID
|
||||||
|
} interpolation_t;
|
||||||
|
|
||||||
typedef struct _mount_proxy {
|
typedef struct _mount_proxy {
|
||||||
/* The mountpoint this proxy is used for */
|
/* The mountpoint this proxy is used for */
|
||||||
char *mountname;
|
char *mountname;
|
||||||
@ -88,6 +95,7 @@ typedef struct _mount_proxy {
|
|||||||
* NULL to not dump.
|
* NULL to not dump.
|
||||||
*/
|
*/
|
||||||
char *dumpfile;
|
char *dumpfile;
|
||||||
|
interpolation_t dumpfile_interpolation;
|
||||||
uint64_t dumpfile_size_limit;
|
uint64_t dumpfile_size_limit;
|
||||||
unsigned int dumpfile_time_limit;
|
unsigned int dumpfile_time_limit;
|
||||||
/* Send contents of file to client before the stream */
|
/* Send contents of file to client before the stream */
|
||||||
|
58
src/source.c
58
src/source.c
@ -634,12 +634,9 @@ static void send_to_listener (source_t *source, client_t *client, int deletion_e
|
|||||||
static bool source_open_dumpfile(source_t *source)
|
static bool source_open_dumpfile(source_t *source)
|
||||||
{
|
{
|
||||||
const char *filename = source->dumpfilename;
|
const char *filename = source->dumpfilename;
|
||||||
|
interpolation_t interpolation = source->dumpfile_interpolation;
|
||||||
time_t curtime = time(NULL);
|
time_t curtime = time(NULL);
|
||||||
#ifndef _WIN32
|
|
||||||
/* some of the below functions seems not to be standard winapi functions */
|
|
||||||
char buffer[PATH_MAX];
|
char buffer[PATH_MAX];
|
||||||
struct tm *loctime;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (!filename) {
|
if (!filename) {
|
||||||
ICECAST_LOG_WARN("Can not open dump file for source %#H. No filename defined.", source->mount);
|
ICECAST_LOG_WARN("Can not open dump file for source %#H. No filename defined.", source->mount);
|
||||||
@ -661,13 +658,46 @@ static bool source_open_dumpfile(source_t *source)
|
|||||||
|
|
||||||
ICECAST_LOG_DDEBUG("source=%p{.mount=%#H, .burst_point=%p, .stream_data=%p, .stream_data_tail=%p, ...}", source, source->mount, source->burst_point, source->stream_data, source->stream_data_tail);
|
ICECAST_LOG_DDEBUG("source=%p{.mount=%#H, .burst_point=%p, .stream_data=%p, .stream_data_tail=%p, ...}", source, source->mount, source->burst_point, source->stream_data, source->stream_data_tail);
|
||||||
|
|
||||||
|
if (interpolation == INTERPOLATION_DEFAULT) {
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
/* Convert it to local time representation. */
|
interpolation = INTERPOLATION_STRFTIME;
|
||||||
loctime = localtime(&curtime);
|
#else
|
||||||
|
interpolation = INTERPOLATION_NONE;
|
||||||
strftime(buffer, sizeof(buffer), filename, loctime);
|
|
||||||
filename = buffer;
|
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (interpolation) {
|
||||||
|
case INTERPOLATION_NONE:
|
||||||
|
/* no-op */
|
||||||
|
break;
|
||||||
|
case INTERPOLATION_STRFTIME:
|
||||||
|
#ifndef _WIN32
|
||||||
|
{
|
||||||
|
/* some of the below functions seems not to be standard winapi functions */
|
||||||
|
struct tm *loctime;
|
||||||
|
|
||||||
|
/* Convert it to local time representation. */
|
||||||
|
loctime = localtime(&curtime);
|
||||||
|
|
||||||
|
strftime(buffer, sizeof(buffer), filename, loctime);
|
||||||
|
filename = buffer;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
ICECAST_LOG_ERROR("Can not interpolation dump file filename for source %#H. strftime() interpolation is not supported by your operating system.", source->mount);
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
case INTERPOLATION_UUID:
|
||||||
|
if (!util_interpolation_uuid(buffer, sizeof(buffer), filename)) {
|
||||||
|
ICECAST_LOG_WARN("Can not open dump file for source %#H. Filename does not interpolate.", source->mount);
|
||||||
|
event_emit_va("dumpfile-error", EVENT_EXTRA_SOURCE, source, EVENT_EXTRA_LIST_END);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
filename = buffer;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ICECAST_LOG_ERROR("Bug. Bad interpolation %i. Source %p on %#H.", (int)interpolation, source, source->mount);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
source->dumpfile = fopen(filename, "ab");
|
source->dumpfile = fopen(filename, "ab");
|
||||||
|
|
||||||
@ -1258,11 +1288,13 @@ static void source_apply_mount (ice_config_t *config, source_t *source, mount_pr
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (mountinfo) {
|
if (mountinfo) {
|
||||||
source->dumpfile_size_limit = mountinfo->dumpfile_size_limit;
|
source->dumpfile_size_limit = mountinfo->dumpfile_size_limit;
|
||||||
source->dumpfile_time_limit = mountinfo->dumpfile_time_limit;
|
source->dumpfile_time_limit = mountinfo->dumpfile_time_limit;
|
||||||
|
source->dumpfile_interpolation = mountinfo->dumpfile_interpolation;
|
||||||
} else {
|
} else {
|
||||||
source->dumpfile_size_limit = 0;
|
source->dumpfile_size_limit = 0;
|
||||||
source->dumpfile_time_limit = 0;
|
source->dumpfile_time_limit = 0;
|
||||||
|
source->dumpfile_interpolation = INTERPOLATION_DEFAULT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -73,6 +73,7 @@ struct source_tag {
|
|||||||
/* Dumpfile related data */
|
/* Dumpfile related data */
|
||||||
/* Config */
|
/* Config */
|
||||||
char *dumpfilename; /* Name of a file to dump incoming stream to */
|
char *dumpfilename; /* Name of a file to dump incoming stream to */
|
||||||
|
interpolation_t dumpfile_interpolation;
|
||||||
uint64_t dumpfile_size_limit;
|
uint64_t dumpfile_size_limit;
|
||||||
unsigned int dumpfile_time_limit;
|
unsigned int dumpfile_time_limit;
|
||||||
/* Runtime */
|
/* Runtime */
|
||||||
|
83
src/util.c
83
src/util.c
@ -39,6 +39,9 @@
|
|||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <igloo/uuid.h>
|
||||||
|
#include <igloo/error.h> /* for igloo_ERROR_NONE */
|
||||||
|
|
||||||
#include "common/net/sock.h"
|
#include "common/net/sock.h"
|
||||||
#include "common/thread/thread.h"
|
#include "common/thread/thread.h"
|
||||||
|
|
||||||
@ -53,6 +56,7 @@
|
|||||||
#include "auth.h"
|
#include "auth.h"
|
||||||
#include "acl.h"
|
#include "acl.h"
|
||||||
#include "listensocket.h"
|
#include "listensocket.h"
|
||||||
|
#include "global.h" /* for igloo_instance */
|
||||||
|
|
||||||
#define CATMODULE "util"
|
#define CATMODULE "util"
|
||||||
|
|
||||||
@ -1271,3 +1275,82 @@ int get_line(FILE *file, char *buf, size_t siz)
|
|||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool util_interpolation_uuid(char * buffer, size_t bufferlen, const char *in)
|
||||||
|
{
|
||||||
|
char *random_uuid = NULL;
|
||||||
|
|
||||||
|
if (!buffer || bufferlen < 1 || !in)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
for (; *in; in++) {
|
||||||
|
if (*in == '%') {
|
||||||
|
in++;
|
||||||
|
switch (*in) {
|
||||||
|
case '%':
|
||||||
|
if (!bufferlen) {
|
||||||
|
free(random_uuid);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
*buffer++ = *in;
|
||||||
|
bufferlen--;
|
||||||
|
break;
|
||||||
|
case 'r':
|
||||||
|
case 'g':
|
||||||
|
if (true) {
|
||||||
|
const char *str;
|
||||||
|
size_t len;
|
||||||
|
|
||||||
|
switch (*in) {
|
||||||
|
case 'r':
|
||||||
|
if (!random_uuid) {
|
||||||
|
if (igloo_uuid_new_random_cstr(&random_uuid, igloo_instance) != igloo_ERROR_NONE) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
str = random_uuid;
|
||||||
|
break;
|
||||||
|
case 'g':
|
||||||
|
str = global_instance_uuid();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
free(random_uuid);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
len = strlen(str);
|
||||||
|
|
||||||
|
if (bufferlen <= len) {
|
||||||
|
free(random_uuid);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(buffer, str, len);
|
||||||
|
buffer += len;
|
||||||
|
bufferlen -= len;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
free(random_uuid);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!bufferlen) {
|
||||||
|
free(random_uuid);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
*buffer++ = *in;
|
||||||
|
bufferlen--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
free(random_uuid);
|
||||||
|
|
||||||
|
if (bufferlen) {
|
||||||
|
*buffer = 0;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
@ -124,4 +124,8 @@ struct tm *localtime_r(const time_t *timep, struct tm *result);
|
|||||||
char *util_conv_string (const char *string, const char *in_charset, const char *out_charset);
|
char *util_conv_string (const char *string, const char *in_charset, const char *out_charset);
|
||||||
|
|
||||||
int get_line(FILE *file, char *buf, size_t siz);
|
int get_line(FILE *file, char *buf, size_t siz);
|
||||||
|
|
||||||
|
/* returns true on successi, when returning false buffer[] is in undefined state. */
|
||||||
|
bool util_interpolation_uuid(char * buffer, size_t bufferlen, const char *in);
|
||||||
|
|
||||||
#endif /* __UTIL_H__ */
|
#endif /* __UTIL_H__ */
|
||||||
|
Loading…
Reference in New Issue
Block a user