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)
|
||||
{
|
||||
if (!href || !*href)
|
||||
@ -1744,8 +1761,13 @@ static void _parse_mount(xmlDocPtr doc,
|
||||
password = (char *)xmlNodeListGetString(doc,
|
||||
node->xmlChildrenNode, 1);
|
||||
} 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,
|
||||
node->xmlChildrenNode, 1);
|
||||
node->xmlChildrenNode, 1);
|
||||
} else if (xmlStrcmp(node->name, XMLSTR("dump-file-size-limit")) == 0) {
|
||||
unsigned int val = mount->dumpfile_size_limit;
|
||||
__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)
|
||||
dst->dumpfile = (char*)xmlStrdup((xmlChar*)src->dumpfile);
|
||||
if (dst->dumpfile_interpolation == INTERPOLATION_DEFAULT)
|
||||
dst->dumpfile_interpolation = src->dumpfile_interpolation;
|
||||
if (!dst->dumpfile_size_limit)
|
||||
dst->dumpfile_size_limit = src->dumpfile_size_limit;
|
||||
if (!dst->dumpfile_time_limit)
|
||||
|
@ -79,6 +79,13 @@ typedef enum {
|
||||
FALLBACK_OVERRIDE_OWN
|
||||
} fallback_override_t;
|
||||
|
||||
typedef enum {
|
||||
INTERPOLATION_DEFAULT = 0,
|
||||
INTERPOLATION_NONE,
|
||||
INTERPOLATION_STRFTIME,
|
||||
INTERPOLATION_UUID
|
||||
} interpolation_t;
|
||||
|
||||
typedef struct _mount_proxy {
|
||||
/* The mountpoint this proxy is used for */
|
||||
char *mountname;
|
||||
@ -88,6 +95,7 @@ typedef struct _mount_proxy {
|
||||
* NULL to not dump.
|
||||
*/
|
||||
char *dumpfile;
|
||||
interpolation_t dumpfile_interpolation;
|
||||
uint64_t dumpfile_size_limit;
|
||||
unsigned int dumpfile_time_limit;
|
||||
/* 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)
|
||||
{
|
||||
const char *filename = source->dumpfilename;
|
||||
interpolation_t interpolation = source->dumpfile_interpolation;
|
||||
time_t curtime = time(NULL);
|
||||
#ifndef _WIN32
|
||||
/* some of the below functions seems not to be standard winapi functions */
|
||||
char buffer[PATH_MAX];
|
||||
struct tm *loctime;
|
||||
#endif
|
||||
|
||||
if (!filename) {
|
||||
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);
|
||||
|
||||
if (interpolation == INTERPOLATION_DEFAULT) {
|
||||
#ifndef _WIN32
|
||||
/* Convert it to local time representation. */
|
||||
loctime = localtime(&curtime);
|
||||
|
||||
strftime(buffer, sizeof(buffer), filename, loctime);
|
||||
filename = buffer;
|
||||
interpolation = INTERPOLATION_STRFTIME;
|
||||
#else
|
||||
interpolation = INTERPOLATION_NONE;
|
||||
#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");
|
||||
|
||||
@ -1258,11 +1288,13 @@ static void source_apply_mount (ice_config_t *config, source_t *source, mount_pr
|
||||
}
|
||||
|
||||
if (mountinfo) {
|
||||
source->dumpfile_size_limit = mountinfo->dumpfile_size_limit;
|
||||
source->dumpfile_time_limit = mountinfo->dumpfile_time_limit;
|
||||
source->dumpfile_size_limit = mountinfo->dumpfile_size_limit;
|
||||
source->dumpfile_time_limit = mountinfo->dumpfile_time_limit;
|
||||
source->dumpfile_interpolation = mountinfo->dumpfile_interpolation;
|
||||
} else {
|
||||
source->dumpfile_size_limit = 0;
|
||||
source->dumpfile_time_limit = 0;
|
||||
source->dumpfile_size_limit = 0;
|
||||
source->dumpfile_time_limit = 0;
|
||||
source->dumpfile_interpolation = INTERPOLATION_DEFAULT;
|
||||
}
|
||||
|
||||
|
||||
|
@ -73,6 +73,7 @@ struct source_tag {
|
||||
/* Dumpfile related data */
|
||||
/* Config */
|
||||
char *dumpfilename; /* Name of a file to dump incoming stream to */
|
||||
interpolation_t dumpfile_interpolation;
|
||||
uint64_t dumpfile_size_limit;
|
||||
unsigned int dumpfile_time_limit;
|
||||
/* Runtime */
|
||||
|
83
src/util.c
83
src/util.c
@ -39,6 +39,9 @@
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#include <igloo/uuid.h>
|
||||
#include <igloo/error.h> /* for igloo_ERROR_NONE */
|
||||
|
||||
#include "common/net/sock.h"
|
||||
#include "common/thread/thread.h"
|
||||
|
||||
@ -53,6 +56,7 @@
|
||||
#include "auth.h"
|
||||
#include "acl.h"
|
||||
#include "listensocket.h"
|
||||
#include "global.h" /* for igloo_instance */
|
||||
|
||||
#define CATMODULE "util"
|
||||
|
||||
@ -1271,3 +1275,82 @@ int get_line(FILE *file, char *buf, size_t siz)
|
||||
}
|
||||
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);
|
||||
|
||||
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__ */
|
||||
|
Loading…
Reference in New Issue
Block a user