[xiph-commits] r12599 - in trunk/ezstream: . doc src
moritz at svn.xiph.org
moritz at svn.xiph.org
Thu Mar 1 16:57:16 PST 2007
Author: moritz
Date: 2007-03-01 16:57:11 -0800 (Thu, 01 Mar 2007)
New Revision: 12599
Modified:
trunk/ezstream/NEWS
trunk/ezstream/doc/ezstream.1.in
trunk/ezstream/src/configfile.c
trunk/ezstream/src/configfile.h
trunk/ezstream/src/ezstream.c
Log:
Allow users to restrict the number of reconnection attempts. This also changes
how reconnections are handled in general: A recovered connection always skips
to the next tune as well, as it seems that at least for Ogg Vorbis, libshout
wants to see an Ogg header after a shout_open(). The new code makes this
behavior consistent among all formats.
Modified: trunk/ezstream/NEWS
===================================================================
--- trunk/ezstream/NEWS 2007-03-01 17:15:42 UTC (rev 12598)
+++ trunk/ezstream/NEWS 2007-03-02 00:57:11 UTC (rev 12599)
@@ -11,6 +11,8 @@
the new <playlist_program> configuration option to 1.
- New <stream_once> configuration option, which makes ezstream play a media
file or playlist once and then exit.
+ - New <reconnect_tries> option to restrict the number of reconnection
+ attempts to a server in case the connection goes down.
- Add feature to skip the currently streaming track, done by sending the
SIGUSR1 signal to the ezstream process.
- New command line option `-q': Suppress standard error output from external
Modified: trunk/ezstream/doc/ezstream.1.in
===================================================================
--- trunk/ezstream/doc/ezstream.1.in 2007-03-01 17:15:42 UTC (rev 12598)
+++ trunk/ezstream/doc/ezstream.1.in 2007-03-02 00:57:11 UTC (rev 12599)
@@ -198,6 +198,13 @@
.Pq zero
for continuous streaming
.Pq the default .
+.It Sy \&<reconnect_tries\ /\&>
+Set how many attempts should be made to reconnect to the Icecast server in case
+the connection is interrupted.
+The default is to try indefinitely, which is equal to setting this
+configuration option to
+.Sy 0
+.Pq zero .
.It Sy \&<svrinfoname\ /\&>
.Pq Optional.
Set the name of the broadcast.
Modified: trunk/ezstream/src/configfile.c
===================================================================
--- trunk/ezstream/src/configfile.c 2007-03-01 17:15:42 UTC (rev 12598)
+++ trunk/ezstream/src/configfile.c 2007-03-02 00:57:11 UTC (rev 12599)
@@ -140,8 +140,8 @@
xmlDocPtr doc;
xmlNodePtr cur;
char *ls_xmlContentPtr;
- int program_set, shuffle_set, streamOnce_set,
- svrinfopublic_set;
+ int program_set, reconnect_set, shuffle_set,
+ streamOnce_set, svrinfopublic_set;
xmlLineNumbersDefault(1);
if ((doc = xmlParseFile(fileName)) == NULL) {
@@ -160,6 +160,7 @@
memset(&ezConfig, '\000', sizeof(ezConfig));
program_set = 0;
+ reconnect_set = 0;
shuffle_set = 0;
streamOnce_set = 0;
svrinfopublic_set = 0;
@@ -270,6 +271,19 @@
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",
+ fileName, xmlGetLineNo(cur));
+ goto config_error;
+ }
+ if (cur->xmlChildrenNode != NULL) {
+ ls_xmlContentPtr = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
+ ezConfig.reconnectAttempts = atoi(ls_xmlContentPtr);
+ 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",
Modified: trunk/ezstream/src/configfile.h
===================================================================
--- trunk/ezstream/src/configfile.h 2007-03-01 17:15:42 UTC (rev 12598)
+++ trunk/ezstream/src/configfile.h 2007-03-02 00:57:11 UTC (rev 12599)
@@ -59,6 +59,7 @@
int shuffle;
int fileNameIsProgram;
int streamOnce;
+ unsigned int reconnectAttempts;
} EZCONFIG;
EZCONFIG * getEZConfig(void);
Modified: trunk/ezstream/src/ezstream.c
===================================================================
--- trunk/ezstream/src/ezstream.c 2007-03-01 17:15:42 UTC (rev 12598)
+++ trunk/ezstream/src/ezstream.c 2007-03-02 00:57:11 UTC (rev 12599)
@@ -83,6 +83,11 @@
# define STRNCASECMP strncasecmp
#endif /* WIN32 */
+#define STREAM_DONE 0
+#define STREAM_CONT 1
+#define STREAM_SKIP 2
+#define STREAM_SERVERR 3
+
#ifdef HAVE___PROGNAME
extern char *__progname;
#else
@@ -130,6 +135,7 @@
char * buildCommandString(const char *, const char *, const char *);
char * processMetadata(shout_t *, const char *, const char *);
FILE * openResource(shout_t *, const char *, int *, char **, int *);
+int reconnectServer(shout_t *, int);
int sendStream(shout_t *, FILE *, const char *, int, void *);
int streamFile(shout_t *, const char *);
int streamPlaylist(shout_t *, const char *);
@@ -566,12 +572,58 @@
}
int
+reconnectServer(shout_t *shout, int closeConn)
+{
+ unsigned int i;
+ int close_conn = closeConn;
+
+ printf("%s: Connection to %s lost.\n", __progname, pezConfig->URL);
+
+ i = 0;
+ while (++i) {
+ printf("%s: Attempting reconnection #", __progname);
+ if (pezConfig->reconnectAttempts > 0)
+ printf("%u/%u: ", i,
+ pezConfig->reconnectAttempts);
+ else
+ printf("%u: ", i);
+
+ if (close_conn == 0)
+ close_conn = 1;
+ else
+ shout_close(shout);
+ if (shout_open(shout) == SHOUTERR_SUCCESS) {
+ printf("OK\n%s: Reconnect to %s successful.\n",
+ __progname, pezConfig->URL);
+ return (1);
+ }
+
+ printf("FAILED: %s\n", shout_get_error(shout));
+
+ if (pezConfig->reconnectAttempts > 0 &&
+ i >= pezConfig->reconnectAttempts)
+ break;
+
+ printf("%s: Waiting 5s for %s to come back ...\n",
+ __progname, pezConfig->URL);
+#ifdef WIN32
+ Sleep(5000);
+#else
+ sleep(5);
+#endif
+ };
+
+ printf("%s: Giving up.\n", __progname);
+ return (0);
+}
+
+int
sendStream(shout_t *shout, FILE *filepstream, const char *fileName,
int isStdin, void *tv)
{
unsigned char buff[4096];
size_t read, total, oldTotal;
- int ret = 0;
+ int ret;
#ifdef HAVE_GETTIMEOFDAY
double kbps = -1.0;
struct timeval timeStamp, *startTime = (struct timeval *)tv;
@@ -587,7 +639,14 @@
#endif /* HAVE_GETTIMEOFDAY */
total = oldTotal = 0;
+ ret = STREAM_DONE;
while ((read = fread(buff, 1, sizeof(buff), filepstream)) > 0) {
+ if (shout_get_connected(shout) != SHOUTERR_CONNECTED &&
+ reconnectServer(shout, 0) == 0) {
+ ret = STREAM_SERVERR;
+ break;
+ }
+
if (rereadPlaylist_notify) {
rereadPlaylist_notify = 0;
if (!pezConfig->fileNameIsProgram)
@@ -596,7 +655,7 @@
}
if (skipTrack) {
skipTrack = 0;
- ret = 2;
+ ret = STREAM_SKIP;
break;
}
@@ -605,27 +664,11 @@
if (shout_send(shout, buff, read) != SHOUTERR_SUCCESS) {
printf("%s: shout_send(): %s\n", __progname,
shout_get_error(shout));
- while (1) {
- printf("%s: Disconnected from server, reconnecting ...\n",
- __progname);
- shout_close(shout);
- if (shout_open(shout) == SHOUTERR_SUCCESS) {
- printf("%s: Reconnect to server successful.\n",
- __progname);
- if (shout_send(shout, buff, read) == SHOUTERR_SUCCESS)
- break;
- printf("%s: shout_send(): %s\n",
- __progname,
- shout_get_error(shout));
- } else {
- printf("%s: Reconnect failed. Waiting 5 seconds ...\n",
- __progname);
-#ifdef WIN32
- Sleep(5000);
-#else
- sleep(5);
-#endif
- }
+ if (reconnectServer(shout, 1))
+ break;
+ else {
+ ret = STREAM_SERVERR;
+ break;
}
}
@@ -680,7 +723,7 @@
if (ferror(filepstream)) {
if (errno == EINTR) {
clearerr(filepstream);
- ret = 1;
+ ret = STREAM_CONT;
} else
printf("%s: streamFile(): Error while reading '%s': %s\n",
__progname, fileName, strerror(errno));
@@ -725,19 +768,23 @@
do {
ret = sendStream(shout, filepstream, fileName, isStdin, NULL);
#endif
- if (ret != 0) {
+ if (ret != STREAM_DONE) {
if (skipTrack && rereadPlaylist) {
skipTrack = 0;
ret = 1;
}
- if (ret == 2 || skipTrack) {
+ if (ret == STREAM_SKIP || skipTrack) {
skipTrack = 0;
if (!isStdin && vFlag)
printf("%s: SIGUSR1 signal received, skipping current track.\n",
__progname);
retval = 1;
- ret = 0;
+ ret = STREAM_DONE;
}
+ if (ret == STREAM_SERVERR) {
+ retval = 0;
+ ret = STREAM_DONE;
+ }
} else
retval = 1;
} while (ret);
More information about the commits
mailing list