diff options
-rw-r--r-- | TODO | 2 | ||||
-rw-r--r-- | doc/mpd.1 | 4 | ||||
-rw-r--r-- | src/audio.c | 2 | ||||
-rw-r--r-- | src/audio.h | 4 | ||||
-rw-r--r-- | src/conf.c | 13 | ||||
-rw-r--r-- | src/conf.h | 1 | ||||
-rw-r--r-- | src/decode.c | 12 | ||||
-rw-r--r-- | src/inputPlugins/flac_plugin.c | 12 | ||||
-rw-r--r-- | src/inputPlugins/ogg_plugin.c | 8 | ||||
-rw-r--r-- | src/inputStream_http.c | 6 | ||||
-rw-r--r-- | src/main.c | 30 | ||||
-rw-r--r-- | src/metadataChunk.c | 4 | ||||
-rw-r--r-- | src/playlist.c | 21 | ||||
-rw-r--r-- | src/tag.c | 24 | ||||
-rw-r--r-- | src/utils.c | 3 |
15 files changed, 89 insertions, 57 deletions
@@ -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 @@ -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; @@ -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; } |