[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