Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
htsstr_substitute: use temporary string buffer on stack instead stati…
…c one
  • Loading branch information
perexg committed Oct 1, 2015
1 parent 812c2e2 commit 19d3b90
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 63 deletions.
135 changes: 76 additions & 59 deletions src/dvr/dvr_rec.c
Expand Up @@ -267,57 +267,61 @@ cleanup_filename(dvr_config_t *cfg, char *s, int dosubs)
/**
*
*/
static char dvrbuf[MAX(PATH_MAX, 512)];

static char *dvr_clean_directory_separator(char *s)
static char *
dvr_clean_directory_separator(char *s, char *tmp, size_t tmplen)
{
char *p, *end;

if (s != dvrbuf) {
end = dvrbuf + sizeof(dvrbuf) - 1;
if (s != tmp) {
end = tmp + tmplen - 1;
/* replace directory separator */
for (p = dvrbuf; *s && p != end; s++, p++)
for (p = tmp; *s && p != end; s++, p++)
*p = *s == '/' ? '-' : *s;
*p = '\0';
return dvrbuf;
return tmp;
} else {
for (; *s; s++)
if (*s == '/')
*s = '-';
return dvrbuf;
return tmp;
}
}

static const char *dvr_do_prefix(const char *id, const char *s)
static const char *
dvr_do_prefix(const char *id, const char *s, char *tmp, size_t tmplen)
{
if (s == NULL) {
dvrbuf[0] = '\0';
tmp[0] = '\0';
} else if (s[0] && !isalpha(id[0])) {
snprintf(dvrbuf, sizeof(dvrbuf), "%c%s", id[0], s);
snprintf(tmp, tmplen, "%c%s", id[0], s);
} else {
strncpy(dvrbuf, s, sizeof(dvrbuf)-1);
dvrbuf[sizeof(dvrbuf)-1] = '\0';
strncpy(tmp, s, tmplen-1);
tmp[tmplen-1] = '\0';
}
return dvr_clean_directory_separator(dvrbuf);
return dvr_clean_directory_separator(tmp, tmp, tmplen);
}


static const char *dvr_sub_title(const char *id, const void *aux)
static const char *
dvr_sub_title(const char *id, const void *aux, char *tmp, size_t tmplen)
{
return dvr_do_prefix(id, lang_str_get(((dvr_entry_t *)aux)->de_title, NULL));
return dvr_do_prefix(id, lang_str_get(((dvr_entry_t *)aux)->de_title, NULL), tmp, tmplen);
}

static const char *dvr_sub_subtitle(const char *id, const void *aux)
static const char *
dvr_sub_subtitle(const char *id, const void *aux, char *tmp, size_t tmplen)
{
return dvr_do_prefix(id, lang_str_get(((dvr_entry_t *)aux)->de_subtitle, NULL));
return dvr_do_prefix(id, lang_str_get(((dvr_entry_t *)aux)->de_subtitle, NULL), tmp, tmplen);
}

static const char *dvr_sub_description(const char *id, const void *aux)
static const char *
dvr_sub_description(const char *id, const void *aux, char *tmp, size_t tmplen)
{
return dvr_do_prefix(id, lang_str_get(((dvr_entry_t *)aux)->de_desc, NULL));
return dvr_do_prefix(id, lang_str_get(((dvr_entry_t *)aux)->de_desc, NULL), tmp, tmplen);
}

static const char *dvr_sub_episode(const char *id, const void *aux)
static const char *
dvr_sub_episode(const char *id, const void *aux, char *tmp, size_t tmplen)
{
const dvr_entry_t *de = aux;
char buf[64];
Expand All @@ -327,41 +331,47 @@ static const char *dvr_sub_episode(const char *id, const void *aux)
epg_episode_number_format(de->de_bcast->episode,
buf, sizeof(buf),
".", "S%02d", NULL, "E%02d", NULL);
return dvr_do_prefix(id, buf);
return dvr_do_prefix(id, buf, tmp, tmplen);
}

static const char *dvr_sub_channel(const char *id, const void *aux)
static const char *
dvr_sub_channel(const char *id, const void *aux, char *tmp, size_t tmplen)
{
return dvr_do_prefix(id, DVR_CH_NAME((dvr_entry_t *)aux));
return dvr_do_prefix(id, DVR_CH_NAME((dvr_entry_t *)aux), tmp, tmplen);
}

static const char *dvr_sub_owner(const char *id, const void *aux)
static const char *
dvr_sub_owner(const char *id, const void *aux, char *tmp, size_t tmplen)
{
return dvr_do_prefix(id, ((dvr_entry_t *)aux)->de_owner);
return dvr_do_prefix(id, ((dvr_entry_t *)aux)->de_owner, tmp, tmplen);
}

static const char *dvr_sub_creator(const char *id, const void *aux)
static const char *
dvr_sub_creator(const char *id, const void *aux, char *tmp, size_t tmplen)
{
return dvr_do_prefix(id, ((dvr_entry_t *)aux)->de_creator);
return dvr_do_prefix(id, ((dvr_entry_t *)aux)->de_creator, tmp, tmplen);
}

static const char *dvr_sub_last_error(const char *id, const void *aux)
static const char *
dvr_sub_last_error(const char *id, const void *aux, char *tmp, size_t tmplen)
{
return dvr_do_prefix(id, streaming_code2txt(((dvr_entry_t *)aux)->de_last_error));
return dvr_do_prefix(id, streaming_code2txt(((dvr_entry_t *)aux)->de_last_error), tmp, tmplen);
}

static const char *dvr_sub_start(const char *id, const void *aux)
static const char *
dvr_sub_start(const char *id, const void *aux, char *tmp, size_t tmplen)
{
char buf[16];
snprintf(buf, sizeof(buf), "%"PRItime_t, (time_t)dvr_entry_get_start_time((dvr_entry_t *)aux));
return dvr_do_prefix(id, buf);
return dvr_do_prefix(id, buf, tmp, tmplen);
}

static const char *dvr_sub_stop(const char *id, const void *aux)
static const char *
dvr_sub_stop(const char *id, const void *aux, char *tmp, size_t tmplen)
{
char buf[16];
snprintf(buf, sizeof(buf), "%"PRItime_t, (time_t)dvr_entry_get_stop_time((dvr_entry_t *)aux));
return dvr_do_prefix(id, buf);
return dvr_do_prefix(id, buf, tmp, tmplen);
}

static htsstr_substitute_t dvr_subs_entry[] = {
Expand Down Expand Up @@ -396,15 +406,16 @@ static htsstr_substitute_t dvr_subs_entry[] = {
{ .id = NULL, .getval = NULL }
};

static const char *dvr_sub_strftime(const char *id, const void *aux)
static const char *
dvr_sub_strftime(const char *id, const void *aux, char *tmp, size_t tmplen)
{
char fid[8], *p;
snprintf(fid, sizeof(fid), "%%%s", id);
strftime(dvrbuf, sizeof(dvrbuf), fid, (struct tm *)aux);
for (p = dvrbuf; *p; p++)
strftime(tmp, tmplen, fid, (struct tm *)aux);
for (p = tmp; *p; p++)
if (*p == ':')
*p = '-';
return dvr_clean_directory_separator(dvrbuf);
return dvr_clean_directory_separator(tmp, tmp, tmplen);
}

static htsstr_substitute_t dvr_subs_time[] = {
Expand Down Expand Up @@ -472,16 +483,18 @@ static htsstr_substitute_t dvr_subs_time[] = {
{ .id = NULL, .getval = NULL }
};

static const char *dvr_sub_str(const char *id, const void *aux)
static const char *
dvr_sub_str(const char *id, const void *aux, char *tmp, size_t tmplen)
{
return (const char *)aux;
}

static const char *dvr_sub_str_separator(const char *id, const void *aux)
static const char *
dvr_sub_str_separator(const char *id, const void *aux, char *tmp, size_t tmplen)
{
strncpy(dvrbuf, (const char *)aux, sizeof(dvrbuf)-1);
dvrbuf[sizeof(dvrbuf)-1] = '\0';
return dvr_clean_directory_separator(dvrbuf);
strncpy(tmp, (const char *)aux, tmplen-1);
tmp[tmplen-1] = '\0';
return dvr_clean_directory_separator(tmp, tmp, tmplen);
}

static htsstr_substitute_t dvr_subs_extension[] = {
Expand All @@ -508,11 +521,12 @@ static htsstr_substitute_t dvr_subs_postproc_entry[] = {
{ .id = NULL, .getval = NULL }
};

static const char *dvr_sub_basename(const char *id, const void *aux)
static const char *
dvr_sub_basename(const char *id, const void *aux, char *tmp, size_t tmplen)
{
strncpy(dvrbuf, (const char *)aux, sizeof(dvrbuf));
dvrbuf[sizeof(dvrbuf)-1] = '\0';
return basename(dvrbuf);
strncpy(tmp, (const char *)aux, tmplen);
tmp[tmplen-1] = '\0';
return basename(tmp);
}

static htsstr_substitute_t dvr_subs_postproc_filename[] = {
Expand All @@ -521,7 +535,8 @@ static htsstr_substitute_t dvr_subs_postproc_filename[] = {
{ .id = NULL, .getval = NULL }
};

static const char *dvr_sub_basic_info(const char *id, const void *aux)
static const char *
dvr_sub_basic_info(const char *id, const void *aux, char *tmp, size_t tmplen)
{
htsmsg_t *info = (htsmsg_t *)aux, *e;
htsmsg_field_t *f;
Expand All @@ -533,13 +548,13 @@ static const char *dvr_sub_basic_info(const char *id, const void *aux)
if (!info)
return "";

dvrbuf[0] = '\0';
tmp[0] = '\0';
HTSMSG_FOREACH(f, info) {
if (!(e = htsmsg_field_get_map(f))) continue;
if ((s = htsmsg_get_str(e, "type")) != NULL) continue;
tvh_strlcatf(dvrbuf, sizeof(dvrbuf), l, "%s%s", l > 0 ? "," : "", s);
tvh_strlcatf(tmp, tmplen, l, "%s%s", l > 0 ? "," : "", s);
}
return dvrbuf;
return tmp;
}

static htsstr_substitute_t dvr_subs_postproc_info[] = {
Expand Down Expand Up @@ -589,6 +604,7 @@ pvr_generate_filename(dvr_entry_t *de, const streaming_start_t *ss)
char path[PATH_MAX];
char ptmp[PATH_MAX];
char number[16];
char tmp[MAX(PATH_MAX, 512)];
char *lastpath = NULL;
int tally = 0;
struct stat st;
Expand Down Expand Up @@ -634,7 +650,7 @@ pvr_generate_filename(dvr_entry_t *de, const streaming_start_t *ss)
fmtstr++;

/* Substitute DVR entry formatters */
htsstr_substitute(fmtstr, path + l, sizeof(path) - l, '$', dvr_subs_entry, de);
htsstr_substitute(fmtstr, path + l, sizeof(path) - l, '$', dvr_subs_entry, de, tmp, sizeof(tmp));

/* Own directory? */
if (de->de_directory) {
Expand All @@ -644,7 +660,7 @@ pvr_generate_filename(dvr_entry_t *de, const streaming_start_t *ss)
else
strcpy(filename, path + l);
if (dir_dosubs) {
htsstr_substitute(de->de_directory+2, ptmp, sizeof(ptmp), '$', dvr_subs_entry, de);
htsstr_substitute(de->de_directory+2, ptmp, sizeof(ptmp), '$', dvr_subs_entry, de, tmp, sizeof(tmp));
} else {
strncpy(ptmp, de->de_directory, sizeof(ptmp)-1);
ptmp[sizeof(ptmp)-1] = '\0';
Expand All @@ -661,11 +677,11 @@ pvr_generate_filename(dvr_entry_t *de, const streaming_start_t *ss)
}

/* Substitute time formatters */
htsstr_substitute(path + l, filename, sizeof(filename), '%', dvr_subs_time, &tm);
htsstr_substitute(path + l, filename, sizeof(filename), '%', dvr_subs_time, &tm, tmp, sizeof(tmp));

/* Substitute extension */
htsstr_substitute(filename, path + l, sizeof(path) - l, '$', dvr_subs_extension,
muxer_suffix(de->de_chain->prch_muxer, ss) ?: "");
muxer_suffix(de->de_chain->prch_muxer, ss) ?: "", tmp, sizeof(tmp));

/* Cleanup all directory names */
x = path + l;
Expand Down Expand Up @@ -727,7 +743,7 @@ pvr_generate_filename(dvr_entry_t *de, const streaming_start_t *ss)
filename[l] = '\0';
}

htsstr_substitute(filename + j, ptmp, sizeof(ptmp), '$', dvr_subs_tally, number);
htsstr_substitute(filename + j, ptmp, sizeof(ptmp), '$', dvr_subs_tally, number, tmp, sizeof(tmp));
s = cleanup_filename(cfg, ptmp, 1);
if (s == NULL) {
free(lastpath);
Expand Down Expand Up @@ -1200,6 +1216,7 @@ static void
dvr_spawn_postproc(dvr_entry_t *de, const char *dvr_postproc)
{
char buf1[2048], *buf2;
char tmp[MAX(PATH_MAX, 512)];
const char *filename;
htsmsg_t *info, *e;
htsmsg_field_t *f;
Expand All @@ -1216,12 +1233,12 @@ dvr_spawn_postproc(dvr_entry_t *de, const char *dvr_postproc)
}

/* Substitute DVR entry formatters */
htsstr_substitute(dvr_postproc, buf1, sizeof(buf1), '%', dvr_subs_postproc_entry, de);
htsstr_substitute(dvr_postproc, buf1, sizeof(buf1), '%', dvr_subs_postproc_entry, de, tmp, sizeof(tmp));
buf2 = tvh_strdupa(buf1);
/* Substitute filename formatters */
htsstr_substitute(buf2, buf1, sizeof(buf1), '%', dvr_subs_postproc_filename, filename);
htsstr_substitute(buf2, buf1, sizeof(buf1), '%', dvr_subs_postproc_filename, filename, tmp, sizeof(tmp));
/* Substitute info formatters */
htsstr_substitute(buf2, buf1, sizeof(buf1), '%', dvr_subs_postproc_info, info);
htsstr_substitute(buf2, buf1, sizeof(buf1), '%', dvr_subs_postproc_info, info, tmp, sizeof(tmp));

args = htsstr_argsplit(buf1);
/* no arguments at all */
Expand Down
5 changes: 3 additions & 2 deletions src/htsstr.c
Expand Up @@ -187,7 +187,8 @@ htsstr_argsplit_free(char **argv) {

char *
htsstr_substitute(const char *src, char *dst, size_t dstlen,
int first, htsstr_substitute_t *sub, const void *aux)
int first, htsstr_substitute_t *sub, const void *aux,
char *tmp, size_t tmplen)
{
htsstr_substitute_t *s;
const char *p, *x, *v;
Expand Down Expand Up @@ -219,7 +220,7 @@ htsstr_substitute(const char *src, char *dst, size_t dstlen,
if (*p == '\0') {
src = x;
if ((l = dstlen) > 0) {
v = s->getval(s->id, aux);
v = s->getval(s->id, aux, tmp, tmplen);
strncpy(dst, v, l);
l = MIN(strlen(v), l);
dst += l;
Expand Down
5 changes: 3 additions & 2 deletions src/htsstr.h
Expand Up @@ -33,11 +33,12 @@ void htsstr_argsplit_free(char **argv);

typedef struct {
const char *id;
const char *(*getval)(const char *id, const void *aux);
const char *(*getval)(const char *id, const void *aux, char *tmp, size_t tmplen);
} htsstr_substitute_t;

char *
htsstr_substitute(const char *src, char *dst, size_t dstlen,
int first, htsstr_substitute_t *sub, const void *aux);
int first, htsstr_substitute_t *sub, const void *aux,
char *tmp, size_t tmplen);

#endif /* HTSSTR_H__ */

0 comments on commit 19d3b90

Please sign in to comment.