mirror of
https://gitlab.xiph.org/xiph/ezstream.git
synced 2024-12-04 14:46:31 -05:00
Improve string to integer conversion stuff, and have another stab at the config
file parsing. Ezstream now prints each error it can find and then bails out, instead of bailing out on the first error. Tweak URL parsing as well, and do some cosmetic changes to the error messages. git-svn-id: https://svn.xiph.org/trunk/ezstream@12603 0101bb08-14d6-0310-b084-bc0e0c8e3800
This commit is contained in:
parent
956f674a44
commit
539bb39322
@ -71,7 +71,7 @@ dnl LIBRARY FUNCTIONS
|
||||
|
||||
AC_CHECK_LIB(gen, basename)
|
||||
AC_CHECK_FUNCS(arc4random gettimeofday random srandomdev stat)
|
||||
AC_REPLACE_FUNCS(getopt strlcat strlcpy)
|
||||
AC_REPLACE_FUNCS(getopt strlcat strlcpy strtonum)
|
||||
if test x"$ac_cv_header_signal_h" = "xyes"; then
|
||||
AC_CHECK_FUNCS([sigaction], [
|
||||
AC_DEFINE(HAVE_SIGNALS, 1, [Define whether we have BSD signals])
|
||||
|
@ -8,6 +8,6 @@ ezstream_LDADD = @LIBOBJS@ @XIPH_LIBS@
|
||||
AM_CFLAGS = @XIPH_CFLAGS@
|
||||
AM_CPPFLAGS = @XIPH_CPPFLAGS@
|
||||
|
||||
EXTRA_DIST = configfile.h getopt.h playlist.h strlfctns.h util.h
|
||||
EXTRA_DIST = configfile.h getopt.h playlist.h strfctns.h util.h
|
||||
|
||||
CLEANFILES = core *.core *~ .*~
|
||||
|
205
src/configfile.c
205
src/configfile.c
@ -28,12 +28,15 @@
|
||||
#include <string.h>
|
||||
|
||||
#include "configfile.h"
|
||||
#include "strfctns.h"
|
||||
#include "util.h"
|
||||
|
||||
#ifndef PATH_MAX
|
||||
# define PATH_MAX 256
|
||||
#endif
|
||||
|
||||
extern char *__progname;
|
||||
|
||||
static EZCONFIG ezConfig;
|
||||
static const char *blankString = "";
|
||||
|
||||
@ -142,6 +145,7 @@ parseConfig(const char *fileName)
|
||||
char *ls_xmlContentPtr;
|
||||
int program_set, reconnect_set, shuffle_set,
|
||||
streamOnce_set, svrinfopublic_set;
|
||||
unsigned int config_error;
|
||||
|
||||
xmlLineNumbersDefault(1);
|
||||
if ((doc = xmlParseFile(fileName)) == NULL) {
|
||||
@ -159,6 +163,7 @@ parseConfig(const char *fileName)
|
||||
|
||||
memset(&ezConfig, '\000', sizeof(ezConfig));
|
||||
|
||||
config_error = 0;
|
||||
program_set = 0;
|
||||
reconnect_set = 0;
|
||||
shuffle_set = 0;
|
||||
@ -168,9 +173,10 @@ parseConfig(const char *fileName)
|
||||
while (cur != NULL) {
|
||||
if (!xmlStrcmp(cur->name, BAD_CAST "url")) {
|
||||
if (ezConfig.URL != NULL) {
|
||||
printf("%s[%ld]: Error: Cannot have multiple <url> elements.\n",
|
||||
printf("%s[%ld]: Error: Cannot have multiple <url> elements\n",
|
||||
fileName, xmlGetLineNo(cur));
|
||||
goto config_error;
|
||||
config_error++;
|
||||
continue;
|
||||
}
|
||||
if (cur->xmlChildrenNode != NULL) {
|
||||
ls_xmlContentPtr = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
|
||||
@ -180,9 +186,10 @@ parseConfig(const char *fileName)
|
||||
}
|
||||
if (!xmlStrcmp(cur->name, BAD_CAST "sourcepassword")) {
|
||||
if (ezConfig.password != NULL) {
|
||||
printf("%s[%ld]: Error: Cannot have multiple <sourcepassword> elements.\n",
|
||||
printf("%s[%ld]: Error: Cannot have multiple <sourcepassword> elements\n",
|
||||
fileName, xmlGetLineNo(cur));
|
||||
goto config_error;
|
||||
config_error++;
|
||||
continue;
|
||||
}
|
||||
if (cur->xmlChildrenNode != NULL) {
|
||||
ls_xmlContentPtr = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
|
||||
@ -192,9 +199,10 @@ parseConfig(const char *fileName)
|
||||
}
|
||||
if (!xmlStrcmp(cur->name, BAD_CAST "format")) {
|
||||
if (ezConfig.format != NULL) {
|
||||
printf("%s[%ld]: Error: Cannot have multiple <format> elements.\n",
|
||||
printf("%s[%ld]: Error: Cannot have multiple <format> elements\n",
|
||||
fileName, xmlGetLineNo(cur));
|
||||
goto config_error;
|
||||
config_error++;
|
||||
continue;
|
||||
}
|
||||
if (cur->xmlChildrenNode != NULL) {
|
||||
char *p;
|
||||
@ -208,16 +216,18 @@ parseConfig(const char *fileName)
|
||||
}
|
||||
if (!xmlStrcmp(cur->name, BAD_CAST "filename")) {
|
||||
if (ezConfig.fileName != NULL) {
|
||||
printf("%s[%ld]: Error: Cannot have multiple <filename> elements.\n",
|
||||
printf("%s[%ld]: Error: Cannot have multiple <filename> elements\n",
|
||||
fileName, xmlGetLineNo(cur));
|
||||
goto config_error;
|
||||
config_error++;
|
||||
continue;
|
||||
}
|
||||
if (cur->xmlChildrenNode != NULL) {
|
||||
ls_xmlContentPtr = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
|
||||
if (strlen(ls_xmlContentPtr) > PATH_MAX - 1) {
|
||||
printf("%s[%ld]: Error: Path or filename in <filename> is too long.\n",
|
||||
printf("%s[%ld]: Error: Path or filename in <filename> is too long\n",
|
||||
fileName, xmlGetLineNo(cur));
|
||||
goto config_error;
|
||||
config_error++;
|
||||
continue;
|
||||
}
|
||||
ezConfig.fileName = xstrdup(ls_xmlContentPtr);
|
||||
xmlFree(ls_xmlContentPtr);
|
||||
@ -225,70 +235,98 @@ parseConfig(const char *fileName)
|
||||
}
|
||||
if (!xmlStrcmp(cur->name, BAD_CAST "playlist_program")) {
|
||||
if (program_set) {
|
||||
printf("%s[%ld]: Error: Cannot have multiple <playlist_program> elements.\n",
|
||||
printf("%s[%ld]: Error: Cannot have multiple <playlist_program> elements\n",
|
||||
fileName, xmlGetLineNo(cur));
|
||||
goto config_error;
|
||||
config_error++;
|
||||
continue;
|
||||
}
|
||||
if (cur->xmlChildrenNode != NULL) {
|
||||
int tmp;
|
||||
const char *errstr;
|
||||
|
||||
ls_xmlContentPtr = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
|
||||
tmp = atoi(ls_xmlContentPtr);
|
||||
ezConfig.fileNameIsProgram = (tmp == 0) ? 0 : 1;
|
||||
ezConfig.fileNameIsProgram = strtonum(ls_xmlContentPtr, 0, 1, &errstr);
|
||||
if (errstr) {
|
||||
printf("%s[%ld]: Error: <playlist_program> may only contain 1 or 0\n",
|
||||
fileName, xmlGetLineNo(cur));
|
||||
config_error++;
|
||||
continue;
|
||||
}
|
||||
xmlFree(ls_xmlContentPtr);
|
||||
program_set = 1;
|
||||
}
|
||||
}
|
||||
if (!xmlStrcmp(cur->name, BAD_CAST "shuffle")) {
|
||||
if (shuffle_set) {
|
||||
printf("%s[%ld]: Error: Cannot have multiple <shuffle> elements.\n",
|
||||
printf("%s[%ld]: Error: Cannot have multiple <shuffle> elements\n",
|
||||
fileName, xmlGetLineNo(cur));
|
||||
goto config_error;
|
||||
config_error++;
|
||||
continue;
|
||||
}
|
||||
if (cur->xmlChildrenNode != NULL) {
|
||||
int tmp;
|
||||
const char *errstr;
|
||||
|
||||
ls_xmlContentPtr = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
|
||||
tmp = atoi(ls_xmlContentPtr);
|
||||
ezConfig.shuffle = (tmp == 0) ? 0 : 1;
|
||||
ezConfig.shuffle = strtonum(ls_xmlContentPtr, 0, 1, &errstr);
|
||||
if (errstr) {
|
||||
printf("%s[%ld]: Error: <shuffle> may only contain 1 or 0\n",
|
||||
fileName, xmlGetLineNo(cur));
|
||||
config_error++;
|
||||
continue;
|
||||
}
|
||||
xmlFree(ls_xmlContentPtr);
|
||||
shuffle_set = 1;
|
||||
}
|
||||
}
|
||||
if (!xmlStrcmp(cur->name, BAD_CAST "stream_once")) {
|
||||
if (streamOnce_set) {
|
||||
printf("%s[%ld]: Error: Cannot have multiple <stream_once> elements.\n",
|
||||
printf("%s[%ld]: Error: Cannot have multiple <stream_once> elements\n",
|
||||
fileName, xmlGetLineNo(cur));
|
||||
goto config_error;
|
||||
config_error++;
|
||||
continue;
|
||||
}
|
||||
if (cur->xmlChildrenNode != NULL) {
|
||||
int tmp;
|
||||
const char *errstr;
|
||||
|
||||
ls_xmlContentPtr = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
|
||||
tmp = atoi(ls_xmlContentPtr);
|
||||
ezConfig.streamOnce = (tmp == 0) ? 0 : 1;
|
||||
ezConfig.streamOnce = strtonum(ls_xmlContentPtr, 0, 1, &errstr);
|
||||
if (errstr) {
|
||||
printf("%s[%ld]: Error: <stream_once> may only contain 1 or 0\n",
|
||||
fileName, xmlGetLineNo(cur));
|
||||
config_error++;
|
||||
continue;
|
||||
}
|
||||
xmlFree(ls_xmlContentPtr);
|
||||
streamOnce_set = 1;
|
||||
}
|
||||
}
|
||||
if (!xmlStrcmp(cur->name, BAD_CAST "reconnect_tries")) {
|
||||
if (reconnect_set) {
|
||||
printf("%s[%ld]: Error: Cannot have multiple <reconnect_tries> elements.\n",
|
||||
printf("%s[%ld]: Error: Cannot have multiple <reconnect_tries> elements\n",
|
||||
fileName, xmlGetLineNo(cur));
|
||||
goto config_error;
|
||||
config_error++;
|
||||
continue;
|
||||
}
|
||||
if (cur->xmlChildrenNode != NULL) {
|
||||
const char *errstr;
|
||||
|
||||
ls_xmlContentPtr = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
|
||||
ezConfig.reconnectAttempts = atoi(ls_xmlContentPtr);
|
||||
ezConfig.reconnectAttempts = strtonum(ls_xmlContentPtr, 0, UINT_MAX, &errstr);
|
||||
if (errstr) {
|
||||
printf("%s[%ld]: Error: In <reconnect_tries>: '%s' is %s\n",
|
||||
fileName, xmlGetLineNo(cur), ls_xmlContentPtr, errstr);
|
||||
config_error++;
|
||||
continue;
|
||||
}
|
||||
xmlFree(ls_xmlContentPtr);
|
||||
reconnect_set = 1;
|
||||
}
|
||||
}
|
||||
if (!xmlStrcmp(cur->name, BAD_CAST "svrinfoname")) {
|
||||
if (ezConfig.serverName != NULL) {
|
||||
printf("%s[%ld]: Error: Cannot have multiple <svrinfoname> elements.\n",
|
||||
printf("%s[%ld]: Error: Cannot have multiple <svrinfoname> elements\n",
|
||||
fileName, xmlGetLineNo(cur));
|
||||
goto config_error;
|
||||
config_error++;
|
||||
continue;
|
||||
}
|
||||
if (cur->xmlChildrenNode != NULL) {
|
||||
ls_xmlContentPtr = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
|
||||
@ -298,9 +336,10 @@ parseConfig(const char *fileName)
|
||||
}
|
||||
if (!xmlStrcmp(cur->name, BAD_CAST "svrinfourl")) {
|
||||
if (ezConfig.serverURL != NULL) {
|
||||
printf("%s[%ld]: Error: Cannot have multiple <svrinfourl> elements.\n",
|
||||
printf("%s[%ld]: Error: Cannot have multiple <svrinfourl> elements\n",
|
||||
fileName, xmlGetLineNo(cur));
|
||||
goto config_error;
|
||||
config_error++;
|
||||
continue;
|
||||
}
|
||||
if (cur->xmlChildrenNode != NULL) {
|
||||
ls_xmlContentPtr = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
|
||||
@ -310,9 +349,10 @@ parseConfig(const char *fileName)
|
||||
}
|
||||
if (!xmlStrcmp(cur->name, BAD_CAST "svrinfogenre")) {
|
||||
if (ezConfig.serverGenre != NULL) {
|
||||
printf("%s[%ld]: Error: Cannot have multiple <svrinfogenre> elements.\n",
|
||||
printf("%s[%ld]: Error: Cannot have multiple <svrinfogenre> elements\n",
|
||||
fileName, xmlGetLineNo(cur));
|
||||
goto config_error;
|
||||
config_error++;
|
||||
continue;
|
||||
}
|
||||
if (cur->xmlChildrenNode != NULL) {
|
||||
ls_xmlContentPtr = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
|
||||
@ -322,9 +362,10 @@ parseConfig(const char *fileName)
|
||||
}
|
||||
if (!xmlStrcmp(cur->name, BAD_CAST "svrinfodescription")) {
|
||||
if (ezConfig.serverDescription != NULL) {
|
||||
printf("%s[%ld]: Error: Cannot have multiple <svrinfodescription> elements.\n",
|
||||
printf("%s[%ld]: Error: Cannot have multiple <svrinfodescription> elements\n",
|
||||
fileName, xmlGetLineNo(cur));
|
||||
goto config_error;
|
||||
config_error++;
|
||||
continue;
|
||||
}
|
||||
if (cur->xmlChildrenNode != NULL) {
|
||||
ls_xmlContentPtr = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
|
||||
@ -334,9 +375,10 @@ parseConfig(const char *fileName)
|
||||
}
|
||||
if (!xmlStrcmp(cur->name, BAD_CAST "svrinfobitrate")) {
|
||||
if (ezConfig.serverBitrate != NULL) {
|
||||
printf("%s[%ld]: Error: Cannot have multiple <svrinfobitrate> elements.\n",
|
||||
printf("%s[%ld]: Error: Cannot have multiple <svrinfobitrate> elements\n",
|
||||
fileName, xmlGetLineNo(cur));
|
||||
goto config_error;
|
||||
config_error++;
|
||||
continue;
|
||||
}
|
||||
if (cur->xmlChildrenNode != NULL) {
|
||||
ls_xmlContentPtr = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
|
||||
@ -347,9 +389,10 @@ parseConfig(const char *fileName)
|
||||
|
||||
if (!xmlStrcmp(cur->name, BAD_CAST "svrinfochannels")) {
|
||||
if (ezConfig.serverChannels != NULL) {
|
||||
printf("%s[%ld]: Error: Cannot have multiple <svrinfochannels> elements.\n",
|
||||
printf("%s[%ld]: Error: Cannot have multiple <svrinfochannels> elements\n",
|
||||
fileName, xmlGetLineNo(cur));
|
||||
goto config_error;
|
||||
config_error++;
|
||||
continue;
|
||||
}
|
||||
if (cur->xmlChildrenNode != NULL) {
|
||||
ls_xmlContentPtr = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
|
||||
@ -359,9 +402,10 @@ parseConfig(const char *fileName)
|
||||
}
|
||||
if (!xmlStrcmp(cur->name, BAD_CAST "svrinfosamplerate")) {
|
||||
if (ezConfig.serverSamplerate != NULL) {
|
||||
printf("%s[%ld]: Error: Cannot have multiple <svrinfosamplerate> elements.\n",
|
||||
printf("%s[%ld]: Error: Cannot have multiple <svrinfosamplerate> elements\n",
|
||||
fileName, xmlGetLineNo(cur));
|
||||
goto config_error;
|
||||
config_error++;
|
||||
continue;
|
||||
}
|
||||
if (cur->xmlChildrenNode != NULL) {
|
||||
ls_xmlContentPtr = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
|
||||
@ -371,9 +415,10 @@ parseConfig(const char *fileName)
|
||||
}
|
||||
if (!xmlStrcmp(cur->name, BAD_CAST "svrinfoquality")) {
|
||||
if (ezConfig.serverQuality != NULL) {
|
||||
printf("%s[%ld]: Error: Cannot have multiple <svrinfoquality> elements.\n",
|
||||
printf("%s[%ld]: Error: Cannot have multiple <svrinfoquality> elements\n",
|
||||
fileName, xmlGetLineNo(cur));
|
||||
goto config_error;
|
||||
config_error++;
|
||||
continue;
|
||||
}
|
||||
if (cur->xmlChildrenNode != NULL) {
|
||||
ls_xmlContentPtr = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
|
||||
@ -383,16 +428,22 @@ parseConfig(const char *fileName)
|
||||
}
|
||||
if (!xmlStrcmp(cur->name, BAD_CAST "svrinfopublic")) {
|
||||
if (svrinfopublic_set) {
|
||||
printf("%s[%ld]: Error: Cannot have multiple <svrinfopublic> elements.\n",
|
||||
printf("%s[%ld]: Error: Cannot have multiple <svrinfopublic> elements\n",
|
||||
fileName, xmlGetLineNo(cur));
|
||||
goto config_error;
|
||||
config_error++;
|
||||
continue;
|
||||
}
|
||||
if (cur->xmlChildrenNode != NULL) {
|
||||
int tmp;
|
||||
const char *errstr;
|
||||
|
||||
ls_xmlContentPtr = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
|
||||
tmp = atoi(ls_xmlContentPtr);
|
||||
ezConfig.serverPublic = (tmp == 0) ? 0 : 1;
|
||||
ezConfig.serverPublic = strtonum(ls_xmlContentPtr, 0, 1, &errstr);
|
||||
if (errstr) {
|
||||
printf("%s[%ld]: Error: <svrinfopublic> may only contain 1 or 0\n",
|
||||
fileName, xmlGetLineNo(cur));
|
||||
config_error++;
|
||||
continue;
|
||||
}
|
||||
xmlFree(ls_xmlContentPtr);
|
||||
svrinfopublic_set = 1;
|
||||
}
|
||||
@ -406,16 +457,22 @@ parseConfig(const char *fileName)
|
||||
while (cur2 != NULL) {
|
||||
if (!xmlStrcmp(cur2->name, BAD_CAST "enable")) {
|
||||
if (enable_set) {
|
||||
printf("%s[%ld]: Error: Cannot have multiple <enable> elements.\n",
|
||||
printf("%s[%ld]: Error: Cannot have multiple <enable> elements\n",
|
||||
fileName, xmlGetLineNo(cur));
|
||||
goto config_error;
|
||||
config_error++;
|
||||
continue;
|
||||
}
|
||||
if (cur2->xmlChildrenNode != NULL) {
|
||||
int tmp;
|
||||
const char *errstr;
|
||||
|
||||
ls_xmlContentPtr = (char *)xmlNodeListGetString(doc, cur2->xmlChildrenNode, 1);
|
||||
tmp = atoi(ls_xmlContentPtr);
|
||||
ezConfig.reencode = (tmp == 0) ? 0 : 1;
|
||||
ezConfig.reencode = strtonum(ls_xmlContentPtr, 0, 1, &errstr);
|
||||
if (errstr) {
|
||||
printf("%s[%ld]: Error: <enable> may only contain 1 or 0\n",
|
||||
fileName, xmlGetLineNo(cur));
|
||||
config_error++;
|
||||
continue;
|
||||
}
|
||||
xmlFree(ls_xmlContentPtr);
|
||||
enable_set = 1;
|
||||
}
|
||||
@ -431,9 +488,10 @@ parseConfig(const char *fileName)
|
||||
while (cur3 != NULL) {
|
||||
if (!xmlStrcmp(cur3->name, BAD_CAST "format")) {
|
||||
if (pformatEncDec->format != NULL) {
|
||||
printf("%s[%ld]: Error: Cannot have multiple <format> elements.\n",
|
||||
printf("%s[%ld]: Error: Cannot have multiple <format> elements\n",
|
||||
fileName, xmlGetLineNo(cur3));
|
||||
goto config_error;
|
||||
config_error++;
|
||||
continue;
|
||||
}
|
||||
if (cur3->xmlChildrenNode != NULL) {
|
||||
char *p;
|
||||
@ -447,9 +505,10 @@ parseConfig(const char *fileName)
|
||||
}
|
||||
if (!xmlStrcmp(cur3->name, BAD_CAST "match")) {
|
||||
if (pformatEncDec->match != NULL) {
|
||||
printf("%s[%ld]: Error: Cannot have multiple <match> elements.\n",
|
||||
printf("%s[%ld]: Error: Cannot have multiple <match> elements\n",
|
||||
fileName, xmlGetLineNo(cur3));
|
||||
goto config_error;
|
||||
config_error++;
|
||||
continue;
|
||||
}
|
||||
if (cur3->xmlChildrenNode != NULL) {
|
||||
char *p;
|
||||
@ -463,9 +522,10 @@ parseConfig(const char *fileName)
|
||||
}
|
||||
if (!xmlStrcmp(cur3->name, BAD_CAST "decode")) {
|
||||
if (pformatEncDec->decoder != NULL) {
|
||||
printf("%s[%ld]: Error: Cannot have multiple <decode> elements.\n",
|
||||
printf("%s[%ld]: Error: Cannot have multiple <decode> elements\n",
|
||||
fileName, xmlGetLineNo(cur3));
|
||||
goto config_error;
|
||||
config_error++;
|
||||
continue;
|
||||
}
|
||||
if (cur3->xmlChildrenNode != NULL) {
|
||||
ls_xmlContentPtr = (char *)xmlNodeListGetString(doc, cur3->xmlChildrenNode, 1);
|
||||
@ -476,7 +536,8 @@ parseConfig(const char *fileName)
|
||||
if ((p = strstr(p, TRACK_PLACEHOLDER)) != NULL) {
|
||||
printf("%s[%ld]: Error: Multiple `%s' placeholders in decoder command\n",
|
||||
fileName, xmlGetLineNo(cur3), TRACK_PLACEHOLDER);
|
||||
goto config_error;
|
||||
config_error++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if ((p = strstr(pformatEncDec->decoder, METADATA_PLACEHOLDER)) != NULL) {
|
||||
@ -484,16 +545,18 @@ parseConfig(const char *fileName)
|
||||
if ((p = strstr(p, METADATA_PLACEHOLDER)) != NULL) {
|
||||
printf("%s[%ld]: Error: Multiple `%s' placeholders in decoder command\n",
|
||||
fileName, xmlGetLineNo(cur3), METADATA_PLACEHOLDER);
|
||||
goto config_error;
|
||||
config_error++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!xmlStrcmp(cur3->name, BAD_CAST "encode")) {
|
||||
if (pformatEncDec->encoder != NULL) {
|
||||
printf("%s[%ld]: Error: Cannot have multiple <encode> elements.\n",
|
||||
printf("%s[%ld]: Error: Cannot have multiple <encode> elements\n",
|
||||
fileName, xmlGetLineNo(cur3));
|
||||
goto config_error;
|
||||
config_error++;
|
||||
continue;
|
||||
}
|
||||
if (cur3->xmlChildrenNode != NULL) {
|
||||
ls_xmlContentPtr = (char *)xmlNodeListGetString(doc, cur3->xmlChildrenNode, 1);
|
||||
@ -502,14 +565,16 @@ parseConfig(const char *fileName)
|
||||
if ((p = strstr(pformatEncDec->encoder, TRACK_PLACEHOLDER)) != NULL) {
|
||||
printf("%s[%ld]: Error: `%s' placeholder not allowed in encoder command\n",
|
||||
fileName, xmlGetLineNo(cur3), TRACK_PLACEHOLDER);
|
||||
goto config_error;
|
||||
config_error++;
|
||||
continue;
|
||||
}
|
||||
if ((p = strstr(pformatEncDec->encoder, METADATA_PLACEHOLDER)) != NULL) {
|
||||
p += strlen(METADATA_PLACEHOLDER);
|
||||
if ((p = strstr(p, METADATA_PLACEHOLDER)) != NULL) {
|
||||
printf("%s[%ld]: Error: Multiple `%s' placeholders in encoder command\n",
|
||||
fileName, xmlGetLineNo(cur3), METADATA_PLACEHOLDER);
|
||||
goto config_error;
|
||||
config_error++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -526,11 +591,13 @@ parseConfig(const char *fileName)
|
||||
}
|
||||
|
||||
xmlFreeDoc(doc);
|
||||
return(1);
|
||||
|
||||
config_error:
|
||||
if (config_error == 0)
|
||||
return (1);
|
||||
|
||||
xmlFreeDoc(doc);
|
||||
freeConfig(&ezConfig);
|
||||
printf("%s: %u configuration errors in %s\n", __progname,
|
||||
config_error, fileName);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
@ -57,11 +57,9 @@
|
||||
#ifndef HAVE_GETOPT
|
||||
# include "getopt.h"
|
||||
#endif
|
||||
#if !defined(HAVE_STRLCAT) || !defined(HAVE_STRLCPY)
|
||||
# include "strlfctns.h"
|
||||
#endif
|
||||
#include "configfile.h"
|
||||
#include "playlist.h"
|
||||
#include "strfctns.h"
|
||||
#include "util.h"
|
||||
|
||||
#ifndef PATH_MAX
|
||||
@ -187,9 +185,10 @@ strrcmp(const char *s, const char *sub)
|
||||
int
|
||||
urlParse(const char *url, char **hostname, int *port, char **mountname)
|
||||
{
|
||||
char *p1, *p2, *p3;
|
||||
char tmpPort[25] = "";
|
||||
size_t hostsiz, mountsiz;
|
||||
char *p1, *p2, *p3;
|
||||
char tmpPort[6] = "";
|
||||
size_t hostsiz, mountsiz;
|
||||
const char *errstr;
|
||||
|
||||
if (hostname == NULL || port == NULL || mountname == NULL) {
|
||||
printf("%s: urlParse(): Internal error: Bad arguments\n",
|
||||
@ -197,24 +196,40 @@ urlParse(const char *url, char **hostname, int *port, char **mountname)
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (strncmp(url, "http://", strlen("http://")) != 0)
|
||||
if (strncmp(url, "http://", strlen("http://")) != 0) {
|
||||
printf("%s: Error: Invalid <url>: Not an HTTP address\n",
|
||||
__progname);
|
||||
return (0);
|
||||
}
|
||||
|
||||
p1 = (char *)(url) + strlen("http://");
|
||||
p2 = strchr(p1, ':');
|
||||
if (p2 == NULL)
|
||||
if (p2 == NULL) {
|
||||
printf("%s: Error: Invalid <url>: Missing port\n",
|
||||
__progname);
|
||||
return (0);
|
||||
}
|
||||
hostsiz = (p2 - p1) + 1;
|
||||
*hostname = xmalloc(hostsiz);
|
||||
strlcpy(*hostname, p1, hostsiz);
|
||||
|
||||
p2++;
|
||||
p3 = strchr(p2, '/');
|
||||
if (p3 == NULL || p3 - p2 >= (int)sizeof(tmpPort))
|
||||
if (p3 == NULL || p3 - p2 >= (int)sizeof(tmpPort)) {
|
||||
printf("%s: Error: Invalid <url>: Missing mountpoint or too long port number\n",
|
||||
__progname);
|
||||
xfree(*hostname);
|
||||
return (0);
|
||||
}
|
||||
|
||||
strlcpy(tmpPort, p2, (p3 - p2) + 1);
|
||||
*port = atoi(tmpPort);
|
||||
*port = strtonum(tmpPort, 1, 65535, &errstr);
|
||||
if (errstr) {
|
||||
printf("%s: Error: Invalid <url>: Port '%s' is %s\n",
|
||||
__progname, tmpPort, errstr);
|
||||
xfree(*hostname);
|
||||
return (0);
|
||||
}
|
||||
|
||||
mountsiz = strlen(p3) + 1;
|
||||
*mountname = xmalloc(mountsiz);
|
||||
@ -269,7 +284,7 @@ buildCommandString(const char *extension, const char *fileName,
|
||||
|
||||
decoder = xstrdup(getFormatDecoder(extension));
|
||||
if (strlen(decoder) == 0) {
|
||||
printf("%s: Unknown extension '%s', cannot decode '%s'.\n",
|
||||
printf("%s: Unknown extension '%s', cannot decode '%s'\n",
|
||||
__progname, extension, fileName);
|
||||
xfree(decoder);
|
||||
return (NULL);
|
||||
@ -371,27 +386,27 @@ processMetadata(shout_t *shout, const char *extension, const char *fileName)
|
||||
if ((ret = ov_open(filepstream, &vf, NULL, 0)) != 0) {
|
||||
switch (ret) {
|
||||
case OV_EREAD:
|
||||
printf("%s: No metadata support: %s: Media read error.\n",
|
||||
printf("%s: No metadata support: %s: Media read error\n",
|
||||
__progname, fileName);
|
||||
break;
|
||||
case OV_ENOTVORBIS:
|
||||
printf("%s: No metadata support: %s: Invalid Vorbis bitstream.\n",
|
||||
printf("%s: No metadata support: %s: Invalid Vorbis bitstream\n",
|
||||
__progname, fileName);
|
||||
break;
|
||||
case OV_EVERSION:
|
||||
printf("%s: No metadata support: %s: Vorbis version mismatch.\n",
|
||||
printf("%s: No metadata support: %s: Vorbis version mismatch\n",
|
||||
__progname, fileName);
|
||||
break;
|
||||
case OV_EBADHEADER:
|
||||
printf("%s: No metadata support: %s: Invalid Vorbis bitstream header.\n",
|
||||
printf("%s: No metadata support: %s: Invalid Vorbis bitstream header\n",
|
||||
__progname, fileName);
|
||||
break;
|
||||
case OV_EFAULT:
|
||||
printf("%s: Fatal: Internal libvorbisfile fault.\n",
|
||||
printf("%s: Fatal: Internal libvorbisfile fault\n",
|
||||
__progname);
|
||||
abort();
|
||||
default:
|
||||
printf("%s: No metadata support: %s: ov_read() returned unknown error.\n",
|
||||
printf("%s: No metadata support: %s: ov_read() returned unknown error\n",
|
||||
__progname, fileName);
|
||||
break;
|
||||
}
|
||||
@ -487,7 +502,7 @@ openResource(shout_t *shout, const char *fileName, int *popenFlag,
|
||||
|
||||
if (strcmp(fileName, "stdin") == 0) {
|
||||
if (vFlag)
|
||||
printf("%s: Reading from standard input.\n",
|
||||
printf("%s: Reading from standard input\n",
|
||||
__progname);
|
||||
if (isStdin != NULL)
|
||||
*isStdin = 1;
|
||||
@ -555,7 +570,7 @@ openResource(shout_t *shout, const char *fileName, int *popenFlag,
|
||||
if (qFlag)
|
||||
dup2(stderr_fd, STDERR_FILENO);
|
||||
} else
|
||||
printf("%s: Error: Cannot determine file type of '%s'.\n",
|
||||
printf("%s: Error: Cannot determine file type of '%s'\n",
|
||||
__progname, fileName);
|
||||
|
||||
xfree(pMetadata);
|
||||
@ -577,7 +592,7 @@ reconnectServer(shout_t *shout, int closeConn)
|
||||
unsigned int i;
|
||||
int close_conn = closeConn;
|
||||
|
||||
printf("%s: Connection to %s lost.\n", __progname, pezConfig->URL);
|
||||
printf("%s: Connection to %s lost\n", __progname, pezConfig->URL);
|
||||
|
||||
i = 0;
|
||||
while (++i) {
|
||||
@ -593,7 +608,7 @@ reconnectServer(shout_t *shout, int closeConn)
|
||||
else
|
||||
shout_close(shout);
|
||||
if (shout_open(shout) == SHOUTERR_SUCCESS) {
|
||||
printf("OK\n%s: Reconnect to %s successful.\n",
|
||||
printf("OK\n%s: Reconnect to %s successful\n",
|
||||
__progname, pezConfig->URL);
|
||||
return (1);
|
||||
}
|
||||
@ -613,7 +628,7 @@ reconnectServer(shout_t *shout, int closeConn)
|
||||
#endif
|
||||
};
|
||||
|
||||
printf("%s: Giving up.\n", __progname);
|
||||
printf("%s: Giving up\n", __progname);
|
||||
return (0);
|
||||
}
|
||||
|
||||
@ -650,7 +665,7 @@ sendStream(shout_t *shout, FILE *filepstream, const char *fileName,
|
||||
if (rereadPlaylist_notify) {
|
||||
rereadPlaylist_notify = 0;
|
||||
if (!pezConfig->fileNameIsProgram)
|
||||
printf("%s: SIGHUP signal received, will reread playlist after this file.\n",
|
||||
printf("%s: SIGHUP signal received, will reread playlist after this file\n",
|
||||
__progname);
|
||||
}
|
||||
if (skipTrack) {
|
||||
@ -776,7 +791,7 @@ streamFile(shout_t *shout, const char *fileName)
|
||||
if (ret == STREAM_SKIP || skipTrack) {
|
||||
skipTrack = 0;
|
||||
if (!isStdin && vFlag)
|
||||
printf("%s: SIGUSR1 signal received, skipping current track.\n",
|
||||
printf("%s: SIGUSR1 signal received, skipping current track\n",
|
||||
__progname);
|
||||
retval = 1;
|
||||
ret = STREAM_DONE;
|
||||
@ -914,7 +929,7 @@ main(int argc, char *argv[])
|
||||
switch (c) {
|
||||
case 'c':
|
||||
if (configFile != NULL) {
|
||||
printf("Error: multiple -c arguments given.\n");
|
||||
printf("Error: multiple -c arguments given\n");
|
||||
usage();
|
||||
return (2);
|
||||
}
|
||||
@ -959,10 +974,10 @@ main(int argc, char *argv[])
|
||||
return (2);
|
||||
}
|
||||
if (vFlag && (st.st_mode & (S_IRGRP | S_IROTH)))
|
||||
printf("%s: Warning: %s is group and/or world readable.\n",
|
||||
printf("%s: Warning: %s is group and/or world readable\n",
|
||||
__progname, configFile);
|
||||
if (st.st_mode & (S_IWGRP | S_IWOTH)) {
|
||||
printf("%s: Error: %s is group and/or world writeable.\n",
|
||||
printf("%s: Error: %s is group and/or world writeable\n",
|
||||
__progname, configFile);
|
||||
return (2);
|
||||
}
|
||||
@ -989,36 +1004,30 @@ main(int argc, char *argv[])
|
||||
return (2);
|
||||
}
|
||||
if (!urlParse(pezConfig->URL, &host, &port, &mount)) {
|
||||
printf("%s: Error: Invalid <url>:\n", configFile);
|
||||
printf("Must be of the form ``http://server:port/mountpoint''.\n");
|
||||
printf("Must be of the form ``http://server:port/mountpoint''\n");
|
||||
return (2);
|
||||
}
|
||||
if ((host == NULL)) {
|
||||
if (strlen(host) == 0) {
|
||||
printf("%s: Error: Invalid <url>: Missing server:\n", configFile);
|
||||
printf("Must be of the form ``http://server:port/mountpoint''.\n");
|
||||
printf("Must be of the form ``http://server:port/mountpoint''\n");
|
||||
return (2);
|
||||
}
|
||||
if ((port < 1 || port > 65535)) {
|
||||
printf("%s: Error: Invalid <url>: Missing or invalid port:\n", configFile);
|
||||
printf("Must be of the form ``http://server:port/mountpoint''.\n");
|
||||
return (2);
|
||||
}
|
||||
if ((mount == NULL)) {
|
||||
if (strlen(mount) == 0) {
|
||||
printf("%s: Error: Invalid <url>: Missing mountpoint:\n", configFile);
|
||||
printf("Must be of the form ``http://server:port/mountpoint''.\n");
|
||||
printf("Must be of the form ``http://server:port/mountpoint''\n");
|
||||
return (2);
|
||||
}
|
||||
if ((pezConfig->password == NULL)) {
|
||||
if (pezConfig->password == NULL) {
|
||||
printf("%s: Error: Missing <sourcepassword>\n", configFile);
|
||||
return (2);
|
||||
}
|
||||
if ((pezConfig->fileName == NULL)) {
|
||||
if (pezConfig->fileName == NULL) {
|
||||
printf("%s: Error: Missing <filename>\n", configFile);
|
||||
return (2);
|
||||
}
|
||||
if (pezConfig->format == NULL) {
|
||||
printf("%s: Warning: Missing <format>:\n", configFile);
|
||||
printf("Specify a stream format of either MP3, VORBIS or THEORA.\n");
|
||||
printf("Specify a stream format of either MP3, VORBIS or THEORA\n");
|
||||
}
|
||||
|
||||
xfree(configFile);
|
||||
|
23
src/strfctns.h
Normal file
23
src/strfctns.h
Normal file
@ -0,0 +1,23 @@
|
||||
#ifndef __STRLFCTNS_H__
|
||||
#define __STRLFCTNS_H__
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_STRLCAT
|
||||
# define strlcat local_strlcat
|
||||
#endif
|
||||
size_t local_strlcat(char *, const char *, size_t);
|
||||
|
||||
#ifndef HAVE_STRLCPY
|
||||
# define strlcpy local_strlcpy
|
||||
#endif
|
||||
size_t local_strlcpy(char *, const char *, size_t);
|
||||
|
||||
#ifndef HAVE_STRTONUM
|
||||
# define strtonum local_strtonum
|
||||
#endif
|
||||
long long local_strtonum(const char *, long long, long long, const char **);
|
||||
|
||||
#endif /* __STRLFCTNS_H__ */
|
@ -24,7 +24,7 @@
|
||||
# include <sys/types.h>
|
||||
#endif
|
||||
#include <string.h>
|
||||
#include "strlfctns.h"
|
||||
#include "strfctns.h"
|
||||
|
||||
/*
|
||||
* Appends src to string dst of size siz (unlike strncat, siz is the
|
||||
|
@ -24,7 +24,7 @@
|
||||
# include <sys/types.h>
|
||||
#endif
|
||||
#include <string.h>
|
||||
#include "strlfctns.h"
|
||||
#include "strfctns.h"
|
||||
|
||||
/*
|
||||
* Copy src to string dst of size siz. At most siz-1 characters
|
||||
|
@ -1,18 +0,0 @@
|
||||
#ifndef __STRLFCTNS_H__
|
||||
#define __STRLFCTNS_H__
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_STRLCAT
|
||||
# define strlcat local_strlcat
|
||||
#endif
|
||||
size_t local_strlcat(char *, const char *, size_t);
|
||||
|
||||
#ifndef HAVE_STRLCPY
|
||||
# define strlcpy local_strlcpy
|
||||
#endif
|
||||
size_t local_strlcpy(char *, const char *, size_t);
|
||||
|
||||
#endif /* __STRLFCTNS_H__ */
|
81
src/strtonum.c
Normal file
81
src/strtonum.c
Normal file
@ -0,0 +1,81 @@
|
||||
/* $OpenBSD: strtonum.c,v 1.6 2004/08/03 19:38:01 millert Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2004 Ted Unangst and Todd Miller
|
||||
* All rights reserved.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <stdlib.h>
|
||||
#include "strfctns.h"
|
||||
|
||||
#define INVALID 1
|
||||
#define TOOSMALL 2
|
||||
#define TOOLARGE 3
|
||||
|
||||
#if !defined(LLONG_MIN) || !defined(LLONG_MAX)
|
||||
# undef LLONG_MIN
|
||||
# undef LLONG_MAX
|
||||
# define LLONG_MIN LONG_LONG_MIN
|
||||
# define LLONG_MAX LONG_LONG_MAX
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
# define strtoll _strtoi64
|
||||
#endif
|
||||
|
||||
long long
|
||||
local_strtonum(const char *numstr, long long minval, long long maxval,
|
||||
const char **errstrp)
|
||||
{
|
||||
long long ll = 0;
|
||||
char *ep;
|
||||
int error = 0;
|
||||
struct errval {
|
||||
const char *errstr;
|
||||
int err;
|
||||
} ev[4] = {
|
||||
{ NULL, 0 },
|
||||
{ "invalid", EINVAL },
|
||||
{ "too small", ERANGE },
|
||||
{ "too large", ERANGE },
|
||||
};
|
||||
|
||||
ev[0].err = errno;
|
||||
errno = 0;
|
||||
if (minval > maxval)
|
||||
error = INVALID;
|
||||
else {
|
||||
ll = strtoll(numstr, &ep, 10);
|
||||
if (numstr == ep || *ep != '\0')
|
||||
error = INVALID;
|
||||
else if ((ll == LLONG_MIN && errno == ERANGE) || ll < minval)
|
||||
error = TOOSMALL;
|
||||
else if ((ll == LLONG_MAX && errno == ERANGE) || ll > maxval)
|
||||
error = TOOLARGE;
|
||||
}
|
||||
if (errstrp != NULL)
|
||||
*errstrp = ev[error].errstr;
|
||||
errno = ev[error].err;
|
||||
if (error)
|
||||
ll = 0;
|
||||
|
||||
return (ll);
|
||||
}
|
Loading…
Reference in New Issue
Block a user