mirror of
https://gitlab.xiph.org/xiph/ezstream.git
synced 2024-12-04 14:46:31 -05:00
Get closer to what Icecast does (or will) expect wrt used codesets. I still
disagree with the new ISO-8859-1 assumption for non-Ogg streams, because (for example) with ID3 tags, a codeset is simply not part of the specification and a better assumption would be that they are in the user's locale. Therefore, it would make more sense, IMO, to clearly specify that ANY metadata sent to Icecast should be UTF-8 and let the source client figure out the rest. This would also answer the question what codeset an /admin user should use if the content type of a mountpoint isn't known (although that can be figured out with an unclean read of the mountpoint's stats beforehand.) git-svn-id: https://svn.xiph.org/trunk/ezstream@13622 0101bb08-14d6-0310-b084-bc0e0c8e3800
This commit is contained in:
parent
256394e811
commit
15064493bc
@ -470,7 +470,7 @@ int
|
|||||||
setMetadata(shout_t *shout, metadata_t *mdata, char **mdata_copy)
|
setMetadata(shout_t *shout, metadata_t *mdata, char **mdata_copy)
|
||||||
{
|
{
|
||||||
shout_metadata_t *shout_mdata = NULL;
|
shout_metadata_t *shout_mdata = NULL;
|
||||||
char *songInfo;
|
char *songInfo, *encSongInfo;
|
||||||
int ret = SHOUTERR_SUCCESS;
|
int ret = SHOUTERR_SUCCESS;
|
||||||
|
|
||||||
if (shout == NULL) {
|
if (shout == NULL) {
|
||||||
@ -496,7 +496,14 @@ setMetadata(shout_t *shout, metadata_t *mdata, char **mdata_copy)
|
|||||||
songInfo = metadata_assemble_string(mdata);
|
songInfo = metadata_assemble_string(mdata);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (shout_metadata_add(shout_mdata, "song", songInfo) != SHOUTERR_SUCCESS) {
|
if (strcmp(pezConfig->format, VORBIS_FORMAT) == 0 ||
|
||||||
|
strcmp(pezConfig->format, THEORA_FORMAT) == 0)
|
||||||
|
encSongInfo = xstrdup(songInfo);
|
||||||
|
else
|
||||||
|
encSongInfo = UTF8toISO8859_1(songInfo, ICONV_TRANSLIT);
|
||||||
|
|
||||||
|
if (shout_metadata_add(shout_mdata, "song", (encSongInfo != NULL) ? encSongInfo : "")
|
||||||
|
!= SHOUTERR_SUCCESS) {
|
||||||
/* Assume SHOUTERR_MALLOC */
|
/* Assume SHOUTERR_MALLOC */
|
||||||
printf("%s: shout_metadata_add(): %s\n", __progname,
|
printf("%s: shout_metadata_add(): %s\n", __progname,
|
||||||
strerror(ENOMEM));
|
strerror(ENOMEM));
|
||||||
@ -511,6 +518,7 @@ setMetadata(shout_t *shout, metadata_t *mdata, char **mdata_copy)
|
|||||||
*mdata_copy = xstrdup(songInfo);
|
*mdata_copy = xstrdup(songInfo);
|
||||||
|
|
||||||
xfree(songInfo);
|
xfree(songInfo);
|
||||||
|
xfree(encSongInfo);
|
||||||
return (ret);
|
return (ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -854,7 +862,7 @@ streamFile(shout_t *shout, const char *fileName)
|
|||||||
char *tmp, *metaData;
|
char *tmp, *metaData;
|
||||||
|
|
||||||
tmp = metadata_assemble_string(mdata);
|
tmp = metadata_assemble_string(mdata);
|
||||||
metaData = utf82char(tmp);
|
metaData = UTF8toCHAR(tmp, ICONV_REPLACE);
|
||||||
xfree(tmp);
|
xfree(tmp);
|
||||||
printf("%s: Streaming ``%s''", __progname, metaData);
|
printf("%s: Streaming ``%s''", __progname, metaData);
|
||||||
if (vFlag)
|
if (vFlag)
|
||||||
|
@ -185,9 +185,9 @@ metadata_use_self(metadata_t *md, FILE **filep)
|
|||||||
fread(&id3tag, 1, sizeof(struct ID3Tag), *filep);
|
fread(&id3tag, 1, sizeof(struct ID3Tag), *filep);
|
||||||
if (memcmp(id3tag.tag, "TAG", 3) == 0) {
|
if (memcmp(id3tag.tag, "TAG", 3) == 0) {
|
||||||
if (strlen(id3tag.artistName) > 0)
|
if (strlen(id3tag.artistName) > 0)
|
||||||
md->artist = char2utf8(id3tag.artistName);
|
md->artist = CHARtoUTF8(id3tag.artistName, ICONV_REPLACE);
|
||||||
if (strlen(id3tag.trackName) > 0)
|
if (strlen(id3tag.trackName) > 0)
|
||||||
md->title = char2utf8(id3tag.trackName);
|
md->title = CHARtoUTF8(id3tag.trackName, ICONV_REPLACE);
|
||||||
}
|
}
|
||||||
} else if (strcmp(extension, ".ogg") == 0) {
|
} else if (strcmp(extension, ".ogg") == 0) {
|
||||||
OggVorbis_File vf;
|
OggVorbis_File vf;
|
||||||
|
87
src/util.c
87
src/util.c
@ -58,9 +58,7 @@
|
|||||||
extern EZCONFIG *pezConfig;
|
extern EZCONFIG *pezConfig;
|
||||||
extern char *__progname;
|
extern char *__progname;
|
||||||
|
|
||||||
#ifdef HAVE_ICONV
|
char * iconvert(const char *, const char *, const char *, int);
|
||||||
char * iconvert(const char *, const char *, const char *);
|
|
||||||
#endif /* HAVE_ICONV */
|
|
||||||
|
|
||||||
int
|
int
|
||||||
strrcmp(const char *s, const char *sub)
|
strrcmp(const char *s, const char *sub)
|
||||||
@ -227,67 +225,68 @@ stream_setup(const char *host, const int port, const char *mount)
|
|||||||
}
|
}
|
||||||
|
|
||||||
char *
|
char *
|
||||||
char2utf8(const char *in_str)
|
CHARtoUTF8(const char *in_str, int mode)
|
||||||
{
|
{
|
||||||
#ifdef HAVE_ICONV
|
#ifndef WIN32
|
||||||
# ifndef WIN32
|
|
||||||
char *codeset;
|
char *codeset;
|
||||||
|
|
||||||
# if defined(HAVE_NL_LANGINFO) && defined(HAVE_SETLOCALE) && defined(CODESET)
|
# if defined(HAVE_NL_LANGINFO) && defined(HAVE_SETLOCALE) && defined(CODESET)
|
||||||
setlocale(LC_CTYPE, "");
|
setlocale(LC_CTYPE, "");
|
||||||
codeset = nl_langinfo(CODESET);
|
codeset = nl_langinfo(CODESET);
|
||||||
setlocale(LC_CTYPE, "C");
|
setlocale(LC_CTYPE, "C");
|
||||||
# else
|
|
||||||
codeset = (char *)"";
|
|
||||||
# endif /* HAVE_NL_LANGINFO && HAVE_SETLOCALE */
|
|
||||||
# else
|
# else
|
||||||
|
codeset = (char *)"";
|
||||||
|
# endif /* HAVE_NL_LANGINFO && HAVE_SETLOCALE */
|
||||||
|
#else
|
||||||
char codeset[24];
|
char codeset[24];
|
||||||
|
|
||||||
snprintf(codeset, sizeof(codeset), "CP%u", GetACP());
|
snprintf(codeset, sizeof(codeset), "CP%u", GetACP());
|
||||||
# endif /* !WIN32 */
|
#endif /* !WIN32 */
|
||||||
|
|
||||||
if (in_str == NULL || strlen(in_str) == 0)
|
if (in_str == NULL || strlen(in_str) == 0)
|
||||||
return (NULL);
|
return (NULL);
|
||||||
|
|
||||||
return (iconvert(in_str, codeset, "UTF-8"));
|
return (iconvert(in_str, codeset, "UTF-8", mode));
|
||||||
#else
|
|
||||||
return (xstrdup(in_str));
|
|
||||||
#endif /* HAVE_ICONV */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
char *
|
char *
|
||||||
utf82char(const char *in_str)
|
UTF8toCHAR(const char *in_str, int mode)
|
||||||
{
|
{
|
||||||
#ifdef HAVE_ICONV
|
#ifndef WIN32
|
||||||
# ifndef WIN32
|
|
||||||
char *codeset;
|
char *codeset;
|
||||||
|
|
||||||
# if defined(HAVE_NL_LANGINFO) && defined(HAVE_SETLOCALE) && defined(CODESET)
|
# if defined(HAVE_NL_LANGINFO) && defined(HAVE_SETLOCALE) && defined(CODESET)
|
||||||
setlocale(LC_CTYPE, "");
|
setlocale(LC_CTYPE, "");
|
||||||
codeset = nl_langinfo(CODESET);
|
codeset = nl_langinfo(CODESET);
|
||||||
setlocale(LC_CTYPE, "C");
|
setlocale(LC_CTYPE, "C");
|
||||||
# else
|
|
||||||
codeset = (char *)"";
|
|
||||||
# endif /* HAVE_NL_LANGINFO && HAVE_SETLOCALE */
|
|
||||||
# else
|
# else
|
||||||
|
codeset = (char *)"";
|
||||||
|
# endif /* HAVE_NL_LANGINFO && HAVE_SETLOCALE */
|
||||||
|
#else
|
||||||
char codeset[24];
|
char codeset[24];
|
||||||
|
|
||||||
snprintf(codeset, sizeof(codeset), "CP%u", GetACP());
|
snprintf(codeset, sizeof(codeset), "CP%u", GetACP());
|
||||||
# endif /* !WIN32 */
|
#endif /* !WIN32 */
|
||||||
|
|
||||||
if (in_str == NULL || strlen(in_str) == 0)
|
if (in_str == NULL || strlen(in_str) == 0)
|
||||||
return (NULL);
|
return (NULL);
|
||||||
|
|
||||||
return (iconvert(in_str, "UTF-8", codeset));
|
return (iconvert(in_str, "UTF-8", codeset, mode));
|
||||||
#else
|
|
||||||
return (xstrdup(in_str));
|
|
||||||
#endif /* HAVE_ICONV */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_ICONV
|
|
||||||
char *
|
char *
|
||||||
iconvert(const char *in_str, const char *from, const char *to)
|
UTF8toISO8859_1(const char *in_str, int mode)
|
||||||
{
|
{
|
||||||
|
if (in_str == NULL || strlen(in_str) == 0)
|
||||||
|
return (NULL);
|
||||||
|
|
||||||
|
return (iconvert(in_str, "UTF-8", "ISO-8859-1", mode));
|
||||||
|
}
|
||||||
|
|
||||||
|
char *
|
||||||
|
iconvert(const char *in_str, const char *from, const char *to, int mode)
|
||||||
|
{
|
||||||
|
#ifdef HAVE_ICONV
|
||||||
iconv_t cd;
|
iconv_t cd;
|
||||||
ICONV_CONST char *input, *ip;
|
ICONV_CONST char *input, *ip;
|
||||||
size_t input_len;
|
size_t input_len;
|
||||||
@ -296,9 +295,31 @@ iconvert(const char *in_str, const char *from, const char *to)
|
|||||||
char buf[BUFSIZ], *bp;
|
char buf[BUFSIZ], *bp;
|
||||||
size_t bufavail;
|
size_t bufavail;
|
||||||
size_t out_pos;
|
size_t out_pos;
|
||||||
|
char *tocode;
|
||||||
|
|
||||||
if ((cd = iconv_open(to, from)) == (iconv_t)-1 &&
|
switch (mode) {
|
||||||
|
size_t siz;
|
||||||
|
|
||||||
|
case ICONV_TRANSLIT:
|
||||||
|
siz = strlen(to) + strlen("//TRANSLIT") + 1;
|
||||||
|
tocode = xcalloc(siz, sizeof(char));
|
||||||
|
snprintf(tocode, siz, "%s//TRANSLIT", to);
|
||||||
|
break;
|
||||||
|
case ICONV_IGNORE:
|
||||||
|
siz = strlen(to) + strlen("//IGNORE") + 1;
|
||||||
|
tocode = xcalloc(siz, sizeof(char));
|
||||||
|
snprintf(tocode, siz, "%s//IGNORE", to);
|
||||||
|
break;
|
||||||
|
case ICONV_REPLACE:
|
||||||
|
/* FALLTHROUGH */
|
||||||
|
default:
|
||||||
|
tocode = xstrdup(to);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((cd = iconv_open(tocode, from)) == (iconv_t)-1 &&
|
||||||
(cd = iconv_open("", from)) == (iconv_t)-1) {
|
(cd = iconv_open("", from)) == (iconv_t)-1) {
|
||||||
|
xfree(tocode);
|
||||||
printf("%s: iconv_open(): %s\n", strerror(errno), __progname);
|
printf("%s: iconv_open(): %s\n", strerror(errno), __progname);
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
@ -340,9 +361,13 @@ iconvert(const char *in_str, const char *from, const char *to)
|
|||||||
if (iconv_close(cd) == -1) {
|
if (iconv_close(cd) == -1) {
|
||||||
printf("%s: iconv_close(): %s\n", strerror(errno), __progname);
|
printf("%s: iconv_close(): %s\n", strerror(errno), __progname);
|
||||||
xfree(output);
|
xfree(output);
|
||||||
|
xfree(tocode);
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
xfree(tocode);
|
||||||
return (output);
|
return (output);
|
||||||
}
|
#else
|
||||||
|
return (xstrdup(in_str));
|
||||||
#endif /* HAVE_ICONV */
|
#endif /* HAVE_ICONV */
|
||||||
|
}
|
||||||
|
@ -20,10 +20,15 @@
|
|||||||
#ifndef __UTIL_H__
|
#ifndef __UTIL_H__
|
||||||
#define __UTIL_H__
|
#define __UTIL_H__
|
||||||
|
|
||||||
|
#define ICONV_REPLACE 0
|
||||||
|
#define ICONV_TRANSLIT 1
|
||||||
|
#define ICONV_IGNORE 2
|
||||||
|
|
||||||
int strrcmp(const char *, const char *);
|
int strrcmp(const char *, const char *);
|
||||||
int strrcasecmp(const char *, const char *);
|
int strrcasecmp(const char *, const char *);
|
||||||
shout_t * stream_setup(const char *, const int, const char *);
|
shout_t * stream_setup(const char *, const int, const char *);
|
||||||
char * char2utf8(const char *);
|
char * CHARtoUTF8(const char *, int);
|
||||||
char * utf82char(const char *);
|
char * UTF8toCHAR(const char *, int);
|
||||||
|
char * UTF8toISO8859_1(const char *, int);
|
||||||
|
|
||||||
#endif /* __UTIL_H__ */
|
#endif /* __UTIL_H__ */
|
||||||
|
Loading…
Reference in New Issue
Block a user