Re-instate internal xmltv search routine (will try to use external tv_find_grabbers), remove use of fixed path for find script and make spawn calls search path if required.
This commit is contained in:
parent
ec3bb46252
commit
71dc6bff73
3 changed files with 111 additions and 27 deletions
|
@ -38,7 +38,8 @@
|
|||
#include "epggrab.h"
|
||||
#include "epggrab/private.h"
|
||||
|
||||
#define XMLTV_FIND_GRABBERS "/usr/bin/tv_find_grabbers"
|
||||
#define XMLTV_FIND "tv_find_grabbers"
|
||||
#define XMLTV_GRAB "tv_grab_"
|
||||
|
||||
static epggrab_channel_tree_t _xmltv_channels;
|
||||
static epggrab_module_t *_xmltv_module;
|
||||
|
@ -527,30 +528,66 @@ static void _xmltv_load_grabbers ( void )
|
|||
size_t i, outlen, p, n;
|
||||
char *outbuf;
|
||||
char name[1000];
|
||||
char *tmp, *path;
|
||||
|
||||
/* Load data */
|
||||
outlen = spawn_and_store_stdout(XMLTV_FIND_GRABBERS, NULL, &outbuf);
|
||||
if ( outlen < 1 ) {
|
||||
tvhlog(LOG_ERR, "xmltv", "%s failed", XMLTV_FIND_GRABBERS);
|
||||
return;
|
||||
}
|
||||
outlen = spawn_and_store_stdout(XMLTV_FIND, NULL, &outbuf);
|
||||
|
||||
/* Process */
|
||||
p = n = i = 0;
|
||||
while ( i < outlen ) {
|
||||
if ( outbuf[i] == '\n' || outbuf[i] == '\0' ) {
|
||||
outbuf[i] = '\0';
|
||||
sprintf(name, "XMLTV: %s", &outbuf[n]);
|
||||
epggrab_module_int_create(NULL, &outbuf[p], name, 3, &outbuf[p],
|
||||
if ( outlen ) {
|
||||
p = n = i = 0;
|
||||
while ( i < outlen ) {
|
||||
if ( outbuf[i] == '\n' || outbuf[i] == '\0' ) {
|
||||
outbuf[i] = '\0';
|
||||
sprintf(name, "XMLTV: %s", &outbuf[n]);
|
||||
epggrab_module_int_create(NULL, &outbuf[p], name, 3, &outbuf[p],
|
||||
NULL, _xmltv_parse, NULL, NULL);
|
||||
p = n = i + 1;
|
||||
} else if ( outbuf[i] == '|' ) {
|
||||
outbuf[i] = '\0';
|
||||
n = i + 1;
|
||||
p = n = i + 1;
|
||||
} else if ( outbuf[i] == '|' ) {
|
||||
outbuf[i] = '\0';
|
||||
n = i + 1;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
i++;
|
||||
free(outbuf);
|
||||
|
||||
/* Internal search */
|
||||
} else if ((tmp = getenv("PATH"))) {
|
||||
tvhlog(LOG_DEBUG, "epggrab", "using internal grab search");
|
||||
char bin[256];
|
||||
char desc[] = "--description";
|
||||
char *argv[] = {
|
||||
NULL,
|
||||
desc,
|
||||
NULL
|
||||
};
|
||||
path = strdup(tmp);
|
||||
tmp = strtok(path, ":");
|
||||
while (tmp) {
|
||||
DIR *dir;
|
||||
struct dirent *de;
|
||||
struct stat st;
|
||||
if ((dir = opendir(tmp))) {
|
||||
while ((de = readdir(dir))) {
|
||||
if (strstr(de->d_name, XMLTV_GRAB) != de->d_name) continue;
|
||||
snprintf(bin, sizeof(bin), "%s/%s", tmp, de->d_name);
|
||||
if (lstat(bin, &st)) continue;
|
||||
if (!(st.st_mode & S_IEXEC)) continue;
|
||||
if (!S_ISREG(st.st_mode)) continue;
|
||||
if ((outlen = spawn_and_store_stdout(bin, argv, &outbuf))) {
|
||||
if (outbuf[outlen-1] == '\n') outbuf[outlen-1] = '\0';
|
||||
snprintf(name, sizeof(name), "XMLTV: %s", outbuf);
|
||||
epggrab_module_int_create(NULL, bin, name, 3, bin,
|
||||
NULL, _xmltv_parse, NULL, NULL);
|
||||
free(outbuf);
|
||||
}
|
||||
}
|
||||
}
|
||||
closedir(dir);
|
||||
tmp = strtok(NULL, ":");
|
||||
}
|
||||
free(path);
|
||||
}
|
||||
free(outbuf);
|
||||
}
|
||||
|
||||
void xmltv_init ( void )
|
||||
|
|
61
src/spawn.c
61
src/spawn.c
|
@ -18,6 +18,7 @@
|
|||
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/stat.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
|
@ -26,6 +27,7 @@
|
|||
#include <assert.h>
|
||||
#include <syslog.h>
|
||||
#include <fcntl.h>
|
||||
#include <dirent.h>
|
||||
|
||||
#include "tvheadend.h"
|
||||
#include "file.h"
|
||||
|
@ -43,6 +45,38 @@ typedef struct spawn {
|
|||
const char *name;
|
||||
} spawn_t;
|
||||
|
||||
/*
|
||||
* Search PATH for executable
|
||||
*/
|
||||
static int
|
||||
_find_exec ( const char *name, char *out, size_t len )
|
||||
{
|
||||
int ret = 0;
|
||||
char bin[512];
|
||||
char *path, *tmp;
|
||||
DIR *dir;
|
||||
struct dirent *de;
|
||||
struct stat st;
|
||||
if (!(path = getenv("PATH"))) return 0;
|
||||
path = strdup(path);
|
||||
tmp = strtok(path, ":");
|
||||
while (tmp && !ret) {
|
||||
if (!(dir = opendir(tmp))) continue;
|
||||
while ((de = readdir(dir))) {
|
||||
if (strstr(de->d_name, name) != de->d_name) continue;
|
||||
snprintf(bin, sizeof(bin), "%s/%s", tmp, de->d_name);
|
||||
if (lstat(bin, &st)) continue;
|
||||
if (!S_ISREG(st.st_mode) || !(st.st_mode & S_IEXEC)) continue;
|
||||
strncpy(out, bin, len);
|
||||
ret = 1;
|
||||
break;
|
||||
}
|
||||
closedir(dir);
|
||||
tmp = strtok(NULL, ":");
|
||||
}
|
||||
free(path);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* The reaper is called once a second to finish of any pending spawns
|
||||
|
@ -118,18 +152,21 @@ spawn_enq(const char *name, int pid)
|
|||
*/
|
||||
|
||||
int
|
||||
spawn_and_store_stdout(const char *prog, char *const argv[], char **outp)
|
||||
spawn_and_store_stdout(const char *prog, char *argv[], char **outp)
|
||||
{
|
||||
pid_t p;
|
||||
int fd[2], f;
|
||||
const char *local_argv[2];
|
||||
char bin[256];
|
||||
const char *local_argv[2] = { NULL, NULL };
|
||||
|
||||
if(argv == NULL) {
|
||||
local_argv[0] = prog;
|
||||
local_argv[1] = NULL;
|
||||
argv = (void *)local_argv;
|
||||
if (*prog != '/' && *prog != '.') {
|
||||
if (!_find_exec(prog, bin, sizeof(bin))) return -1;
|
||||
prog = bin;
|
||||
}
|
||||
|
||||
if(!argv) argv = (void *)local_argv;
|
||||
if (!argv[0]) argv[0] = (char*)prog;
|
||||
|
||||
pthread_mutex_lock(&fork_lock);
|
||||
|
||||
if(pipe(fd) == -1) {
|
||||
|
@ -188,9 +225,19 @@ spawn_and_store_stdout(const char *prog, char *const argv[], char **outp)
|
|||
* The function will return the size of the buffer
|
||||
*/
|
||||
int
|
||||
spawnv(const char *prog, char *const argv[])
|
||||
spawnv(const char *prog, char *argv[])
|
||||
{
|
||||
pid_t p;
|
||||
char bin[256];
|
||||
const char *local_argv[2] = { NULL, NULL };
|
||||
|
||||
if (*prog != '/' && *prog != '.') {
|
||||
if (!_find_exec(prog, bin, sizeof(bin))) return -1;
|
||||
prog = bin;
|
||||
}
|
||||
|
||||
if(!argv) argv = (void *)local_argv;
|
||||
if (!argv[0]) argv[0] = (char*)prog;
|
||||
|
||||
p = fork();
|
||||
|
||||
|
|
|
@ -19,9 +19,9 @@
|
|||
#ifndef SPAWN_H
|
||||
#define SPAWN_H
|
||||
|
||||
int spawn_and_store_stdout(const char *prog, char *const argv[], char **outp);
|
||||
int spawn_and_store_stdout(const char *prog, char *argv[], char **outp);
|
||||
|
||||
int spawnv(const char *prog, char *const argv[]);
|
||||
int spawnv(const char *prog, char *argv[]);
|
||||
|
||||
void spawn_reaper(void);
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue