Merge remote-tracking branch 'adamsutton/master'
This commit is contained in:
commit
4ef72fb276
11 changed files with 197 additions and 59 deletions
1
Makefile
1
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 \
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
80
src/file.c
Normal file
80
src/file.c
Normal file
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#define MAX_RDBUF_SIZE 8192
|
||||
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#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;
|
||||
}
|
26
src/file.h
Normal file
26
src/file.h
Normal file
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef FILE_H
|
||||
#define FILE_H
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
size_t file_readall ( int fd, char **outbuf );
|
||||
|
||||
#endif /* FILE_H */
|
34
src/htsmsg.c
34
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;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
|
|
14
src/htsmsg.h
14
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.
|
||||
*
|
||||
|
|
|
@ -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')
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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_ */
|
||||
|
|
59
src/spawn.c
59
src/spawn.c
|
@ -28,6 +28,7 @@
|
|||
#include <fcntl.h>
|
||||
|
||||
#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);
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue