1
0
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:
Philipp Schafft 2022-10-25 09:05:24 +00:00 committed by Philipp Schafft
parent 5cf8cb9a99
commit 43a8c04134
6 changed files with 166 additions and 14 deletions

View File

@ -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,6 +1761,11 @@ 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);
} else if (xmlStrcmp(node->name, XMLSTR("dump-file-size-limit")) == 0) {
@ -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)

View File

@ -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 */

View File

@ -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
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");
@ -1260,9 +1290,11 @@ 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_interpolation = mountinfo->dumpfile_interpolation;
} else {
source->dumpfile_size_limit = 0;
source->dumpfile_time_limit = 0;
source->dumpfile_interpolation = INTERPOLATION_DEFAULT;
}

View File

@ -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 */

View File

@ -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;
}

View File

@ -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__ */