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