aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--TODO2
-rw-r--r--doc/mpd.14
-rw-r--r--src/audio.c2
-rw-r--r--src/audio.h4
-rw-r--r--src/conf.c13
-rw-r--r--src/conf.h1
-rw-r--r--src/decode.c12
-rw-r--r--src/inputPlugins/flac_plugin.c12
-rw-r--r--src/inputPlugins/ogg_plugin.c8
-rw-r--r--src/inputStream_http.c6
-rw-r--r--src/main.c30
-rw-r--r--src/metadataChunk.c4
-rw-r--r--src/playlist.c21
-rw-r--r--src/tag.c24
-rw-r--r--src/utils.c3
15 files changed, 89 insertions, 57 deletions
diff --git a/TODO b/TODO
index 7039e03c6..1cdff6f18 100644
--- a/TODO
+++ b/TODO
@@ -11,7 +11,7 @@
and peak's to compute the the scale for files missing
replaygain tags (make this a config file option)
-*) Optimize read() on cleints
+*) Optimize read() on clients
*) Add libshout && vorbis encoding support
diff --git a/doc/mpd.1 b/doc/mpd.1
index 16f05d6ff..e1911f13a 100644
--- a/doc/mpd.1
+++ b/doc/mpd.1
@@ -77,6 +77,10 @@ This specifies the character set used for the filesystem. A list of supported
character sets can be obtained by running "iconv -l". The default is
determined from the locale when the db was originally created.
.TP
+.B id3v1_encoding <charset>
+This specifies the character set used for the ID3v1 tags. Supported characters
+sets also can be obtained from the iconv. By default ISO8859-1 is used.
+.TP
.B bind_to_address <ip address or hostname or any>
This specifies which address MPD binds to and listens on. The default is "any",
which binds to all available addresses.
diff --git a/src/audio.c b/src/audio.c
index 605bf796e..1679bd573 100644
--- a/src/audio.c
+++ b/src/audio.c
@@ -39,7 +39,7 @@ static ao_device * audio_device = NULL;
static AudioFormat * audio_configFormat = NULL;
-static void copyAudioFormat(AudioFormat * dest, AudioFormat * src) {
+void copyAudioFormat(AudioFormat * dest, AudioFormat * src) {
dest->sampleRate = src->sampleRate;
dest->bits = src->bits;
dest->channels = src->channels;
diff --git a/src/audio.h b/src/audio.h
index 9b49b140e..ac0f04951 100644
--- a/src/audio.h
+++ b/src/audio.h
@@ -22,6 +22,7 @@
#include "../config.h"
#include "mpd_types.h"
+#include "tag.h"
#include <stdio.h>
@@ -33,6 +34,8 @@ typedef struct _AudioFormat {
volatile mpd_sint8 bits;
} AudioFormat;
+void copyAudioFormat(AudioFormat * dest, AudioFormat * src);
+
void getOutputAudioFormat(AudioFormat * inFormat, AudioFormat * outFormat);
void initAudioConfig();
@@ -56,4 +59,3 @@ void audioError();
int isCurrentAudioFormat(AudioFormat * audioFormat);
#endif
-/* vim:set shiftwidth=4 tabstop=8 expandtab: */
diff --git a/src/conf.c b/src/conf.c
index 1eadc36fe..3b6aa8242 100644
--- a/src/conf.c
+++ b/src/conf.c
@@ -37,7 +37,7 @@
#define CONF_COMMENT '#'
-#define CONF_NUMBER_OF_PARAMS 34
+#define CONF_NUMBER_OF_PARAMS 35
#define CONF_NUMBER_OF_PATHS 6
#define CONF_NUMBER_OF_REQUIRED 5
#define CONF_NUMBER_OF_ALLOW_CATS 1
@@ -130,7 +130,8 @@ char ** readConf(char * file) {
"http_proxy_port",
"http_proxy_user",
"http_proxy_password",
- "replaygain_preamp"
+ "replaygain_preamp",
+ "id3v1_encoding"
};
int conf_absolutePaths[CONF_NUMBER_OF_PATHS] = {
@@ -160,6 +161,7 @@ char ** readConf(char * file) {
int i;
int numberOfArgs;
short allowCat[CONF_NUMBER_OF_PARAMS];
+ int count = 0;
for(i=0;i<CONF_NUMBER_OF_PARAMS;i++) allowCat[i] = 0;
@@ -171,19 +173,22 @@ char ** readConf(char * file) {
}
while(myFgets(string,sizeof(string),fp)) {
+ count++;
+
if(string[0]==CONF_COMMENT) continue;
numberOfArgs = buffer2array(string,&array);
if(numberOfArgs==0) continue;
if(2!=numberOfArgs) {
- ERROR("improperly formated config line: %s\n",string);
+ ERROR("improperly formated config file at line %i: %s\n",count,string);
exit(EXIT_FAILURE);
}
i = 0;
while(i<CONF_NUMBER_OF_PARAMS && 0!=strcmp(conf_strings[i],array[0])) i++;
if(i>=CONF_NUMBER_OF_PARAMS) {
- ERROR("unrecognized line in conf: %s\n",string);
+ ERROR("unrecognized paramater in conf at line %i: %s\n",count,string);
exit(EXIT_FAILURE);
}
+
if(conf_params[i]!=NULL) {
if(allowCat[i]) {
conf_params[i] = realloc(conf_params[i],
diff --git a/src/conf.h b/src/conf.h
index 6a06b0f0b..d8c5f0fa0 100644
--- a/src/conf.h
+++ b/src/conf.h
@@ -55,6 +55,7 @@
#define CONF_HTTP_PROXY_USER 31
#define CONF_HTTP_PROXY_PASSWORD 32
#define CONF_REPLAYGAIN_PREAMP 33
+#define CONF_ID3V1_ENCODING 34
#define CONF_CAT_CHAR "\n"
diff --git a/src/decode.c b/src/decode.c
index 6034c141b..852767253 100644
--- a/src/decode.c
+++ b/src/decode.c
@@ -115,7 +115,7 @@ int calculateCrossFadeChunks(PlayerControl * pc, AudioFormat * af) {
MAXPATHLEN); \
pc->erroredUrl[MAXPATHLEN] = '\0'; \
pc->error = PLAYER_ERROR_AUDIO; \
- ERROR("problems opeing audio device while playing \"%s\"", pc->utf8url); \
+ ERROR("problems opening audio device while playing \"%s\"", pc->utf8url); \
quitDecode(pc,dc); \
return; \
} \
@@ -157,7 +157,6 @@ int waitOnDecode(PlayerControl * pc, DecoderControl * dc, OutputBuffer * cb,
}
pc->totalTime = pc->fileTime;
- pc->elapsedTime = 0;
pc->bitRate = 0;
pc->sampleRate = 0;
pc->bits = 0;
@@ -228,7 +227,7 @@ int decodeSeek(PlayerControl * pc, DecoderControl * dc, OutputBuffer * cb,
MAXPATHLEN); \
pc->erroredUrl[MAXPATHLEN] = '\0'; \
pc->error = PLAYER_ERROR_AUDIO; \
- ERROR("problems opeing audio device while playing \"%s\"", pc->utf8url); \
+ ERROR("problems opening audio device while playing \"%s\"", pc->utf8url); \
quitDecode(pc,dc); \
return; \
} \
@@ -286,7 +285,11 @@ void decodeStart(PlayerControl * pc, OutputBuffer * cb, DecoderControl * dc) {
dc->start = 0;
while(!inputStreamAtEOF(&inStream) && bufferInputStream(&inStream) < 0
- && !dc->stop);
+ && !dc->stop)
+ {
+ /* sleep so we don't consume 100% of the cpu */
+ my_usleep(1000);
+ }
if(dc->stop) {
dc->state = DECODE_STATE_STOP;
@@ -461,6 +464,7 @@ void decodeParent(PlayerControl * pc, DecoderControl * dc, OutputBuffer * cb) {
if(waitOnDecode(pc,dc,cb,&decodeWaitedOn)<0) return;
+ pc->elapsedTime = 0;
pc->state = PLAYER_STATE_PLAY;
pc->play = 0;
kill(getppid(),SIGUSR1);
diff --git a/src/inputPlugins/flac_plugin.c b/src/inputPlugins/flac_plugin.c
index eec99f233..1adf5a349 100644
--- a/src/inputPlugins/flac_plugin.c
+++ b/src/inputPlugins/flac_plugin.c
@@ -277,7 +277,7 @@ void flacError(const FLAC__SeekableStreamDecoder *dec,
ERROR("crc mismatch %s\n", data->path);
break;
default:
- ERROR("unknow flac error %s\n", data->path);
+ ERROR("unknown flac error %s\n", data->path);
}
}
@@ -298,7 +298,7 @@ void flacPrintErroredState(FLAC__SeekableStreamDecoderState state,
ERROR("flac seekable stream error: %s\n",file);
break;
case FLAC__SEEKABLE_STREAM_DECODER_ALREADY_INITIALIZED:
- ERROR("flac decoder already initilaized: %s\n",file);
+ ERROR("flac decoder already initialized: %s\n",file);
break;
case FLAC__SEEKABLE_STREAM_DECODER_INVALID_CALLBACK:
ERROR("invalid flac callback\n");
@@ -352,16 +352,16 @@ void flacParseReplayGain(const FLAC__StreamMetadata *block, FlacData * data) {
}
if(!found || state == REPLAYGAIN_TRACK) {
- if(flacFindVorbisCommentFloat(block,"replaygain_track_gain",
- &gain))
- {
+ found = flacFindVorbisCommentFloat(block,
+ "replaygain_track_gain", &gain);
+ if(found) {
peak = 0.0;
flacFindVorbisCommentFloat(block,
"replaygain_track_peak",&peak);
}
}
- data->replayGainScale = computeReplayGainScale(gain,peak);
+ if(found) data->replayGainScale = computeReplayGainScale(gain,peak);
}
void flacMetadata(const FLAC__SeekableStreamDecoder *dec,
diff --git a/src/inputPlugins/ogg_plugin.c b/src/inputPlugins/ogg_plugin.c
index c65de71aa..5d461586e 100644
--- a/src/inputPlugins/ogg_plugin.c
+++ b/src/inputPlugins/ogg_plugin.c
@@ -157,12 +157,16 @@ float ogg_getReplayGainScale(char ** comments) {
if(albumGainFound) {
return computeReplayGainScale(albumGain,albumPeak);
}
- return computeReplayGainScale(trackGain,trackPeak);
+ else if(trackGainFound) {
+ return computeReplayGainScale(trackGain,trackPeak);
+ }
case REPLAYGAIN_TRACK:
if(trackGainFound) {
return computeReplayGainScale(trackGain,trackPeak);
}
- return computeReplayGainScale(albumGain,albumPeak);
+ else if(albumGainFound) {
+ return computeReplayGainScale(albumGain,albumPeak);
+ }
}
return 1.0;
diff --git a/src/inputStream_http.c b/src/inputStream_http.c
index e12866ef6..2e0755d96 100644
--- a/src/inputStream_http.c
+++ b/src/inputStream_http.c
@@ -570,7 +570,9 @@ static int getHTTPHello(InputStream * inStream) {
else if(0 == strncmp(cur, "\r\nicy-metaint:", 14)) {
data->icyMetaint = atoi(cur+14);
}
- else if(0 == strncmp(cur, "\r\nicy-name:", 11)) {
+ else if(0 == strncmp(cur, "\r\nicy-name:", 11) ||
+ 0 == strncmp(cur, "\r\nice-name:", 11))
+ {
int incr = 11;
char * temp = strstr(cur+incr,"\r\n");
if(!temp) break;
@@ -601,7 +603,7 @@ static int getHTTPHello(InputStream * inStream) {
*temp = '\0';
if(inStream->mime) free(inStream->mime);
while(*(incr+cur) == ' ') incr++;
- inStream->mime = strdup(cur+15);
+ inStream->mime = strdup(cur+incr);
*temp = '\r';
}
diff --git a/src/main.c b/src/main.c
index c34c71f5b..9c0361328 100644
--- a/src/main.c
+++ b/src/main.c
@@ -229,21 +229,14 @@ void establishListen(Options * options) {
void changeToUser(Options * options) {
if (options->usr && strlen(options->usr)) {
- int uid, gid;
-#ifdef _BSD_SOURCE
- gid_t gid_list[NGROUPS_MAX];
-#endif
-
/* get uid */
struct passwd * userpwd;
if ((userpwd = getpwnam(options->usr)) == NULL) {
ERROR("no such user: %s\n", options->usr);
exit(EXIT_FAILURE);
}
- uid = userpwd->pw_uid;
- gid = userpwd->pw_gid;
- if(setgid(gid) == -1) {
+ if(setgid(userpwd->pw_gid) == -1) {
ERROR("cannot setgid of user %s: %s\n", options->usr,
strerror(errno));
exit(EXIT_FAILURE);
@@ -253,33 +246,24 @@ void changeToUser(Options * options) {
/* init suplementary groups
* (must be done before we change our uid)
*/
- if (initgroups(options->usr, gid) == -1) {
- ERROR("cannot init suplementary groups "
- "of user %s: %s\n", options->usr,
- strerror(errno));
- }
- else if(getgroups(NGROUPS_MAX, gid_list) == -1) {
- ERROR("cannot get groups "
+ if (initgroups(options->usr, userpwd->pw_gid) == -1) {
+ WARNING("cannot init suplementary groups "
"of user %s: %s\n", options->usr,
strerror(errno));
- exit(EXIT_FAILURE);
- }
- else if(setgroups(NGROUPS_MAX, gid_list) == -1) {
- ERROR("cannot set groups "
- "of user %s: %s\n", options->usr,
- strerror(errno));
- exit(EXIT_FAILURE);
}
#endif
/* set uid */
- if (setuid(uid) == -1) {
+ if (setuid(userpwd->pw_uid) == -1) {
ERROR("cannot change to uid of user "
"%s: %s\n", options->usr,
strerror(errno));
exit(EXIT_FAILURE);
}
+ if(userpwd->pw_dir) {
+ setenv("HOME", userpwd->pw_dir, 1);
+ }
}
}
diff --git a/src/metadataChunk.c b/src/metadataChunk.c
index 49cba9d90..84817eb0e 100644
--- a/src/metadataChunk.c
+++ b/src/metadataChunk.c
@@ -38,7 +38,7 @@ void initMetadataChunk(MetadataChunk * chunk) {
MpdTag * metadataChunkToMpdTagDup(MetadataChunk * chunk) {
MpdTag * ret = newMpdTag();
- chunk->buffer[METADATA_BUFFER_LENGTH] = '\0';
+ chunk->buffer[METADATA_BUFFER_LENGTH-1] = '\0';
dupElementToTag(ret->name, chunk->name);
dupElementToTag(ret->title, chunk->title);
@@ -65,6 +65,8 @@ void copyMpdTagToMetadataChunk(MpdTag * tag, MetadataChunk * chunk) {
initMetadataChunk(chunk);
+ if(!tag) return;
+
copyStringToChunk(tag->name, chunk->name);
copyStringToChunk(tag->title, chunk->title);
copyStringToChunk(tag->artist, chunk->artist);
diff --git a/src/playlist.c b/src/playlist.c
index 1eba3b7be..3baeb4719 100644
--- a/src/playlist.c
+++ b/src/playlist.c
@@ -167,7 +167,7 @@ void initPlaylist() {
memset(playlist.songs,0,sizeof(char *)*playlist_max_length);
- srand(time(NULL));
+ srandom(time(NULL));
if(getConf()[CONF_STATE_FILE]) {
playlist_stateFile = getConf()[CONF_STATE_FILE];
@@ -635,7 +635,7 @@ int addSongToPlaylist(FILE * fp, Song * song) {
else */if(playlist.queued>=0) start = playlist.queued+1;
else start = playlist.current+1;
if(start < playlist.length) {
- swap = rand()%(playlist.length-start);
+ swap = random()%(playlist.length-start);
swap+=start;
swapOrder(playlist.length-1,swap);
}
@@ -1129,7 +1129,7 @@ void randomizeOrder(int start,int end) {
}
for(i=start;i<=end;i++) {
- ri = rand()%(end-start+1)+start;
+ ri = random()%(end-start+1)+start;
if(ri==playlist.current) playlist.current = i;
else if(i==playlist.current) playlist.current = ri;
swapOrder(i,ri);
@@ -1220,7 +1220,7 @@ int shufflePlaylist(FILE * fp) {
}
/* shuffle the rest of the list */
for(;i<playlist.length;i++) {
- ri = rand()%(playlist.length-1)+1;
+ ri = random()%(playlist.length-1)+1;
swapSongs(i,ri);
}
@@ -1318,7 +1318,7 @@ int savePlaylist(FILE * fp, char * utf8file) {
int loadPlaylist(FILE * fp, char * utf8file) {
FILE * fileP;
- char s[MAXPATHLEN*1];
+ char s[MAXPATHLEN+1];
int slength = 0;
char * temp = strdup(utf8ToFsCharset(utf8file));
char * rfile = malloc(strlen(temp)+strlen(".")+
@@ -1328,6 +1328,7 @@ int loadPlaylist(FILE * fp, char * utf8file) {
int parentlen = strlen(parent);
char * erroredFile = NULL;
int tempInt;
+ int commentCharFound = 0;
strcpy(rfile,temp);
strcat(rfile,".");
@@ -1353,7 +1354,11 @@ int loadPlaylist(FILE * fp, char * utf8file) {
while((tempInt = fgetc(fileP))!=EOF) {
s[slength] = tempInt;
if(s[slength]=='\n' || s[slength]=='\0') {
+ commentCharFound = 0;
s[slength] = '\0';
+ if(s[0]==PLAYLIST_COMMENT) {
+ commentCharFound = 1;
+ }
if(strncmp(s,musicDir,strlen(musicDir))==0) {
strcpy(s,&(s[strlen(musicDir)]));
}
@@ -1379,7 +1384,7 @@ int loadPlaylist(FILE * fp, char * utf8file) {
temp = fsCharsetToUtf8(s);
if(!temp) continue;
temp = strdup(temp);
- if(s[0]==PLAYLIST_COMMENT && !getSongFromDB(temp)
+ if(commentCharFound && !getSongFromDB(temp)
&& !isRemoteUrl(temp))
{
free(temp);
@@ -1393,7 +1398,9 @@ int loadPlaylist(FILE * fp, char * utf8file) {
else if(slength==MAXPATHLEN) {
s[slength] = '\0';
commandError(fp, ACK_ERROR_PLAYLIST_LOAD,
- "\"%s\" too long", s);
+ "line in \"%s\" is too long", utf8file);
+ ERROR("line \"%s\" in playlist \"%s\" is too long\n",
+ s, utf8file);
while(fclose(fileP) && errno==EINTR);
if(erroredFile) free(erroredFile);
return -1;
diff --git a/src/tag.c b/src/tag.c
index 3f95f024d..c5719ed8f 100644
--- a/src/tag.c
+++ b/src/tag.c
@@ -23,6 +23,8 @@
#include "utf8.h"
#include "log.h"
#include "inputStream.h"
+#include "conf.h"
+#include "charConv.h"
#include <sys/stat.h>
#include <stdlib.h>
@@ -54,16 +56,20 @@ void printMpdTag(FILE * fp, MpdTag * tag) {
temp = latin1StrToUtf8Dup(str); \
free(str); \
str = temp; \
- stripReturnChar(str); \
} \
}
void validateUtf8Tag(MpdTag * tag) {
fixUtf8(tag->artist);
+ stripReturnChar(tag->artist);
fixUtf8(tag->album);
+ stripReturnChar(tag->artist);
fixUtf8(tag->track);
+ stripReturnChar(tag->artist);
fixUtf8(tag->title);
+ stripReturnChar(tag->artist);
fixUtf8(tag->name);
+ stripReturnChar(tag->artist);
}
#ifdef HAVE_ID3TAG
@@ -87,6 +93,18 @@ char * getID3Info(struct id3_tag * tag, char * id) {
utf8 = id3_ucs4_utf8duplicate(ucs4);
if(!utf8) return NULL;
+ if(getConf()[CONF_ID3V1_ENCODING]
+ && (id3_tag_options(tag, 0, 0) & ID3_TAG_OPTION_ID3V1)) {
+
+ char* isostr;
+ setCharSetConversion("ISO-8859-1", "UTF-8");
+ isostr = convStrDup(utf8);
+ free(utf8);
+ setCharSetConversion("UTF-8", getConf()[CONF_ID3V1_ENCODING]);
+ utf8 = convStrDup(isostr);
+ free(isostr);
+ }
+
return utf8;
}
#endif
@@ -99,28 +117,24 @@ MpdTag * parseId3Tag(struct id3_tag * tag) {
str = getID3Info(tag,ID3_FRAME_ARTIST);
if(str) {
if(!ret) ret = newMpdTag();
- stripReturnChar(str);
ret->artist = str;
}
str = getID3Info(tag,ID3_FRAME_TITLE);
if(str) {
if(!ret) ret = newMpdTag();
- stripReturnChar(str);
ret->title = str;
}
str = getID3Info(tag,ID3_FRAME_ALBUM);
if(str) {
if(!ret) ret = newMpdTag();
- stripReturnChar(str);
ret->album = str;
}
str = getID3Info(tag,ID3_FRAME_TRACK);
if(str) {
if(!ret) ret = newMpdTag();
- stripReturnChar(str);
ret->track = str;
}
diff --git a/src/utils.c b/src/utils.c
index fbcf3d9dd..a057fa33f 100644
--- a/src/utils.c
+++ b/src/utils.c
@@ -32,6 +32,9 @@ char * myFgets(char * buffer, int bufferSize, FILE * fp) {
if(ret && strlen(buffer)>0 && buffer[strlen(buffer)-1]=='\n') {
buffer[strlen(buffer)-1] = '\0';
}
+ if(ret && strlen(buffer)>0 && buffer[strlen(buffer)-1]=='\r') {
+ buffer[strlen(buffer)-1] = '\0';
+ }
return ret;
}