Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
spawn: move argument parser from iptv_pipe
  • Loading branch information
perexg committed Dec 1, 2014
1 parent bd20a53 commit bb31907
Show file tree
Hide file tree
Showing 3 changed files with 91 additions and 73 deletions.
95 changes: 22 additions & 73 deletions src/input/mpegts/iptv/iptv_pipe.c
Expand Up @@ -32,88 +32,30 @@
* Connect UDP/RTP
*/
static int
iptv_pipe_start ( iptv_mux_t *im, const char *_raw, const url_t *url )
iptv_pipe_start ( iptv_mux_t *im, const char *raw, const url_t *url )
{
char *argv[64], *envp[32], *f, *raw, *s, *p, *a;
int i = 1, rd;
char **argv = NULL, **envp = NULL;
const char *replace[] = { "${service_name}", im->mm_iptv_svcname ?: "", NULL };
int rd;
pid_t pid;

if (strncmp(_raw, "pipe://", 7))
return -1;
if (strncmp(raw, "pipe://", 7))
goto err;

s = raw = tvh_strdupa(_raw + 7);
if (spawn_parse_args(&argv, 64, raw + 7, replace))
goto err;

argv[0] = NULL;
if (spawn_parse_args(&envp, 64, im->mm_iptv_env ?: "", NULL))
goto err;

while (*s && *s != ' ')
s++;
if (*s == ' ') {
*(char *)s = '\0';
s++;
}

while (*s && i < ARRAY_SIZE(argv) - 1) {
f = s;
while (*s && *s != ' ') {
while (*s && *s != ' ' && *s != '\\')
s++;
if (*s == '\\') {
memmove(s, s + 1, strlen(s));
if (*s)
s++;
}
}
if (f != s) {
if (*s) {
*(char *)s = '\0';
s++;
}
p = strstr(f, "${service_name}");
if (p) {
a = alloca(strlen(f) + strlen(im->mm_iptv_svcname ?: ""));
*p = '\0';
strcpy(a, f);
strcat(a, im->mm_iptv_svcname ?: "");
strcat(a, p + 15);
f = a;
}
argv[i++] = f;
}
}
argv[i] = NULL;

s = im->mm_iptv_env ? tvh_strdupa(im->mm_iptv_env) : (char *)"";
i = 0;
while (*s && i < ARRAY_SIZE(envp) - 1) {
f = s;
while (*s && *s != '=')
s++;
if (*s != '=')
break;
while (*s && *s != ' ') {
while (*s && *s != ' ' && *s != '\\')
s++;
if (*s == '\\') {
memmove(s, s + 1, strlen(s));
if (*s)
s++;
}
}
if (f != s) {
if (*s) {
*s = '\0';
s++;
}
envp[i++] = f;
}
}
envp[i] = NULL;

if (spawn_and_give_stdout(raw, argv, envp, &rd, &pid, 1)) {
if (spawn_and_give_stdout(argv[0], argv, envp, &rd, &pid, 1)) {
tvherror("iptv", "Unable to start pipe '%s' (wrong executable?)", raw);
return -1;
goto err;
}

spawn_free_args(argv);
spawn_free_args(envp);

fcntl(rd, F_SETFD, fcntl(rd, F_GETFD) | FD_CLOEXEC);
fcntl(rd, F_SETFL, fcntl(rd, F_GETFL) | O_NONBLOCK);

Expand All @@ -125,6 +67,13 @@ iptv_pipe_start ( iptv_mux_t *im, const char *_raw, const url_t *url )
if (url)
iptv_input_mux_started(im);
return 0;

err:
if (argv)
spawn_free_args(argv);
if (envp)
spawn_free_args(envp);
return -1;
}

static void
Expand Down
65 changes: 65 additions & 0 deletions src/spawn.c
Expand Up @@ -324,6 +324,71 @@ spawn_enq(const char *name, int pid)
}


/**
*
*/
int
spawn_parse_args(char ***argv, int argc, const char *cmd, const char **replace)
{
char *s, *f, *p, *a;
const char **r;
int i = 0, l;

if (!argv || !cmd)
return -1;

s = tvh_strdupa(cmd);
*argv = calloc(argc, sizeof(char *));

while (*s && i < argc - 1) {
f = s;
while (*s && *s != ' ') {
while (*s && *s != ' ' && *s != '\\')
s++;
if (*s == '\\') {
memmove(s, s + 1, strlen(s));
if (*s)
s++;
}
}
if (f != s) {
if (*s) {
*(char *)s = '\0';
s++;
}
for (r = replace; r && *r; r += 2) {
p = strstr(f, *r);
if (p) {
l = strlen(*r);
a = malloc(strlen(f) + strlen(r[1]) + 1);
*p = '\0';
strcpy(a, f);
strcat(a, r[1]);
strcat(a, p + l);
*argv[i++] = f;
break;
}
}
if (r && *r)
continue;
(*argv)[i++] = strdup(f);
}
}
(*argv)[i] = NULL;
return 0;
}

/**
*
*/
void
spawn_free_args(char **argv)
{
char **a = argv;
for (; *a; a++)
free(*a);
free(argv);
}

/**
* Execute the given program and return its standard output as file-descriptor (pipe).
Expand Down
4 changes: 4 additions & 0 deletions src/spawn.h
Expand Up @@ -25,6 +25,10 @@ void spawn_error ( const char *fmt, ... );

int find_exec ( const char *name, char *out, size_t len );

int spawn_parse_args(char ***argv, int argc, const char *cmd, const char **replace);

void spawn_free_args(char **argv);

int spawn_and_give_stdout(const char *prog, char *argv[], char *envp[],
int *rd, pid_t *pid, int redir_stderr);

Expand Down

0 comments on commit bb31907

Please sign in to comment.