diff options
-rw-r--r-- | TODO | 18 | ||||
-rw-r--r-- | doc/mpdconf.example | 10 | ||||
-rw-r--r-- | src/conf.c | 4 | ||||
-rw-r--r-- | src/conf.h | 2 | ||||
-rw-r--r-- | src/directory.c | 51 | ||||
-rw-r--r-- | src/directory.h | 2 | ||||
-rw-r--r-- | src/listen.c | 25 | ||||
-rw-r--r-- | src/listen.h | 2 | ||||
-rw-r--r-- | src/main.c | 121 | ||||
-rw-r--r-- | src/myfprintf.c | 9 | ||||
-rw-r--r-- | src/myfprintf.h | 3 | ||||
-rw-r--r-- | src/path.c | 59 | ||||
-rw-r--r-- | src/path.h | 2 |
13 files changed, 152 insertions, 156 deletions
@@ -4,24 +4,16 @@ *) add 2-3 tree for sorted data structures *) remove changes made to linked list for TagTracker -*) debugging/errors - *) more info for failing to read/write db - *) more info for stat'ing errors for music and playlist directory - *) add error codes for status->error +*) add error codes for status->error -*) config - *) make db_file required and port optional in the config file - *) remove command line config options, and require a config file - *) Cleanup Config File Code - -*) metadata todo - *) parsing of lame tags (including getting replaygain and gapless info) - *) implement apev2 and id3v1 tag reader from xmms-musepack plugin - *) only use libid3tag for id3v2 tags, use internal impl for id3v1 tags +*) Cleanup Config File Code *) input plugins *) Handle mp1 and mp2 files (including files with mp3 suffixes) *) add support for playing aac streams (gee, thanks icecast) + *) parsing of lame tags (including getting replaygain and gapless info) + *) implement apev2 and id3v1 tag reader from xmms-musepack plugin + *) only use libid3tag for id3v2 tags, use internal impl for id3v1 tags *) aduio output *) allowing "pausing" of audio output devices diff --git a/doc/mpdconf.example b/doc/mpdconf.example index e360b9cc3..f4f64a76e 100644 --- a/doc/mpdconf.example +++ b/doc/mpdconf.example @@ -3,9 +3,9 @@ # Check the mpd man page, "man mpd". ##################### REQUIRED ########################### -port "6600" music_directory "~/music" -playlist_directory "~/.mpd/playlists" +playlist_directory "~/music" +db_file "~/.mpd/mpd.db" log_file "~/.mpd/mpd.log" error_file "~/.mpd/mpd.error" ########################################################## @@ -112,10 +112,6 @@ audio_output { #################### OPTIONAL FILES ###################### # -# Location of DB file -# -#db_file "~/.mpd/mpd.db" -# # The state file (if set) will be a file # for storing all current information # (playlist, playing/paused, etc...) from @@ -200,6 +196,8 @@ audio_output { ################ MISCELLANEOUS OPTIONS ################### # +#port "6600" +# # This sets the metadata mpd will use, to disable all metadata, set to "none" # NOTE: comment's are disabled by default # diff --git a/src/conf.c b/src/conf.c index 9c08bb3da..2d5bcc5a4 100644 --- a/src/conf.c +++ b/src/conf.c @@ -361,7 +361,7 @@ BlockParam * getBlockParam(ConfigParam * param, char * name) { return ret; } -char * parseConfigFilePath(char * name, int force) { +ConfigParam * parseConfigFilePath(char * name, int force) { ConfigParam * param = getConfigParam(name); char * path; @@ -426,5 +426,5 @@ char * parseConfigFilePath(char * name, int force) { param->value = newPath; } - return param->value; + return param; } diff --git a/src/conf.h b/src/conf.h index ca9da3acf..ca9eb058e 100644 --- a/src/conf.h +++ b/src/conf.h @@ -90,6 +90,6 @@ void registerConfigParam(char * name, int repeats, int block); BlockParam * getBlockParam(ConfigParam * param, char * name); -char * parseConfigFilePath(char * name, int force); +ConfigParam * parseConfigFilePath(char * name, int force); #endif diff --git a/src/directory.c b/src/directory.c index b30d2051b..3249d6382 100644 --- a/src/directory.c +++ b/src/directory.c @@ -46,6 +46,7 @@ #include <stdio.h> #include <errno.h> #include <signal.h> +#include <assert.h> #define DIRECTORY_DIR "directory: " #define DIRECTORY_MTIME "mtime: " @@ -64,11 +65,9 @@ #define DIRECTORY_RETURN_UPDATE 1 #define DIRECTORY_RETURN_ERROR -1 -Directory * mp3rootDirectory = NULL; +static Directory * mp3rootDirectory = NULL; -char * directory_db; - -time_t directory_dbModTime = 0; +static time_t directory_dbModTime = 0; volatile int directory_updatePid = 0; @@ -110,6 +109,15 @@ int inodeFoundInParent(Directory * parent, ino_t inode, dev_t device); int statDirectory(Directory * dir); +static char * getDbFile() { + ConfigParam * param = parseConfigFilePath(CONF_DB_FILE, 1); + + assert(param); + assert(param->value); + + return param->value; +} + void clearUpdatePid() { directory_updatePid = 0; } @@ -207,8 +215,6 @@ int updateInit(FILE * fp, List * pathList) { /* ignore signals since we don't want them to corrupt the db*/ ignoreSignals(); if(writeDirectoryDB()<0) { - ERROR("problems writing music db file, \"%s\"\n", - directory_db); exit(DIRECTORY_UPDATE_EXIT_ERROR); } exit(DIRECTORY_UPDATE_EXIT_UPDATE); @@ -753,7 +759,10 @@ int addSubDirectoryToDirectory(Directory * directory, char * shortname, int addToDirectory(Directory * directory, char * shortname, char * name) { struct stat st; - if(myStat(name, &st)) return -1; + if(myStat(name, &st)) { + DEBUG("failed to stat %s: %s\n", name, strerror(errno)); + return -1; + } if(S_ISREG(st.st_mode) && hasMusicSuffix(name)) { Song * song; @@ -979,6 +988,7 @@ void sortDirectory(Directory * directory) { int writeDirectoryDB() { FILE * fp; + char * dbFile = getDbFile(); DEBUG("removing empty directories from DB\n"); deleteEmptyDirectoriesInDirectory(mp3rootDirectory); @@ -989,8 +999,12 @@ int writeDirectoryDB() { DEBUG("writing DB\n"); - while(!(fp=fopen(directory_db,"w")) && errno==EINTR); - if(!fp) return -1; + while(!(fp=fopen(dbFile,"w")) && errno==EINTR); + if(!fp) { + ERROR("unable to write to db file \"%s\": %s\n", + dbFile, strerror(errno)); + return -1; + } /* block signals when writing the db so we don't get a corrupted db*/ myfprintf(fp,"%s\n",DIRECTORY_INFO_BEGIN); @@ -1006,12 +1020,17 @@ int writeDirectoryDB() { } int readDirectoryDB() { - FILE * fp; + FILE * fp = NULL; + char * dbFile = getDbFile(); struct stat st; if(!mp3rootDirectory) mp3rootDirectory = newDirectory(NULL, NULL); - while(!(fp=fopen(directory_db,"r")) && errno==EINTR); - if(!fp) return -1; + while(!(fp=fopen(dbFile,"r")) && errno==EINTR); + if(fp == NULL) { + ERROR("unable open db file \"%s\": %s\n", + dbFile, strerror(errno)); + return -1; + } /* get initial info */ { @@ -1090,7 +1109,7 @@ int readDirectoryDB() { stats.numberOfSongs = countSongsIn(stderr,NULL); stats.dbPlayTime = sumSongTimesIn(stderr,NULL); - if(stat(directory_db,&st)==0) directory_dbModTime = st.st_mtime; + if(stat(dbFile,&st)==0) directory_dbModTime = st.st_mtime; return 0; } @@ -1102,13 +1121,11 @@ void updateMp3Directory() { return; case 1: if(writeDirectoryDB()<0) { - ERROR("problems writing music db file, \"%s\"\n", - directory_db); exit(EXIT_FAILURE); } - /* something was updated and db should be written */ break; default: + /* something was updated and db should be written */ ERROR("problems updating music db\n"); exit(EXIT_FAILURE); } @@ -1192,7 +1209,7 @@ void initMp3Directory() { stats.numberOfSongs = countSongsIn(stderr,NULL); stats.dbPlayTime = sumSongTimesIn(stderr,NULL); - if(stat(directory_db,&st)==0) directory_dbModTime = st.st_mtime; + if(stat(getDbFile(),&st)==0) directory_dbModTime = st.st_mtime; } Song * getSongDetails(char * file, char ** shortnameRet, diff --git a/src/directory.h b/src/directory.h index a0a615265..48807ea87 100644 --- a/src/directory.h +++ b/src/directory.h @@ -42,8 +42,6 @@ typedef struct _Directory { DirectoryStat * stat; } Directory; -extern char * directory_db; - void readDirectoryDBIfUpdateIsFinished(); void clearUpdatePid(); diff --git a/src/listen.c b/src/listen.c index 9d33698a0..48732b4ea 100644 --- a/src/listen.c +++ b/src/listen.c @@ -39,7 +39,9 @@ #define MAXHOSTNAME 1024 -#define ALLOW_REUSE 1 +#define ALLOW_REUSE 1 + +#define DEFAULT_PORT 6600 int * listenSockets = NULL; int numberOfListenSockets = 0; @@ -166,8 +168,25 @@ static int establishListen(unsigned int port, ConfigParam * param) { return sock; } -void establish(unsigned int port) { - ConfigParam * param = getNextConfigParam(CONF_BIND_TO_ADDRESS, NULL); +void listenOnPort() { + int port = DEFAULT_PORT; + ConfigParam * param = getNextConfigParam(CONF_BIND_TO_ADDRESS,NULL); + + { + ConfigParam * portParam = getConfigParam(CONF_PORT); + + if(portParam) { + char * test; + port = strtol(portParam->value, &test, 10); + if(port <= 0 || *test != '\0') { + ERROR("%s \"%s\" specified at line %i is not a " + "positive integer", CONF_PORT, + portParam->value, + portParam->line); + exit(EXIT_FAILURE); + } + } + } do { numberOfListenSockets++; diff --git a/src/listen.h b/src/listen.h index 1030d9b19..771594435 100644 --- a/src/listen.h +++ b/src/listen.h @@ -26,7 +26,7 @@ #include <sys/types.h> #include <unistd.h> -void establish(unsigned int port); +void listenOnPort(); void getConnections(fd_set * fds); diff --git a/src/main.c b/src/main.c index 98b29c9fc..9a7912f59 100644 --- a/src/main.c +++ b/src/main.c @@ -55,13 +55,6 @@ #define USER_CONFIG_FILE_LOCATION "/.mpdconf" typedef struct _Options { - char * portStr; - char * musicDirArg; - char * playlistDirArg; - char * logFile; - char * errorFile; - char * usr; - char * dbFile; int daemon; int stdOutput; int createDB; @@ -103,12 +96,10 @@ void version() { void parseOptions(int argc, char ** argv, Options * options) { int argcLeft = argc; - options->usr = NULL; options->daemon = 1; options->stdOutput = 0; options->createDB = 0; options->updateDB = 0; - options->dbFile = NULL; if(argc>1) { int i = 1; @@ -158,55 +149,30 @@ void parseOptions(int argc, char ** argv, Options * options) { } } - if(argcLeft==6) { - options->portStr = argv[argc-5]; - options->musicDirArg = argv[argc-4]; - options->playlistDirArg = argv[argc-3]; - options->logFile = argv[argc-2]; - options->errorFile = argv[argc-1]; - return; - } - else if(argcLeft<=2) { - int conf = 0; + if(argcLeft<=2) { if(argcLeft==2) { readConf(argv[argc-1]); - conf = 1; + return; } else if(argcLeft==1) { - FILE * fp; + struct stat st; char * homedir = getenv("HOME"); char userfile[MAXPATHLEN+1] = ""; if(homedir && (strlen(homedir)+ - strlen(USER_CONFIG_FILE_LOCATION)) < - MAXPATHLEN) { + strlen(USER_CONFIG_FILE_LOCATION)) < + MAXPATHLEN) { strcpy(userfile,homedir); strcat(userfile,USER_CONFIG_FILE_LOCATION); } - if(strlen(userfile) && (fp=fopen(userfile,"r"))) { - fclose(fp); + if(strlen(userfile) && (0 == stat(userfile,&st))) { readConf(userfile); - conf = 1; + return; } - else if((fp=fopen(SYSTEM_CONFIG_FILE_LOCATION,"r"))) { - fclose(fp); + else if(0 == stat(SYSTEM_CONFIG_FILE_LOCATION,&st)) { readConf(SYSTEM_CONFIG_FILE_LOCATION); - conf = 1; + return; } } - if(conf) { - options->portStr = forceAndGetConfigParamValue( - CONF_PORT); - options->musicDirArg = - parseConfigFilePath(CONF_MUSIC_DIR, 1); - options->playlistDirArg = - parseConfigFilePath(CONF_PLAYLIST_DIR, 1); - options->logFile = parseConfigFilePath(CONF_LOG_FILE,1); - options->errorFile = - parseConfigFilePath(CONF_ERROR_FILE, 1); - options->usr = getConfigParamValue(CONF_USER); - options->dbFile = parseConfigFilePath(CONF_DB_FILE, 0); - return; - } } usage(argv); @@ -220,28 +186,20 @@ void closeAllFDs() { for(i = 3; i < fds; i++) close(i); } -void establishListen(Options * options) { - int port; - - if((port = atoi(options->portStr))<0) { - ERROR("problem with port number\n"); - exit(EXIT_FAILURE); - } - - if(options->createDB <= 0 && !options->updateDB) establish(port); -} - -void changeToUser(Options * options) { - if (options->usr && strlen(options->usr)) { +void changeToUser() { + ConfigParam * param = getConfigParam(CONF_USER); + + if (param && strlen(param->value)) { /* get uid */ struct passwd * userpwd; - if ((userpwd = getpwnam(options->usr)) == NULL) { - ERROR("no such user: %s\n", options->usr); + if ((userpwd = getpwnam(param->value)) == NULL) { + ERROR("no such user \"%s\" at line %i\n", param->value, + param->line); exit(EXIT_FAILURE); } if(setgid(userpwd->pw_gid) == -1) { - ERROR("cannot setgid of user %s: %s\n", options->usr, + ERROR("cannot setgid for user \"%s\" at line %i: %s\n", param->value, param->line, strerror(errno)); exit(EXIT_FAILURE); } @@ -250,9 +208,10 @@ void changeToUser(Options * options) { /* init suplementary groups * (must be done before we change our uid) */ - if (initgroups(options->usr, userpwd->pw_gid) == -1) { + if (initgroups(param->value, userpwd->pw_gid) == -1) { WARNING("cannot init suplementary groups " - "of user %s: %s\n", options->usr, + "of user \"%s\" at line %i: %s\n", + param->value, param->line, strerror(errno)); } #endif @@ -260,11 +219,13 @@ void changeToUser(Options * options) { /* set uid */ if (setuid(userpwd->pw_uid) == -1) { ERROR("cannot change to uid of user " - "%s: %s\n", options->usr, + "\"%s\" at line %i: %s\n", + param->value, param->line, strerror(errno)); exit(EXIT_FAILURE); } + /* this is needed by libs such as arts */ if(userpwd->pw_dir) { setenv("HOME", userpwd->pw_dir, 1); } @@ -272,6 +233,9 @@ void changeToUser(Options * options) { } void openLogFiles(Options * options, FILE ** out, FILE ** err) { + ConfigParam * logParam = parseConfigFilePath(CONF_LOG_FILE, 1); + ConfigParam * errorParam = parseConfigFilePath(CONF_ERROR_FILE, 1); + mode_t prev; if(options->stdOutput) { @@ -282,15 +246,16 @@ void openLogFiles(Options * options, FILE ** out, FILE ** err) { /* be sure to create log files w/ rw permissions*/ prev = umask(0066); - if(NULL==(*out=fopen(options->logFile,"a"))) { - ERROR("problem opening file \"%s\" for writing\n", - options->logFile); + if(NULL==(*out=fopen(logParam->value,"a"))) { + ERROR("problem opening log file \"%s\" (config line %i) for " + "writing\n", logParam->value, logParam->line); exit(EXIT_FAILURE); } - if(NULL==(*err=fopen(options->errorFile,"a"))) { - ERROR("problem opening file \"%s\" for writing\n", - options->errorFile); + if(NULL==(*err=fopen(errorParam->value,"a"))) { + ERROR("problem opening error file \"%s\" (config line %i) for " + "writing\n", errorParam->value, + errorParam->line); exit(EXIT_FAILURE); } @@ -298,23 +263,16 @@ void openLogFiles(Options * options, FILE ** out, FILE ** err) { } void openDB(Options * options, char * argv0) { - if(!options->dbFile) directory_db = strdup(rpp2app(".mpddb")); - else directory_db = strdup(options->dbFile); - if(options->createDB>0 || readDirectoryDB()<0) { if(options->createDB<0) { ERROR("can't open db file and using \"--no-create-db\"" " command line option\n"); - ERROR("try running \"%s --create-db\"\n", - argv0); + ERROR("try running \"%s --create-db\"\n", argv0); exit(EXIT_FAILURE); } flushWarningLog(); initMp3Directory(); - if(writeDirectoryDB()<0) { - ERROR("problem opening db for reading or writing\n"); - exit(EXIT_FAILURE); - } + if(writeDirectoryDB()<0) exit(EXIT_FAILURE); if(options->createDB) exit(EXIT_SUCCESS); } if(options->updateDB) { @@ -372,8 +330,7 @@ void setupLogOutput(Options * options, FILE * out, FILE * err) { exit(EXIT_FAILURE); } - myfprintfStdLogMode(out, err, options->logFile, - options->errorFile); + myfprintfStdLogMode(out, err); flushWarningLog(); } @@ -408,13 +365,13 @@ int main(int argc, char * argv[]) { initTagConfig(); initLog(); - establishListen(&options); + if(options.createDB <= 0 && !options.updateDB) listenOnPort(); - changeToUser(&options); + changeToUser(); openLogFiles(&options, &out, &err); - initPaths(options.playlistDirArg,options.musicDirArg); + initPaths(); initPermissions(); initReplayGainState(); diff --git a/src/myfprintf.c b/src/myfprintf.c index 8cd394c26..a959b6609 100644 --- a/src/myfprintf.c +++ b/src/myfprintf.c @@ -20,6 +20,7 @@ #include "interface.h" #include "path.h" #include "log.h" +#include "conf.h" #include <stdarg.h> #include <sys/param.h> @@ -57,14 +58,12 @@ void blockingWrite(int fd, char * string, int len) { } } -void myfprintfStdLogMode(FILE * out, FILE * err, char * outFilename, - char * errFilename) -{ +void myfprintfStdLogMode(FILE * out, FILE * err) { myfprintf_stdLogMode = 1; myfprintf_out = out; myfprintf_err = err; - myfprintf_outFilename = prependCwdToPathDup(outFilename); - myfprintf_errFilename = prependCwdToPathDup(errFilename); + myfprintf_outFilename = getConfigParamValue(CONF_LOG_FILE); + myfprintf_errFilename = getConfigParamValue(CONF_ERROR_FILE); } void myfprintf(FILE * fp, char * format, ... ) { diff --git a/src/myfprintf.h b/src/myfprintf.h index ad42ec794..4ffe9725a 100644 --- a/src/myfprintf.h +++ b/src/myfprintf.h @@ -23,8 +23,7 @@ #include <stdio.h> -void myfprintfStdLogMode(FILE * out, FILE * err, char * outFilename, - char * errFilename); +void myfprintfStdLogMode(FILE * out, FILE * err); void myfprintf(FILE * fp, char * format, ... ); diff --git a/src/path.c b/src/path.c index 1d599bda3..c35be7f04 100644 --- a/src/path.c +++ b/src/path.c @@ -28,6 +28,7 @@ #include <sys/stat.h> #include <unistd.h> #include <errno.h> +#include <dirent.h> #ifdef HAVE_LOCALE #ifdef HAVE_LANGINFO_CODESET @@ -110,36 +111,52 @@ char * getFsCharset() { return fsCharset; } -void initPaths(char * playlistDirArg, char * musicDirArg) { +static char * appendSlash(char ** path) { + char * temp = *path; + int len = strlen(temp); + + if(temp[len-1] != '/') { + temp = strdup(*path); + free(*path); + *path = malloc(len+2); + memset(*path, 0, len+2); + memcpy(*path, temp, len); + (*path)[len] = '/'; + } + + return * path; +} + +void initPaths() { + ConfigParam * musicParam = parseConfigFilePath(CONF_MUSIC_DIR, 1); + ConfigParam * playlistParam = parseConfigFilePath(CONF_PLAYLIST_DIR, 1); + ConfigParam * fsCharsetParam = getConfigParam(CONF_FS_CHARSET); + char * charset = NULL; char * originalLocale; - struct stat st; - ConfigParam * param; + DIR * dir; - playlistDir = prependCwdToPathDup(playlistDirArg); - if((stat(playlistDir,&st))<0) { - ERROR("problem stat'ing \"%s\": %s\n", playlistDirArg, strerror(errno)); - exit(EXIT_FAILURE); - } - if(!S_ISDIR(st.st_mode)) { - ERROR("\"%s\" is not a directory: %s\n", playlistDirArg, strerror(errno)); - exit(EXIT_FAILURE); - } + musicDir = appendSlash(&musicParam->value); + playlistDir = appendSlash(&playlistParam->value); - musicDir = prependCwdToPathDup(musicDirArg); - if((stat(musicDir,&st))<0) { - ERROR("problem stat'ing \"%s\"\n",musicDirArg); + if((dir = opendir(playlistDir)) == NULL) { + ERROR("cannot open %s \"%s\" (config line %i): %s\n", + CONF_PLAYLIST_DIR, playlistParam->value, + playlistParam->line, strerror(errno)); exit(EXIT_FAILURE); } - if(!S_ISDIR(st.st_mode)) { - ERROR("\"%s\" is not a directory\n",musicDirArg); + closedir(dir); + + if((dir = opendir(musicDir)) == NULL) { + ERROR("cannot open %s \"%s\" (config line %i): %s\n", + CONF_MUSIC_DIR, musicParam->value, + musicParam->line, strerror(errno)); exit(EXIT_FAILURE); } + closedir(dir); - param = getConfigParam(CONF_FS_CHARSET); - - if(param) { - charset = strdup(param->value); + if(fsCharsetParam) { + charset = strdup(fsCharsetParam->value); } #ifdef HAVE_LOCALE #ifdef HAVE_LANGINFO_CODESET diff --git a/src/path.h b/src/path.h index 5e33a21f4..34b726f6f 100644 --- a/src/path.h +++ b/src/path.h @@ -25,7 +25,7 @@ extern char * musicDir; -void initPaths(char * playlistDirArg, char * musicDirArg); +void initPaths(); void finishPaths(); |