diff --git a/Makefile b/Makefile
index 52694582..b27448a6 100644
--- a/Makefile
+++ b/Makefile
@@ -42,6 +42,7 @@ SRCS = src/main.c \
src/tcp.c \
src/http.c \
src/notify.c \
+ src/file.c \
src/epg.c \
src/xmltv.c \
src/spawn.c \
diff --git a/src/dvb/dvb_preconf.c b/src/dvb/dvb_preconf.c
index ef1cf6d9..18aa4f25 100644
--- a/src/dvb/dvb_preconf.c
+++ b/src/dvb/dvb_preconf.c
@@ -64,7 +64,9 @@ dvb_mux_preconf_add(th_dvb_adapter_t *tda, const struct mux *m, int num,
break;
case FE_QPSK:
+#if DVB_API_VERSION > 5
dmc.dmc_fe_delsys = SYS_DVBS;
+#endif
dmc.dmc_fe_params.u.qpsk.symbol_rate = m->symrate;
dmc.dmc_fe_params.u.qpsk.fec_inner = m->fec;
diff --git a/src/dvb/dvb_tables.c b/src/dvb/dvb_tables.c
index b68ba3d1..b46d097c 100644
--- a/src/dvb/dvb_tables.c
+++ b/src/dvb/dvb_tables.c
@@ -288,7 +288,7 @@ tdt_add(th_dvb_mux_instance_t *tdmi, struct dmx_sct_filter_params *fparams,
// this
LIST_FOREACH(t, &tdmi->tdmi_tables, tdt_link) {
if(pid == t->tdt_pid &&
- tdt->tdt_callback == callback && tdt->tdt_opaque == opaque) {
+ t->tdt_callback == callback && t->tdt_opaque == opaque) {
free(tdt);
free(fparams);
return;
diff --git a/src/file.c b/src/file.c
new file mode 100644
index 00000000..77316871
--- /dev/null
+++ b/src/file.c
@@ -0,0 +1,80 @@
+/*
+ * Process file functions
+ * Copyright (C) 2008 Andreas Ă–man
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#define MAX_RDBUF_SIZE 8192
+
+#include
+#include
+#include
+#include
+#include "queue.h"
+#include "file.h"
+
+typedef struct file_read_buf {
+ TAILQ_ENTRY(file_read_buf) link;
+ int size;
+ char buf[MAX_RDBUF_SIZE];
+} file_read_buf_t;
+
+TAILQ_HEAD(file_read_buf_queue, file_read_buf);
+
+size_t file_readall ( int fd, char **outp )
+{
+ int r, totalsize = 0;
+ struct file_read_buf_queue bufs;
+ file_read_buf_t *b = NULL;
+ char *outbuf;
+
+ TAILQ_INIT(&bufs);
+ while(1) {
+ if(b == NULL) {
+ b = malloc(sizeof(file_read_buf_t));
+ b->size = 0;
+ TAILQ_INSERT_TAIL(&bufs, b, link);
+ }
+
+ r = read(fd, b->buf + b->size, MAX_RDBUF_SIZE - b->size);
+ if(r < 1)
+ break;
+ b->size += r;
+ totalsize += r;
+ if(b->size == MAX_RDBUF_SIZE)
+ b = NULL;
+ }
+
+ close(fd);
+
+ if(totalsize == 0) {
+ free(b);
+ *outp = NULL;
+ return 0;
+ }
+
+ outbuf = malloc(totalsize + 1);
+ r = 0;
+ while((b = TAILQ_FIRST(&bufs)) != NULL) {
+ memcpy(outbuf + r, b->buf, b->size);
+ r+= b->size;
+ TAILQ_REMOVE(&bufs, b, link);
+ free(b);
+ }
+ assert(r == totalsize);
+ *outp = outbuf;
+ outbuf[totalsize] = 0;
+ return totalsize;
+}
diff --git a/src/file.h b/src/file.h
new file mode 100644
index 00000000..9523a908
--- /dev/null
+++ b/src/file.h
@@ -0,0 +1,26 @@
+/*
+ * Process file operations
+ * Copyright (C) 2012 Adam Sutton
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#ifndef FILE_H
+#define FILE_H
+
+#include
+
+size_t file_readall ( int fd, char **outbuf );
+
+#endif /* FILE_H */
diff --git a/src/htsmsg.c b/src/htsmsg.c
index 6de14e4e..dab63ee0 100644
--- a/src/htsmsg.c
+++ b/src/htsmsg.c
@@ -196,6 +196,16 @@ htsmsg_add_s64(htsmsg_t *msg, const char *name, int64_t s64)
f->hmf_s64 = s64;
}
+/*
+ *
+ */
+void
+htsmsg_add_u64(htsmsg_t *msg, const char *name, uint64_t u64)
+{
+ htsmsg_field_t *f = htsmsg_field_add(msg, name, HMF_S64, HMF_NAME_ALLOCED);
+ f->hmf_s64 = u64;
+}
+
/*
*
*/
@@ -306,6 +316,30 @@ htsmsg_get_s64(htsmsg_t *msg, const char *name, int64_t *s64p)
return 0;
}
+/**
+ *
+ */
+int
+htsmsg_get_u64(htsmsg_t *msg, const char *name, uint64_t *u64p)
+{
+ htsmsg_field_t *f;
+
+ if((f = htsmsg_field_find(msg, name)) == NULL)
+ return HTSMSG_ERR_FIELD_NOT_FOUND;
+
+ switch(f->hmf_type) {
+ default:
+ return HTSMSG_ERR_CONVERSION_IMPOSSIBLE;
+ case HMF_STR:
+ *u64p = strtoull(f->hmf_str, NULL, 0);
+ break;
+ case HMF_S64:
+ *u64p = f->hmf_s64;
+ break;
+ }
+ return 0;
+}
+
/*
*
diff --git a/src/htsmsg.h b/src/htsmsg.h
index 6df3abf6..c601394a 100644
--- a/src/htsmsg.h
+++ b/src/htsmsg.h
@@ -107,6 +107,11 @@ void htsmsg_add_u32(htsmsg_t *msg, const char *name, uint32_t u32);
*/
void htsmsg_add_s32(htsmsg_t *msg, const char *name, int32_t s32);
+/**
+ * Add an integer field where source is unsigned 64 bit.
+ */
+void htsmsg_add_u64(htsmsg_t *msg, const char *name, uint64_t u64);
+
/**
* Add an integer field where source is signed 64 bit.
*/
@@ -171,6 +176,15 @@ int htsmsg_get_s32(htsmsg_t *msg, const char *name, int32_t *s32p);
*/
int htsmsg_get_s64(htsmsg_t *msg, const char *name, int64_t *s64p);
+/**
+ * Get an integer as an unsigned 64 bit integer.
+ *
+ * @return HTSMSG_ERR_FIELD_NOT_FOUND - Field does not exist
+ * HTSMSG_ERR_CONVERSION_IMPOSSIBLE - Field is not an integer or
+ * out of range for the requested storage.
+ */
+int htsmsg_get_u64(htsmsg_t *msg, const char *name, uint64_t *u64p);
+
/**
* Get pointer to a binary field. No copying of data is performed.
*
diff --git a/src/htsmsg_json.c b/src/htsmsg_json.c
index a302247d..ff1aa6f7 100644
--- a/src/htsmsg_json.c
+++ b/src/htsmsg_json.c
@@ -164,7 +164,11 @@ htsmsg_json_parse_string(const char *s, const char **endp)
if(*s == '\\') {
esc = 1;
- } else if(*s == '"' && s[-1] != '\\') {
+ /* skip the escape */
+ s++;
+ if (*s == 'u') s += 4;
+ // Note: we could detect the lack of support here!
+ } else if(*s == '"') {
*endp = s + 1;
@@ -184,6 +188,8 @@ htsmsg_json_parse_string(const char *s, const char **endp)
a++;
if(*a == 'b')
*b++ = '\b';
+ else if(*a == '\\')
+ *b++ = '\\';
else if(*a == 'f')
*b++ = '\f';
else if(*a == 'n')
diff --git a/src/htsmsg_xml.c b/src/htsmsg_xml.c
index 77e27b00..e9f69165 100644
--- a/src/htsmsg_xml.c
+++ b/src/htsmsg_xml.c
@@ -693,7 +693,7 @@ htsmsg_xml_parse_cd(xmlparser_t *xp, htsmsg_t *parent, char *src)
}
}
- if(y == 1 && c > 1) {
+ if(y == 1 && c > 0) {
/* One segment UTF-8 (or 7bit ASCII),
use data directly from source */
@@ -865,3 +865,29 @@ htsmsg_xml_deserialize(char *src, char *errbuf, size_t errbufsize)
return NULL;
}
+
+/*
+ * Get cdata string field
+ */
+const char *
+htsmsg_xml_get_cdata_str(htsmsg_t *tags, const char *name)
+{
+ htsmsg_t *sub;
+ if((sub = htsmsg_get_map(tags, name)) == NULL)
+ return NULL;
+ return htsmsg_get_str(sub, "cdata");
+}
+
+/*
+ * Get cdata u32 field
+ */
+int
+htsmsg_xml_get_cdata_u32(htsmsg_t *tags, const char *name, uint32_t *u32)
+{
+ htsmsg_t *sub;
+ if((sub = htsmsg_get_map(tags, name)) == NULL)
+ return HTSMSG_ERR_FIELD_NOT_FOUND;
+ return htsmsg_get_u32(sub, "cdata", u32);
+}
+
+
diff --git a/src/htsmsg_xml.h b/src/htsmsg_xml.h
index ff723ac0..16e548c2 100644
--- a/src/htsmsg_xml.h
+++ b/src/htsmsg_xml.h
@@ -23,5 +23,7 @@
#include "htsbuf.h"
htsmsg_t *htsmsg_xml_deserialize(char *src, char *errbuf, size_t errbufsize);
+const char *htsmsg_xml_get_cdata_str (htsmsg_t *tags, const char *tag);
+int htsmsg_xml_get_cdata_u32 (htsmsg_t *tags, const char *tag, uint32_t *u32);
#endif /* HTSMSG_XML_H_ */
diff --git a/src/spawn.c b/src/spawn.c
index 9d59c597..953a2c79 100644
--- a/src/spawn.c
+++ b/src/spawn.c
@@ -28,6 +28,7 @@
#include
#include "tvheadend.h"
+#include "file.h"
#include "spawn.h"
extern char **environ;
@@ -43,21 +44,6 @@ typedef struct spawn {
} spawn_t;
-/**
- * Structs for reading back output from a spawn via a pipe
- */
-TAILQ_HEAD(spawn_output_buf_queue, spawn_output_buf);
-
-#define MAX_SOB_SIZE 4000
-
-typedef struct spawn_output_buf {
- TAILQ_ENTRY(spawn_output_buf) sob_link;
- int sob_size;
- char sob_buf[MAX_SOB_SIZE];
-} spawn_output_buf_t;
-
-
-
/**
* The reaper is called once a second to finish of any pending spawns
*/
@@ -135,10 +121,7 @@ int
spawn_and_store_stdout(const char *prog, char *const argv[], char **outp)
{
pid_t p;
- int fd[2], r, totalsize = 0, f;
- char *outbuf;
- struct spawn_output_buf_queue bufs;
- spawn_output_buf_t *b = NULL;
+ int fd[2], f;
const char *local_argv[2];
if(argv == NULL) {
@@ -194,43 +177,7 @@ spawn_and_store_stdout(const char *prog, char *const argv[], char **outp)
close(fd[1]);
- TAILQ_INIT(&bufs);
- while(1) {
- if(b == NULL) {
- b = malloc(sizeof(spawn_output_buf_t));
- b->sob_size = 0;
- TAILQ_INSERT_TAIL(&bufs, b, sob_link);
- }
-
- r = read(fd[0], b->sob_buf + b->sob_size, MAX_SOB_SIZE - b->sob_size);
- if(r < 1)
- break;
- b->sob_size += r;
- totalsize += r;
- if(b->sob_size == MAX_SOB_SIZE)
- b = NULL;
- }
-
- close(fd[0]);
-
- if(totalsize == 0) {
- free(b);
- *outp = NULL;
- return 0;
- }
-
- outbuf = malloc(totalsize + 1);
- r = 0;
- while((b = TAILQ_FIRST(&bufs)) != NULL) {
- memcpy(outbuf + r, b->sob_buf, b->sob_size);
- r+= b->sob_size;
- TAILQ_REMOVE(&bufs, b, sob_link);
- free(b);
- }
- assert(r == totalsize);
- *outp = outbuf;
- outbuf[totalsize] = 0;
- return totalsize;
+ return file_readall(fd[0], outp);
}