[xiph-commits] r12701 - trunk/ezstream/src

moritz at svn.xiph.org moritz at svn.xiph.org
Fri Mar 9 18:27:53 PST 2007


Author: moritz
Date: 2007-03-09 18:27:48 -0800 (Fri, 09 Mar 2007)
New Revision: 12701

Modified:
   trunk/ezstream/src/configfile.c
   trunk/ezstream/src/configfile.h
   trunk/ezstream/src/ezstream.c
   trunk/ezstream/src/metadata.c
   trunk/ezstream/src/metadata.h
Log:
Commit work-in-progress towards more fine-grained control over metadata. This
has not been checked for changes to previous behavior and isn't complete, yet.
More to come.


Modified: trunk/ezstream/src/configfile.c
===================================================================
--- trunk/ezstream/src/configfile.c	2007-03-09 21:25:12 UTC (rev 12700)
+++ trunk/ezstream/src/configfile.c	2007-03-10 02:27:48 UTC (rev 12701)
@@ -36,7 +36,9 @@
 static EZCONFIG		 ezConfig;
 static const char	*blankString = "";
 
-void	freeConfig(EZCONFIG *);
+void	        freeConfig(EZCONFIG *);
+unsigned int	checkDecoderLine(const char *, const char *, long);
+unsigned int	checkEncoderLine(const char *, const char *, long);
 
 EZCONFIG *
 getEZConfig(void)
@@ -82,59 +84,6 @@
 	return (blankString);
 }
 
-void
-freeConfig(EZCONFIG *cfg)
-{
-	unsigned int	i;
-
-	if (cfg == NULL)
-		return;
-
-	if (cfg->URL != NULL)
-		xfree(cfg->URL);
-	if (cfg->password != NULL)
-		xfree(cfg->password);
-	if (cfg->format != NULL)
-		xfree(cfg->format);
-	if (cfg->fileName != NULL)
-		xfree(cfg->fileName);
-	if (cfg->metadataProgram != NULL)
-		xfree(cfg->metadataProgram);
-	if (cfg->serverName != NULL)
-		xfree(cfg->serverName);
-	if (cfg->serverURL != NULL)
-		xfree(cfg->serverURL);
-	if (cfg->serverGenre != NULL)
-		xfree(cfg->serverGenre);
-	if (cfg->serverDescription != NULL)
-		xfree(cfg->serverDescription);
-	if (cfg->serverBitrate != NULL)
-		xfree(cfg->serverBitrate);
-	if (cfg->serverChannels != NULL)
-		xfree(cfg->serverChannels);
-	if (cfg->serverSamplerate != NULL)
-		xfree(cfg->serverSamplerate);
-	if (cfg->serverQuality != NULL)
-		xfree(cfg->serverQuality);
-	if (cfg->encoderDecoders != NULL) {
-		for (i = 0; i < MAX_FORMAT_ENCDEC; i++) {
-			if (cfg->encoderDecoders[i] != NULL) {
-				if (cfg->encoderDecoders[i]->format != NULL)
-					xfree(cfg->encoderDecoders[i]->format);
-				if (cfg->encoderDecoders[i]->match != NULL)
-					xfree(cfg->encoderDecoders[i]->match);
-				if (cfg->encoderDecoders[i]->encoder != NULL)
-					xfree(cfg->encoderDecoders[i]->encoder);
-				if (cfg->encoderDecoders[i]->decoder != NULL)
-					xfree(cfg->encoderDecoders[i]->decoder);
-				xfree(cfg->encoderDecoders[i]);
-			}
-		}
-	}
-
-	memset(cfg, 0, sizeof(EZCONFIG));
-}
-
 int
 parseConfig(const char *fileName)
 {
@@ -496,7 +445,6 @@
 				if (!xmlStrcmp(cur2->name, BAD_CAST "encdec")) {
 					xmlNodePtr	 cur3;
 					FORMAT_ENCDEC	*pformatEncDec;
-					char		*p;
 
 					pformatEncDec = xcalloc(1, sizeof(FORMAT_ENCDEC));
 
@@ -544,27 +492,17 @@
 								continue;
 							}
 							if (cur3->xmlChildrenNode != NULL) {
+								unsigned int	ret;
+
 								ls_xmlContentPtr = (char *)xmlNodeListGetString(doc, cur3->xmlChildrenNode, 1);
 								pformatEncDec->decoder = xstrdup(ls_xmlContentPtr);
 								xmlFree(ls_xmlContentPtr);
-								if ((p = strstr(pformatEncDec->decoder, TRACK_PLACEHOLDER)) != NULL) {
-									p += strlen(TRACK_PLACEHOLDER);
-									if ((p = strstr(p, TRACK_PLACEHOLDER)) != NULL) {
-										printf("%s[%ld]: Error: Multiple `%s' placeholders in decoder command\n",
-										       fileName, xmlGetLineNo(cur3), TRACK_PLACEHOLDER);
-										config_error++;
-										continue;
-									}
+								if ((ret = checkDecoderLine(pformatEncDec->decoder,
+											    fileName, xmlGetLineNo(cur3)))
+								    > 0) {
+									config_error += ret;
+									continue;
 								}
-								if ((p = strstr(pformatEncDec->decoder, METADATA_PLACEHOLDER)) != NULL) {
-									p += strlen(METADATA_PLACEHOLDER);
-									if ((p = strstr(p, METADATA_PLACEHOLDER)) != NULL) {
-										printf("%s[%ld]: Error: Multiple `%s' placeholders in decoder command\n",
-										       fileName, xmlGetLineNo(cur3), METADATA_PLACEHOLDER);
-										config_error++;
-										continue;
-									}
-								}
 							}
 						}
 						if (!xmlStrcmp(cur3->name, BAD_CAST "encode")) {
@@ -575,24 +513,17 @@
 								continue;
 							}
 							if (cur3->xmlChildrenNode != NULL) {
+								unsigned int	ret;
+
 								ls_xmlContentPtr = (char *)xmlNodeListGetString(doc, cur3->xmlChildrenNode, 1);
 								pformatEncDec->encoder = xstrdup(ls_xmlContentPtr);
 								xmlFree(ls_xmlContentPtr);
-								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);
-									config_error++;
+								if ((ret = checkEncoderLine(pformatEncDec->encoder,
+											    fileName, xmlGetLineNo(cur3)))
+								    > 0) {
+									config_error += ret;
 									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);
-										config_error++;
-										continue;
-									}
-								}
 							}
 						}
 					}
@@ -614,3 +545,139 @@
 
 	return (0);
 }
+
+void
+freeConfig(EZCONFIG *cfg)
+{
+	unsigned int	i;
+
+	if (cfg == NULL)
+		return;
+
+	if (cfg->URL != NULL)
+		xfree(cfg->URL);
+	if (cfg->password != NULL)
+		xfree(cfg->password);
+	if (cfg->format != NULL)
+		xfree(cfg->format);
+	if (cfg->fileName != NULL)
+		xfree(cfg->fileName);
+	if (cfg->metadataProgram != NULL)
+		xfree(cfg->metadataProgram);
+	if (cfg->serverName != NULL)
+		xfree(cfg->serverName);
+	if (cfg->serverURL != NULL)
+		xfree(cfg->serverURL);
+	if (cfg->serverGenre != NULL)
+		xfree(cfg->serverGenre);
+	if (cfg->serverDescription != NULL)
+		xfree(cfg->serverDescription);
+	if (cfg->serverBitrate != NULL)
+		xfree(cfg->serverBitrate);
+	if (cfg->serverChannels != NULL)
+		xfree(cfg->serverChannels);
+	if (cfg->serverSamplerate != NULL)
+		xfree(cfg->serverSamplerate);
+	if (cfg->serverQuality != NULL)
+		xfree(cfg->serverQuality);
+	if (cfg->encoderDecoders != NULL) {
+		for (i = 0; i < MAX_FORMAT_ENCDEC; i++) {
+			if (cfg->encoderDecoders[i] != NULL) {
+				if (cfg->encoderDecoders[i]->format != NULL)
+					xfree(cfg->encoderDecoders[i]->format);
+				if (cfg->encoderDecoders[i]->match != NULL)
+					xfree(cfg->encoderDecoders[i]->match);
+				if (cfg->encoderDecoders[i]->encoder != NULL)
+					xfree(cfg->encoderDecoders[i]->encoder);
+				if (cfg->encoderDecoders[i]->decoder != NULL)
+					xfree(cfg->encoderDecoders[i]->decoder);
+				xfree(cfg->encoderDecoders[i]);
+			}
+		}
+	}
+
+	memset(cfg, 0, sizeof(EZCONFIG));
+}
+
+unsigned int
+checkDecoderLine(const char *str, const char *file, long line)
+{
+	unsigned int	  errors;
+	char		 *p;
+
+	errors = 0;
+	if ((p = strstr(str, TRACK_PLACEHOLDER)) != NULL) {
+		p += strlen(TRACK_PLACEHOLDER);
+		if ((p = strstr(p, TRACK_PLACEHOLDER)) != NULL) {
+			printf("%s[%ld]: Error: Multiple `%s' placeholders in decoder command\n",
+			       file, line, TRACK_PLACEHOLDER);
+			errors++;
+		}
+	}
+	if ((p = strstr(str, METADATA_PLACEHOLDER)) != NULL) {
+		p += strlen(METADATA_PLACEHOLDER);
+		if ((p = strstr(p, METADATA_PLACEHOLDER)) != NULL) {
+			printf("%s[%ld]: Error: Multiple `%s' placeholders in decoder command\n",
+			       file, line, METADATA_PLACEHOLDER);
+			errors++;
+		}
+	}
+	if ((p = strstr(str, ARTIST_PLACEHOLDER)) != NULL) {
+		p += strlen(ARTIST_PLACEHOLDER);
+		if ((p = strstr(p, ARTIST_PLACEHOLDER)) != NULL) {
+			printf("%s[%ld]: Error: Multiple `%s' placeholders in decoder command\n",
+			       file, line, ARTIST_PLACEHOLDER);
+			errors++;
+		}
+	}
+	if ((p = strstr(str, TITLE_PLACEHOLDER)) != NULL) {
+		p += strlen(TITLE_PLACEHOLDER);
+		if ((p = strstr(p, TITLE_PLACEHOLDER)) != NULL) {
+			printf("%s[%ld]: Error: Multiple `%s' placeholders in decoder command\n",
+			       file, line, TITLE_PLACEHOLDER);
+			errors++;
+		}
+	}
+
+	return (errors);
+}
+
+unsigned int
+checkEncoderLine(const char *str, const char *file, long line)
+{
+	unsigned int	   errors;
+	char		  *p;
+
+	errors = 0;
+	if ((p = strstr(str, TRACK_PLACEHOLDER)) != NULL) {
+		printf("%s[%ld]: Error: `%s' placeholder not allowed in encoder command\n",
+		       file, line, TRACK_PLACEHOLDER);
+		errors++;
+	}
+	if ((p = strstr(str, 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",
+			       file, line, METADATA_PLACEHOLDER);
+			errors++;
+		}
+	}
+	if ((p = strstr(str, ARTIST_PLACEHOLDER)) != NULL) {
+		p += strlen(ARTIST_PLACEHOLDER);
+		if ((p = strstr(p, ARTIST_PLACEHOLDER)) != NULL) {
+			printf("%s[%ld]: Error: Multiple `%s' placeholders in encoder command\n",
+			       file, line, ARTIST_PLACEHOLDER);
+			errors++;
+		}
+	}
+	if ((p = strstr(str, TITLE_PLACEHOLDER)) != NULL) {
+		p += strlen(TITLE_PLACEHOLDER);
+		if ((p = strstr(p, TITLE_PLACEHOLDER)) != NULL) {
+			printf("%s[%ld]: Error: Multiple `%s' placeholders in encoder command\n",
+			       file, line, TITLE_PLACEHOLDER);
+			errors++;
+		}
+	}
+
+	return (errors);
+}

Modified: trunk/ezstream/src/configfile.h
===================================================================
--- trunk/ezstream/src/configfile.h	2007-03-09 21:25:12 UTC (rev 12700)
+++ trunk/ezstream/src/configfile.h	2007-03-10 02:27:48 UTC (rev 12701)
@@ -31,6 +31,8 @@
 
 #define TRACK_PLACEHOLDER	"@T@"
 #define METADATA_PLACEHOLDER	"@M@"
+#define ARTIST_PLACEHOLDER	"@a@"
+#define TITLE_PLACEHOLDER	"@t@"
 
 typedef struct tag_FORMAT_ENCDEC {
 	char	*format;

Modified: trunk/ezstream/src/ezstream.c
===================================================================
--- trunk/ezstream/src/ezstream.c	2007-03-09 21:25:12 UTC (rev 12700)
+++ trunk/ezstream/src/ezstream.c	2007-03-10 02:27:48 UTC (rev 12701)
@@ -82,7 +82,6 @@
 int			 metadataFromProgram;
 
 EZCONFIG		*pezConfig = NULL;
-static const char	*blankString = "";
 playlist_t		*playlist = NULL;
 int			 playlistMode = 0;
 
@@ -110,18 +109,19 @@
 	char genre;
 } ID3Tag;
 
-int	urlParse(const char *, char **, int *, char **);
-void	replaceString(const char *, char *, size_t, const char *, const char *);
-char *	buildCommandString(const char *, const char *, const char *);
-char *	processMetadata(shout_t *, 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 *);
-char *	getProgname(const char *);
-void	usage(void);
-void	usageHelp(void);
+int		urlParse(const char *, char **, int *, char **);
+void		replaceString(const char *, char *, size_t, const char *, const char *);
+char *		buildCommandString(const char *, const char *, metadata_t *);
+metadata_t *	getMetadata(const char *);
+int		setMetadata(shout_t *, metadata_t *, 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 *);
+char *		getProgname(const char *);
+void		usage(void);
+void		usageHelp(void);
 
 #ifdef HAVE_SIGNALS
 void	sig_handler(int);
@@ -225,7 +225,7 @@
 
 char *
 buildCommandString(const char *extension, const char *fileName,
-		   const char *metadata)
+		   metadata_t *mdata)
 {
 	char	*commandString = NULL;
 	size_t	 commandStringLen = 0;
@@ -248,10 +248,10 @@
 	replaceString(decoder, newDecoder, newDecoderLen, TRACK_PLACEHOLDER,
 		      fileName);
 	if (strstr(decoder, METADATA_PLACEHOLDER) != NULL) {
-		size_t tmpLen = strlen(newDecoder) + strlen(metadata) + 1;
+		size_t tmpLen = strlen(newDecoder) + strlen(metadata_get_string(mdata)) + 1;
 		char *tmpStr = xcalloc(1, tmpLen);
 		replaceString(newDecoder, tmpStr, tmpLen, METADATA_PLACEHOLDER,
-			      metadata);
+			      metadata_get_string(mdata));
 		xfree(newDecoder);
 		newDecoder = tmpStr;
 	}
@@ -272,10 +272,10 @@
 		return (commandString);
 	}
 
-	newEncoderLen = strlen(encoder) + strlen(metadata) + 1;
+	newEncoderLen = strlen(encoder) + strlen(metadata_get_string(mdata)) + 1;
 	newEncoder = xcalloc(1, newEncoderLen);
 	replaceString(encoder, newEncoder, newEncoderLen, METADATA_PLACEHOLDER,
-		      metadata);
+		      metadata_get_string(mdata));
 
 	commandStringLen = strlen(newDecoder) + strlen(" | ") +
 		strlen(newEncoder) + 1;
@@ -291,21 +291,18 @@
 	return (commandString);
 }
 
-char *
-processMetadata(shout_t *shout, const char *fileName)
+metadata_t *
+getMetadata(const char *fileName)
 {
-	char			*songInfo = NULL;
-	shout_metadata_t	*shout_mdata = NULL;
-	metadata_t              *mdata = NULL;
+	metadata_t	*mdata;
 
 	if (metadataFromProgram) {
 		if ((mdata = metadata_program(fileName)) == NULL)
 			return (NULL);
 
-		if (!metadata_program_update(mdata, METADATA_STRING)) {
+		if (!metadata_program_update(mdata, METADATA_ALL)) {
 			metadata_free(&mdata);
-			songInfo = xstrdup(blankString);
-			return (songInfo);
+			return (NULL);
 		}
 	} else {
 		if ((mdata = metadata_file(fileName)) == NULL)
@@ -313,40 +310,78 @@
 
 		if (!metadata_file_update(mdata)) {
 			metadata_free(&mdata);
-			songInfo = xstrdup(blankString);
-			return (songInfo);
+			return (NULL);
 		}
 	}
 
-	songInfo = xstrdup(metadata_get_string(mdata));
-	metadata_free(&mdata);
+	return (mdata);
+}
 
+int
+setMetadata(shout_t *shout, metadata_t *mdata, char **mdata_copy)
+{
+	shout_metadata_t	*shout_mdata = NULL;
+	char			*songInfo;
+	int			 ret = SHOUTERR_SUCCESS;
+
+	if (shout == NULL) {
+		printf("%s: setMetadata(): Internal error: NULL shout_t\n",
+		       __progname);
+		abort();
+	}
+
+	if (mdata == NULL)
+		return 1;
+
 	if ((shout_mdata = shout_metadata_new()) == NULL) {
 		printf("%s: shout_metadata_new(): %s\n", __progname,
 		       strerror(ENOMEM));
 		exit(1);
 	}
-	shout_metadata_add(shout_mdata, "song", songInfo);
-	shout_set_metadata(shout, shout_mdata);
+
+	if (metadata_get_artist(mdata) == NULL && metadata_get_title(mdata) == NULL)
+		songInfo = xstrdup(metadata_get_string(mdata));
+	else
+		songInfo = metadata_assemble_string(mdata);
+
+	if (shout_metadata_add(shout_mdata, "song", songInfo) != SHOUTERR_SUCCESS) {
+		/* Assume SHOUTERR_MALLOC */
+		printf("%s: shout_metadata_add(): %s\n", __progname,
+		       strerror(ENOMEM));
+		exit(1);
+	}
+	if ((ret = shout_set_metadata(shout, shout_mdata)) != SHOUTERR_SUCCESS)
+		printf("%s: shout_set_metadata(): %s\n",
+		       __progname, shout_get_error(shout));
 	shout_metadata_free(shout_mdata);
+	if (ret == SHOUTERR_SUCCESS &&
+	    mdata_copy != NULL && *mdata_copy == NULL)
+		*mdata_copy = xstrdup(songInfo);
 
-	return (songInfo);
+	xfree(songInfo);
+	return (ret);
 }
 
 FILE *
 openResource(shout_t *shout, const char *fileName, int *popenFlag,
 	     char **metaCopy, int *isStdin)
 {
-	FILE	*filep = NULL;
-	char	 extension[25];
-	char	*p = NULL;
-	char	*pMetadata = NULL;
-	char	*pCommandString = NULL;
+	FILE		*filep = NULL;
+	char		 extension[25];
+	char		*p = NULL;
+	char		*pCommandString = NULL;
+	metadata_t	*mdata;
 
 	if (strcmp(fileName, "stdin") == 0) {
-		if (metadataFromProgram &&
-		    processMetadata(shout, pezConfig->metadataProgram) == NULL)
-			return (filep);
+		if (metadataFromProgram) {
+			if ((mdata = getMetadata(pezConfig->metadataProgram)) == NULL)
+				return (NULL);
+			if (setMetadata(shout, mdata, metaCopy) != SHOUTERR_SUCCESS) {
+				metadata_free(&mdata);
+				return (NULL);
+			}
+			metadata_free(&mdata);
+		}
 
 		if (vFlag)
 			printf("%s: Reading from standard input\n",
@@ -359,6 +394,7 @@
 		filep = stdin;
 		return (filep);
 	}
+
 	if (isStdin != NULL)
 		*isStdin = 0;
 
@@ -375,20 +411,22 @@
 		return (filep);
 	}
 
-	if (metadataFromProgram)
-		pMetadata = processMetadata(shout, pezConfig->metadataProgram);
-	else
-		pMetadata = processMetadata(shout, fileName);
-	if (pMetadata == NULL)
-		return (filep);
+	if (metadataFromProgram) {
+		if ((mdata = getMetadata(pezConfig->metadataProgram)) == NULL)
+			return (NULL);
+	} else {
+		if ((mdata = getMetadata(fileName)) == NULL)
+			return (NULL);
+	}
 	if (metaCopy != NULL)
-		*metaCopy = xstrdup(pMetadata);
+		*metaCopy = metadata_assemble_string(mdata);
 
 	*popenFlag = 0;
 	if (pezConfig->reencode) {
 		int	stderr_fd = dup(fileno(stderr));
 
-		pCommandString = buildCommandString(extension, fileName, pMetadata);
+		pCommandString = buildCommandString(extension, fileName, mdata);
+		metadata_free(&mdata);
 		if (vFlag > 1)
 			printf("%s: Running command `%s`\n", __progname,
 			       pCommandString);
@@ -428,11 +466,10 @@
 		if (qFlag)
 			dup2(stderr_fd, fileno(stderr));
 
-		xfree(pMetadata);
 		return (filep);
 	}
 
-	xfree(pMetadata);
+	metadata_free(&mdata);
 
 	if ((filep = fopen(fileName, "rb")) == NULL)
 		printf("%s: %s: %s\n", __progname, fileName,
@@ -662,15 +699,23 @@
 			if (ret == STREAM_UPDMDATA || queryMetadata) {
 				queryMetadata = 0;
 				if (metadataFromProgram) {
-					char	*mdataStr;
+					char		*mdataStr = NULL;
+					metadata_t	*mdata;
 
 					if (vFlag > 1)
 						printf("%s: Querying '%s' for fresh metadata\n",
 						       __progname, pezConfig->metadataProgram);
-					if ((mdataStr = processMetadata(shout, pezConfig->metadataProgram)) == NULL) {
+					if ((mdata = getMetadata(pezConfig->metadataProgram)) == NULL) {
 						retval = 0;
 						ret = STREAM_DONE;
+						continue;
 					}
+					if (setMetadata(shout, mdata, &mdataStr) != SHOUTERR_SUCCESS) {
+						retval = 0;
+						ret = STREAM_DONE;
+						continue;
+					}
+					metadata_free(&mdata);
 					printf("%s: New metadata: ``%s''\n",
 					       __progname, mdataStr);
 					xfree(mdataStr);

Modified: trunk/ezstream/src/metadata.c
===================================================================
--- trunk/ezstream/src/metadata.c	2007-03-09 21:25:12 UTC (rev 12700)
+++ trunk/ezstream/src/metadata.c	2007-03-10 02:27:48 UTC (rev 12701)
@@ -44,6 +44,7 @@
 #include "util.h"
 
 extern char	*__progname;
+extern int	 vFlag;
 
 struct metadata {
 	char	*filename;
@@ -298,34 +299,14 @@
 void
 metadata_process_md(metadata_t *md)
 {
-	size_t	siz = 0;
-
 	if (md == NULL) {
 		printf("%s: metadata_process_md(): Internal error: Bad arguments\n",
 		       __progname);
 		abort();
 	}
 
-	if (md->string != NULL)
-		return;
-
-	if (md->artist != NULL)
-		siz += strlen(md->artist);
-	if (md->title != NULL) {
-		if (siz > 0)
-			siz += strlen(" - ");
-		siz += strlen(md->title);
-	}
-	siz++;
-	md->string = xcalloc(1, siz);
-
-	if (md->artist != NULL)
-		strlcpy(md->string, md->artist, siz);
-	if (md->title != NULL) {
-		if (md->artist != NULL)
-			strlcat(md->string, " - ", siz);
-		strlcat(md->string, md->title, siz);
-	}
+	if (md->string == NULL)
+		md->string = metadata_assemble_string(md);
 }
 
 metadata_t *
@@ -467,6 +448,8 @@
 		    !metadata_program_update(md, METADATA_ARTIST) ||
 		    !metadata_program_update(md, METADATA_TITLE))
 			return (0);
+		else
+			return (1);
 		break;
 	case METADATA_STRING:
 		strlcpy(command, md->filename, sizeof(command));
@@ -491,6 +474,9 @@
 
 	fflush(NULL);
 	errno = 0;
+	if (vFlag > 1)
+		printf("%s: Running command `%s`\n", __progname,
+		       command);
 	if ((filep = popen(command, "r")) == NULL) {
 		printf("%s: playlist_run_program(): Error while executing '%s'",
 		       __progname, command);
@@ -591,3 +577,40 @@
 
 	return (md->title);
 }
+
+char *
+metadata_assemble_string(metadata_t *md)
+{
+	size_t	  siz;
+	char	 *str;
+
+	if (md == NULL) {
+		printf("%s: metadata_assemble_string(): Internal error: Bad arguments\n",
+		       __progname);
+		abort();
+	}
+
+	if (md->artist == NULL && md->title == NULL && md->program == 0)
+		return (metadata_get_name(md->filename));
+
+	siz = 0;
+	if (md->artist != NULL)
+		siz += strlen(md->artist);
+	if (md->title != NULL) {
+		if (siz > 0)
+			siz += strlen(" - ");
+		siz += strlen(md->title);
+	}
+	siz++;
+	str = xcalloc(1, siz);
+
+	if (md->artist != NULL)
+		strlcpy(str, md->artist, siz);
+	if (md->title != NULL) {
+		if (md->artist != NULL)
+			strlcat(str, " - ", siz);
+		strlcat(str, md->title, siz);
+	}
+
+	return (str);
+}

Modified: trunk/ezstream/src/metadata.h
===================================================================
--- trunk/ezstream/src/metadata.h	2007-03-09 21:25:12 UTC (rev 12700)
+++ trunk/ezstream/src/metadata.h	2007-03-10 02:27:48 UTC (rev 12701)
@@ -92,4 +92,11 @@
  */
 const char *	metadata_get_title(metadata_t *);
 
+/*
+ * Allocates and returns a meaningful string based on a metadata handle's
+ * content. The result is what metadata_get_string() defaults to if an external
+ * program is not used.
+ */
+char *		metadata_assemble_string(metadata_t *);
+
 #endif /* __METADATA_H__ */



More information about the commits mailing list