mpg123-1.30.1

This commit is contained in:
Ozkan Sezer
2022-07-13 03:25:24 +03:00
parent c46daebce1
commit 586c237857
8 changed files with 156 additions and 79 deletions

View File

@@ -65,12 +65,28 @@ static char *catstr(const char *par, const char *value)
static int got_curl = -1;
static int got_wget = -1;
static int check_program(char **argv)
// Check if program executes, also test if given token occurs in its output.
// Returns 0 if not, 1 if exec works, 2 if also token found.
// Token has to be < 1024 characters in length.
static int check_program(char * const *argv, const char *token)
{
int fd[2];
int gottoken = 0;
if(token)
{
if(pipe(fd))
return 0;
compat_binmode(fd[0], TRUE);
compat_binmode(fd[1], TRUE);
}
pid_t pid = fork();
if(pid == 0)
{
int outfd = open("/dev/null", O_WRONLY);
int outfd = fd[1];
if(token)
close(fd[0]);
else
outfd = open("/dev/null", O_WRONLY);
dup2(outfd, STDOUT_FILENO);
int infd = open("/dev/null", O_RDONLY);
dup2(infd, STDIN_FILENO);
@@ -81,10 +97,41 @@ static int check_program(char **argv)
}
else if(pid > 0)
{
if(token)
{
char buf[1024];
close(fd[1]);
size_t toklen = strlen(token);
if(toklen > 0 && toklen < sizeof(buf))
{
size_t bufoff = 0;
size_t got;
while( (got = unintr_read(fd[0], buf+bufoff, sizeof(buf)-1-bufoff)) )
{
bufoff += got;
buf[bufoff] = 0; // Now it's a terminated string.
if(!gottoken && strstr(buf, token))
gottoken = 1;
if(gottoken)
bufoff = 0; // just forget everything
else if(bufoff > toklen)
{
// Remember the last toklen-1 bytes to compare later.
memmove(buf, buf+bufoff-toklen+1, toklen-1);
bufoff = toklen-1;
}
}
}
close(fd[0]);
}
int stat;
if( (waitpid(pid, &stat, 0) == pid)
&& WIFEXITED(stat) && WEXITSTATUS(stat)==0 )
return 1;
return 1+gottoken;
} else if(token)
{
close(fd[0]);
close(fd[1]);
}
return 0; // false, not there
}
@@ -147,6 +194,9 @@ static char **curl_argv(const char *url, const char * const * client_head)
"curl" // begins with program name
#ifdef DEBUG
, "--verbose"
#else
, "--silent"
, "--show-error"
#endif
, "--dump-header"
, "-"
@@ -156,6 +206,8 @@ static char **curl_argv(const char *url, const char * const * client_head)
// Get the count of argument strings right!
// Fixed args + agent + client headers [+ auth] + URL + NULL
int argc = sizeof(base_args)/sizeof(char*)+2+2*cheads+1+1;
if(got_curl > 1)
argc++; // add --http0.9
char *httpauth = NULL;
if(param.httpauth && (httpauth = compat_strdup(param.httpauth)))
argc += 2;
@@ -168,6 +220,8 @@ static char **curl_argv(const char *url, const char * const * client_head)
int an = 0;
for(;an<sizeof(base_args)/sizeof(char*); ++an)
argv[an] = compat_strdup(base_args[an]);
if(got_curl > 1)
argv[an++] = compat_strdup("--http0.9");
argv[an++] = compat_strdup("--user-agent");
argv[an++] = compat_strdup(PACKAGE_NAME "/" PACKAGE_VERSION);
for(size_t ch=0; ch < cheads; ++ch)
@@ -188,29 +242,38 @@ static char **curl_argv(const char *url, const char * const * client_head)
net123_handle *net123_open(const char *url, const char * const * client_head)
{
int use_curl = 0;
char * const curl_check_argv[] = { "curl", "--help", "all", NULL };
char * const wget_check_argv[] = { "wget", "--version", NULL };
// Semi-threadsafe: The check might take place multiple times, but writing the integer
// should be safe enough.
if(!strcmp("auto",param.network_backend))
{
char *curl_argv[] = { "curl", "--version", NULL };
char *wget_argv[] = { "wget", "--version", NULL };
if(got_curl < 0)
got_curl = check_program(curl_argv);
if(got_wget < 0)
got_wget = check_program(wget_argv);
if(got_wget < 1 && got_curl == 1)
got_wget = check_program(wget_check_argv, NULL);
if(!got_wget && got_curl < 0)
got_curl = check_program(curl_check_argv, "--http0.9");
if(got_wget < 1 && got_curl)
use_curl = 1;
} else if(!strcmp("curl", param.network_backend))
{
if(got_curl < 0) // Still need to know if HTTP/0.9 option is there.
got_curl = check_program(curl_check_argv, "--http0.9");
use_curl = 1;
} else if(!strcmp("wget", param.network_backend))
{
if(got_wget < 0)
got_wget = check_program(wget_check_argv, NULL);
use_curl = 0;
} else
{
merror("invalid network backend specified: %s", param.network_backend);
return NULL;
}
if((!use_curl && !got_wget) || (use_curl && !got_curl))
{
error("missing working network helper program (wget or curl)");
return NULL;
}
int fd[2];
int hi = -1; // index of header value that might get a continuation line
@@ -252,20 +315,23 @@ net123_handle *net123_open(const char *url, const char * const * client_head)
if(!argv)
exit(1);
errno = 0;
if(param.verbose > 2)
if(!param.quiet)
{
char **a = argv;
fprintf(stderr, "HTTP helper command:\n");
while(*a)
if(param.verbose > 2)
{
fprintf(stderr, " %s\n", *a);
++a;
char **a = argv;
fprintf(stderr, "HTTP helper command:\n");
while(*a)
{
fprintf(stderr, " %s\n", *a);
++a;
}
}
} else
{
int errfd = open("/dev/null", O_WRONLY);
dup2(errfd, STDERR_FILENO);
}
#ifndef DEBUG
int errfd = open("/dev/null", O_WRONLY);
dup2(errfd, STDERR_FILENO);
#endif
execvp(argv[0], argv);
merror("cannot execute %s: %s", argv[0], strerror(errno));
exit(1);

View File

@@ -159,9 +159,11 @@ int stream_parse_headers(struct stream *sd)
int hn = sizeof(head)/sizeof(char*);
int hi = -1;
int got_ok = 0;
int got_line = 0;
debug("parsing headers");
while(stream_getline(sd, &line) > 0)
{
got_line = 1;
mdebug("HTTP in: %s", line.p);
if(line.p[0] == 0)
{
@@ -239,7 +241,11 @@ int stream_parse_headers(struct stream *sd)
if(param.verbose > 1)
fprintf(stderr, "Info: ICY interval %li\n", (long)sd->htd.icy_interval);
}
if(!got_ok)
if(!got_line)
{
error("no data at all from network resource");
ret = -1;
} else if(!got_ok)
{
error("missing positive server response");
ret = -1;
@@ -273,8 +279,6 @@ struct stream *stream_open(const char *url)
sd->fd = STDIN_FILENO;
compat_binmode(STDIN_FILENO, TRUE);
}
else if(!strncasecmp("file://", url, 7))
url+= 7; // use local file access for files, the scheme may be useful
#ifdef NET123
else if(!strncasecmp("http://", url, 7) || !strncasecmp("https://", url, 8))
{
@@ -287,7 +291,7 @@ struct stream *stream_open(const char *url)
append_accept(&accept);
client_head[1] = accept.p;
sd->nh = net123_open(url, client_head);
if(stream_parse_headers(sd))
if(!sd->nh || stream_parse_headers(sd))
{
stream_close(sd);
return NULL;
@@ -311,11 +315,13 @@ struct stream *stream_open(const char *url)
else
{
// plain file access
if(!strncasecmp("file://", url, 7))
url+= 7; // Might be useful to prepend file scheme prefix for local stuff.
errno = 0;
sd->fd = compat_open(url, O_RDONLY|O_BINARY);
if(sd->fd < 0)
{
merror("failed to open file: %s", strerror(errno));
merror("failed to open file: %s: %s", url, strerror(errno));
stream_close(sd);
return NULL;
}