From b843ae1dde619605a318002b2c2326a9cce380f0 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Mon, 6 Oct 2008 18:48:45 +0200 Subject: song: don't make the struct packed The "packed" attribute may have negative side effects on performance. Remove the "packed" attribute, and increase the size of "song.url" to a multiple of the machine word size. --- src/song.c | 2 +- src/song.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/song.c b/src/song.c index c9301386d..03f65dd0d 100644 --- a/src/song.c +++ b/src/song.c @@ -37,7 +37,7 @@ static Song * song_alloc(const char *url, Directory *parent) assert(url); urllen = strlen(url); assert(urllen); - song = xmalloc(sizeof(Song) + urllen); + song = xmalloc(sizeof(*song) - sizeof(song->url) + urllen + 1); song->tag = NULL; memcpy(song->url, url, urllen + 1); diff --git a/src/song.h b/src/song.h index 9aa9efa94..58506280b 100644 --- a/src/song.h +++ b/src/song.h @@ -37,7 +37,7 @@ typedef struct _Song { struct mpd_tag *tag; struct _Directory *parentDir; time_t mtime; - char url[1]; + char url[sizeof(size_t)]; } mpd_packed Song; Song *newSong(const char *url, struct _Directory *parentDir); -- cgit v1.2.3 From b0dd57ac8f35755b5d367365d1a80d3a5b9527e8 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Tue, 7 Oct 2008 22:15:06 +0200 Subject: song: really make the song struct non-packed Somehow I must have missed this in commit 22e40b61. --- src/song.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/song.h b/src/song.h index 58506280b..46cf8f5cb 100644 --- a/src/song.h +++ b/src/song.h @@ -38,7 +38,7 @@ typedef struct _Song { struct _Directory *parentDir; time_t mtime; char url[sizeof(size_t)]; -} mpd_packed Song; +} Song; Song *newSong(const char *url, struct _Directory *parentDir); -- cgit v1.2.3 From 0b4c78339608179841838798517485208cee08a2 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Wed, 8 Oct 2008 06:55:10 +0200 Subject: dirvec: moved code to dirvec.c Having all functions as static (non-inline) functions generates GCC warnings, and duplicates binary code across several object files. Most of dirvec's methods are too complex for becoming inline functions. Move them all to dirvec.c and publish the prototypes in dirvec.h. --- src/Makefile.am | 1 + src/dirvec.c | 69 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/dirvec.h | 67 +++++-------------------------------------------------- 3 files changed, 75 insertions(+), 62 deletions(-) create mode 100644 src/dirvec.c (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index bfefd5eec..89577360c 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -113,6 +113,7 @@ mpd_SOURCES = \ dbUtils.c \ decode.c \ directory.c \ + dirvec.c \ inputPlugin.c \ inputStream.c \ inputStream_file.c \ diff --git a/src/dirvec.c b/src/dirvec.c new file mode 100644 index 000000000..f84aa37fc --- /dev/null +++ b/src/dirvec.c @@ -0,0 +1,69 @@ +#include "dirvec.h" +#include "os_compat.h" +#include "utils.h" + +static size_t dv_size(struct dirvec *dv) +{ + return dv->nr * sizeof(Directory *); +} + +/* Only used for sorting/searching a dirvec, not general purpose compares */ +static int dirvec_cmp(const void *d1, const void *d2) +{ + const Directory *a = ((const Directory * const *)d1)[0]; + const Directory *b = ((const Directory * const *)d2)[0]; + return strcmp(a->path, b->path); +} + +void dirvec_sort(struct dirvec *dv) +{ + qsort(dv->base, dv->nr, sizeof(Directory *), dirvec_cmp); +} + +Directory *dirvec_find(struct dirvec *dv, const char *path) +{ + int i; + + for (i = dv->nr; --i >= 0; ) + if (!strcmp(dv->base[i]->path, path)) + return dv->base[i]; + return NULL; +} + +int dirvec_delete(struct dirvec *dv, Directory *del) +{ + int i; + + for (i = dv->nr; --i >= 0; ) { + if (dv->base[i] != del) + continue; + /* we _don't_ call freeDirectory() here */ + if (!--dv->nr) { + free(dv->base); + dv->base = NULL; + } else { + memmove(&dv->base[i], &dv->base[i + 1], + (dv->nr - i + 1) * sizeof(Directory *)); + dv->base = xrealloc(dv->base, dv_size(dv)); + } + return i; + } + + return -1; /* not found */ +} + +void dirvec_add(struct dirvec *dv, Directory *add) +{ + ++dv->nr; + dv->base = xrealloc(dv->base, dv_size(dv)); + dv->base[dv->nr - 1] = add; +} + +void dirvec_destroy(struct dirvec *dv) +{ + if (dv->base) { + free(dv->base); + dv->base = NULL; + } + dv->nr = 0; +} diff --git a/src/dirvec.h b/src/dirvec.h index 8b2f634e2..94abd681f 100644 --- a/src/dirvec.h +++ b/src/dirvec.h @@ -2,72 +2,15 @@ #define DIRVEC_H #include "directory.h" -#include "os_compat.h" -#include "utils.h" -static size_t dv_size(struct dirvec *dv) -{ - return dv->nr * sizeof(Directory *); -} +void dirvec_sort(struct dirvec *dv); -/* Only used for sorting/searching a dirvec, not general purpose compares */ -static int dirvec_cmp(const void *d1, const void *d2) -{ - const Directory *a = ((const Directory * const *)d1)[0]; - const Directory *b = ((const Directory * const *)d2)[0]; - return strcmp(a->path, b->path); -} +Directory *dirvec_find(struct dirvec *dv, const char *path); -static void dirvec_sort(struct dirvec *dv) -{ - qsort(dv->base, dv->nr, sizeof(Directory *), dirvec_cmp); -} +int dirvec_delete(struct dirvec *dv, Directory *del); -static Directory *dirvec_find(struct dirvec *dv, const char *path) -{ - int i; +void dirvec_add(struct dirvec *dv, Directory *add); - for (i = dv->nr; --i >= 0; ) - if (!strcmp(dv->base[i]->path, path)) - return dv->base[i]; - return NULL; -} +void dirvec_destroy(struct dirvec *dv); -static int dirvec_delete(struct dirvec *dv, Directory *del) -{ - int i; - - for (i = dv->nr; --i >= 0; ) { - if (dv->base[i] != del) - continue; - /* we _don't_ call freeDirectory() here */ - if (!--dv->nr) { - free(dv->base); - dv->base = NULL; - } else { - memmove(&dv->base[i], &dv->base[i + 1], - (dv->nr - i + 1) * sizeof(Directory *)); - dv->base = xrealloc(dv->base, dv_size(dv)); - } - return i; - } - - return -1; /* not found */ -} - -static void dirvec_add(struct dirvec *dv, Directory *add) -{ - ++dv->nr; - dv->base = xrealloc(dv->base, dv_size(dv)); - dv->base[dv->nr - 1] = add; -} - -static void dirvec_destroy(struct dirvec *dv) -{ - if (dv->base) { - free(dv->base); - dv->base = NULL; - } - dv->nr = 0; -} #endif /* DIRVEC_H */ -- cgit v1.2.3 From 6f43d71628db3c9acb9e0693216885685566b7d3 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Wed, 8 Oct 2008 10:48:48 +0200 Subject: directory: moved code to update.c The source directory.c mixes several libraries: directory object management, database management and database update, resulting in a 1000+ line monster. Move the whole database update code to update.c. --- src/Makefile.am | 2 + src/command.c | 1 + src/directory.c | 570 +---------------------------------------------------- src/directory.h | 21 +- src/main.c | 1 + src/sig_handlers.c | 1 + src/update.c | 560 ++++++++++++++++++++++++++++++++++++++++++++++++++++ src/update.h | 44 +++++ 8 files changed, 629 insertions(+), 571 deletions(-) create mode 100644 src/update.c create mode 100644 src/update.h (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index 89577360c..0925f16b2 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -42,6 +42,7 @@ mpd_headers = \ dbUtils.h \ decode.h \ directory.h \ + update.h \ dirvec.h \ gcc.h \ inputPlugin.h \ @@ -114,6 +115,7 @@ mpd_SOURCES = \ decode.c \ directory.c \ dirvec.c \ + update.c \ inputPlugin.c \ inputStream.c \ inputStream_file.c \ diff --git a/src/command.c b/src/command.c index 6ce5cbed5..4fe1f7410 100644 --- a/src/command.c +++ b/src/command.c @@ -20,6 +20,7 @@ #include "playlist.h" #include "ls.h" #include "directory.h" +#include "update.h" #include "volume.h" #include "stats.h" #include "myfprintf.h" diff --git a/src/directory.c b/src/directory.c index 6dbf7a638..f6bb50913 100644 --- a/src/directory.c +++ b/src/directory.c @@ -22,14 +22,13 @@ #include "log.h" #include "ls.h" #include "path.h" -#include "playlist.h" #include "stats.h" #include "utils.h" #include "ack.h" #include "myfprintf.h" #include "dbUtils.h" -#include "main_notify.h" #include "dirvec.h" +#include "update.h" #define DIRECTORY_DIR "directory: " #define DIRECTORY_MTIME "mtime: " /* DEPRECATED, noop-read-only */ @@ -40,61 +39,12 @@ #define DIRECTORY_MPD_VERSION "mpd_version: " #define DIRECTORY_FS_CHARSET "fs_charset: " -enum update_return { - UPDATE_RETURN_ERROR = -1, - UPDATE_RETURN_NOUPDATE = 0, - UPDATE_RETURN_UPDATED = 1 -}; - -enum update_progress { - UPDATE_PROGRESS_IDLE = 0, - UPDATE_PROGRESS_RUNNING = 1, - UPDATE_PROGRESS_DONE = 2 -} progress; - -/* make this dynamic?, or maybe this is big enough... */ -static char *update_paths[32]; -static size_t update_paths_nr; - static Directory *music_root; static time_t directory_dbModTime; -static pthread_t update_thr; - -static const int update_task_id_max = 1 << 15; - -static int update_task_id; - -static Song *delete; - -static struct condition delete_cond; - -static int addToDirectory(Directory * directory, const char *name); - -static void freeDirectory(Directory * directory); - -static enum update_return exploreDirectory(Directory * directory); - -static enum update_return updateDirectory(Directory * directory); - static void deleteEmptyDirectoriesInDirectory(Directory * directory); -static void delete_song(Directory *dir, Song *del); - -static enum update_return addSubDirectoryToDirectory(Directory * directory, - const char *name, struct stat *st); - -static Directory *getDirectory(const char *name); - -static enum update_return updatePath(const char *utf8path); - -static void sortDirectory(Directory * directory); - -static int inodeFoundInParent(Directory * parent, ino_t inode, dev_t device); - -static int statDirectory(Directory * dir); - static char *getDbFile(void) { ConfigParam *param = parseConfigFilePath(CONF_DB_FILE, 1); @@ -105,106 +55,7 @@ static char *getDbFile(void) return param->value; } -int isUpdatingDB(void) -{ - return (progress != UPDATE_PROGRESS_IDLE) ? update_task_id : 0; -} - -static void * update_task(void *_path) -{ - enum update_return ret = UPDATE_RETURN_NOUPDATE; - - if (_path) { - ret = updatePath((char *)_path); - free(_path); - } else { - ret = updateDirectory(music_root); - } - - if (ret == UPDATE_RETURN_UPDATED && writeDirectoryDB() < 0) - ret = UPDATE_RETURN_ERROR; - progress = UPDATE_PROGRESS_DONE; - wakeup_main_task(); - return (void *)ret; -} - -static void spawn_update_task(char *path) -{ - pthread_attr_t attr; - - assert(pthread_equal(pthread_self(), main_task)); - - progress = UPDATE_PROGRESS_RUNNING; - pthread_attr_init(&attr); - if (pthread_create(&update_thr, &attr, update_task, path)) - FATAL("Failed to spawn update task: %s\n", strerror(errno)); - if (++update_task_id > update_task_id_max) - update_task_id = 1; - DEBUG("spawned thread for update job id %i\n", update_task_id); -} - -void reap_update_task(void) -{ - enum update_return ret; - - assert(pthread_equal(pthread_self(), main_task)); - - cond_enter(&delete_cond); - if (delete) { - char tmp[MPD_PATH_MAX]; - LOG("removing: %s\n", get_song_url(tmp, delete)); - deleteASongFromPlaylist(delete); - delete = NULL; - cond_signal(&delete_cond); - } - cond_leave(&delete_cond); - - if (progress != UPDATE_PROGRESS_DONE) - return; - if (pthread_join(update_thr, (void **)&ret)) - FATAL("error joining update thread: %s\n", strerror(errno)); - if (ret == UPDATE_RETURN_UPDATED) - playlistVersionChange(); - - if (update_paths_nr) { - char *path = update_paths[0]; - memmove(&update_paths[0], &update_paths[1], - --update_paths_nr * sizeof(char *)); - spawn_update_task(path); - } else { - progress = UPDATE_PROGRESS_IDLE; - } -} - -int directory_update_init(char *path) -{ - assert(pthread_equal(pthread_self(), main_task)); - - if (progress != UPDATE_PROGRESS_IDLE) { - int next_task_id; - - if (!path) - return -1; - if (update_paths_nr == ARRAY_SIZE(update_paths)) - return -1; - assert(update_paths_nr < ARRAY_SIZE(update_paths)); - update_paths[update_paths_nr++] = path; - next_task_id = update_task_id + update_paths_nr; - - return next_task_id > update_task_id_max ? 1 : next_task_id; - } - spawn_update_task(path); - return update_task_id; -} - -static void directory_set_stat(Directory * dir, const struct stat *st) -{ - dir->inode = st->st_ino; - dir->device = st->st_dev; - dir->stat = 1; -} - -static Directory *newDirectory(const char *dirname, Directory * parent) +Directory *newDirectory(const char *dirname, Directory * parent) { Directory *directory; @@ -217,7 +68,7 @@ static Directory *newDirectory(const char *dirname, Directory * parent) return directory; } -static void freeDirectory(Directory * directory) +void freeDirectory(Directory * directory) { dirvec_destroy(&directory->children); songvec_destroy(&directory->songs); @@ -228,23 +79,6 @@ static void freeDirectory(Directory * directory) /*getDirectoryPath(NULL); */ } -static void delete_song(Directory *dir, Song *del) -{ - /* first, prevent traversers in main task from getting this */ - songvec_delete(&dir->songs, del); - - /* now take it out of the playlist (in the main_task) */ - cond_enter(&delete_cond); - assert(!delete); - delete = del; - wakeup_main_task(); - do { cond_wait(&delete_cond); } while (delete); - cond_leave(&delete_cond); - - /* finally, all possible references gone, free it */ - freeJustSong(del); -} - static void deleteEmptyDirectoriesInDirectory(Directory * directory) { int i; @@ -259,400 +93,16 @@ static void deleteEmptyDirectoriesInDirectory(Directory * directory) dirvec_destroy(dv); } -static enum update_return -updateInDirectory(Directory * directory, const char *name) -{ - Song *song; - struct stat st; - - if (myStat(name, &st)) - return UPDATE_RETURN_ERROR; - - if (S_ISREG(st.st_mode) && hasMusicSuffix(name, 0)) { - const char *shortname = mpd_basename(name); - - if (!(song = songvec_find(&directory->songs, shortname))) { - addToDirectory(directory, name); - return UPDATE_RETURN_UPDATED; - } else if (st.st_mtime != song->mtime) { - LOG("updating %s\n", name); - if (updateSongInfo(song) < 0) - delete_song(directory, song); - return UPDATE_RETURN_UPDATED; - } - } else if (S_ISDIR(st.st_mode)) { - Directory *subdir = dirvec_find(&directory->children, name); - if (subdir) { - assert(directory == subdir->parent); - directory_set_stat(subdir, &st); - return updateDirectory(subdir); - } else { - return addSubDirectoryToDirectory(directory, name, &st); - } - } - - return UPDATE_RETURN_NOUPDATE; -} - -/* we don't look at hidden files nor files with newlines in them */ -static int skip_path(const char *path) -{ - return (path[0] == '.' || strchr(path, '\n')) ? 1 : 0; -} - -struct delete_data { - char *tmp; - Directory *dir; - enum update_return ret; -}; - -/* passed to songvec_for_each */ -static int delete_song_if_removed(Song *song, void *_data) -{ - struct delete_data *data = _data; - - data->tmp = get_song_url(data->tmp, song); - assert(data->tmp); - - if (!isFile(data->tmp, NULL)) { - delete_song(data->dir, song); - data->ret = UPDATE_RETURN_UPDATED; - } - return 0; -} - -static enum update_return -removeDeletedFromDirectory(char *path_max_tmp, Directory * directory) -{ - enum update_return ret = UPDATE_RETURN_NOUPDATE; - int i; - struct dirvec *dv = &directory->children; - struct delete_data data; - - for (i = dv->nr; --i >= 0; ) { - if (isDir(dv->base[i]->path)) - continue; - LOG("removing directory: %s\n", dv->base[i]->path); - dirvec_delete(dv, dv->base[i]); - ret = UPDATE_RETURN_UPDATED; - } - - data.dir = directory; - data.tmp = path_max_tmp; - data.ret = ret; - songvec_for_each(&directory->songs, delete_song_if_removed, &data); - - return data.ret; -} - -static Directory *addDirectoryPathToDB(const char *utf8path) -{ - char path_max_tmp[MPD_PATH_MAX]; - char *parent; - Directory *parentDirectory; - Directory *directory; - Song *conflicting; - - parent = parent_path(path_max_tmp, utf8path); - - if (strlen(parent) == 0) - parentDirectory = music_root; - else - parentDirectory = addDirectoryPathToDB(parent); - - if (!parentDirectory) - return NULL; - - if ((directory = dirvec_find(&parentDirectory->children, utf8path))) { - assert(parentDirectory == directory->parent); - } else { - struct stat st; - if (myStat(utf8path, &st) < 0 || - inodeFoundInParent(parentDirectory, st.st_ino, st.st_dev)) - return NULL; - else { - directory = newDirectory(utf8path, parentDirectory); - dirvec_add(&parentDirectory->children, directory); - } - } - - /* if we're adding directory paths, make sure to delete filenames - with potentially the same name */ - conflicting = songvec_find(&parentDirectory->songs, - mpd_basename(directory->path)); - if (conflicting) - delete_song(parentDirectory, conflicting); - - return directory; -} - -static Directory *addParentPathToDB(const char *utf8path) -{ - char *parent; - char path_max_tmp[MPD_PATH_MAX]; - Directory *parentDirectory; - - parent = parent_path(path_max_tmp, utf8path); - - if (strlen(parent) == 0) - parentDirectory = music_root; - else - parentDirectory = addDirectoryPathToDB(parent); - - if (!parentDirectory) - return NULL; - - return (Directory *) parentDirectory; -} - -static enum update_return updatePath(const char *utf8path) -{ - Directory *directory; - Directory *parentDirectory; - Song *song; - time_t mtime; - enum update_return ret = UPDATE_RETURN_NOUPDATE; - char path_max_tmp[MPD_PATH_MAX]; - - assert(utf8path); - - /* if path is in the DB try to update it, or else delete it */ - if ((directory = getDirectory(utf8path))) { - parentDirectory = directory->parent; - - /* if this update directory is successfull, we are done */ - if ((ret = updateDirectory(directory)) >= 0) { - sortDirectory(directory); - return ret; - } - /* we don't want to delete the root directory */ - else if (directory == music_root) { - return UPDATE_RETURN_NOUPDATE; - } - /* if updateDirectory fails, means we should delete it */ - else { - LOG("removing directory: %s\n", utf8path); - dirvec_delete(&parentDirectory->children, directory); - ret = UPDATE_RETURN_UPDATED; - /* don't return, path maybe a song now */ - } - } else if ((song = getSongFromDB(utf8path))) { - parentDirectory = song->parentDir; - if (!parentDirectory->stat - && statDirectory(parentDirectory) < 0) { - return UPDATE_RETURN_NOUPDATE; - } - /* if this song update is successful, we are done */ - else if (!inodeFoundInParent(parentDirectory->parent, - parentDirectory->inode, - parentDirectory->device) && - isMusic(get_song_url(path_max_tmp, song), &mtime, 0)) { - if (song->mtime == mtime) - return UPDATE_RETURN_NOUPDATE; - else if (updateSongInfo(song) == 0) - return UPDATE_RETURN_UPDATED; - else { - delete_song(parentDirectory, song); - return UPDATE_RETURN_UPDATED; - } - } - /* if updateDirectory fails, means we should delete it */ - else { - delete_song(parentDirectory, song); - ret = UPDATE_RETURN_UPDATED; - /* don't return, path maybe a directory now */ - } - } - - /* path not found in the db, see if it actually exists on the fs. - * Also, if by chance a directory was replaced by a file of the same - * name or vice versa, we need to add it to the db - */ - if (isDir(utf8path) || isMusic(utf8path, NULL, 0)) { - parentDirectory = addParentPathToDB(utf8path); - if (!parentDirectory || (!parentDirectory->stat && - statDirectory(parentDirectory) < 0)) { - } else if (0 == inodeFoundInParent(parentDirectory->parent, - parentDirectory->inode, - parentDirectory->device) - && addToDirectory(parentDirectory, utf8path) - > 0) { - ret = UPDATE_RETURN_UPDATED; - } - } - - return ret; -} - -static const char *opendir_path(char *path_max_tmp, const char *dirname) -{ - if (*dirname != '\0') - return rmp2amp_r(path_max_tmp, - utf8_to_fs_charset(path_max_tmp, dirname)); - return musicDir; -} - -static enum update_return updateDirectory(Directory * directory) -{ - DIR *dir; - const char *dirname = getDirectoryPath(directory); - struct dirent *ent; - char path_max_tmp[MPD_PATH_MAX]; - enum update_return ret = UPDATE_RETURN_NOUPDATE; - - if (!directory->stat && statDirectory(directory) < 0) - return UPDATE_RETURN_ERROR; - else if (inodeFoundInParent(directory->parent, - directory->inode, - directory->device)) - return UPDATE_RETURN_ERROR; - - dir = opendir(opendir_path(path_max_tmp, dirname)); - if (!dir) - return UPDATE_RETURN_ERROR; - - if (removeDeletedFromDirectory(path_max_tmp, directory) > 0) - ret = UPDATE_RETURN_UPDATED; - - while ((ent = readdir(dir))) { - char *utf8; - if (skip_path(ent->d_name)) - continue; - - utf8 = fs_charset_to_utf8(path_max_tmp, ent->d_name); - if (!utf8) - continue; - - if (directory->path) - utf8 = pfx_dir(path_max_tmp, utf8, strlen(utf8), - dirname, strlen(dirname)); - if (updateInDirectory(directory, path_max_tmp) > 0) - ret = UPDATE_RETURN_UPDATED; - } - - closedir(dir); - - return ret; -} - -static enum update_return exploreDirectory(Directory * directory) -{ - DIR *dir; - const char *dirname = getDirectoryPath(directory); - struct dirent *ent; - char path_max_tmp[MPD_PATH_MAX]; - enum update_return ret = UPDATE_RETURN_NOUPDATE; - - DEBUG("explore: attempting to opendir: %s\n", dirname); - - dir = opendir(opendir_path(path_max_tmp, dirname)); - if (!dir) - return UPDATE_RETURN_ERROR; - - DEBUG("explore: %s\n", dirname); - - while ((ent = readdir(dir))) { - char *utf8; - if (skip_path(ent->d_name)) - continue; - - utf8 = fs_charset_to_utf8(path_max_tmp, ent->d_name); - if (!utf8) - continue; - - DEBUG("explore: found: %s (%s)\n", ent->d_name, utf8); - - if (directory->path) - utf8 = pfx_dir(path_max_tmp, utf8, strlen(utf8), - dirname, strlen(dirname)); - if (addToDirectory(directory, path_max_tmp) > 0) - ret = UPDATE_RETURN_UPDATED; - } - - closedir(dir); - - return ret; -} - -static int statDirectory(Directory * dir) -{ - struct stat st; - - if (myStat(getDirectoryPath(dir), &st) < 0) - return -1; - - directory_set_stat(dir, &st); - - return 0; -} - -static int inodeFoundInParent(Directory * parent, ino_t inode, dev_t device) -{ - while (parent) { - if (!parent->stat && statDirectory(parent) < 0) - return -1; - if (parent->inode == inode && parent->device == device) { - DEBUG("recursive directory found\n"); - return 1; - } - parent = parent->parent; - } - - return 0; -} - -static enum update_return addSubDirectoryToDirectory(Directory * directory, - const char *name, struct stat *st) +void directory_finish(void) { - Directory *subDirectory; - - if (inodeFoundInParent(directory, st->st_ino, st->st_dev)) - return UPDATE_RETURN_NOUPDATE; - - subDirectory = newDirectory(name, directory); - directory_set_stat(subDirectory, st); - - if (exploreDirectory(subDirectory) < 1) { - freeDirectory(subDirectory); - return UPDATE_RETURN_NOUPDATE; - } - - dirvec_add(&directory->children, subDirectory); - - return UPDATE_RETURN_UPDATED; + freeDirectory(music_root); } -static int addToDirectory(Directory * directory, const char *name) +Directory * directory_get_root(void) { - struct stat st; - - if (myStat(name, &st)) { - DEBUG("failed to stat %s: %s\n", name, strerror(errno)); - return -1; - } + assert(music_root != NULL); - if (S_ISREG(st.st_mode) && - hasMusicSuffix(name, 0) && isMusic(name, NULL, 0)) { - Song *song; - const char *shortname = mpd_basename(name); - - if (!(song = newSong(shortname, directory))) - return -1; - songvec_add(&directory->songs, song); - LOG("added %s\n", name); - return 1; - } else if (S_ISDIR(st.st_mode)) { - return addSubDirectoryToDirectory(directory, name, &st); - } - - DEBUG("addToDirectory: %s is not a directory or music\n", name); - - return -1; -} - -void directory_finish(void) -{ - freeDirectory(music_root); + return music_root; } int isRootDirectory(const char *name) @@ -690,7 +140,7 @@ static Directory *getSubDirectory(Directory * directory, const char *name) return found; } -static Directory *getDirectory(const char *name) +Directory *getDirectory(const char *name) { return getSubDirectory(music_root, name); } @@ -812,7 +262,7 @@ static void readDirectoryInfo(FILE * fp, Directory * directory) } } -static void sortDirectory(Directory * directory) +void sortDirectory(Directory * directory) { int i; struct dirvec *dv = &directory->children; diff --git a/src/directory.h b/src/directory.h index 20b784166..c43f8f3c5 100644 --- a/src/directory.h +++ b/src/directory.h @@ -37,23 +37,22 @@ typedef struct _Directory { unsigned stat; /* not needed if ino_t == dev_t == 0 is impossible */ } Directory; -void reap_update_task(void); - -int isUpdatingDB(void); - -/* - * returns the non-negative update job ID on success, - * returns -1 if busy - * @path will be freed by this function and should not be reused - */ -int directory_update_init(char *path); - void directory_init(void); void directory_finish(void); int isRootDirectory(const char *name); +Directory * directory_get_root(void); + +Directory * newDirectory(const char *dirname, Directory * parent); + +void freeDirectory(Directory * directory); + +Directory * getDirectory(const char *name); + +void sortDirectory(Directory * directory); + int printDirectoryInfo(int fd, const char *dirname); int checkDirectoryDB(void); diff --git a/src/main.c b/src/main.c index c0acc260b..baf448fdd 100644 --- a/src/main.c +++ b/src/main.c @@ -20,6 +20,7 @@ #include "command.h" #include "playlist.h" #include "directory.h" +#include "update.h" #include "listen.h" #include "conf.h" #include "path.h" diff --git a/src/sig_handlers.c b/src/sig_handlers.c index e4ac21f22..854188c51 100644 --- a/src/sig_handlers.c +++ b/src/sig_handlers.c @@ -20,6 +20,7 @@ #include "sig_handlers.h" #include "playlist.h" #include "directory.h" +#include "update.h" #include "command.h" #include "signal_check.h" #include "log.h" diff --git a/src/update.c b/src/update.c new file mode 100644 index 000000000..6c21444b6 --- /dev/null +++ b/src/update.c @@ -0,0 +1,560 @@ +/* the Music Player Daemon (MPD) + * Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com) + * Copyright (C) 2008 Max Kellermann + * This project's homepage is: http://www.musicpd.org + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "update.h" +#include "log.h" +#include "ls.h" +#include "path.h" +#include "playlist.h" +#include "utils.h" +#include "main_notify.h" +#include "dirvec.h" +#include "condition.h" +#include "update.h" + +enum update_progress { + UPDATE_PROGRESS_IDLE = 0, + UPDATE_PROGRESS_RUNNING = 1, + UPDATE_PROGRESS_DONE = 2 +} progress; + +/* make this dynamic?, or maybe this is big enough... */ +static char *update_paths[32]; +static size_t update_paths_nr; + +static pthread_t update_thr; + +static const int update_task_id_max = 1 << 15; + +static int update_task_id; + +static Song *delete; + +static struct condition delete_cond; + +int isUpdatingDB(void) +{ + return (progress != UPDATE_PROGRESS_IDLE) ? update_task_id : 0; +} + +static void directory_set_stat(Directory * dir, const struct stat *st) +{ + dir->inode = st->st_ino; + dir->device = st->st_dev; + dir->stat = 1; +} + +static void delete_song(Directory *dir, Song *del) +{ + /* first, prevent traversers in main task from getting this */ + songvec_delete(&dir->songs, del); + + /* now take it out of the playlist (in the main_task) */ + cond_enter(&delete_cond); + assert(!delete); + delete = del; + wakeup_main_task(); + do { cond_wait(&delete_cond); } while (delete); + cond_leave(&delete_cond); + + /* finally, all possible references gone, free it */ + freeJustSong(del); +} + +struct delete_data { + char *tmp; + Directory *dir; + enum update_return ret; +}; + +/* passed to songvec_for_each */ +static int delete_song_if_removed(Song *song, void *_data) +{ + struct delete_data *data = _data; + + data->tmp = get_song_url(data->tmp, song); + assert(data->tmp); + + if (!isFile(data->tmp, NULL)) { + delete_song(data->dir, song); + data->ret = UPDATE_RETURN_UPDATED; + } + return 0; +} + +static enum update_return +removeDeletedFromDirectory(char *path_max_tmp, Directory * directory) +{ + enum update_return ret = UPDATE_RETURN_NOUPDATE; + int i; + struct dirvec *dv = &directory->children; + struct delete_data data; + + for (i = dv->nr; --i >= 0; ) { + if (isDir(dv->base[i]->path)) + continue; + LOG("removing directory: %s\n", dv->base[i]->path); + dirvec_delete(dv, dv->base[i]); + ret = UPDATE_RETURN_UPDATED; + } + + data.dir = directory; + data.tmp = path_max_tmp; + data.ret = ret; + songvec_for_each(&directory->songs, delete_song_if_removed, &data); + + return data.ret; +} + +static const char *opendir_path(char *path_max_tmp, const char *dirname) +{ + if (*dirname != '\0') + return rmp2amp_r(path_max_tmp, + utf8_to_fs_charset(path_max_tmp, dirname)); + return musicDir; +} + +static int statDirectory(Directory * dir) +{ + struct stat st; + + if (myStat(getDirectoryPath(dir), &st) < 0) + return -1; + + directory_set_stat(dir, &st); + + return 0; +} + +static int inodeFoundInParent(Directory * parent, ino_t inode, dev_t device) +{ + while (parent) { + if (!parent->stat && statDirectory(parent) < 0) + return -1; + if (parent->inode == inode && parent->device == device) { + DEBUG("recursive directory found\n"); + return 1; + } + parent = parent->parent; + } + + return 0; +} + +static enum update_return +addSubDirectoryToDirectory(Directory * directory, + const char *name, struct stat *st) +{ + Directory *subDirectory; + + if (inodeFoundInParent(directory, st->st_ino, st->st_dev)) + return UPDATE_RETURN_NOUPDATE; + + subDirectory = newDirectory(name, directory); + directory_set_stat(subDirectory, st); + + if (exploreDirectory(subDirectory) != UPDATE_RETURN_UPDATED) { + freeDirectory(subDirectory); + return UPDATE_RETURN_NOUPDATE; + } + + dirvec_add(&directory->children, subDirectory); + + return UPDATE_RETURN_UPDATED; +} + +static enum update_return +addToDirectory(Directory * directory, const char *name) +{ + struct stat st; + + if (myStat(name, &st)) { + DEBUG("failed to stat %s: %s\n", name, strerror(errno)); + return UPDATE_RETURN_ERROR; + } + if (S_ISREG(st.st_mode) && + hasMusicSuffix(name, 0) && isMusic(name, NULL, 0)) { + Song *song; + const char *shortname = mpd_basename(name); + + if (!(song = newSong(shortname, directory))) + return -1; + songvec_add(&directory->songs, song); + LOG("added %s\n", name); + return UPDATE_RETURN_UPDATED; + } else if (S_ISDIR(st.st_mode)) { + return addSubDirectoryToDirectory(directory, name, &st); + } + + DEBUG("addToDirectory: %s is not a directory or music\n", name); + + return UPDATE_RETURN_ERROR; +} + +static enum update_return updateDirectory(Directory * directory); + +static enum update_return +updateInDirectory(Directory * directory, const char *name) +{ + Song *song; + struct stat st; + + if (myStat(name, &st)) + return UPDATE_RETURN_ERROR; + + if (S_ISREG(st.st_mode) && hasMusicSuffix(name, 0)) { + const char *shortname = mpd_basename(name); + + if (!(song = songvec_find(&directory->songs, shortname))) { + addToDirectory(directory, name); + return UPDATE_RETURN_UPDATED; + } else if (st.st_mtime != song->mtime) { + LOG("updating %s\n", name); + if (updateSongInfo(song) < 0) + delete_song(directory, song); + return UPDATE_RETURN_UPDATED; + } + } else if (S_ISDIR(st.st_mode)) { + Directory *subdir = dirvec_find(&directory->children, name); + if (subdir) { + assert(directory == subdir->parent); + directory_set_stat(subdir, &st); + return updateDirectory(subdir); + } else { + return addSubDirectoryToDirectory(directory, name, &st); + } + } + + return UPDATE_RETURN_NOUPDATE; +} + +/* we don't look at hidden files nor files with newlines in them */ +static int skip_path(const char *path) +{ + return (path[0] == '.' || strchr(path, '\n')) ? 1 : 0; +} + +enum update_return exploreDirectory(Directory * directory) +{ + DIR *dir; + const char *dirname = getDirectoryPath(directory); + struct dirent *ent; + char path_max_tmp[MPD_PATH_MAX]; + enum update_return ret = UPDATE_RETURN_NOUPDATE; + + DEBUG("explore: attempting to opendir: %s\n", dirname); + + dir = opendir(opendir_path(path_max_tmp, dirname)); + if (!dir) + return UPDATE_RETURN_ERROR; + + DEBUG("explore: %s\n", dirname); + + while ((ent = readdir(dir))) { + char *utf8; + if (skip_path(ent->d_name)) + continue; + + utf8 = fs_charset_to_utf8(path_max_tmp, ent->d_name); + if (!utf8) + continue; + + DEBUG("explore: found: %s (%s)\n", ent->d_name, utf8); + + if (directory->path) + utf8 = pfx_dir(path_max_tmp, utf8, strlen(utf8), + dirname, strlen(dirname)); + if (addToDirectory(directory, path_max_tmp) == + UPDATE_RETURN_UPDATED) + ret = UPDATE_RETURN_UPDATED; + } + + closedir(dir); + + return ret; +} + +static enum update_return updateDirectory(Directory * directory) +{ + DIR *dir; + const char *dirname = getDirectoryPath(directory); + struct dirent *ent; + char path_max_tmp[MPD_PATH_MAX]; + enum update_return ret = UPDATE_RETURN_NOUPDATE; + + if (!directory->stat && statDirectory(directory) < 0) + return UPDATE_RETURN_ERROR; + else if (inodeFoundInParent(directory->parent, + directory->inode, + directory->device)) + return UPDATE_RETURN_ERROR; + + dir = opendir(opendir_path(path_max_tmp, dirname)); + if (!dir) + return UPDATE_RETURN_ERROR; + + if (removeDeletedFromDirectory(path_max_tmp, directory) > 0) + ret = UPDATE_RETURN_UPDATED; + + while ((ent = readdir(dir))) { + char *utf8; + if (skip_path(ent->d_name)) + continue; + + utf8 = fs_charset_to_utf8(path_max_tmp, ent->d_name); + if (!utf8) + continue; + + if (directory->path) + utf8 = pfx_dir(path_max_tmp, utf8, strlen(utf8), + dirname, strlen(dirname)); + if (updateInDirectory(directory, path_max_tmp) > 0) + ret = UPDATE_RETURN_UPDATED; + } + + closedir(dir); + + return ret; +} + +static Directory *addDirectoryPathToDB(const char *utf8path) +{ + char path_max_tmp[MPD_PATH_MAX]; + char *parent; + Directory *parentDirectory; + Directory *directory; + Song *conflicting; + + parent = parent_path(path_max_tmp, utf8path); + + if (strlen(parent) == 0) + parentDirectory = directory_get_root(); + else + parentDirectory = addDirectoryPathToDB(parent); + + if (!parentDirectory) + return NULL; + + if ((directory = dirvec_find(&parentDirectory->children, utf8path))) { + assert(parentDirectory == directory->parent); + } else { + struct stat st; + if (myStat(utf8path, &st) < 0 || + inodeFoundInParent(parentDirectory, st.st_ino, st.st_dev)) + return NULL; + else { + directory = newDirectory(utf8path, parentDirectory); + dirvec_add(&parentDirectory->children, directory); + } + } + + /* if we're adding directory paths, make sure to delete filenames + with potentially the same name */ + conflicting = songvec_find(&parentDirectory->songs, + mpd_basename(directory->path)); + if (conflicting) + delete_song(parentDirectory, conflicting); + + return directory; +} + +static Directory *addParentPathToDB(const char *utf8path) +{ + char *parent; + char path_max_tmp[MPD_PATH_MAX]; + Directory *parentDirectory; + + parent = parent_path(path_max_tmp, utf8path); + + if (strlen(parent) == 0) + parentDirectory = directory_get_root(); + else + parentDirectory = addDirectoryPathToDB(parent); + + if (!parentDirectory) + return NULL; + + return (Directory *) parentDirectory; +} + +static enum update_return updatePath(const char *utf8path) +{ + Directory *directory; + Directory *parentDirectory; + Song *song; + time_t mtime; + enum update_return ret = UPDATE_RETURN_NOUPDATE; + char path_max_tmp[MPD_PATH_MAX]; + + assert(utf8path); + + /* if path is in the DB try to update it, or else delete it */ + if ((directory = getDirectory(utf8path))) { + parentDirectory = directory->parent; + + /* if this update directory is successfull, we are done */ + if ((ret = updateDirectory(directory)) >= 0) { + sortDirectory(directory); + return ret; + } + /* we don't want to delete the root directory */ + else if (directory == directory_get_root()) { + return UPDATE_RETURN_NOUPDATE; + } + /* if updateDirectory fails, means we should delete it */ + else { + LOG("removing directory: %s\n", utf8path); + dirvec_delete(&parentDirectory->children, directory); + ret = UPDATE_RETURN_UPDATED; + /* don't return, path maybe a song now */ + } + } else if ((song = getSongFromDB(utf8path))) { + parentDirectory = song->parentDir; + if (!parentDirectory->stat + && statDirectory(parentDirectory) < 0) { + return UPDATE_RETURN_NOUPDATE; + } + /* if this song update is successful, we are done */ + else if (!inodeFoundInParent(parentDirectory->parent, + parentDirectory->inode, + parentDirectory->device) && + isMusic(get_song_url(path_max_tmp, song), &mtime, 0)) { + if (song->mtime == mtime) + return UPDATE_RETURN_NOUPDATE; + else if (updateSongInfo(song) == 0) + return UPDATE_RETURN_UPDATED; + else { + delete_song(parentDirectory, song); + return UPDATE_RETURN_UPDATED; + } + } + /* if updateDirectory fails, means we should delete it */ + else { + delete_song(parentDirectory, song); + ret = UPDATE_RETURN_UPDATED; + /* don't return, path maybe a directory now */ + } + } + + /* path not found in the db, see if it actually exists on the fs. + * Also, if by chance a directory was replaced by a file of the same + * name or vice versa, we need to add it to the db + */ + if (isDir(utf8path) || isMusic(utf8path, NULL, 0)) { + parentDirectory = addParentPathToDB(utf8path); + if (!parentDirectory || (!parentDirectory->stat && + statDirectory(parentDirectory) < 0)) { + } else if (0 == inodeFoundInParent(parentDirectory->parent, + parentDirectory->inode, + parentDirectory->device) + && addToDirectory(parentDirectory, utf8path) + == UPDATE_RETURN_UPDATED) { + ret = UPDATE_RETURN_UPDATED; + } + } + + return ret; +} + +static void * update_task(void *_path) +{ + enum update_return ret = UPDATE_RETURN_NOUPDATE; + + if (_path) { + ret = updatePath((char *)_path); + free(_path); + } else { + ret = updateDirectory(directory_get_root()); + } + + if (ret == UPDATE_RETURN_UPDATED && writeDirectoryDB() < 0) + ret = UPDATE_RETURN_ERROR; + progress = UPDATE_PROGRESS_DONE; + wakeup_main_task(); + return (void *)ret; +} + +static void spawn_update_task(char *path) +{ + pthread_attr_t attr; + + assert(pthread_equal(pthread_self(), main_task)); + + progress = UPDATE_PROGRESS_RUNNING; + pthread_attr_init(&attr); + if (pthread_create(&update_thr, &attr, update_task, path)) + FATAL("Failed to spawn update task: %s\n", strerror(errno)); + if (++update_task_id > update_task_id_max) + update_task_id = 1; + DEBUG("spawned thread for update job id %i\n", update_task_id); +} + +int directory_update_init(char *path) +{ + assert(pthread_equal(pthread_self(), main_task)); + + if (progress != UPDATE_PROGRESS_IDLE) { + int next_task_id; + + if (!path) + return -1; + if (update_paths_nr == ARRAY_SIZE(update_paths)) + return -1; + assert(update_paths_nr < ARRAY_SIZE(update_paths)); + update_paths[update_paths_nr++] = path; + next_task_id = update_task_id + update_paths_nr; + + return next_task_id > update_task_id_max ? 1 : next_task_id; + } + spawn_update_task(path); + return update_task_id; +} + +void reap_update_task(void) +{ + enum update_return ret; + + assert(pthread_equal(pthread_self(), main_task)); + + cond_enter(&delete_cond); + if (delete) { + char tmp[MPD_PATH_MAX]; + LOG("removing: %s\n", get_song_url(tmp, delete)); + deleteASongFromPlaylist(delete); + delete = NULL; + cond_signal(&delete_cond); + } + cond_leave(&delete_cond); + + if (progress != UPDATE_PROGRESS_DONE) + return; + if (pthread_join(update_thr, (void **)&ret)) + FATAL("error joining update thread: %s\n", strerror(errno)); + if (ret == UPDATE_RETURN_UPDATED) + playlistVersionChange(); + + if (update_paths_nr) { + char *path = update_paths[0]; + memmove(&update_paths[0], &update_paths[1], + --update_paths_nr * sizeof(char *)); + spawn_update_task(path); + } else { + progress = UPDATE_PROGRESS_IDLE; + } +} diff --git a/src/update.h b/src/update.h new file mode 100644 index 000000000..132ef175d --- /dev/null +++ b/src/update.h @@ -0,0 +1,44 @@ +/* the Music Player Daemon (MPD) + * Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com) + * Copyright (C) 2008 Max Kellermann + * This project's homepage is: http://www.musicpd.org + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef UPDATE_H +#define UPDATE_H + +#include "directory.h" + +enum update_return { + UPDATE_RETURN_ERROR = -1, + UPDATE_RETURN_NOUPDATE = 0, + UPDATE_RETURN_UPDATED = 1 +}; + +int isUpdatingDB(void); + +enum update_return exploreDirectory(Directory * directory); + +/* + * returns the non-negative update job ID on success, + * returns -1 if busy + * @path will be freed by this function and should not be reused + */ +int directory_update_init(char *path); + +void reap_update_task(void); + +#endif -- cgit v1.2.3 From 7b5c84829768b8ee2ac0ad131045736afc586643 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Wed, 8 Oct 2008 10:48:49 +0200 Subject: directory: added directory_is_empty() directory_is_empty() is a tiny inline function which determine if a directory has any child objects (sub directories or songs). --- src/directory.c | 2 +- src/directory.h | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/directory.c b/src/directory.c index f6bb50913..38f32c271 100644 --- a/src/directory.c +++ b/src/directory.c @@ -86,7 +86,7 @@ static void deleteEmptyDirectoriesInDirectory(Directory * directory) for (i = dv->nr; --i >= 0; ) { deleteEmptyDirectoriesInDirectory(dv->base[i]); - if (!dv->base[i]->children.nr && !dv->base[i]->songs.nr) + if (directory_is_empty(dv->base[i])) dirvec_delete(dv, dv->base[i]); } if (!dv->nr) diff --git a/src/directory.h b/src/directory.h index c43f8f3c5..552bbe28e 100644 --- a/src/directory.h +++ b/src/directory.h @@ -49,6 +49,11 @@ Directory * newDirectory(const char *dirname, Directory * parent); void freeDirectory(Directory * directory); +static inline int directory_is_empty(Directory *directory) +{ + return directory->children.nr == 0 && directory->songs.nr == 0; +} + Directory * getDirectory(const char *name); void sortDirectory(Directory * directory); -- cgit v1.2.3 From b5d3970c075987d7439e2b60ea043606f46a3bab Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Wed, 8 Oct 2008 10:48:55 +0200 Subject: update: merged exploreDirectory() into updateDirectory() exploreDirectory() duplicates some code in updateDirectory(). Merge both functions, and use directory_is_empty() to determine whether update or explore mode should be used. --- src/directory.c | 2 +- src/update.c | 60 +++++++++++++-------------------------------------------- src/update.h | 2 +- 3 files changed, 15 insertions(+), 49 deletions(-) (limited to 'src') diff --git a/src/directory.c b/src/directory.c index 38f32c271..83835c15a 100644 --- a/src/directory.c +++ b/src/directory.c @@ -506,7 +506,7 @@ int traverseAllIn(const char *name, void directory_init(void) { music_root = newDirectory(NULL, NULL); - exploreDirectory(music_root); + updateDirectory(music_root); stats.numberOfSongs = countSongsIn(NULL); stats.dbPlayTime = sumSongTimesIn(NULL); } diff --git a/src/update.c b/src/update.c index 6c21444b6..4a2c11e94 100644 --- a/src/update.c +++ b/src/update.c @@ -169,7 +169,7 @@ addSubDirectoryToDirectory(Directory * directory, subDirectory = newDirectory(name, directory); directory_set_stat(subDirectory, st); - if (exploreDirectory(subDirectory) != UPDATE_RETURN_UPDATED) { + if (updateDirectory(subDirectory) != UPDATE_RETURN_UPDATED) { freeDirectory(subDirectory); return UPDATE_RETURN_NOUPDATE; } @@ -207,8 +207,6 @@ addToDirectory(Directory * directory, const char *name) return UPDATE_RETURN_ERROR; } -static enum update_return updateDirectory(Directory * directory); - static enum update_return updateInDirectory(Directory * directory, const char *name) { @@ -250,48 +248,9 @@ static int skip_path(const char *path) return (path[0] == '.' || strchr(path, '\n')) ? 1 : 0; } -enum update_return exploreDirectory(Directory * directory) -{ - DIR *dir; - const char *dirname = getDirectoryPath(directory); - struct dirent *ent; - char path_max_tmp[MPD_PATH_MAX]; - enum update_return ret = UPDATE_RETURN_NOUPDATE; - - DEBUG("explore: attempting to opendir: %s\n", dirname); - - dir = opendir(opendir_path(path_max_tmp, dirname)); - if (!dir) - return UPDATE_RETURN_ERROR; - - DEBUG("explore: %s\n", dirname); - - while ((ent = readdir(dir))) { - char *utf8; - if (skip_path(ent->d_name)) - continue; - - utf8 = fs_charset_to_utf8(path_max_tmp, ent->d_name); - if (!utf8) - continue; - - DEBUG("explore: found: %s (%s)\n", ent->d_name, utf8); - - if (directory->path) - utf8 = pfx_dir(path_max_tmp, utf8, strlen(utf8), - dirname, strlen(dirname)); - if (addToDirectory(directory, path_max_tmp) == - UPDATE_RETURN_UPDATED) - ret = UPDATE_RETURN_UPDATED; - } - - closedir(dir); - - return ret; -} - -static enum update_return updateDirectory(Directory * directory) +enum update_return updateDirectory(Directory * directory) { + int was_empty = directory_is_empty(directory); DIR *dir; const char *dirname = getDirectoryPath(directory); struct dirent *ent; @@ -309,7 +268,8 @@ static enum update_return updateDirectory(Directory * directory) if (!dir) return UPDATE_RETURN_ERROR; - if (removeDeletedFromDirectory(path_max_tmp, directory) > 0) + if (!was_empty && + removeDeletedFromDirectory(path_max_tmp, directory) > 0) ret = UPDATE_RETURN_UPDATED; while ((ent = readdir(dir))) { @@ -324,8 +284,14 @@ static enum update_return updateDirectory(Directory * directory) if (directory->path) utf8 = pfx_dir(path_max_tmp, utf8, strlen(utf8), dirname, strlen(dirname)); - if (updateInDirectory(directory, path_max_tmp) > 0) - ret = UPDATE_RETURN_UPDATED; + if (was_empty) { + if (addToDirectory(directory, path_max_tmp) == + UPDATE_RETURN_UPDATED) + ret = UPDATE_RETURN_UPDATED; + } else { + if (updateInDirectory(directory, path_max_tmp) > 0) + ret = UPDATE_RETURN_UPDATED; + } } closedir(dir); diff --git a/src/update.h b/src/update.h index 132ef175d..4e59e39b1 100644 --- a/src/update.h +++ b/src/update.h @@ -30,7 +30,7 @@ enum update_return { int isUpdatingDB(void); -enum update_return exploreDirectory(Directory * directory); +enum update_return updateDirectory(Directory * directory); /* * returns the non-negative update job ID on success, -- cgit v1.2.3 From c84c73df00e5e1710d84fdb4be6352d849da8f2b Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Wed, 8 Oct 2008 10:49:05 +0200 Subject: directory: converted typedef Directory to struct directory The struct can be forward-declared by other headers, which relaxes the header dependencies. --- src/dbUtils.c | 11 +++++------ src/directory.c | 57 ++++++++++++++++++++++++++++++--------------------------- src/directory.h | 22 +++++++++++----------- src/dirvec.c | 17 +++++++++-------- src/dirvec.h | 8 ++++---- src/song.c | 6 +++--- src/song.h | 6 +++--- src/update.c | 42 ++++++++++++++++++++++-------------------- src/update.h | 4 ++-- 9 files changed, 89 insertions(+), 84 deletions(-) (limited to 'src') diff --git a/src/dbUtils.c b/src/dbUtils.c index bd990e96d..4c52fffc2 100644 --- a/src/dbUtils.c +++ b/src/dbUtils.c @@ -45,8 +45,7 @@ typedef struct _SearchStats { unsigned long playTime; } SearchStats; -static int countSongsInDirectory(Directory * directory, - void *data) +static int countSongsInDirectory(struct directory *directory, void *data) { int *count = (int *)data; @@ -55,7 +54,7 @@ static int countSongsInDirectory(Directory * directory, return 0; } -static int printDirectoryInDirectory(Directory * directory, void *data) +static int printDirectoryInDirectory(struct directory *directory, void *data) { int fd = (int)(size_t)data; if (directory->path) { @@ -336,15 +335,15 @@ int listAllUniqueTags(int fd, int type, int numConditionals, return ret; } -static int sumSavedFilenameMemoryInDirectory(Directory * dir, void *data) +static int sumSavedFilenameMemoryInDirectory(struct directory *dir, void *data) { int *sum = data; if (!dir->path) return 0; - *sum += (strlen(getDirectoryPath(dir)) + 1 - sizeof(Directory *)) * - dir->songs.nr; + *sum += (strlen(getDirectoryPath(dir)) + 1 + - sizeof(struct directory *)) * dir->songs.nr; return 0; } diff --git a/src/directory.c b/src/directory.c index 83835c15a..2a49fe8ff 100644 --- a/src/directory.c +++ b/src/directory.c @@ -39,11 +39,11 @@ #define DIRECTORY_MPD_VERSION "mpd_version: " #define DIRECTORY_FS_CHARSET "fs_charset: " -static Directory *music_root; +static struct directory *music_root; static time_t directory_dbModTime; -static void deleteEmptyDirectoriesInDirectory(Directory * directory); +static void deleteEmptyDirectoriesInDirectory(struct directory * directory); static char *getDbFile(void) { @@ -55,11 +55,11 @@ static char *getDbFile(void) return param->value; } -Directory *newDirectory(const char *dirname, Directory * parent) +struct directory * newDirectory(const char *dirname, struct directory * parent) { - Directory *directory; + struct directory *directory; - directory = xcalloc(1, sizeof(Directory)); + directory = xcalloc(1, sizeof(*directory)); if (dirname && strlen(dirname)) directory->path = xstrdup(dirname); @@ -68,7 +68,7 @@ Directory *newDirectory(const char *dirname, Directory * parent) return directory; } -void freeDirectory(Directory * directory) +void freeDirectory(struct directory * directory) { dirvec_destroy(&directory->children); songvec_destroy(&directory->songs); @@ -79,7 +79,7 @@ void freeDirectory(Directory * directory) /*getDirectoryPath(NULL); */ } -static void deleteEmptyDirectoriesInDirectory(Directory * directory) +static void deleteEmptyDirectoriesInDirectory(struct directory * directory) { int i; struct dirvec *dv = &directory->children; @@ -98,7 +98,7 @@ void directory_finish(void) freeDirectory(music_root); } -Directory * directory_get_root(void) +struct directory * directory_get_root(void) { assert(music_root != NULL); @@ -110,10 +110,11 @@ int isRootDirectory(const char *name) return (!name || name[0] == '\0' || !strcmp(name, "/")); } -static Directory *getSubDirectory(Directory * directory, const char *name) +static struct directory * +getSubDirectory(struct directory * directory, const char *name) { - Directory *cur = directory; - Directory *found = NULL; + struct directory *cur = directory; + struct directory *found = NULL; char *duplicated; char *locate; @@ -140,7 +141,7 @@ static Directory *getSubDirectory(Directory * directory, const char *name) return found; } -Directory *getDirectory(const char *name) +struct directory * getDirectory(const char *name) { return getSubDirectory(music_root, name); } @@ -160,7 +161,7 @@ static int printDirectoryList(int fd, struct dirvec *dv) int printDirectoryInfo(int fd, const char *name) { - Directory *directory; + struct directory *directory; if ((directory = getDirectory(name)) == NULL) return -1; @@ -187,7 +188,7 @@ static int directory_song_write(Song *song, void *data) } /* TODO error checking */ -static int writeDirectoryInfo(int fd, Directory * directory) +static int writeDirectoryInfo(int fd, struct directory * directory) { struct dirvec *children = &directory->children; size_t i; @@ -198,7 +199,7 @@ static int writeDirectoryInfo(int fd, Directory * directory) return -1; for (i = 0; i < children->nr; ++i) { - Directory *cur = children->base[i]; + struct directory *cur = children->base[i]; const char *base = mpd_basename(cur->path); if (fdprintf(fd, DIRECTORY_DIR "%s\n", base) < 0) @@ -224,7 +225,7 @@ static int writeDirectoryInfo(int fd, Directory * directory) return 0; } -static void readDirectoryInfo(FILE * fp, Directory * directory) +static void readDirectoryInfo(FILE * fp, struct directory * directory) { char buffer[MPD_PATH_MAX * 2]; int bufferSize = MPD_PATH_MAX * 2; @@ -234,7 +235,7 @@ static void readDirectoryInfo(FILE * fp, Directory * directory) while (myFgets(buffer, bufferSize, fp) && prefixcmp(buffer, DIRECTORY_END)) { if (!prefixcmp(buffer, DIRECTORY_DIR)) { - Directory *subdir; + struct directory *subdir; strcpy(key, &(buffer[strlen(DIRECTORY_DIR)])); if (!myFgets(buffer, bufferSize, fp)) @@ -262,7 +263,7 @@ static void readDirectoryInfo(FILE * fp, Directory * directory) } } -void sortDirectory(Directory * directory) +void sortDirectory(struct directory * directory) { int i; struct dirvec *dv = &directory->children; @@ -460,10 +461,11 @@ int readDirectoryDB(void) return 0; } -static int traverseAllInSubDirectory(Directory * directory, - int (*forEachSong) (Song *, void *), - int (*forEachDir) (Directory *, void *), - void *data) +static int +traverseAllInSubDirectory(struct directory * directory, + int (*forEachSong) (Song *, void *), + int (*forEachDir) (struct directory *, void *), + void *data) { struct dirvec *dv = &directory->children; int err = 0; @@ -485,11 +487,12 @@ static int traverseAllInSubDirectory(Directory * directory, return err; } -int traverseAllIn(const char *name, - int (*forEachSong) (Song *, void *), - int (*forEachDir) (Directory *, void *), void *data) +int +traverseAllIn(const char *name, + int (*forEachSong) (Song *, void *), + int (*forEachDir) (struct directory *, void *), void *data) { - Directory *directory; + struct directory *directory; if ((directory = getDirectory(name)) == NULL) { Song *song; @@ -514,7 +517,7 @@ void directory_init(void) Song *getSongFromDB(const char *file) { Song *song = NULL; - Directory *directory; + struct directory *directory; char *dir = NULL; char *duplicated = xstrdup(file); char *shortname = strrchr(duplicated, '/'); diff --git a/src/directory.h b/src/directory.h index 552bbe28e..d604800e8 100644 --- a/src/directory.h +++ b/src/directory.h @@ -23,19 +23,19 @@ #include "songvec.h" struct dirvec { - struct _Directory **base; + struct directory **base; size_t nr; }; -typedef struct _Directory { +struct directory { char *path; struct dirvec children; struct songvec songs; - struct _Directory *parent; + struct directory *parent; ino_t inode; dev_t device; unsigned stat; /* not needed if ino_t == dev_t == 0 is impossible */ -} Directory; +}; void directory_init(void); @@ -43,20 +43,20 @@ void directory_finish(void); int isRootDirectory(const char *name); -Directory * directory_get_root(void); +struct directory * directory_get_root(void); -Directory * newDirectory(const char *dirname, Directory * parent); +struct directory * newDirectory(const char *dirname, struct directory *parent); -void freeDirectory(Directory * directory); +void freeDirectory(struct directory *directory); -static inline int directory_is_empty(Directory *directory) +static inline int directory_is_empty(struct directory *directory) { return directory->children.nr == 0 && directory->songs.nr == 0; } -Directory * getDirectory(const char *name); +struct directory * getDirectory(const char *name); -void sortDirectory(Directory * directory); +void sortDirectory(struct directory * directory); int printDirectoryInfo(int fd, const char *dirname); @@ -72,7 +72,7 @@ time_t getDbModTime(void); int traverseAllIn(const char *name, int (*forEachSong) (Song *, void *), - int (*forEachDir) (Directory *, void *), void *data); + int (*forEachDir) (struct directory *, void *), void *data); #define getDirectoryPath(dir) ((dir && dir->path) ? dir->path : "") diff --git a/src/dirvec.c b/src/dirvec.c index f84aa37fc..9226fca74 100644 --- a/src/dirvec.c +++ b/src/dirvec.c @@ -1,26 +1,27 @@ #include "dirvec.h" +#include "directory.h" #include "os_compat.h" #include "utils.h" static size_t dv_size(struct dirvec *dv) { - return dv->nr * sizeof(Directory *); + return dv->nr * sizeof(struct directory *); } /* Only used for sorting/searching a dirvec, not general purpose compares */ static int dirvec_cmp(const void *d1, const void *d2) { - const Directory *a = ((const Directory * const *)d1)[0]; - const Directory *b = ((const Directory * const *)d2)[0]; + const struct directory *a = ((const struct directory * const *)d1)[0]; + const struct directory *b = ((const struct directory * const *)d2)[0]; return strcmp(a->path, b->path); } void dirvec_sort(struct dirvec *dv) { - qsort(dv->base, dv->nr, sizeof(Directory *), dirvec_cmp); + qsort(dv->base, dv->nr, sizeof(struct directory *), dirvec_cmp); } -Directory *dirvec_find(struct dirvec *dv, const char *path) +struct directory *dirvec_find(struct dirvec *dv, const char *path) { int i; @@ -30,7 +31,7 @@ Directory *dirvec_find(struct dirvec *dv, const char *path) return NULL; } -int dirvec_delete(struct dirvec *dv, Directory *del) +int dirvec_delete(struct dirvec *dv, struct directory *del) { int i; @@ -43,7 +44,7 @@ int dirvec_delete(struct dirvec *dv, Directory *del) dv->base = NULL; } else { memmove(&dv->base[i], &dv->base[i + 1], - (dv->nr - i + 1) * sizeof(Directory *)); + (dv->nr - i + 1) * sizeof(struct directory *)); dv->base = xrealloc(dv->base, dv_size(dv)); } return i; @@ -52,7 +53,7 @@ int dirvec_delete(struct dirvec *dv, Directory *del) return -1; /* not found */ } -void dirvec_add(struct dirvec *dv, Directory *add) +void dirvec_add(struct dirvec *dv, struct directory *add) { ++dv->nr; dv->base = xrealloc(dv->base, dv_size(dv)); diff --git a/src/dirvec.h b/src/dirvec.h index 94abd681f..31719fcc8 100644 --- a/src/dirvec.h +++ b/src/dirvec.h @@ -1,15 +1,15 @@ #ifndef DIRVEC_H #define DIRVEC_H -#include "directory.h" +struct dirvec; void dirvec_sort(struct dirvec *dv); -Directory *dirvec_find(struct dirvec *dv, const char *path); +struct directory *dirvec_find(struct dirvec *dv, const char *path); -int dirvec_delete(struct dirvec *dv, Directory *del); +int dirvec_delete(struct dirvec *dv, struct directory *del); -void dirvec_add(struct dirvec *dv, Directory *add); +void dirvec_add(struct dirvec *dv, struct directory *add); void dirvec_destroy(struct dirvec *dv); diff --git a/src/song.c b/src/song.c index 03f65dd0d..f8a949578 100644 --- a/src/song.c +++ b/src/song.c @@ -29,7 +29,7 @@ #include "os_compat.h" -static Song * song_alloc(const char *url, Directory *parent) +static Song * song_alloc(const char *url, struct directory *parent) { size_t urllen; Song *song; @@ -46,7 +46,7 @@ static Song * song_alloc(const char *url, Directory *parent) return song; } -Song *newSong(const char *url, Directory * parentDir) +Song *newSong(const char *url, struct directory *parentDir) { Song *song; assert(*url); @@ -160,7 +160,7 @@ static int matchesAnMpdTagItemKey(char *buffer, int *itemType) return 0; } -void readSongInfoIntoList(FILE * fp, Directory * parentDir) +void readSongInfoIntoList(FILE * fp, struct directory * parentDir) { char buffer[MPD_PATH_MAX + 1024]; int bufferSize = MPD_PATH_MAX + 1024; diff --git a/src/song.h b/src/song.h index 46cf8f5cb..fcba961f0 100644 --- a/src/song.h +++ b/src/song.h @@ -35,12 +35,12 @@ typedef struct _Song { struct mpd_tag *tag; - struct _Directory *parentDir; + struct directory *parentDir; time_t mtime; char url[sizeof(size_t)]; } Song; -Song *newSong(const char *url, struct _Directory *parentDir); +Song *newSong(const char *url, struct directory *parentDir); void freeJustSong(Song *); @@ -49,7 +49,7 @@ ssize_t song_print_info(Song * song, int fd); /* like song_print_info, but casts data into an fd first */ int song_print_info_x(Song * song, void *data); -void readSongInfoIntoList(FILE * fp, struct _Directory *parent); +void readSongInfoIntoList(FILE * fp, struct directory *parent); int updateSongInfo(Song * song); diff --git a/src/update.c b/src/update.c index 4a2c11e94..00561cab1 100644 --- a/src/update.c +++ b/src/update.c @@ -18,6 +18,7 @@ */ #include "update.h" +#include "directory.h" #include "log.h" #include "ls.h" #include "path.h" @@ -53,14 +54,14 @@ int isUpdatingDB(void) return (progress != UPDATE_PROGRESS_IDLE) ? update_task_id : 0; } -static void directory_set_stat(Directory * dir, const struct stat *st) +static void directory_set_stat(struct directory *dir, const struct stat *st) { dir->inode = st->st_ino; dir->device = st->st_dev; dir->stat = 1; } -static void delete_song(Directory *dir, Song *del) +static void delete_song(struct directory *dir, Song *del) { /* first, prevent traversers in main task from getting this */ songvec_delete(&dir->songs, del); @@ -79,7 +80,7 @@ static void delete_song(Directory *dir, Song *del) struct delete_data { char *tmp; - Directory *dir; + struct directory *dir; enum update_return ret; }; @@ -99,7 +100,7 @@ static int delete_song_if_removed(Song *song, void *_data) } static enum update_return -removeDeletedFromDirectory(char *path_max_tmp, Directory * directory) +removeDeletedFromDirectory(char *path_max_tmp, struct directory *directory) { enum update_return ret = UPDATE_RETURN_NOUPDATE; int i; @@ -130,7 +131,7 @@ static const char *opendir_path(char *path_max_tmp, const char *dirname) return musicDir; } -static int statDirectory(Directory * dir) +static int statDirectory(struct directory *dir) { struct stat st; @@ -142,7 +143,8 @@ static int statDirectory(Directory * dir) return 0; } -static int inodeFoundInParent(Directory * parent, ino_t inode, dev_t device) +static int +inodeFoundInParent(struct directory *parent, ino_t inode, dev_t device) { while (parent) { if (!parent->stat && statDirectory(parent) < 0) @@ -158,10 +160,10 @@ static int inodeFoundInParent(Directory * parent, ino_t inode, dev_t device) } static enum update_return -addSubDirectoryToDirectory(Directory * directory, +addSubDirectoryToDirectory(struct directory *directory, const char *name, struct stat *st) { - Directory *subDirectory; + struct directory *subDirectory; if (inodeFoundInParent(directory, st->st_ino, st->st_dev)) return UPDATE_RETURN_NOUPDATE; @@ -180,7 +182,7 @@ addSubDirectoryToDirectory(Directory * directory, } static enum update_return -addToDirectory(Directory * directory, const char *name) +addToDirectory(struct directory *directory, const char *name) { struct stat st; @@ -208,7 +210,7 @@ addToDirectory(Directory * directory, const char *name) } static enum update_return -updateInDirectory(Directory * directory, const char *name) +updateInDirectory(struct directory *directory, const char *name) { Song *song; struct stat st; @@ -229,7 +231,7 @@ updateInDirectory(Directory * directory, const char *name) return UPDATE_RETURN_UPDATED; } } else if (S_ISDIR(st.st_mode)) { - Directory *subdir = dirvec_find(&directory->children, name); + struct directory *subdir = dirvec_find(&directory->children, name); if (subdir) { assert(directory == subdir->parent); directory_set_stat(subdir, &st); @@ -248,7 +250,7 @@ static int skip_path(const char *path) return (path[0] == '.' || strchr(path, '\n')) ? 1 : 0; } -enum update_return updateDirectory(Directory * directory) +enum update_return updateDirectory(struct directory *directory) { int was_empty = directory_is_empty(directory); DIR *dir; @@ -299,12 +301,12 @@ enum update_return updateDirectory(Directory * directory) return ret; } -static Directory *addDirectoryPathToDB(const char *utf8path) +static struct directory * addDirectoryPathToDB(const char *utf8path) { char path_max_tmp[MPD_PATH_MAX]; char *parent; - Directory *parentDirectory; - Directory *directory; + struct directory *parentDirectory; + struct directory *directory; Song *conflicting; parent = parent_path(path_max_tmp, utf8path); @@ -340,11 +342,11 @@ static Directory *addDirectoryPathToDB(const char *utf8path) return directory; } -static Directory *addParentPathToDB(const char *utf8path) +static struct directory * addParentPathToDB(const char *utf8path) { char *parent; char path_max_tmp[MPD_PATH_MAX]; - Directory *parentDirectory; + struct directory *parentDirectory; parent = parent_path(path_max_tmp, utf8path); @@ -356,13 +358,13 @@ static Directory *addParentPathToDB(const char *utf8path) if (!parentDirectory) return NULL; - return (Directory *) parentDirectory; + return (struct directory *) parentDirectory; } static enum update_return updatePath(const char *utf8path) { - Directory *directory; - Directory *parentDirectory; + struct directory *directory; + struct directory *parentDirectory; Song *song; time_t mtime; enum update_return ret = UPDATE_RETURN_NOUPDATE; diff --git a/src/update.h b/src/update.h index 4e59e39b1..65ffdc3bf 100644 --- a/src/update.h +++ b/src/update.h @@ -20,7 +20,7 @@ #ifndef UPDATE_H #define UPDATE_H -#include "directory.h" +struct directory; enum update_return { UPDATE_RETURN_ERROR = -1, @@ -30,7 +30,7 @@ enum update_return { int isUpdatingDB(void); -enum update_return updateDirectory(Directory * directory); +enum update_return updateDirectory(struct directory *directory); /* * returns the non-negative update job ID on success, -- cgit v1.2.3 From 79e8abb461fa848cce3717333ee5cfa55ee91c71 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Wed, 8 Oct 2008 10:49:11 +0200 Subject: song: converted typedef Song to struct song Again, a data type which can be forward-declared. [ew: * used "struct mpd_song" instead to avoid token duplication (like I did with "struct mpd_tag") as there's no good abbreviation for "song" and identical tokens on the same line don't read well * rewritten using perl -i -p -e 's/\bSong\b/struct mpd_song/g' src/*.[ch] since it was too hard to merge * also, I don't care much for forward declarations ] --- src/dbUtils.c | 19 ++++++++++--------- src/directory.c | 12 ++++++------ src/directory.h | 4 ++-- src/locate.c | 12 ++++++++---- src/locate.h | 6 ++++-- src/playlist.c | 27 ++++++++++++++------------- src/playlist.h | 4 ++-- src/song.c | 28 ++++++++++++++-------------- src/song.h | 22 +++++++++++----------- src/songvec.c | 22 +++++++++++----------- src/songvec.h | 11 ++++++----- src/stats.c | 2 +- src/storedPlaylist.c | 4 ++-- src/storedPlaylist.h | 2 +- src/update.c | 14 +++++++------- 15 files changed, 99 insertions(+), 90 deletions(-) (limited to 'src') diff --git a/src/dbUtils.c b/src/dbUtils.c index 4c52fffc2..eb11ff19e 100644 --- a/src/dbUtils.c +++ b/src/dbUtils.c @@ -68,7 +68,7 @@ struct search_data { LocateTagItemArray array; }; -static int searchInDirectory(Song * song, void *_data) +static int searchInDirectory(struct mpd_song * song, void *_data) { struct search_data *data = _data; int fd = data->fd; @@ -110,7 +110,7 @@ int searchForSongsIn(int fd, const char *name, int numItems, return ret; } -static int findInDirectory(Song * song, void *_data) +static int findInDirectory(struct mpd_song * song, void *_data) { struct search_data *data = _data; int fd = data->fd; @@ -139,7 +139,7 @@ static void printSearchStats(int fd, SearchStats *stats) fdprintf(fd, "playtime: %li\n", stats->playTime); } -static int searchStatsInDirectory(Song * song, void *data) +static int searchStatsInDirectory(struct mpd_song * song, void *data) { SearchStats *stats = data; @@ -177,7 +177,8 @@ int printAllIn(int fd, const char *name) printDirectoryInDirectory, (void*)(size_t)fd); } -static int directoryAddSongToPlaylist(Song * song, mpd_unused void *data) +static int +directoryAddSongToPlaylist(struct mpd_song * song, mpd_unused void *data) { return addSongToPlaylist(song, NULL); } @@ -186,7 +187,7 @@ struct add_data { const char *path; }; -static int directoryAddSongToStoredPlaylist(Song *song, void *_data) +static int directoryAddSongToStoredPlaylist(struct mpd_song *song, void *_data) { struct add_data *data = _data; @@ -209,7 +210,7 @@ int addAllInToStoredPlaylist(const char *name, const char *utf8file) &data); } -static int sumSongTime(Song * song, void *data) +static int sumSongTime(struct mpd_song * song, void *data) { unsigned long *sum_time = (unsigned long *)data; @@ -263,7 +264,7 @@ static void freeListCommandItem(ListCommandItem * item) } static void visitTag(int fd, struct strset *set, - Song * song, enum tag_type tagType) + struct mpd_song * song, enum tag_type tagType) { int i; struct mpd_tag *tag = song->tag; @@ -291,7 +292,7 @@ struct list_tags_data { struct strset *set; }; -static int listUniqueTagsInDirectory(Song * song, void *_data) +static int listUniqueTagsInDirectory(struct mpd_song * song, void *_data) { struct list_tags_data *data = _data; ListCommandItem *item = data->item; @@ -348,7 +349,7 @@ static int sumSavedFilenameMemoryInDirectory(struct directory *dir, void *data) return 0; } -static int sumSavedFilenameMemoryInSong(Song * song, void *data) +static int sumSavedFilenameMemoryInSong(struct mpd_song * song, void *data) { int *sum = data; diff --git a/src/directory.c b/src/directory.c index 2a49fe8ff..93bde7de9 100644 --- a/src/directory.c +++ b/src/directory.c @@ -173,7 +173,7 @@ int printDirectoryInfo(int fd, const char *name) return 0; } -static int directory_song_write(Song *song, void *data) +static int directory_song_write(struct mpd_song *song, void *data) { int fd = (int)(size_t)data; @@ -463,7 +463,7 @@ int readDirectoryDB(void) static int traverseAllInSubDirectory(struct directory * directory, - int (*forEachSong) (Song *, void *), + int (*forEachSong) (struct mpd_song *, void *), int (*forEachDir) (struct directory *, void *), void *data) { @@ -489,13 +489,13 @@ traverseAllInSubDirectory(struct directory * directory, int traverseAllIn(const char *name, - int (*forEachSong) (Song *, void *), + int (*forEachSong) (struct mpd_song *, void *), int (*forEachDir) (struct directory *, void *), void *data) { struct directory *directory; if ((directory = getDirectory(name)) == NULL) { - Song *song; + struct mpd_song *song; if ((song = getSongFromDB(name)) && forEachSong) { return forEachSong(song, data); } @@ -514,9 +514,9 @@ void directory_init(void) stats.dbPlayTime = sumSongTimesIn(NULL); } -Song *getSongFromDB(const char *file) +struct mpd_song *getSongFromDB(const char *file) { - Song *song = NULL; + struct mpd_song *song = NULL; struct directory *directory; char *dir = NULL; char *duplicated = xstrdup(file); diff --git a/src/directory.h b/src/directory.h index d604800e8..72de511e7 100644 --- a/src/directory.h +++ b/src/directory.h @@ -66,12 +66,12 @@ int writeDirectoryDB(void); int readDirectoryDB(void); -Song *getSongFromDB(const char *file); +struct mpd_song *getSongFromDB(const char *file); time_t getDbModTime(void); int traverseAllIn(const char *name, - int (*forEachSong) (Song *, void *), + int (*forEachSong) (struct mpd_song *, void *), int (*forEachDir) (struct directory *, void *), void *data); #define getDirectoryPath(dir) ((dir && dir->path) ? dir->path : "") diff --git a/src/locate.c b/src/locate.c index 6101dd95b..dfe1e2236 100644 --- a/src/locate.c +++ b/src/locate.c @@ -121,7 +121,8 @@ void freeLocateTagItem(LocateTagItem * item) free(item); } -static int strstrSearchTag(Song * song, enum tag_type type, char *str) +static int strstrSearchTag(struct mpd_song * song, + enum tag_type type, char *str) { int i; char *duplicate; @@ -166,7 +167,8 @@ static int strstrSearchTag(Song * song, enum tag_type type, char *str) return ret; } -int strstrSearchTags(Song * song, int numItems, LocateTagItem * items) +int +strstrSearchTags(struct mpd_song * song, int numItems, LocateTagItem * items) { int i; @@ -180,7 +182,8 @@ int strstrSearchTags(Song * song, int numItems, LocateTagItem * items) return 1; } -static int tagItemFoundAndMatches(Song * song, enum tag_type type, char *str) +static int +tagItemFoundAndMatches(struct mpd_song * song, enum tag_type type, char *str) { int i; int8_t visitedTypes[TAG_NUM_OF_ITEM_TYPES] = { 0 }; @@ -220,7 +223,8 @@ static int tagItemFoundAndMatches(Song * song, enum tag_type type, char *str) } -int tagItemsFoundAndMatches(Song * song, int numItems, LocateTagItem * items) +int tagItemsFoundAndMatches(struct mpd_song * song, + int numItems, LocateTagItem * items) { int i; diff --git a/src/locate.h b/src/locate.h index 7a817828a..0ccc497ff 100644 --- a/src/locate.h +++ b/src/locate.h @@ -44,8 +44,10 @@ void freeLocateTagItemArray(int count, LocateTagItem * array); void freeLocateTagItem(LocateTagItem * item); -int strstrSearchTags(Song * song, int numItems, LocateTagItem * items); +int strstrSearchTags(struct mpd_song * song, + int numItems, LocateTagItem * items); -int tagItemsFoundAndMatches(Song * song, int numItems, LocateTagItem * items); +int tagItemsFoundAndMatches(struct mpd_song * song, + int numItems, LocateTagItem * items); #endif diff --git a/src/playlist.c b/src/playlist.c index 696636993..ea9f5719c 100644 --- a/src/playlist.c +++ b/src/playlist.c @@ -41,7 +41,7 @@ enum _playlist_state { static enum _playlist_state playlist_state; struct _playlist { - Song **songs; + struct mpd_song **songs; /* holds version a song was modified on */ uint32_t *songMod; int *order; @@ -157,7 +157,8 @@ void initPlaylist(void) playlist_saveAbsolutePaths = DEFAULT_PLAYLIST_SAVE_ABSOLUTE_PATHS; - playlist.songs = xcalloc(playlist_max_length, sizeof(Song *)); + playlist.songs = xcalloc(playlist_max_length, + sizeof(struct mpd_song *)); playlist.songMod = xmalloc(sizeof(uint32_t) * playlist_max_length); playlist.order = xmalloc(sizeof(int) * playlist_max_length); playlist.idToPosition = xmalloc(sizeof(int) * playlist_max_length * @@ -440,7 +441,7 @@ enum playlist_result playlistId(int fd, int id) static void swapSongs(int song1, int song2) { - Song *sTemp; + struct mpd_song *sTemp; int iTemp; assert(song1 < playlist.length); @@ -463,7 +464,7 @@ static void swapSongs(int song1, int song2) playlist.positionToId[song2] = iTemp; } -static Song *song_at(int order_num) +static struct mpd_song *song_at(int order_num) { if (order_num >= 0 && order_num < playlist.length) { assert(playlist.songs[playlist.order[order_num]]); @@ -536,7 +537,7 @@ void playlist_queue_next(void) char *playlist_queued_url(char utf8url[MPD_PATH_MAX]) { - Song *song; + struct mpd_song *song; assert(pthread_equal(pthread_self(), dc.thread)); pthread_mutex_lock(&queue_lock); @@ -570,7 +571,7 @@ static int clear_queue(void) enum playlist_result addToPlaylist(const char *url, int *added_id) { - Song *song; + struct mpd_song *song; DEBUG("add to playlist: %s\n", url); @@ -585,7 +586,7 @@ enum playlist_result addToPlaylist(const char *url, int *added_id) int addToStoredPlaylist(const char *url, const char *utf8file) { - Song *song; + struct mpd_song *song; DEBUG("add to stored playlist: %s\n", url); @@ -604,7 +605,7 @@ int addToStoredPlaylist(const char *url, const char *utf8file) return ACK_ERROR_NO_EXIST; } -enum playlist_result addSongToPlaylist(Song * song, int *added_id) +enum playlist_result addSongToPlaylist(struct mpd_song * song, int *added_id) { int id; @@ -798,7 +799,7 @@ enum playlist_result deleteFromPlaylistById(int id) return deleteFromPlaylist(playlist.idToPosition[id]); } -void deleteASongFromPlaylist(const Song * song) +void deleteASongFromPlaylist(const struct mpd_song * song) { int i; @@ -917,7 +918,7 @@ enum playlist_result playPlaylistById(int id, int stopOnError) /* This is used when we stream data out to shout while playing static files */ struct mpd_tag *playlist_current_tag(void) { - Song *song = song_at(playlist.current); + struct mpd_song *song = song_at(playlist.current); /* Non-file song tags can get swept out from under us */ return (song && song_is_file(song)) ? song->tag : NULL; @@ -926,7 +927,7 @@ struct mpd_tag *playlist_current_tag(void) /* This receives dynamic metadata updates from streams */ static void sync_metadata(void) { - Song *song; + struct mpd_song *song; struct mpd_tag *tag; if (!(tag = metadata_pipe_current())) @@ -998,7 +999,7 @@ void setPlaylistRepeatStatus(int status) enum playlist_result moveSongInPlaylist(int from, int to) { int i; - Song *tmpSong; + struct mpd_song *tmpSong; int tmpId; int currentSong; int queued_is_current = (playlist.queued == playlist.current); @@ -1361,7 +1362,7 @@ int PlaylistInfo(int fd, const char *utf8file, int detail) int wrote = 0; if (detail) { - Song *song = getSongFromDB(temp); + struct mpd_song *song = getSongFromDB(temp); if (song) { song_print_info(song, fd); wrote = 1; diff --git a/src/playlist.h b/src/playlist.h index 2be2711e5..f4df8ce41 100644 --- a/src/playlist.h +++ b/src/playlist.h @@ -57,7 +57,7 @@ enum playlist_result addToPlaylist(const char *file, int *added_id); int addToStoredPlaylist(const char *file, const char *utf8file); -enum playlist_result addSongToPlaylist(Song * song, int *added_id); +enum playlist_result addSongToPlaylist(struct mpd_song * song, int *added_id); void showPlaylist(int fd); @@ -93,7 +93,7 @@ enum playlist_result savePlaylist(const char *utf8file); enum playlist_result deletePlaylist(const char *utf8file); -void deleteASongFromPlaylist(const Song * song); +void deleteASongFromPlaylist(const struct mpd_song * song); enum playlist_result moveSongInPlaylist(int from, int to); diff --git a/src/song.c b/src/song.c index f8a949578..be84bfa4b 100644 --- a/src/song.c +++ b/src/song.c @@ -29,10 +29,10 @@ #include "os_compat.h" -static Song * song_alloc(const char *url, struct directory *parent) +static struct mpd_song * song_alloc(const char *url, struct directory *parent) { size_t urllen; - Song *song; + struct mpd_song *song; assert(url); urllen = strlen(url); @@ -46,9 +46,9 @@ static Song * song_alloc(const char *url, struct directory *parent) return song; } -Song *newSong(const char *url, struct directory *parentDir) +struct mpd_song *newSong(const char *url, struct directory *parentDir) { - Song *song; + struct mpd_song *song; assert(*url); if (strchr(url, '\n')) { @@ -79,14 +79,14 @@ Song *newSong(const char *url, struct directory *parentDir) return song; } -void freeJustSong(Song * song) +void freeJustSong(struct mpd_song * song) { if (song->tag) tag_free(song->tag); free(song); } -ssize_t song_print_url(Song *song, int fd) +ssize_t song_print_url(struct mpd_song *song, int fd) { if (song->parentDir && song->parentDir->path) return fdprintf(fd, "%s%s/%s\n", SONG_FILE, @@ -94,7 +94,7 @@ ssize_t song_print_url(Song *song, int fd) return fdprintf(fd, "%s%s\n", SONG_FILE, song->url); } -ssize_t song_print_info(Song *song, int fd) +ssize_t song_print_info(struct mpd_song *song, int fd) { ssize_t ret = song_print_url(song, fd); @@ -106,19 +106,19 @@ ssize_t song_print_info(Song *song, int fd) return ret; } -int song_print_info_x(Song * song, void *data) +int song_print_info_x(struct mpd_song * song, void *data) { return song_print_info(song, (int)(size_t)data); } -int song_print_url_x(Song * song, void *data) +int song_print_url_x(struct mpd_song * song, void *data) { return song_print_url(song, (int)(size_t)data); } -static void insertSongIntoList(struct songvec *sv, Song *newsong) +static void insertSongIntoList(struct songvec *sv, struct mpd_song *newsong) { - Song *existing = songvec_find(sv, newsong->url); + struct mpd_song *existing = songvec_find(sv, newsong->url); if (!existing) { songvec_add(sv, newsong); @@ -164,7 +164,7 @@ void readSongInfoIntoList(FILE * fp, struct directory * parentDir) { char buffer[MPD_PATH_MAX + 1024]; int bufferSize = MPD_PATH_MAX + 1024; - Song *song = NULL; + struct mpd_song *song = NULL; struct songvec *sv = &parentDir->songs; int itemType; @@ -207,7 +207,7 @@ void readSongInfoIntoList(FILE * fp, struct directory * parentDir) insertSongIntoList(sv, song); } -int updateSongInfo(Song * song) +int updateSongInfo(struct mpd_song * song) { if (song_is_file(song)) { InputPlugin *plugin; @@ -238,7 +238,7 @@ int updateSongInfo(Song * song) return 0; } -char *get_song_url(char *path_max_tmp, Song *song) +char *get_song_url(char *path_max_tmp, struct mpd_song *song) { if (!song) return NULL; diff --git a/src/song.h b/src/song.h index fcba961f0..eaccf7080 100644 --- a/src/song.h +++ b/src/song.h @@ -33,30 +33,30 @@ #define SONG_FILE "file: " #define SONG_TIME "Time: " -typedef struct _Song { +struct mpd_song { struct mpd_tag *tag; struct directory *parentDir; time_t mtime; char url[sizeof(size_t)]; -} Song; +}; -Song *newSong(const char *url, struct directory *parentDir); +struct mpd_song *newSong(const char *url, struct directory *parentDir); -void freeJustSong(Song *); +void freeJustSong(struct mpd_song *); -ssize_t song_print_info(Song * song, int fd); +ssize_t song_print_info(struct mpd_song * song, int fd); /* like song_print_info, but casts data into an fd first */ -int song_print_info_x(Song * song, void *data); +int song_print_info_x(struct mpd_song * song, void *data); void readSongInfoIntoList(FILE * fp, struct directory *parent); -int updateSongInfo(Song * song); +int updateSongInfo(struct mpd_song * song); -ssize_t song_print_url(Song * song, int fd); +ssize_t song_print_url(struct mpd_song * song, int fd); /* like song_print_url_x, but casts data into an fd first */ -int song_print_url_x(Song * song, void *data); +int song_print_url_x(struct mpd_song * song, void *data); /* * get_song_url - Returns a path of a song in UTF8-encoded form @@ -64,9 +64,9 @@ int song_print_url_x(Song * song, void *data); * buffer is assumed to be MPD_PATH_MAX or greater (including * terminating '\0'). */ -char *get_song_url(char *path_max_tmp, Song * song); +char *get_song_url(char *path_max_tmp, struct mpd_song * song); -static inline int song_is_file(const Song *song) +static inline int song_is_file(const struct mpd_song *song) { return !!song->parentDir; } diff --git a/src/songvec.c b/src/songvec.c index cf0991029..c4f702aef 100644 --- a/src/songvec.c +++ b/src/songvec.c @@ -7,27 +7,27 @@ static pthread_mutex_t nr_lock = PTHREAD_MUTEX_INITIALIZER; /* Only used for sorting/searchin a songvec, not general purpose compares */ static int songvec_cmp(const void *s1, const void *s2) { - const Song *a = ((const Song * const *)s1)[0]; - const Song *b = ((const Song * const *)s2)[0]; + const struct mpd_song *a = ((const struct mpd_song * const *)s1)[0]; + const struct mpd_song *b = ((const struct mpd_song * const *)s2)[0]; return strcmp(a->url, b->url); } static size_t sv_size(struct songvec *sv) { - return sv->nr * sizeof(Song *); + return sv->nr * sizeof(struct mpd_song *); } void songvec_sort(struct songvec *sv) { pthread_mutex_lock(&nr_lock); - qsort(sv->base, sv->nr, sizeof(Song *), songvec_cmp); + qsort(sv->base, sv->nr, sizeof(struct mpd_song *), songvec_cmp); pthread_mutex_unlock(&nr_lock); } -Song *songvec_find(struct songvec *sv, const char *url) +struct mpd_song *songvec_find(struct songvec *sv, const char *url) { int i; - Song *ret = NULL; + struct mpd_song *ret = NULL; pthread_mutex_lock(&nr_lock); for (i = sv->nr; --i >= 0; ) { @@ -40,7 +40,7 @@ Song *songvec_find(struct songvec *sv, const char *url) return ret; } -int songvec_delete(struct songvec *sv, const Song *del) +int songvec_delete(struct songvec *sv, const struct mpd_song *del) { int i; @@ -54,7 +54,7 @@ int songvec_delete(struct songvec *sv, const Song *del) sv->base = NULL; } else { memmove(&sv->base[i], &sv->base[i + 1], - (sv->nr - i + 1) * sizeof(Song *)); + (sv->nr - i + 1) * sizeof(struct mpd_song *)); sv->base = xrealloc(sv->base, sv_size(sv)); } break; @@ -64,7 +64,7 @@ int songvec_delete(struct songvec *sv, const Song *del) return i; } -void songvec_add(struct songvec *sv, Song *add) +void songvec_add(struct songvec *sv, struct mpd_song *add) { pthread_mutex_lock(&nr_lock); ++sv->nr; @@ -84,13 +84,13 @@ void songvec_destroy(struct songvec *sv) pthread_mutex_unlock(&nr_lock); } -int songvec_for_each(struct songvec *sv, int (*fn)(Song *, void *), void *arg) +int songvec_for_each(struct songvec *sv, int (*fn)(struct mpd_song *, void *), void *arg) { size_t i; pthread_mutex_lock(&nr_lock); for (i = 0; i < sv->nr; ++i) { - Song *song = sv->base[i]; + struct mpd_song *song = sv->base[i]; assert(song); assert(*song->url); diff --git a/src/songvec.h b/src/songvec.h index dbe6be508..341c404c7 100644 --- a/src/songvec.h +++ b/src/songvec.h @@ -5,20 +5,21 @@ #include "os_compat.h" struct songvec { - Song **base; + struct mpd_song **base; size_t nr; }; void songvec_sort(struct songvec *sv); -Song *songvec_find(struct songvec *sv, const char *url); +struct mpd_song *songvec_find(struct songvec *sv, const char *url); -int songvec_delete(struct songvec *sv, const Song *del); +int songvec_delete(struct songvec *sv, const struct mpd_song *del); -void songvec_add(struct songvec *sv, Song *add); +void songvec_add(struct songvec *sv, struct mpd_song *add); void songvec_destroy(struct songvec *sv); -int songvec_for_each(struct songvec *sv, int (*fn)(Song *, void *), void *arg); +int songvec_for_each(struct songvec *sv, + int (*fn)(struct mpd_song *, void *), void *arg); #endif /* SONGVEC_H */ diff --git a/src/stats.c b/src/stats.c index 4555907db..f200a48b3 100644 --- a/src/stats.c +++ b/src/stats.c @@ -40,7 +40,7 @@ struct visit_data { struct strset *set; }; -static int visit_tag_items(Song *song, void *_data) +static int visit_tag_items(struct mpd_song *song, void *_data) { const struct visit_data *data = _data; unsigned i; diff --git a/src/storedPlaylist.c b/src/storedPlaylist.c index 265301392..482e9e241 100644 --- a/src/storedPlaylist.c +++ b/src/storedPlaylist.c @@ -110,7 +110,7 @@ List *loadStoredPlaylist(const char *utf8path) while (myFgets(buffer, sizeof(buffer), file)) { char *s = buffer; - Song *song; + struct mpd_song *song; if (*s == PLAYLIST_COMMENT) continue; @@ -263,7 +263,7 @@ removeOneSongFromStoredPlaylistByPath(const char *utf8path, int pos) } enum playlist_result -appendSongToStoredPlaylistByPath(const char *utf8path, Song *song) +appendSongToStoredPlaylistByPath(const char *utf8path, struct mpd_song *song) { FILE *file; char *s; diff --git a/src/storedPlaylist.h b/src/storedPlaylist.h index 964669d35..4721bcc98 100644 --- a/src/storedPlaylist.h +++ b/src/storedPlaylist.h @@ -35,7 +35,7 @@ enum playlist_result removeOneSongFromStoredPlaylistByPath(const char *utf8path, int pos); enum playlist_result -appendSongToStoredPlaylistByPath(const char *utf8path, Song *song); +appendSongToStoredPlaylistByPath(const char *utf8path, struct mpd_song *song); enum playlist_result renameStoredPlaylist(const char *utf8from, const char *utf8to); diff --git a/src/update.c b/src/update.c index 00561cab1..674ad0519 100644 --- a/src/update.c +++ b/src/update.c @@ -45,7 +45,7 @@ static const int update_task_id_max = 1 << 15; static int update_task_id; -static Song *delete; +static struct mpd_song *delete; static struct condition delete_cond; @@ -61,7 +61,7 @@ static void directory_set_stat(struct directory *dir, const struct stat *st) dir->stat = 1; } -static void delete_song(struct directory *dir, Song *del) +static void delete_song(struct directory *dir, struct mpd_song *del) { /* first, prevent traversers in main task from getting this */ songvec_delete(&dir->songs, del); @@ -85,7 +85,7 @@ struct delete_data { }; /* passed to songvec_for_each */ -static int delete_song_if_removed(Song *song, void *_data) +static int delete_song_if_removed(struct mpd_song *song, void *_data) { struct delete_data *data = _data; @@ -192,7 +192,7 @@ addToDirectory(struct directory *directory, const char *name) } if (S_ISREG(st.st_mode) && hasMusicSuffix(name, 0) && isMusic(name, NULL, 0)) { - Song *song; + struct mpd_song *song; const char *shortname = mpd_basename(name); if (!(song = newSong(shortname, directory))) @@ -212,7 +212,7 @@ addToDirectory(struct directory *directory, const char *name) static enum update_return updateInDirectory(struct directory *directory, const char *name) { - Song *song; + struct mpd_song *song; struct stat st; if (myStat(name, &st)) @@ -307,7 +307,7 @@ static struct directory * addDirectoryPathToDB(const char *utf8path) char *parent; struct directory *parentDirectory; struct directory *directory; - Song *conflicting; + struct mpd_song *conflicting; parent = parent_path(path_max_tmp, utf8path); @@ -365,7 +365,7 @@ static enum update_return updatePath(const char *utf8path) { struct directory *directory; struct directory *parentDirectory; - Song *song; + struct mpd_song *song; time_t mtime; enum update_return ret = UPDATE_RETURN_NOUPDATE; char path_max_tmp[MPD_PATH_MAX]; -- cgit v1.2.3 From 0211656d2d33b343181412938d78263a06b62587 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Wed, 8 Oct 2008 10:49:26 +0200 Subject: CPP include cleanup Include only headers which are really used. [ew: this is totally different from Max's branch] --- src/inputPlugin.c | 1 + src/inputPlugin.h | 2 ++ src/log.h | 2 -- src/song.h | 2 -- 4 files changed, 3 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/inputPlugin.c b/src/inputPlugin.c index 1ab118ceb..2bb05c018 100644 --- a/src/inputPlugin.c +++ b/src/inputPlugin.c @@ -17,6 +17,7 @@ */ #include "inputPlugin.h" +#include "list.h" static List *inputPlugin_list; diff --git a/src/inputPlugin.h b/src/inputPlugin.h index 0fd39ea9f..4338ce471 100644 --- a/src/inputPlugin.h +++ b/src/inputPlugin.h @@ -23,6 +23,8 @@ #include "outputBuffer.h" #include "metadata_pipe.h" #include "decode.h" +#include "tag.h" +#include "tag_id3.h" /* valid values for streamTypes in the InputPlugin struct: */ #define INPUT_PLUGIN_STREAM_FILE 0x01 diff --git a/src/log.h b/src/log.h index 4026df282..734c4756c 100644 --- a/src/log.h +++ b/src/log.h @@ -19,9 +19,7 @@ #ifndef LOG_H #define LOG_H -#include "../config.h" #include "gcc.h" -#include "os_compat.h" #define LOG_LEVEL_LOW 0 #define LOG_LEVEL_SECURE 1 diff --git a/src/song.h b/src/song.h index eaccf7080..88adde0f0 100644 --- a/src/song.h +++ b/src/song.h @@ -22,8 +22,6 @@ #include "../config.h" #include "os_compat.h" #include "tag.h" -#include "list.h" -#include "gcc.h" #define SONG_KEY "key: " #define SONG_MTIME "mtime: " -- cgit v1.2.3 From 5f15ba96cf5fa641d34d4e98ae8e0972fa6fef0c Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Wed, 8 Oct 2008 11:05:02 +0200 Subject: playlist: simplified setPlaylistRandomStatus() Check the old status before assigning. This saves a temporary variable. --- src/playlist.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'src') diff --git a/src/playlist.c b/src/playlist.c index ea9f5719c..02800c2ba 100644 --- a/src/playlist.c +++ b/src/playlist.c @@ -1146,11 +1146,7 @@ static void randomizeOrder(int start, int end) void setPlaylistRandomStatus(int status) { - int statusWas = playlist.random; - - playlist.random = status; - - if (status != statusWas) { + if (status != playlist.random) { if (playlist.random) randomizeOrder(0, playlist.length - 1); else -- cgit v1.2.3 From d24e17ebdd5eeb16c87b897a9ecb52a5704a52b3 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Wed, 8 Oct 2008 11:05:25 +0200 Subject: song: replaced all song constructors Provide separate constructors for creating a remote song, a local song, and one for loading data from a song file. This way, we can add more assertions. --- src/playlist.c | 4 ++-- src/song.c | 52 ++++++++++++++++++++++++++++++---------------------- src/song.h | 15 +++++++++++++-- src/update.c | 2 +- 4 files changed, 46 insertions(+), 27 deletions(-) (limited to 'src') diff --git a/src/playlist.c b/src/playlist.c index 02800c2ba..22df8be5d 100644 --- a/src/playlist.c +++ b/src/playlist.c @@ -577,7 +577,7 @@ enum playlist_result addToPlaylist(const char *url, int *added_id) if ((song = getSongFromDB(url))) { } else if (!(isValidRemoteUtf8Url(url) && - (song = newSong(url, NULL)))) { + (song = song_remote_new(url)))) { return PLAYLIST_RESULT_NO_SUCH_SONG; } @@ -596,7 +596,7 @@ int addToStoredPlaylist(const char *url, const char *utf8file) if (!isValidRemoteUtf8Url(url)) return ACK_ERROR_NO_EXIST; - if ((song = newSong(url, NULL))) { + if ((song = song_remote_new(url))) { int ret = appendSongToStoredPlaylistByPath(utf8file, song); freeJustSong(song); return ret; diff --git a/src/song.c b/src/song.c index be84bfa4b..cf9994086 100644 --- a/src/song.c +++ b/src/song.c @@ -46,34 +46,41 @@ static struct mpd_song * song_alloc(const char *url, struct directory *parent) return song; } -struct mpd_song *newSong(const char *url, struct directory *parentDir) +struct mpd_song * song_remote_new(const char *url) +{ + return song_alloc(url, NULL); +} + +struct mpd_song * song_file_new(const char *path, struct directory *parent) +{ + assert(parent != NULL); + + return song_alloc(path, parent); +} + +struct mpd_song * song_file_load(const char *path, struct directory *parent) { struct mpd_song *song; - assert(*url); + unsigned int next = 0; + InputPlugin *plugin; + char path_max_tmp[MPD_PATH_MAX]; + char *abs_path; - if (strchr(url, '\n')) { - DEBUG("newSong: '%s' is not a valid uri\n", url); + if (strchr(path, '\n')) { + DEBUG("song_file_load: '%s' is not a valid uri\n", path); return NULL; } - song = song_alloc(url, parentDir); - - if (song_is_file(song)) { - InputPlugin *plugin; - unsigned int next = 0; - char path_max_tmp[MPD_PATH_MAX]; - char *abs_path = rmp2amp_r(path_max_tmp, - get_song_url(path_max_tmp, song)); + song = song_file_new(path, parent); + abs_path = rmp2amp_r(path_max_tmp, get_song_url(path_max_tmp, song)); - while (!song->tag && (plugin = isMusic(abs_path, - &(song->mtime), - next++))) { - song->tag = plugin->tagDupFunc(abs_path); - } - if (!song->tag || song->tag->time < 0) { - freeJustSong(song); - song = NULL; - } + while (!song->tag && + (plugin = isMusic(abs_path, &song->mtime, next++))) { + song->tag = plugin->tagDupFunc(abs_path); + } + if (!song->tag || song->tag->time < 0) { + freeJustSong(song); + return NULL; } return song; @@ -172,7 +179,8 @@ void readSongInfoIntoList(FILE * fp, struct directory * parentDir) if (!prefixcmp(buffer, SONG_KEY)) { if (song) insertSongIntoList(sv, song); - song = song_alloc(buffer + strlen(SONG_KEY), parentDir); + song = song_file_new(buffer + strlen(SONG_KEY), + parentDir); } else if (*buffer == 0) { /* ignore empty lines (starting with '\0') */ } else if (song == NULL) { diff --git a/src/song.h b/src/song.h index 88adde0f0..0d2f976ac 100644 --- a/src/song.h +++ b/src/song.h @@ -38,10 +38,21 @@ struct mpd_song { char url[sizeof(size_t)]; }; -struct mpd_song *newSong(const char *url, struct directory *parentDir); - void freeJustSong(struct mpd_song *); +/** allocate a new song with a remote URL */ +struct mpd_song * song_remote_new(const char *url); + +/** allocate a new song with a local file name */ +struct mpd_song * song_file_new(const char *path, struct directory *parent); + +/** + * allocate a new song structure with a local file name and attempt to + * load its metadata. If all decoder plugin fail to read its meta + * data, NULL is returned. + */ +struct mpd_song * song_file_load(const char *path, struct directory *parent); + ssize_t song_print_info(struct mpd_song * song, int fd); /* like song_print_info, but casts data into an fd first */ diff --git a/src/update.c b/src/update.c index 674ad0519..c40f25694 100644 --- a/src/update.c +++ b/src/update.c @@ -195,7 +195,7 @@ addToDirectory(struct directory *directory, const char *name) struct mpd_song *song; const char *shortname = mpd_basename(name); - if (!(song = newSong(shortname, directory))) + if (!(song = song_file_load(shortname, directory))) return -1; songvec_add(&directory->songs, song); LOG("added %s\n", name); -- cgit v1.2.3 From e6f87010949c1d659b27c5db5707e23230d3eaf0 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Wed, 8 Oct 2008 11:05:34 +0200 Subject: song: removed CamelCase CamelCase is ugly... rename all functions. --- src/directory.c | 2 +- src/locate.c | 4 ++-- src/playlist.c | 18 +++++++++--------- src/song.c | 35 +++++++++++++++++------------------ src/song.h | 12 ++++++------ src/storedPlaylist.c | 4 ++-- src/update.c | 14 +++++++------- 7 files changed, 44 insertions(+), 45 deletions(-) (limited to 'src') diff --git a/src/directory.c b/src/directory.c index 93bde7de9..f76dd9c95 100644 --- a/src/directory.c +++ b/src/directory.c @@ -536,7 +536,7 @@ struct mpd_song *getSongFromDB(const char *file) goto out; if (!(song = songvec_find(&directory->songs, shortname))) goto out; - assert(song->parentDir == directory); + assert(song->parent == directory); out: free(duplicated); diff --git a/src/locate.c b/src/locate.c index dfe1e2236..96fa4ee58 100644 --- a/src/locate.c +++ b/src/locate.c @@ -132,7 +132,7 @@ static int strstrSearchTag(struct mpd_song * song, if (type == LOCATE_TAG_FILE_TYPE || type == LOCATE_TAG_ANY_TYPE) { char path_max_tmp[MPD_PATH_MAX]; - string_toupper(get_song_url(path_max_tmp, song)); + string_toupper(song_get_url(song, path_max_tmp)); if (strstr(path_max_tmp, str)) ret = 1; if (ret == 1 || type == LOCATE_TAG_FILE_TYPE) @@ -190,7 +190,7 @@ tagItemFoundAndMatches(struct mpd_song * song, enum tag_type type, char *str) if (type == LOCATE_TAG_FILE_TYPE || type == LOCATE_TAG_ANY_TYPE) { char path_max_tmp[MPD_PATH_MAX]; - if (0 == strcmp(str, get_song_url(path_max_tmp, song))) + if (0 == strcmp(str, song_get_url(song, path_max_tmp))) return 1; if (type == LOCATE_TAG_FILE_TYPE) return 0; diff --git a/src/playlist.c b/src/playlist.c index 22df8be5d..24f74b02d 100644 --- a/src/playlist.c +++ b/src/playlist.c @@ -189,7 +189,7 @@ void finishPlaylist(void) for (i = playlist.length; --i >= 0; ) { if (!song_is_file(playlist.songs[i])) - freeJustSong(playlist.songs[i]); + song_free(playlist.songs[i]); } playlist.length = 0; @@ -214,7 +214,7 @@ void clearPlaylist(void) for (i = playlist.length; --i >= 0 ; ) { if (!song_is_file(playlist.songs[i])) - freeJustSong(playlist.songs[i]); + song_free(playlist.songs[i]); playlist.idToPosition[playlist.positionToId[i]] = -1; playlist.songs[i] = NULL; } @@ -236,7 +236,7 @@ void showPlaylist(int fd) for (i = 0; i < playlist.length; i++) fdprintf(fd, "%i:%s\n", i, - get_song_url(path_max_tmp, playlist.songs[i])); + song_get_url(playlist.songs[i], path_max_tmp)); } void savePlaylistState(int fd) @@ -543,7 +543,7 @@ char *playlist_queued_url(char utf8url[MPD_PATH_MAX]) pthread_mutex_lock(&queue_lock); song = song_at(playlist.queued); - return song ? get_song_url(utf8url, song) : NULL; + return song ? song_get_url(song, utf8url) : NULL; } static void queue_song_locked(int order_num) @@ -598,7 +598,7 @@ int addToStoredPlaylist(const char *url, const char *utf8file) if ((song = song_remote_new(url))) { int ret = appendSongToStoredPlaylistByPath(utf8file, song); - freeJustSong(song); + song_free(song); return ret; } @@ -741,7 +741,7 @@ enum playlist_result deleteFromPlaylist(int song) } if (!song_is_file(playlist.songs[song])) - freeJustSong(playlist.songs[song]); + song_free(playlist.songs[song]); playlist.idToPosition[playlist.positionToId[song]] = -1; @@ -842,7 +842,7 @@ static void play_order_num(int order_num, float seek_time) assert(song_at(order_num)); DEBUG("playlist: play %i:\"%s\"\n", order_num, - get_song_url(path, song_at(order_num))); + song_get_url(song_at(order_num), path)); dc_trigger_action(DC_ACTION_STOP, 0); queue_song_locked(order_num); @@ -1259,7 +1259,7 @@ enum playlist_result savePlaylist(const char *utf8file) for (i = 0; i < playlist.length; i++) { char tmp[MPD_PATH_MAX]; - get_song_url(path_max_tmp, playlist.songs[i]); + song_get_url(playlist.songs[i], path_max_tmp); utf8_to_fs_charset(tmp, path_max_tmp); if (playlist_saveAbsolutePaths && @@ -1326,7 +1326,7 @@ enum playlist_result seekSongInPlaylist(int song, float seek_time) */ } - DEBUG("playlist: seek %i:\"%s\"\n", i, get_song_url(path, song_at(i))); + DEBUG("playlist: seek %i:\"%s\"\n", i, song_get_url(song_at(i), path)); play_order_num(i, seek_time); return PLAYLIST_RESULT_SUCCESS; } diff --git a/src/song.c b/src/song.c index cf9994086..5803d4f97 100644 --- a/src/song.c +++ b/src/song.c @@ -41,7 +41,7 @@ static struct mpd_song * song_alloc(const char *url, struct directory *parent) song->tag = NULL; memcpy(song->url, url, urllen + 1); - song->parentDir = parent; + song->parent = parent; return song; } @@ -72,21 +72,21 @@ struct mpd_song * song_file_load(const char *path, struct directory *parent) } song = song_file_new(path, parent); - abs_path = rmp2amp_r(path_max_tmp, get_song_url(path_max_tmp, song)); + abs_path = rmp2amp_r(path_max_tmp, song_get_url(song, path_max_tmp)); while (!song->tag && (plugin = isMusic(abs_path, &song->mtime, next++))) { song->tag = plugin->tagDupFunc(abs_path); } if (!song->tag || song->tag->time < 0) { - freeJustSong(song); + song_free(song); return NULL; } return song; } -void freeJustSong(struct mpd_song * song) +void song_free(struct mpd_song * song) { if (song->tag) tag_free(song->tag); @@ -95,9 +95,9 @@ void freeJustSong(struct mpd_song * song) ssize_t song_print_url(struct mpd_song *song, int fd) { - if (song->parentDir && song->parentDir->path) + if (song->parent && song->parent->path) return fdprintf(fd, "%s%s/%s\n", SONG_FILE, - getDirectoryPath(song->parentDir), song->url); + getDirectoryPath(song->parent), song->url); return fdprintf(fd, "%s%s\n", SONG_FILE, song->url); } @@ -146,10 +146,10 @@ static void insertSongIntoList(struct songvec *sv, struct mpd_song *newsong) if (old_tag) tag_free(old_tag); } - /* prevent tag_free in freeJustSong */ + /* prevent tag_free in song_free */ newsong->tag = NULL; } - freeJustSong(newsong); + song_free(newsong); } } @@ -167,20 +167,19 @@ static int matchesAnMpdTagItemKey(char *buffer, int *itemType) return 0; } -void readSongInfoIntoList(FILE * fp, struct directory * parentDir) +void readSongInfoIntoList(FILE * fp, struct directory * parent) { char buffer[MPD_PATH_MAX + 1024]; int bufferSize = MPD_PATH_MAX + 1024; struct mpd_song *song = NULL; - struct songvec *sv = &parentDir->songs; + struct songvec *sv = &parent->songs; int itemType; while (myFgets(buffer, bufferSize, fp) && 0 != strcmp(SONG_END, buffer)) { if (!prefixcmp(buffer, SONG_KEY)) { if (song) insertSongIntoList(sv, song); - song = song_file_new(buffer + strlen(SONG_KEY), - parentDir); + song = song_file_new(buffer + strlen(SONG_KEY), parent); } else if (*buffer == 0) { /* ignore empty lines (starting with '\0') */ } else if (song == NULL) { @@ -215,7 +214,7 @@ void readSongInfoIntoList(FILE * fp, struct directory * parentDir) insertSongIntoList(sv, song); } -int updateSongInfo(struct mpd_song * song) +int song_file_update(struct mpd_song * song) { if (song_is_file(song)) { InputPlugin *plugin; @@ -225,7 +224,7 @@ int updateSongInfo(struct mpd_song * song) struct mpd_tag *old_tag = song->tag; struct mpd_tag *new_tag = NULL; - utf8_to_fs_charset(abs_path, get_song_url(path_max_tmp, song)); + utf8_to_fs_charset(abs_path, song_get_url(song, path_max_tmp)); rmp2amp_r(abs_path, abs_path); while ((plugin = isMusic(abs_path, &song->mtime, next++))) { @@ -246,18 +245,18 @@ int updateSongInfo(struct mpd_song * song) return 0; } -char *get_song_url(char *path_max_tmp, struct mpd_song *song) +char *song_get_url(struct mpd_song *song, char *path_max_tmp) { if (!song) return NULL; assert(*song->url); - if (!song->parentDir || !song->parentDir->path) + if (!song->parent || !song->parent->path) strcpy(path_max_tmp, song->url); else pfx_dir(path_max_tmp, song->url, strlen(song->url), - getDirectoryPath(song->parentDir), - strlen(getDirectoryPath(song->parentDir))); + getDirectoryPath(song->parent), + strlen(getDirectoryPath(song->parent))); return path_max_tmp; } diff --git a/src/song.h b/src/song.h index 0d2f976ac..338bcf6c1 100644 --- a/src/song.h +++ b/src/song.h @@ -33,12 +33,12 @@ struct mpd_song { struct mpd_tag *tag; - struct directory *parentDir; + struct directory *parent; time_t mtime; char url[sizeof(size_t)]; }; -void freeJustSong(struct mpd_song *); +void song_free(struct mpd_song *); /** allocate a new song with a remote URL */ struct mpd_song * song_remote_new(const char *url); @@ -60,7 +60,7 @@ int song_print_info_x(struct mpd_song * song, void *data); void readSongInfoIntoList(FILE * fp, struct directory *parent); -int updateSongInfo(struct mpd_song * song); +int song_file_update(struct mpd_song * song); ssize_t song_print_url(struct mpd_song * song, int fd); @@ -68,16 +68,16 @@ ssize_t song_print_url(struct mpd_song * song, int fd); int song_print_url_x(struct mpd_song * song, void *data); /* - * get_song_url - Returns a path of a song in UTF8-encoded form + * song_get_url - Returns a path of a song in UTF8-encoded form * path_max_tmp is the argument that the URL is written to, this * buffer is assumed to be MPD_PATH_MAX or greater (including * terminating '\0'). */ -char *get_song_url(char *path_max_tmp, struct mpd_song * song); +char *song_get_url(struct mpd_song * song, char *path_max_tmp); static inline int song_is_file(const struct mpd_song *song) { - return !!song->parentDir; + return !!song->parent; } #endif diff --git a/src/storedPlaylist.c b/src/storedPlaylist.c index 482e9e241..b74ef1404 100644 --- a/src/storedPlaylist.c +++ b/src/storedPlaylist.c @@ -119,7 +119,7 @@ List *loadStoredPlaylist(const char *utf8path) memmove(s, s + musicDir_len + 1, strlen(s + musicDir_len + 1) + 1); if ((song = getSongFromDB(s))) { - get_song_url(path_max_tmp, song); + song_get_url(song, path_max_tmp); insertInListWithoutKey(list, xstrdup(path_max_tmp)); } else if (isValidRemoteUtf8Url(s)) insertInListWithoutKey(list, xstrdup(s)); @@ -295,7 +295,7 @@ appendSongToStoredPlaylistByPath(const char *utf8path, struct mpd_song *song) return PLAYLIST_RESULT_TOO_LARGE; } - s = utf8_to_fs_charset(path_max_tmp2, get_song_url(path_max_tmp, song)); + s = utf8_to_fs_charset(path_max_tmp2, song_get_url(song, path_max_tmp)); if (playlist_saveAbsolutePaths && song_is_file(song)) s = rmp2amp_r(path_max_tmp, s); diff --git a/src/update.c b/src/update.c index c40f25694..e7a49e56e 100644 --- a/src/update.c +++ b/src/update.c @@ -75,7 +75,7 @@ static void delete_song(struct directory *dir, struct mpd_song *del) cond_leave(&delete_cond); /* finally, all possible references gone, free it */ - freeJustSong(del); + song_free(del); } struct delete_data { @@ -89,7 +89,7 @@ static int delete_song_if_removed(struct mpd_song *song, void *_data) { struct delete_data *data = _data; - data->tmp = get_song_url(data->tmp, song); + data->tmp = song_get_url(song, data->tmp); assert(data->tmp); if (!isFile(data->tmp, NULL)) { @@ -226,7 +226,7 @@ updateInDirectory(struct directory *directory, const char *name) return UPDATE_RETURN_UPDATED; } else if (st.st_mtime != song->mtime) { LOG("updating %s\n", name); - if (updateSongInfo(song) < 0) + if (song_file_update(song) < 0) delete_song(directory, song); return UPDATE_RETURN_UPDATED; } @@ -393,7 +393,7 @@ static enum update_return updatePath(const char *utf8path) /* don't return, path maybe a song now */ } } else if ((song = getSongFromDB(utf8path))) { - parentDirectory = song->parentDir; + parentDirectory = song->parent; if (!parentDirectory->stat && statDirectory(parentDirectory) < 0) { return UPDATE_RETURN_NOUPDATE; @@ -402,10 +402,10 @@ static enum update_return updatePath(const char *utf8path) else if (!inodeFoundInParent(parentDirectory->parent, parentDirectory->inode, parentDirectory->device) && - isMusic(get_song_url(path_max_tmp, song), &mtime, 0)) { + isMusic(song_get_url(song, path_max_tmp), &mtime, 0)) { if (song->mtime == mtime) return UPDATE_RETURN_NOUPDATE; - else if (updateSongInfo(song) == 0) + else if (song_file_update(song) == 0) return UPDATE_RETURN_UPDATED; else { delete_song(parentDirectory, song); @@ -503,7 +503,7 @@ void reap_update_task(void) cond_enter(&delete_cond); if (delete) { char tmp[MPD_PATH_MAX]; - LOG("removing: %s\n", get_song_url(tmp, delete)); + LOG("removing: %s\n", song_get_url(delete, tmp)); deleteASongFromPlaylist(delete); delete = NULL; cond_signal(&delete_cond); -- cgit v1.2.3 From e4ca5f5b5c051f98b90070303a83f53b68851034 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Wed, 8 Oct 2008 11:05:38 +0200 Subject: song: don't check song_is_file() in song_file_update() This function was never used on remote songs. Replace the runtime check with an assertion. --- src/song.c | 48 ++++++++++++++++++++++++------------------------ 1 file changed, 24 insertions(+), 24 deletions(-) (limited to 'src') diff --git a/src/song.c b/src/song.c index 5803d4f97..f76c1e4d9 100644 --- a/src/song.c +++ b/src/song.c @@ -216,31 +216,31 @@ void readSongInfoIntoList(FILE * fp, struct directory * parent) int song_file_update(struct mpd_song * song) { - if (song_is_file(song)) { - InputPlugin *plugin; - unsigned int next = 0; - char path_max_tmp[MPD_PATH_MAX]; - char abs_path[MPD_PATH_MAX]; - struct mpd_tag *old_tag = song->tag; - struct mpd_tag *new_tag = NULL; - - utf8_to_fs_charset(abs_path, song_get_url(song, path_max_tmp)); - rmp2amp_r(abs_path, abs_path); - - while ((plugin = isMusic(abs_path, &song->mtime, next++))) { - if ((new_tag = plugin->tagDupFunc(abs_path))) - break; - } - if (new_tag && tag_equal(new_tag, old_tag)) { - tag_free(new_tag); - } else { - song->tag = new_tag; - if (old_tag) - tag_free(old_tag); - } - if (!song->tag || song->tag->time < 0) - return -1; + InputPlugin *plugin; + unsigned int next = 0; + char path_max_tmp[MPD_PATH_MAX]; + char abs_path[MPD_PATH_MAX]; + struct mpd_tag *old_tag = song->tag; + struct mpd_tag *new_tag = NULL; + + assert(song_is_file(song)); + + utf8_to_fs_charset(abs_path, song_get_url(song, path_max_tmp)); + rmp2amp_r(abs_path, abs_path); + + while ((plugin = isMusic(abs_path, &song->mtime, next++))) { + if ((new_tag = plugin->tagDupFunc(abs_path))) + break; + } + if (new_tag && tag_equal(new_tag, old_tag)) { + tag_free(new_tag); + } else { + song->tag = new_tag; + if (old_tag) + tag_free(old_tag); } + if (!song->tag || song->tag->time < 0) + return -1; return 0; } -- cgit v1.2.3 From aae48c97fb3d2b0140daa8e49459a7afe3488683 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Wed, 8 Oct 2008 11:06:26 +0200 Subject: song: song_file_update() returns boolean Instead of returning 0 or -1, return true on success and false on failure. This seems more natural, and when the C library was designed, there was no "bool" data type. [ew: changing to bool semantics but sticking with integer type since bool is C99 and I don't require a C99 compiler, and I don't feel like writing compatibility wrappers to support it. _Bool is usually (always?) a signed int anyways. ] --- src/song.c | 4 +--- src/update.c | 4 ++-- 2 files changed, 3 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/song.c b/src/song.c index f76c1e4d9..09a92223c 100644 --- a/src/song.c +++ b/src/song.c @@ -239,10 +239,8 @@ int song_file_update(struct mpd_song * song) if (old_tag) tag_free(old_tag); } - if (!song->tag || song->tag->time < 0) - return -1; - return 0; + return (song->tag && song->tag->time >= 0); } char *song_get_url(struct mpd_song *song, char *path_max_tmp) diff --git a/src/update.c b/src/update.c index e7a49e56e..594e7f48c 100644 --- a/src/update.c +++ b/src/update.c @@ -226,7 +226,7 @@ updateInDirectory(struct directory *directory, const char *name) return UPDATE_RETURN_UPDATED; } else if (st.st_mtime != song->mtime) { LOG("updating %s\n", name); - if (song_file_update(song) < 0) + if (!song_file_update(song)) delete_song(directory, song); return UPDATE_RETURN_UPDATED; } @@ -405,7 +405,7 @@ static enum update_return updatePath(const char *utf8path) isMusic(song_get_url(song, path_max_tmp), &mtime, 0)) { if (song->mtime == mtime) return UPDATE_RETURN_NOUPDATE; - else if (song_file_update(song) == 0) + else if (song_file_update(song)) return UPDATE_RETURN_UPDATED; else { delete_song(parentDirectory, song); -- cgit v1.2.3 From 81bdc3f625ecce1eca87009caf89e98abd405f51 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Wed, 8 Oct 2008 11:06:27 +0200 Subject: song: use song_file_update() in song_file_load() Eliminate duplicated code. --- src/song.c | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) (limited to 'src') diff --git a/src/song.c b/src/song.c index 09a92223c..18f2bca21 100644 --- a/src/song.c +++ b/src/song.c @@ -61,10 +61,6 @@ struct mpd_song * song_file_new(const char *path, struct directory *parent) struct mpd_song * song_file_load(const char *path, struct directory *parent) { struct mpd_song *song; - unsigned int next = 0; - InputPlugin *plugin; - char path_max_tmp[MPD_PATH_MAX]; - char *abs_path; if (strchr(path, '\n')) { DEBUG("song_file_load: '%s' is not a valid uri\n", path); @@ -72,13 +68,7 @@ struct mpd_song * song_file_load(const char *path, struct directory *parent) } song = song_file_new(path, parent); - abs_path = rmp2amp_r(path_max_tmp, song_get_url(song, path_max_tmp)); - - while (!song->tag && - (plugin = isMusic(abs_path, &song->mtime, next++))) { - song->tag = plugin->tagDupFunc(abs_path); - } - if (!song->tag || song->tag->time < 0) { + if (!song_file_update(song)) { song_free(song); return NULL; } -- cgit v1.2.3 From f8e2879c37b9ee5953e71456ba777363f7dc30fc Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Wed, 8 Oct 2008 11:06:44 +0200 Subject: directory: converted isRootDirectory() to an inline function The function isRootDirectory() is tiny and can be converted to an inline function. Don't allow name==NULL. --- src/directory.c | 10 +++++----- src/directory.h | 6 +++++- 2 files changed, 10 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/directory.c b/src/directory.c index f76dd9c95..25a6bcec8 100644 --- a/src/directory.c +++ b/src/directory.c @@ -105,11 +105,6 @@ struct directory * directory_get_root(void) return music_root; } -int isRootDirectory(const char *name) -{ - return (!name || name[0] == '\0' || !strcmp(name, "/")); -} - static struct directory * getSubDirectory(struct directory * directory, const char *name) { @@ -118,6 +113,8 @@ getSubDirectory(struct directory * directory, const char *name) char *duplicated; char *locate; + assert(name != NULL); + if (isRootDirectory(name)) return directory; @@ -143,6 +140,9 @@ getSubDirectory(struct directory * directory, const char *name) struct directory * getDirectory(const char *name) { + if (name == NULL) + return music_root; + return getSubDirectory(music_root, name); } diff --git a/src/directory.h b/src/directory.h index 72de511e7..127da678c 100644 --- a/src/directory.h +++ b/src/directory.h @@ -41,7 +41,11 @@ void directory_init(void); void directory_finish(void); -int isRootDirectory(const char *name); +static inline int isRootDirectory(const char *name) +{ + /* TODO: verify and remove !name check */ + return (!name || *name == '\0' || !strcmp(name, "/")); +} struct directory * directory_get_root(void); -- cgit v1.2.3 From 729523ec80f35a683c982054628cd47d2161d3d4 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Wed, 8 Oct 2008 11:07:35 +0200 Subject: directory: moved code to database.c Taming the directory.c monster, part II: move the database management stuff to database. directory.c should only contain code which works on directory objects. --- src/Makefile.am | 2 + src/command.c | 1 + src/database.c | 321 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/database.h | 50 ++++++++ src/dbUtils.c | 2 +- src/directory.c | 324 ++------------------------------------------------- src/directory.h | 36 +++--- src/main.c | 2 +- src/playlist.c | 2 +- src/sig_handlers.c | 2 +- src/songvec.c | 3 +- src/songvec.h | 2 +- src/stats.c | 2 +- src/storedPlaylist.c | 2 +- src/update.c | 2 +- 15 files changed, 418 insertions(+), 335 deletions(-) create mode 100644 src/database.c create mode 100644 src/database.h (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index 0925f16b2..e4cc17c3f 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -39,6 +39,7 @@ mpd_headers = \ command.h \ condition.h \ conf.h \ + database.h \ dbUtils.h \ decode.h \ directory.h \ @@ -111,6 +112,7 @@ mpd_SOURCES = \ command.c \ condition.c \ conf.c \ + database.c \ dbUtils.c \ decode.c \ directory.c \ diff --git a/src/command.c b/src/command.c index 4fe1f7410..4923ee5d5 100644 --- a/src/command.c +++ b/src/command.c @@ -19,6 +19,7 @@ #include "command.h" #include "playlist.h" #include "ls.h" +#include "database.h" #include "directory.h" #include "update.h" #include "volume.h" diff --git a/src/database.c b/src/database.c new file mode 100644 index 000000000..b4c73db69 --- /dev/null +++ b/src/database.c @@ -0,0 +1,321 @@ +/* the Music Player Daemon (MPD) + * Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com) + * Copyright (C) 2008 Max Kellermann + * This project's homepage is: http://www.musicpd.org + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "database.h" +#include "directory.h" +#include "song.h" +#include "conf.h" +#include "log.h" +#include "ls.h" +#include "path.h" +#include "stats.h" +#include "utils.h" +#include "dbUtils.h" +#include "update.h" +#include "os_compat.h" +#include "myfprintf.h" + +static struct directory *music_root; + +static time_t directory_dbModTime; + +void directory_init(void) +{ + music_root = newDirectory(NULL, NULL); + updateDirectory(music_root); + stats.numberOfSongs = countSongsIn(NULL); + stats.dbPlayTime = sumSongTimesIn(NULL); +} + +void directory_finish(void) +{ + freeDirectory(music_root); +} + +struct directory * directory_get_root(void) +{ + assert(music_root != NULL); + + return music_root; +} + +struct directory * getDirectory(const char *name) +{ + if (name == NULL) + return music_root; + + return getSubDirectory(music_root, name); +} + +struct mpd_song *getSongFromDB(const char *file) +{ + struct mpd_song *song = NULL; + struct directory *directory; + char *dir = NULL; + char *duplicated = xstrdup(file); + char *shortname = strrchr(duplicated, '/'); + + DEBUG("get song: %s\n", file); + + if (!shortname) { + shortname = duplicated; + } else { + *shortname = '\0'; + ++shortname; + dir = duplicated; + } + + if (!(directory = getDirectory(dir))) + goto out; + if (!(song = songvec_find(&directory->songs, shortname))) + goto out; + assert(song->parent == directory); + +out: + free(duplicated); + return song; +} + +int traverseAllIn(const char *name, + int (*forEachSong) (struct mpd_song *, void *), + int (*forEachDir) (struct directory *, void *), void *data) +{ + struct directory *directory; + + if ((directory = getDirectory(name)) == NULL) { + struct mpd_song *song; + if ((song = getSongFromDB(name)) && forEachSong) { + return forEachSong(song, data); + } + return -1; + } + + return traverseAllInSubDirectory(directory, forEachSong, forEachDir, + data); +} + +int printDirectoryInfo(int fd, const char *name) +{ + struct directory *directory; + + if ((directory = getDirectory(name)) == NULL) + return -1; + return directory_print(fd, directory); +} + +static char *getDbFile(void) +{ + ConfigParam *param = parseConfigFilePath(CONF_DB_FILE, 1); + + assert(param); + assert(param->value); + + return param->value; +} + +int checkDirectoryDB(void) +{ + struct stat st; + char *dbFile = getDbFile(); + + /* Check if the file exists */ + if (access(dbFile, F_OK)) { + /* If the file doesn't exist, we can't check if we can write + * it, so we are going to try to get the directory path, and + * see if we can write a file in that */ + char dirPath[MPD_PATH_MAX]; + parent_path(dirPath, dbFile); + if (*dirPath == '\0') + strcpy(dirPath, "/"); + + /* Check that the parent part of the path is a directory */ + if (stat(dirPath, &st) < 0) { + ERROR("Couldn't stat parent directory of db file " + "\"%s\": %s\n", dbFile, strerror(errno)); + return -1; + } + + if (!S_ISDIR(st.st_mode)) { + ERROR("Couldn't create db file \"%s\" because the " + "parent path is not a directory\n", dbFile); + return -1; + } + + /* Check if we can write to the directory */ + if (access(dirPath, R_OK | W_OK)) { + ERROR("Can't create db file in \"%s\": %s\n", dirPath, + strerror(errno)); + return -1; + } + + return 0; + } + + /* Path exists, now check if it's a regular file */ + if (stat(dbFile, &st) < 0) { + ERROR("Couldn't stat db file \"%s\": %s\n", dbFile, + strerror(errno)); + return -1; + } + + if (!S_ISREG(st.st_mode)) { + ERROR("db file \"%s\" is not a regular file\n", dbFile); + return -1; + } + + /* And check that we can write to it */ + if (access(dbFile, R_OK | W_OK)) { + ERROR("Can't open db file \"%s\" for reading/writing: %s\n", + dbFile, strerror(errno)); + return -1; + } + + return 0; +} + +int writeDirectoryDB(void) +{ + int fd; + char *dbFile = getDbFile(); + struct stat st; + + DEBUG("removing empty directories from DB\n"); + deleteEmptyDirectoriesInDirectory(music_root); + + DEBUG("sorting DB\n"); + + sortDirectory(music_root); + + DEBUG("writing DB\n"); + + fd = open(dbFile, O_WRONLY|O_TRUNC|O_CREAT, 0666); + if (fd < 0) { + ERROR("unable to write to db file \"%s\": %s\n", + dbFile, strerror(errno)); + return -1; + } + + /* + * TODO: block signals when writing the db so we don't get a corrupted + * db (or unexpected failures). fdprintf() needs better error handling + */ + fdprintf(fd, + DIRECTORY_INFO_BEGIN "\n" + DIRECTORY_MPD_VERSION VERSION "\n" + DIRECTORY_FS_CHARSET "%s\n" + DIRECTORY_INFO_END "\n", getFsCharset()); + + if (writeDirectoryInfo(fd, music_root) < 0) { + ERROR("Failed to write to database file: %s\n", + strerror(errno)); + xclose(fd); + return -1; + } + xclose(fd); + + if (stat(dbFile, &st) == 0) + directory_dbModTime = st.st_mtime; + + return 0; +} + +int readDirectoryDB(void) +{ + FILE *fp = NULL; + char *dbFile = getDbFile(); + struct stat st; + + if (!music_root) + music_root = newDirectory(NULL, NULL); + while (!(fp = fopen(dbFile, "r")) && errno == EINTR) ; + if (fp == NULL) { + ERROR("unable to open db file \"%s\": %s\n", + dbFile, strerror(errno)); + return -1; + } + + /* get initial info */ + { + char buffer[100]; + int bufferSize = 100; + int foundFsCharset = 0; + int foundVersion = 0; + + if (!myFgets(buffer, bufferSize, fp)) + FATAL("Error reading db, fgets\n"); + if (0 == strcmp(DIRECTORY_INFO_BEGIN, buffer)) { + while (myFgets(buffer, bufferSize, fp) && + 0 != strcmp(DIRECTORY_INFO_END, buffer)) { + if (!prefixcmp(buffer, DIRECTORY_MPD_VERSION)) + { + if (foundVersion) + FATAL("already found version in db\n"); + foundVersion = 1; + } else if (!prefixcmp(buffer, + DIRECTORY_FS_CHARSET)) { + char *fsCharset; + char *tempCharset; + + if (foundFsCharset) + FATAL("already found fs charset in db\n"); + + foundFsCharset = 1; + + fsCharset = &(buffer[strlen(DIRECTORY_FS_CHARSET)]); + if ((tempCharset = getConfigParamValue(CONF_FS_CHARSET)) + && strcmp(fsCharset, tempCharset)) { + WARNING("Using \"%s\" for the " + "filesystem charset " + "instead of \"%s\"\n", + fsCharset, tempCharset); + WARNING("maybe you need to " + "recreate the db?\n"); + setFsCharset(fsCharset); + } + } else { + FATAL("directory: unknown line in db info: %s\n", + buffer); + } + } + } else { + ERROR("db info not found in db file\n"); + ERROR("you should recreate the db using --create-db\n"); + while (fclose(fp) && errno == EINTR) ; + return -1; + } + } + + DEBUG("reading DB\n"); + + readDirectoryInfo(fp, music_root); + while (fclose(fp) && errno == EINTR) ; + + stats.numberOfSongs = countSongsIn(NULL); + stats.dbPlayTime = sumSongTimesIn(NULL); + + if (stat(dbFile, &st) == 0) + directory_dbModTime = st.st_mtime; + + return 0; +} + +time_t getDbModTime(void) +{ + return directory_dbModTime; +} diff --git a/src/database.h b/src/database.h new file mode 100644 index 000000000..e3ed64f0c --- /dev/null +++ b/src/database.h @@ -0,0 +1,50 @@ +/* the Music Player Daemon (MPD) + * Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com) + * Copyright (C) 2008 Max Kellermann + * This project's homepage is: http://www.musicpd.org + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef DATABASE_H +#define DATABASE_H + +#include "os_compat.h" +#include "directory.h" + +void directory_init(void); + +void directory_finish(void); + +struct directory * directory_get_root(void); + +struct directory * getDirectory(const char *name); + +struct mpd_song * getSongFromDB(const char *file); + +int traverseAllIn(const char *name, + int (*forEachSong) (struct mpd_song *, void *), + int (*forEachDir) (struct directory *, void *), void *data); + +int printDirectoryInfo(int fd, const char *name); + +int checkDirectoryDB(void); + +int writeDirectoryDB(void); + +int readDirectoryDB(void); + +time_t getDbModTime(void); + +#endif /* DATABASE_H */ diff --git a/src/dbUtils.c b/src/dbUtils.c index eb11ff19e..7d1d185a3 100644 --- a/src/dbUtils.c +++ b/src/dbUtils.c @@ -18,7 +18,7 @@ #include "dbUtils.h" -#include "directory.h" +#include "database.h" #include "myfprintf.h" #include "utils.h" #include "playlist.h" diff --git a/src/directory.c b/src/directory.c index 25a6bcec8..b38d3b52c 100644 --- a/src/directory.c +++ b/src/directory.c @@ -17,43 +17,14 @@ */ #include "directory.h" +#include "database.h" -#include "conf.h" #include "log.h" -#include "ls.h" #include "path.h" -#include "stats.h" #include "utils.h" #include "ack.h" #include "myfprintf.h" -#include "dbUtils.h" #include "dirvec.h" -#include "update.h" - -#define DIRECTORY_DIR "directory: " -#define DIRECTORY_MTIME "mtime: " /* DEPRECATED, noop-read-only */ -#define DIRECTORY_BEGIN "begin: " -#define DIRECTORY_END "end: " -#define DIRECTORY_INFO_BEGIN "info_begin" -#define DIRECTORY_INFO_END "info_end" -#define DIRECTORY_MPD_VERSION "mpd_version: " -#define DIRECTORY_FS_CHARSET "fs_charset: " - -static struct directory *music_root; - -static time_t directory_dbModTime; - -static void deleteEmptyDirectoriesInDirectory(struct directory * directory); - -static char *getDbFile(void) -{ - ConfigParam *param = parseConfigFilePath(CONF_DB_FILE, 1); - - assert(param); - assert(param->value); - - return param->value; -} struct directory * newDirectory(const char *dirname, struct directory * parent) { @@ -79,7 +50,7 @@ void freeDirectory(struct directory * directory) /*getDirectoryPath(NULL); */ } -static void deleteEmptyDirectoriesInDirectory(struct directory * directory) +void deleteEmptyDirectoriesInDirectory(struct directory * directory) { int i; struct dirvec *dv = &directory->children; @@ -93,19 +64,7 @@ static void deleteEmptyDirectoriesInDirectory(struct directory * directory) dirvec_destroy(dv); } -void directory_finish(void) -{ - freeDirectory(music_root); -} - -struct directory * directory_get_root(void) -{ - assert(music_root != NULL); - - return music_root; -} - -static struct directory * +struct directory * getSubDirectory(struct directory * directory, const char *name) { struct directory *cur = directory; @@ -138,15 +97,7 @@ getSubDirectory(struct directory * directory, const char *name) return found; } -struct directory * getDirectory(const char *name) -{ - if (name == NULL) - return music_root; - - return getSubDirectory(music_root, name); -} - -static int printDirectoryList(int fd, struct dirvec *dv) +static int printDirectoryList(int fd, const struct dirvec *dv) { size_t i; @@ -159,17 +110,13 @@ static int printDirectoryList(int fd, struct dirvec *dv) return 0; } -int printDirectoryInfo(int fd, const char *name) +int directory_print(int fd, const struct directory *directory) { - struct directory *directory; - - if ((directory = getDirectory(name)) == NULL) + if (printDirectoryList(fd, &directory->children) < 0) + return -1; + if (songvec_for_each(&directory->songs, song_print_info_x, + (void *)(size_t)fd) < 0) return -1; - - printDirectoryList(fd, &directory->children); - songvec_for_each(&directory->songs, - song_print_info_x, (void *)(size_t)fd); - return 0; } @@ -188,7 +135,7 @@ static int directory_song_write(struct mpd_song *song, void *data) } /* TODO error checking */ -static int writeDirectoryInfo(int fd, struct directory * directory) +int writeDirectoryInfo(int fd, struct directory * directory) { struct dirvec *children = &directory->children; size_t i; @@ -225,7 +172,7 @@ static int writeDirectoryInfo(int fd, struct directory * directory) return 0; } -static void readDirectoryInfo(FILE * fp, struct directory * directory) +void readDirectoryInfo(FILE * fp, struct directory * directory) { char buffer[MPD_PATH_MAX * 2]; int bufferSize = MPD_PATH_MAX * 2; @@ -275,193 +222,7 @@ void sortDirectory(struct directory * directory) sortDirectory(dv->base[i]); } -int checkDirectoryDB(void) -{ - struct stat st; - char *dbFile = getDbFile(); - - /* Check if the file exists */ - if (access(dbFile, F_OK)) { - /* If the file doesn't exist, we can't check if we can write - * it, so we are going to try to get the directory path, and - * see if we can write a file in that */ - char dirPath[MPD_PATH_MAX]; - parent_path(dirPath, dbFile); - if (*dirPath == '\0') - strcpy(dirPath, "/"); - - /* Check that the parent part of the path is a directory */ - if (stat(dirPath, &st) < 0) { - ERROR("Couldn't stat parent directory of db file " - "\"%s\": %s\n", dbFile, strerror(errno)); - return -1; - } - - if (!S_ISDIR(st.st_mode)) { - ERROR("Couldn't create db file \"%s\" because the " - "parent path is not a directory\n", dbFile); - return -1; - } - - /* Check if we can write to the directory */ - if (access(dirPath, R_OK | W_OK)) { - ERROR("Can't create db file in \"%s\": %s\n", dirPath, - strerror(errno)); - return -1; - } - - return 0; - } - - /* Path exists, now check if it's a regular file */ - if (stat(dbFile, &st) < 0) { - ERROR("Couldn't stat db file \"%s\": %s\n", dbFile, - strerror(errno)); - return -1; - } - - if (!S_ISREG(st.st_mode)) { - ERROR("db file \"%s\" is not a regular file\n", dbFile); - return -1; - } - - /* And check that we can write to it */ - if (access(dbFile, R_OK | W_OK)) { - ERROR("Can't open db file \"%s\" for reading/writing: %s\n", - dbFile, strerror(errno)); - return -1; - } - - return 0; -} - -int writeDirectoryDB(void) -{ - int fd; - char *dbFile = getDbFile(); - struct stat st; - - DEBUG("removing empty directories from DB\n"); - deleteEmptyDirectoriesInDirectory(music_root); - - DEBUG("sorting DB\n"); - - sortDirectory(music_root); - - DEBUG("writing DB\n"); - - fd = open(dbFile, O_WRONLY|O_TRUNC|O_CREAT, 0666); - if (fd < 0) { - ERROR("unable to write to db file \"%s\": %s\n", - dbFile, strerror(errno)); - return -1; - } - - /* - * TODO: block signals when writing the db so we don't get a corrupted - * db (or unexpected failures). fdprintf() needs better error handling - */ - fdprintf(fd, - DIRECTORY_INFO_BEGIN "\n" - DIRECTORY_MPD_VERSION VERSION "\n" - DIRECTORY_FS_CHARSET "%s\n" - DIRECTORY_INFO_END "\n", getFsCharset()); - - if (writeDirectoryInfo(fd, music_root) < 0) { - ERROR("Failed to write to database file: %s\n", - strerror(errno)); - xclose(fd); - return -1; - } - xclose(fd); - - if (stat(dbFile, &st) == 0) - directory_dbModTime = st.st_mtime; - - return 0; -} - -int readDirectoryDB(void) -{ - FILE *fp = NULL; - char *dbFile = getDbFile(); - struct stat st; - - if (!music_root) - music_root = newDirectory(NULL, NULL); - while (!(fp = fopen(dbFile, "r")) && errno == EINTR) ; - if (fp == NULL) { - ERROR("unable to open db file \"%s\": %s\n", - dbFile, strerror(errno)); - return -1; - } - - /* get initial info */ - { - char buffer[100]; - int bufferSize = 100; - int foundFsCharset = 0; - int foundVersion = 0; - - if (!myFgets(buffer, bufferSize, fp)) - FATAL("Error reading db, fgets\n"); - if (0 == strcmp(DIRECTORY_INFO_BEGIN, buffer)) { - while (myFgets(buffer, bufferSize, fp) && - 0 != strcmp(DIRECTORY_INFO_END, buffer)) { - if (!prefixcmp(buffer, DIRECTORY_MPD_VERSION)) - { - if (foundVersion) - FATAL("already found version in db\n"); - foundVersion = 1; - } else if (!prefixcmp(buffer, - DIRECTORY_FS_CHARSET)) { - char *fsCharset; - char *tempCharset; - - if (foundFsCharset) - FATAL("already found fs charset in db\n"); - - foundFsCharset = 1; - - fsCharset = &(buffer[strlen(DIRECTORY_FS_CHARSET)]); - if ((tempCharset = getConfigParamValue(CONF_FS_CHARSET)) - && strcmp(fsCharset, tempCharset)) { - WARNING("Using \"%s\" for the " - "filesystem charset " - "instead of \"%s\"\n", - fsCharset, tempCharset); - WARNING("maybe you need to " - "recreate the db?\n"); - setFsCharset(fsCharset); - } - } else { - FATAL("directory: unknown line in db info: %s\n", - buffer); - } - } - } else { - ERROR("db info not found in db file\n"); - ERROR("you should recreate the db using --create-db\n"); - while (fclose(fp) && errno == EINTR) ; - return -1; - } - } - - DEBUG("reading DB\n"); - - readDirectoryInfo(fp, music_root); - while (fclose(fp) && errno == EINTR) ; - - stats.numberOfSongs = countSongsIn(NULL); - stats.dbPlayTime = sumSongTimesIn(NULL); - - if (stat(dbFile, &st) == 0) - directory_dbModTime = st.st_mtime; - - return 0; -} - -static int +int traverseAllInSubDirectory(struct directory * directory, int (*forEachSong) (struct mpd_song *, void *), int (*forEachDir) (struct directory *, void *), @@ -486,64 +247,3 @@ traverseAllInSubDirectory(struct directory * directory, return err; } - -int -traverseAllIn(const char *name, - int (*forEachSong) (struct mpd_song *, void *), - int (*forEachDir) (struct directory *, void *), void *data) -{ - struct directory *directory; - - if ((directory = getDirectory(name)) == NULL) { - struct mpd_song *song; - if ((song = getSongFromDB(name)) && forEachSong) { - return forEachSong(song, data); - } - return -1; - } - - return traverseAllInSubDirectory(directory, forEachSong, forEachDir, - data); -} - -void directory_init(void) -{ - music_root = newDirectory(NULL, NULL); - updateDirectory(music_root); - stats.numberOfSongs = countSongsIn(NULL); - stats.dbPlayTime = sumSongTimesIn(NULL); -} - -struct mpd_song *getSongFromDB(const char *file) -{ - struct mpd_song *song = NULL; - struct directory *directory; - char *dir = NULL; - char *duplicated = xstrdup(file); - char *shortname = strrchr(duplicated, '/'); - - DEBUG("get song: %s\n", file); - - if (!shortname) { - shortname = duplicated; - } else { - *shortname = '\0'; - ++shortname; - dir = duplicated; - } - - if (!(directory = getDirectory(dir))) - goto out; - if (!(song = songvec_find(&directory->songs, shortname))) - goto out; - assert(song->parent == directory); - -out: - free(duplicated); - return song; -} - -time_t getDbModTime(void) -{ - return directory_dbModTime; -} diff --git a/src/directory.h b/src/directory.h index 127da678c..84913c036 100644 --- a/src/directory.h +++ b/src/directory.h @@ -22,6 +22,15 @@ #include "song.h" #include "songvec.h" +#define DIRECTORY_DIR "directory: " +#define DIRECTORY_MTIME "mtime: " /* DEPRECATED, noop-read-only */ +#define DIRECTORY_BEGIN "begin: " +#define DIRECTORY_END "end: " +#define DIRECTORY_INFO_BEGIN "info_begin" +#define DIRECTORY_INFO_END "info_end" +#define DIRECTORY_MPD_VERSION "mpd_version: " +#define DIRECTORY_FS_CHARSET "fs_charset: " + struct dirvec { struct directory **base; size_t nr; @@ -37,18 +46,12 @@ struct directory { unsigned stat; /* not needed if ino_t == dev_t == 0 is impossible */ }; -void directory_init(void); - -void directory_finish(void); - static inline int isRootDirectory(const char *name) { /* TODO: verify and remove !name check */ return (!name || *name == '\0' || !strcmp(name, "/")); } -struct directory * directory_get_root(void); - struct directory * newDirectory(const char *dirname, struct directory *parent); void freeDirectory(struct directory *directory); @@ -58,26 +61,31 @@ static inline int directory_is_empty(struct directory *directory) return directory->children.nr == 0 && directory->songs.nr == 0; } -struct directory * getDirectory(const char *name); - -void sortDirectory(struct directory * directory); - int printDirectoryInfo(int fd, const char *dirname); -int checkDirectoryDB(void); +void deleteEmptyDirectoriesInDirectory(struct directory *directory); -int writeDirectoryDB(void); +struct directory * +getSubDirectory(struct directory *directory, const char *name); -int readDirectoryDB(void); +int directory_print(int fd, const struct directory *directory); struct mpd_song *getSongFromDB(const char *file); -time_t getDbModTime(void); +int writeDirectoryInfo(int fd, struct directory *directory); + +void readDirectoryInfo(FILE *fp, struct directory *directory); + +void sortDirectory(struct directory * directory); int traverseAllIn(const char *name, int (*forEachSong) (struct mpd_song *, void *), int (*forEachDir) (struct directory *, void *), void *data); +int traverseAllInSubDirectory(struct directory *directory, + int (*forEachSong) (struct mpd_song *, void *), + int (*forEachDir) (struct directory *, void *), void *data); + #define getDirectoryPath(dir) ((dir && dir->path) ? dir->path : "") #endif diff --git a/src/main.c b/src/main.c index baf448fdd..5c6957f20 100644 --- a/src/main.c +++ b/src/main.c @@ -19,7 +19,7 @@ #include "client.h" #include "command.h" #include "playlist.h" -#include "directory.h" +#include "database.h" #include "update.h" #include "listen.h" #include "conf.h" diff --git a/src/playlist.c b/src/playlist.c index 24f74b02d..118733543 100644 --- a/src/playlist.c +++ b/src/playlist.c @@ -22,7 +22,7 @@ #include "ls.h" #include "tag.h" #include "conf.h" -#include "directory.h" +#include "database.h" #include "log.h" #include "path.h" #include "utils.h" diff --git a/src/sig_handlers.c b/src/sig_handlers.c index 854188c51..1c09eda5b 100644 --- a/src/sig_handlers.c +++ b/src/sig_handlers.c @@ -19,7 +19,7 @@ #include "sig_handlers.h" #include "playlist.h" -#include "directory.h" +#include "database.h" #include "update.h" #include "command.h" #include "signal_check.h" diff --git a/src/songvec.c b/src/songvec.c index c4f702aef..c306ab640 100644 --- a/src/songvec.c +++ b/src/songvec.c @@ -84,7 +84,8 @@ void songvec_destroy(struct songvec *sv) pthread_mutex_unlock(&nr_lock); } -int songvec_for_each(struct songvec *sv, int (*fn)(struct mpd_song *, void *), void *arg) +int songvec_for_each(const struct songvec *sv, + int (*fn)(struct mpd_song *, void *), void *arg) { size_t i; diff --git a/src/songvec.h b/src/songvec.h index 341c404c7..0779552ae 100644 --- a/src/songvec.h +++ b/src/songvec.h @@ -19,7 +19,7 @@ void songvec_add(struct songvec *sv, struct mpd_song *add); void songvec_destroy(struct songvec *sv); -int songvec_for_each(struct songvec *sv, +int songvec_for_each(const struct songvec *sv, int (*fn)(struct mpd_song *, void *), void *arg); #endif /* SONGVEC_H */ diff --git a/src/stats.c b/src/stats.c index f200a48b3..61cdd1f92 100644 --- a/src/stats.c +++ b/src/stats.c @@ -19,7 +19,7 @@ #include "stats.h" -#include "directory.h" +#include "database.h" #include "myfprintf.h" #include "outputBuffer.h" #include "tag.h" diff --git a/src/storedPlaylist.c b/src/storedPlaylist.c index b74ef1404..c83f7115d 100644 --- a/src/storedPlaylist.c +++ b/src/storedPlaylist.c @@ -20,7 +20,7 @@ #include "path.h" #include "utils.h" #include "ls.h" -#include "directory.h" +#include "database.h" #include "os_compat.h" static ListNode *nodeOfStoredPlaylist(List *list, int idx) diff --git a/src/update.c b/src/update.c index 594e7f48c..8560dde38 100644 --- a/src/update.c +++ b/src/update.c @@ -18,7 +18,7 @@ */ #include "update.h" -#include "directory.h" +#include "database.h" #include "log.h" #include "ls.h" #include "path.h" -- cgit v1.2.3 From 0576b8abf8b2fd25105f6e0190a93ddec298e9fb Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Wed, 8 Oct 2008 11:07:39 +0200 Subject: database: removed printDirectoryInfo() The same can be achieved with directory_print(db_get_directory()). --- src/command.c | 5 ++++- src/database.c | 9 --------- src/database.h | 2 -- 3 files changed, 4 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/command.c b/src/command.c index 4923ee5d5..7d1e2f306 100644 --- a/src/command.c +++ b/src/command.c @@ -559,15 +559,18 @@ static int handleLsInfo(int fd, mpd_unused int *permission, int argc, char *argv[]) { const char *path = ""; + const struct directory *directory; if (argc == 2) path = argv[1]; - if (printDirectoryInfo(fd, path) < 0) { + if (!(directory = getDirectory(path))) { commandError(fd, ACK_ERROR_NO_EXIST, "directory not found"); return -1; } + directory_print(fd, directory); + if (isRootDirectory(path)) return lsPlaylists(fd, path); diff --git a/src/database.c b/src/database.c index b4c73db69..c0c03f3e4 100644 --- a/src/database.c +++ b/src/database.c @@ -110,15 +110,6 @@ int traverseAllIn(const char *name, data); } -int printDirectoryInfo(int fd, const char *name) -{ - struct directory *directory; - - if ((directory = getDirectory(name)) == NULL) - return -1; - return directory_print(fd, directory); -} - static char *getDbFile(void) { ConfigParam *param = parseConfigFilePath(CONF_DB_FILE, 1); diff --git a/src/database.h b/src/database.h index e3ed64f0c..f6f320002 100644 --- a/src/database.h +++ b/src/database.h @@ -37,8 +37,6 @@ int traverseAllIn(const char *name, int (*forEachSong) (struct mpd_song *, void *), int (*forEachDir) (struct directory *, void *), void *data); -int printDirectoryInfo(int fd, const char *name); - int checkDirectoryDB(void); int writeDirectoryDB(void); -- cgit v1.2.3 From 4629f646077109f7c6185aab92560da52c237412 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Wed, 8 Oct 2008 11:07:55 +0200 Subject: database: renamed functions, "db_" prefix and no CamelCase Yet another CamelCase removal patch. --- src/command.c | 2 +- src/database.c | 34 +++++++++++++++++----------------- src/database.h | 20 ++++++++++---------- src/dbUtils.c | 22 +++++++++++----------- src/directory.c | 2 +- src/directory.h | 4 ++-- src/main.c | 12 ++++++------ src/playlist.c | 6 +++--- src/sig_handlers.c | 2 +- src/stats.c | 4 ++-- src/storedPlaylist.c | 2 +- src/update.c | 14 +++++++------- 12 files changed, 62 insertions(+), 62 deletions(-) (limited to 'src') diff --git a/src/command.c b/src/command.c index 7d1e2f306..0f9852592 100644 --- a/src/command.c +++ b/src/command.c @@ -564,7 +564,7 @@ static int handleLsInfo(int fd, mpd_unused int *permission, if (argc == 2) path = argv[1]; - if (!(directory = getDirectory(path))) { + if (!(directory = db_get_directory(path))) { commandError(fd, ACK_ERROR_NO_EXIST, "directory not found"); return -1; } diff --git a/src/database.c b/src/database.c index c0c03f3e4..bb6cfcd52 100644 --- a/src/database.c +++ b/src/database.c @@ -35,7 +35,7 @@ static struct directory *music_root; static time_t directory_dbModTime; -void directory_init(void) +void db_init(void) { music_root = newDirectory(NULL, NULL); updateDirectory(music_root); @@ -43,19 +43,19 @@ void directory_init(void) stats.dbPlayTime = sumSongTimesIn(NULL); } -void directory_finish(void) +void db_finish(void) { freeDirectory(music_root); } -struct directory * directory_get_root(void) +struct directory * db_get_root(void) { assert(music_root != NULL); return music_root; } -struct directory * getDirectory(const char *name) +struct directory * db_get_directory(const char *name) { if (name == NULL) return music_root; @@ -63,7 +63,7 @@ struct directory * getDirectory(const char *name) return getSubDirectory(music_root, name); } -struct mpd_song *getSongFromDB(const char *file) +struct mpd_song *db_get_song(const char *file) { struct mpd_song *song = NULL; struct directory *directory; @@ -81,7 +81,7 @@ struct mpd_song *getSongFromDB(const char *file) dir = duplicated; } - if (!(directory = getDirectory(dir))) + if (!(directory = db_get_directory(dir))) goto out; if (!(song = songvec_find(&directory->songs, shortname))) goto out; @@ -92,15 +92,15 @@ out: return song; } -int traverseAllIn(const char *name, +int db_walk(const char *name, int (*forEachSong) (struct mpd_song *, void *), int (*forEachDir) (struct directory *, void *), void *data) { struct directory *directory; - if ((directory = getDirectory(name)) == NULL) { + if ((directory = db_get_directory(name)) == NULL) { struct mpd_song *song; - if ((song = getSongFromDB(name)) && forEachSong) { + if ((song = db_get_song(name)) && forEachSong) { return forEachSong(song, data); } return -1; @@ -110,7 +110,7 @@ int traverseAllIn(const char *name, data); } -static char *getDbFile(void) +static char *db_get_file(void) { ConfigParam *param = parseConfigFilePath(CONF_DB_FILE, 1); @@ -120,10 +120,10 @@ static char *getDbFile(void) return param->value; } -int checkDirectoryDB(void) +int db_check(void) { struct stat st; - char *dbFile = getDbFile(); + char *dbFile = db_get_file(); /* Check if the file exists */ if (access(dbFile, F_OK)) { @@ -180,10 +180,10 @@ int checkDirectoryDB(void) return 0; } -int writeDirectoryDB(void) +int db_save(void) { int fd; - char *dbFile = getDbFile(); + char *dbFile = db_get_file(); struct stat st; DEBUG("removing empty directories from DB\n"); @@ -226,10 +226,10 @@ int writeDirectoryDB(void) return 0; } -int readDirectoryDB(void) +int db_load(void) { FILE *fp = NULL; - char *dbFile = getDbFile(); + char *dbFile = db_get_file(); struct stat st; if (!music_root) @@ -306,7 +306,7 @@ int readDirectoryDB(void) return 0; } -time_t getDbModTime(void) +time_t db_get_mtime(void) { return directory_dbModTime; } diff --git a/src/database.h b/src/database.h index f6f320002..0eb7d535d 100644 --- a/src/database.h +++ b/src/database.h @@ -23,26 +23,26 @@ #include "os_compat.h" #include "directory.h" -void directory_init(void); +void db_init(void); -void directory_finish(void); +void db_finish(void); -struct directory * directory_get_root(void); +struct directory * db_get_root(void); -struct directory * getDirectory(const char *name); +struct directory * db_get_directory(const char *name); -struct mpd_song * getSongFromDB(const char *file); +struct mpd_song * db_get_song(const char *file); -int traverseAllIn(const char *name, +int db_walk(const char *name, int (*forEachSong) (struct mpd_song *, void *), int (*forEachDir) (struct directory *, void *), void *data); -int checkDirectoryDB(void); +int db_check(void); -int writeDirectoryDB(void); +int db_save(void); -int readDirectoryDB(void); +int db_load(void); -time_t getDbModTime(void); +time_t db_get_mtime(void); #endif /* DATABASE_H */ diff --git a/src/dbUtils.c b/src/dbUtils.c index 7d1d185a3..5320c0dac 100644 --- a/src/dbUtils.c +++ b/src/dbUtils.c @@ -98,7 +98,7 @@ int searchForSongsIn(int fd, const char *name, int numItems, data.array.numItems = numItems; data.array.items = items; - ret = traverseAllIn(name, searchInDirectory, NULL, &data); + ret = db_walk(name, searchInDirectory, NULL, &data); for (i = 0; i < numItems; i++) { free(items[i].needle); @@ -130,7 +130,7 @@ int findSongsIn(int fd, const char *name, int numItems, LocateTagItem * items) data.array.numItems = numItems; data.array.items = items; - return traverseAllIn(name, findInDirectory, NULL, &data); + return db_walk(name, findInDirectory, NULL, &data); } static void printSearchStats(int fd, SearchStats *stats) @@ -164,7 +164,7 @@ int searchStatsForSongsIn(int fd, const char *name, int numItems, stats.numberOfSongs = 0; stats.playTime = 0; - ret = traverseAllIn(name, searchStatsInDirectory, NULL, &stats); + ret = db_walk(name, searchStatsInDirectory, NULL, &stats); if (ret == 0) printSearchStats(fd, &stats); @@ -173,7 +173,7 @@ int searchStatsForSongsIn(int fd, const char *name, int numItems, int printAllIn(int fd, const char *name) { - return traverseAllIn(name, song_print_url_x, + return db_walk(name, song_print_url_x, printDirectoryInDirectory, (void*)(size_t)fd); } @@ -198,7 +198,7 @@ static int directoryAddSongToStoredPlaylist(struct mpd_song *song, void *_data) int addAllIn(const char *name) { - return traverseAllIn(name, directoryAddSongToPlaylist, NULL, NULL); + return db_walk(name, directoryAddSongToPlaylist, NULL, NULL); } int addAllInToStoredPlaylist(const char *name, const char *utf8file) @@ -206,7 +206,7 @@ int addAllInToStoredPlaylist(const char *name, const char *utf8file) struct add_data data; data.path = utf8file; - return traverseAllIn(name, directoryAddSongToStoredPlaylist, NULL, + return db_walk(name, directoryAddSongToStoredPlaylist, NULL, &data); } @@ -222,7 +222,7 @@ static int sumSongTime(struct mpd_song * song, void *data) int printInfoForAllIn(int fd, const char *name) { - return traverseAllIn(name, song_print_info_x, + return db_walk(name, song_print_info_x, printDirectoryInDirectory, (void*)(size_t)fd); } @@ -231,7 +231,7 @@ int countSongsIn(const char *name) int count = 0; void *ptr = (void *)&count; - traverseAllIn(name, NULL, countSongsInDirectory, ptr); + db_walk(name, NULL, countSongsInDirectory, ptr); return count; } @@ -241,7 +241,7 @@ unsigned long sumSongTimesIn(const char *name) unsigned long dbPlayTime = 0; void *ptr = (void *)&dbPlayTime; - traverseAllIn(name, sumSongTime, NULL, ptr); + db_walk(name, sumSongTime, NULL, ptr); return dbPlayTime; } @@ -318,7 +318,7 @@ int listAllUniqueTags(int fd, int type, int numConditionals, data.set = strset_new(); } - ret = traverseAllIn(NULL, listUniqueTagsInDirectory, NULL, &data); + ret = db_walk(NULL, listUniqueTagsInDirectory, NULL, &data); if (type >= 0 && type <= TAG_NUM_OF_ITEM_TYPES) { const char *value; @@ -362,7 +362,7 @@ void printSavedMemoryFromFilenames(void) { int sum = 0; - traverseAllIn(NULL, sumSavedFilenameMemoryInSong, + db_walk(NULL, sumSavedFilenameMemoryInSong, sumSavedFilenameMemoryInDirectory, (void *)&sum); DEBUG("saved memory from filenames: %i\n", sum); diff --git a/src/directory.c b/src/directory.c index b38d3b52c..501bda275 100644 --- a/src/directory.c +++ b/src/directory.c @@ -195,7 +195,7 @@ void readDirectoryInfo(FILE * fp, struct directory * directory) if (prefixcmp(buffer, DIRECTORY_BEGIN)) FATAL("Error reading db at line: %s\n", buffer); name = &(buffer[strlen(DIRECTORY_BEGIN)]); - if ((subdir = getDirectory(name))) { + if ((subdir = db_get_directory(name))) { assert(subdir->parent == directory); } else { subdir = newDirectory(name, directory); diff --git a/src/directory.h b/src/directory.h index 84913c036..5401fc98c 100644 --- a/src/directory.h +++ b/src/directory.h @@ -70,7 +70,7 @@ getSubDirectory(struct directory *directory, const char *name); int directory_print(int fd, const struct directory *directory); -struct mpd_song *getSongFromDB(const char *file); +struct mpd_song *db_get_song(const char *file); int writeDirectoryInfo(int fd, struct directory *directory); @@ -78,7 +78,7 @@ void readDirectoryInfo(FILE *fp, struct directory *directory); void sortDirectory(struct directory * directory); -int traverseAllIn(const char *name, +int db_walk(const char *name, int (*forEachSong) (struct mpd_song *, void *), int (*forEachDir) (struct directory *, void *), void *data); diff --git a/src/main.c b/src/main.c index 5c6957f20..07f0f528a 100644 --- a/src/main.c +++ b/src/main.c @@ -269,17 +269,17 @@ static void changeToUser(void) static void openDB(Options * options, char *argv0) { - if (options->createDB > 0 || readDirectoryDB() < 0) { + if (options->createDB > 0 || db_load() < 0) { if (options->createDB < 0) { FATAL("can't open db file and using " "\"--no-create-db\" command line option\n" "try running \"%s --create-db\"\n", argv0); } flushWarningLog(); - if (checkDirectoryDB() < 0) + if (db_check() < 0) exit(EXIT_FAILURE); - directory_init(); - if (writeDirectoryDB() < 0) + db_init(); + if (db_save() < 0) exit(EXIT_FAILURE); if (options->createDB) exit(EXIT_SUCCESS); @@ -451,8 +451,8 @@ int main(int argc, char *argv[]) finishPlaylist(); start = clock(); - directory_finish(); - DEBUG("directory_finish took %f seconds\n", + db_finish(); + DEBUG("db_finish took %f seconds\n", ((float)(clock()-start))/CLOCKS_PER_SEC); finishNormalization(); diff --git a/src/playlist.c b/src/playlist.c index 118733543..8a7b5cf7f 100644 --- a/src/playlist.c +++ b/src/playlist.c @@ -575,7 +575,7 @@ enum playlist_result addToPlaylist(const char *url, int *added_id) DEBUG("add to playlist: %s\n", url); - if ((song = getSongFromDB(url))) { + if ((song = db_get_song(url))) { } else if (!(isValidRemoteUtf8Url(url) && (song = song_remote_new(url)))) { return PLAYLIST_RESULT_NO_SUCH_SONG; @@ -590,7 +590,7 @@ int addToStoredPlaylist(const char *url, const char *utf8file) DEBUG("add to stored playlist: %s\n", url); - if ((song = getSongFromDB(url))) + if ((song = db_get_song(url))) return appendSongToStoredPlaylistByPath(utf8file, song); if (!isValidRemoteUtf8Url(url)) @@ -1358,7 +1358,7 @@ int PlaylistInfo(int fd, const char *utf8file, int detail) int wrote = 0; if (detail) { - struct mpd_song *song = getSongFromDB(temp); + struct mpd_song *song = db_get_song(temp); if (song) { song_print_info(song, fd); wrote = 1; diff --git a/src/sig_handlers.c b/src/sig_handlers.c index 1c09eda5b..5a4ebe57d 100644 --- a/src/sig_handlers.c +++ b/src/sig_handlers.c @@ -36,7 +36,7 @@ int handlePendingSignals(void) DEBUG("got SIGHUP, rereading DB\n"); signal_clear(SIGHUP); if (!isUpdatingDB()) { - readDirectoryDB(); + db_load(); playlistVersionChange(); } if (cycle_log_files() < 0) diff --git a/src/stats.c b/src/stats.c index 61cdd1f92..abe03444a 100644 --- a/src/stats.c +++ b/src/stats.c @@ -65,7 +65,7 @@ static unsigned int getNumberOfTagItems(int type) data.type = type; data.set = strset_new(); - traverseAllIn(NULL, visit_tag_items, NULL, &data); + db_walk(NULL, visit_tag_items, NULL, &data); ret = strset_size(data.set); strset_free(data.set); @@ -88,6 +88,6 @@ int printStats(int fd) time(NULL) - stats.daemonStart, (long)(ob_get_total_time() + 0.5), stats.dbPlayTime, - getDbModTime()); + db_get_mtime()); return 0; } diff --git a/src/storedPlaylist.c b/src/storedPlaylist.c index c83f7115d..2e6828483 100644 --- a/src/storedPlaylist.c +++ b/src/storedPlaylist.c @@ -118,7 +118,7 @@ List *loadStoredPlaylist(const char *utf8path) !strncmp(s, musicDir, musicDir_len)) memmove(s, s + musicDir_len + 1, strlen(s + musicDir_len + 1) + 1); - if ((song = getSongFromDB(s))) { + if ((song = db_get_song(s))) { song_get_url(song, path_max_tmp); insertInListWithoutKey(list, xstrdup(path_max_tmp)); } else if (isValidRemoteUtf8Url(s)) diff --git a/src/update.c b/src/update.c index 8560dde38..52e61167d 100644 --- a/src/update.c +++ b/src/update.c @@ -312,7 +312,7 @@ static struct directory * addDirectoryPathToDB(const char *utf8path) parent = parent_path(path_max_tmp, utf8path); if (strlen(parent) == 0) - parentDirectory = directory_get_root(); + parentDirectory = db_get_root(); else parentDirectory = addDirectoryPathToDB(parent); @@ -351,7 +351,7 @@ static struct directory * addParentPathToDB(const char *utf8path) parent = parent_path(path_max_tmp, utf8path); if (strlen(parent) == 0) - parentDirectory = directory_get_root(); + parentDirectory = db_get_root(); else parentDirectory = addDirectoryPathToDB(parent); @@ -373,7 +373,7 @@ static enum update_return updatePath(const char *utf8path) assert(utf8path); /* if path is in the DB try to update it, or else delete it */ - if ((directory = getDirectory(utf8path))) { + if ((directory = db_get_directory(utf8path))) { parentDirectory = directory->parent; /* if this update directory is successfull, we are done */ @@ -382,7 +382,7 @@ static enum update_return updatePath(const char *utf8path) return ret; } /* we don't want to delete the root directory */ - else if (directory == directory_get_root()) { + else if (directory == db_get_root()) { return UPDATE_RETURN_NOUPDATE; } /* if updateDirectory fails, means we should delete it */ @@ -392,7 +392,7 @@ static enum update_return updatePath(const char *utf8path) ret = UPDATE_RETURN_UPDATED; /* don't return, path maybe a song now */ } - } else if ((song = getSongFromDB(utf8path))) { + } else if ((song = db_get_song(utf8path))) { parentDirectory = song->parent; if (!parentDirectory->stat && statDirectory(parentDirectory) < 0) { @@ -448,10 +448,10 @@ static void * update_task(void *_path) ret = updatePath((char *)_path); free(_path); } else { - ret = updateDirectory(directory_get_root()); + ret = updateDirectory(db_get_root()); } - if (ret == UPDATE_RETURN_UPDATED && writeDirectoryDB() < 0) + if (ret == UPDATE_RETURN_UPDATED && db_save() < 0) ret = UPDATE_RETURN_ERROR; progress = UPDATE_PROGRESS_DONE; wakeup_main_task(); -- cgit v1.2.3 From a76121ea81f452c0d5e21d6a2fb6f200a80faf7b Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Wed, 8 Oct 2008 11:07:58 +0200 Subject: directory: eliminate CamelCase CamelCase is ugly, rename the functions. [ew: "directory_get_directory" was too confusing, using "directory_get_subdir" instead (old function was named "getSubDirectory")] --- src/database.c | 18 +++++++++--------- src/dbUtils.c | 4 ++-- src/directory.c | 40 ++++++++++++++++++++-------------------- src/directory.h | 18 +++++++++--------- src/dirvec.c | 2 +- src/song.c | 6 +++--- src/update.c | 12 ++++++------ 7 files changed, 50 insertions(+), 50 deletions(-) (limited to 'src') diff --git a/src/database.c b/src/database.c index bb6cfcd52..98e50ad87 100644 --- a/src/database.c +++ b/src/database.c @@ -37,7 +37,7 @@ static time_t directory_dbModTime; void db_init(void) { - music_root = newDirectory(NULL, NULL); + music_root = directory_new(NULL, NULL); updateDirectory(music_root); stats.numberOfSongs = countSongsIn(NULL); stats.dbPlayTime = sumSongTimesIn(NULL); @@ -45,7 +45,7 @@ void db_init(void) void db_finish(void) { - freeDirectory(music_root); + directory_free(music_root); } struct directory * db_get_root(void) @@ -60,7 +60,7 @@ struct directory * db_get_directory(const char *name) if (name == NULL) return music_root; - return getSubDirectory(music_root, name); + return directory_get_subdir(music_root, name); } struct mpd_song *db_get_song(const char *file) @@ -106,7 +106,7 @@ int db_walk(const char *name, return -1; } - return traverseAllInSubDirectory(directory, forEachSong, forEachDir, + return directory_walk(directory, forEachSong, forEachDir, data); } @@ -187,11 +187,11 @@ int db_save(void) struct stat st; DEBUG("removing empty directories from DB\n"); - deleteEmptyDirectoriesInDirectory(music_root); + directory_prune_empty(music_root); DEBUG("sorting DB\n"); - sortDirectory(music_root); + directory_sort(music_root); DEBUG("writing DB\n"); @@ -212,7 +212,7 @@ int db_save(void) DIRECTORY_FS_CHARSET "%s\n" DIRECTORY_INFO_END "\n", getFsCharset()); - if (writeDirectoryInfo(fd, music_root) < 0) { + if (directory_save(fd, music_root) < 0) { ERROR("Failed to write to database file: %s\n", strerror(errno)); xclose(fd); @@ -233,7 +233,7 @@ int db_load(void) struct stat st; if (!music_root) - music_root = newDirectory(NULL, NULL); + music_root = directory_new(NULL, NULL); while (!(fp = fopen(dbFile, "r")) && errno == EINTR) ; if (fp == NULL) { ERROR("unable to open db file \"%s\": %s\n", @@ -294,7 +294,7 @@ int db_load(void) DEBUG("reading DB\n"); - readDirectoryInfo(fp, music_root); + directory_load(fp, music_root); while (fclose(fp) && errno == EINTR) ; stats.numberOfSongs = countSongsIn(NULL); diff --git a/src/dbUtils.c b/src/dbUtils.c index 5320c0dac..aa7e639b7 100644 --- a/src/dbUtils.c +++ b/src/dbUtils.c @@ -58,7 +58,7 @@ static int printDirectoryInDirectory(struct directory *directory, void *data) { int fd = (int)(size_t)data; if (directory->path) { - fdprintf(fd, "directory: %s\n", getDirectoryPath(directory)); + fdprintf(fd, "directory: %s\n", directory_get_path(directory)); } return 0; } @@ -343,7 +343,7 @@ static int sumSavedFilenameMemoryInDirectory(struct directory *dir, void *data) if (!dir->path) return 0; - *sum += (strlen(getDirectoryPath(dir)) + 1 + *sum += (strlen(directory_get_path(dir)) + 1 - sizeof(struct directory *)) * dir->songs.nr; return 0; diff --git a/src/directory.c b/src/directory.c index 501bda275..f79cc2dbc 100644 --- a/src/directory.c +++ b/src/directory.c @@ -26,7 +26,7 @@ #include "myfprintf.h" #include "dirvec.h" -struct directory * newDirectory(const char *dirname, struct directory * parent) +struct directory * directory_new(const char *dirname, struct directory * parent) { struct directory *directory; @@ -39,7 +39,7 @@ struct directory * newDirectory(const char *dirname, struct directory * parent) return directory; } -void freeDirectory(struct directory * directory) +void directory_free(struct directory * directory) { dirvec_destroy(&directory->children); songvec_destroy(&directory->songs); @@ -47,16 +47,16 @@ void freeDirectory(struct directory * directory) free(directory->path); free(directory); /* this resets last dir returned */ - /*getDirectoryPath(NULL); */ + /*directory_get_path(NULL); */ } -void deleteEmptyDirectoriesInDirectory(struct directory * directory) +void directory_prune_empty(struct directory * directory) { int i; struct dirvec *dv = &directory->children; for (i = dv->nr; --i >= 0; ) { - deleteEmptyDirectoriesInDirectory(dv->base[i]); + directory_prune_empty(dv->base[i]); if (directory_is_empty(dv->base[i])) dirvec_delete(dv, dv->base[i]); } @@ -65,7 +65,7 @@ void deleteEmptyDirectoriesInDirectory(struct directory * directory) } struct directory * -getSubDirectory(struct directory * directory, const char *name) +directory_get_subdir(struct directory * directory, const char *name) { struct directory *cur = directory; struct directory *found = NULL; @@ -97,13 +97,13 @@ getSubDirectory(struct directory * directory, const char *name) return found; } -static int printDirectoryList(int fd, const struct dirvec *dv) +static int dirvec_print(int fd, const struct dirvec *dv) { size_t i; for (i = 0; i < dv->nr; ++i) { if (fdprintf(fd, DIRECTORY_DIR "%s\n", - getDirectoryPath(dv->base[i])) < 0) + directory_get_path(dv->base[i])) < 0) return -1; } @@ -112,7 +112,7 @@ static int printDirectoryList(int fd, const struct dirvec *dv) int directory_print(int fd, const struct directory *directory) { - if (printDirectoryList(fd, &directory->children) < 0) + if (dirvec_print(fd, &directory->children) < 0) return -1; if (songvec_for_each(&directory->songs, song_print_info_x, (void *)(size_t)fd) < 0) @@ -135,14 +135,14 @@ static int directory_song_write(struct mpd_song *song, void *data) } /* TODO error checking */ -int writeDirectoryInfo(int fd, struct directory * directory) +int directory_save(int fd, struct directory * directory) { struct dirvec *children = &directory->children; size_t i; if (directory->path && fdprintf(fd, DIRECTORY_BEGIN "%s\n", - getDirectoryPath(directory)) < 0) + directory_get_path(directory)) < 0) return -1; for (i = 0; i < children->nr; ++i) { @@ -151,7 +151,7 @@ int writeDirectoryInfo(int fd, struct directory * directory) if (fdprintf(fd, DIRECTORY_DIR "%s\n", base) < 0) return -1; - if (writeDirectoryInfo(fd, cur) < 0) + if (directory_save(fd, cur) < 0) return -1; } @@ -167,12 +167,12 @@ int writeDirectoryInfo(int fd, struct directory * directory) if (directory->path && fdprintf(fd, DIRECTORY_END "%s\n", - getDirectoryPath(directory)) < 0) + directory_get_path(directory)) < 0) return -1; return 0; } -void readDirectoryInfo(FILE * fp, struct directory * directory) +void directory_load(FILE * fp, struct directory * directory) { char buffer[MPD_PATH_MAX * 2]; int bufferSize = MPD_PATH_MAX * 2; @@ -198,10 +198,10 @@ void readDirectoryInfo(FILE * fp, struct directory * directory) if ((subdir = db_get_directory(name))) { assert(subdir->parent == directory); } else { - subdir = newDirectory(name, directory); + subdir = directory_new(name, directory); dirvec_add(&directory->children, subdir); } - readDirectoryInfo(fp, subdir); + directory_load(fp, subdir); } else if (!prefixcmp(buffer, SONG_BEGIN)) { readSongInfoIntoList(fp, directory); } else { @@ -210,7 +210,7 @@ void readDirectoryInfo(FILE * fp, struct directory * directory) } } -void sortDirectory(struct directory * directory) +void directory_sort(struct directory * directory) { int i; struct dirvec *dv = &directory->children; @@ -219,11 +219,11 @@ void sortDirectory(struct directory * directory) songvec_sort(&directory->songs); for (i = dv->nr; --i >= 0; ) - sortDirectory(dv->base[i]); + directory_sort(dv->base[i]); } int -traverseAllInSubDirectory(struct directory * directory, +directory_walk(struct directory * directory, int (*forEachSong) (struct mpd_song *, void *), int (*forEachDir) (struct directory *, void *), void *data) @@ -242,7 +242,7 @@ traverseAllInSubDirectory(struct directory * directory, } for (j = 0; err >= 0 && j < dv->nr; ++j) - err = traverseAllInSubDirectory(dv->base[j], forEachSong, + err = directory_walk(dv->base[j], forEachSong, forEachDir, data); return err; diff --git a/src/directory.h b/src/directory.h index 5401fc98c..a95e0d7db 100644 --- a/src/directory.h +++ b/src/directory.h @@ -52,9 +52,9 @@ static inline int isRootDirectory(const char *name) return (!name || *name == '\0' || !strcmp(name, "/")); } -struct directory * newDirectory(const char *dirname, struct directory *parent); +struct directory * directory_new(const char *dirname, struct directory *parent); -void freeDirectory(struct directory *directory); +void directory_free(struct directory *directory); static inline int directory_is_empty(struct directory *directory) { @@ -63,29 +63,29 @@ static inline int directory_is_empty(struct directory *directory) int printDirectoryInfo(int fd, const char *dirname); -void deleteEmptyDirectoriesInDirectory(struct directory *directory); +void directory_prune_empty(struct directory *directory); struct directory * -getSubDirectory(struct directory *directory, const char *name); +directory_get_subdir(struct directory *directory, const char *name); int directory_print(int fd, const struct directory *directory); struct mpd_song *db_get_song(const char *file); -int writeDirectoryInfo(int fd, struct directory *directory); +int directory_save(int fd, struct directory *directory); -void readDirectoryInfo(FILE *fp, struct directory *directory); +void directory_load(FILE *fp, struct directory *directory); -void sortDirectory(struct directory * directory); +void directory_sort(struct directory * directory); int db_walk(const char *name, int (*forEachSong) (struct mpd_song *, void *), int (*forEachDir) (struct directory *, void *), void *data); -int traverseAllInSubDirectory(struct directory *directory, +int directory_walk(struct directory *directory, int (*forEachSong) (struct mpd_song *, void *), int (*forEachDir) (struct directory *, void *), void *data); -#define getDirectoryPath(dir) ((dir && dir->path) ? dir->path : "") +#define directory_get_path(dir) ((dir && dir->path) ? dir->path : "") #endif diff --git a/src/dirvec.c b/src/dirvec.c index 9226fca74..3ec5b7af1 100644 --- a/src/dirvec.c +++ b/src/dirvec.c @@ -38,7 +38,7 @@ int dirvec_delete(struct dirvec *dv, struct directory *del) for (i = dv->nr; --i >= 0; ) { if (dv->base[i] != del) continue; - /* we _don't_ call freeDirectory() here */ + /* we _don't_ call directory_free() here */ if (!--dv->nr) { free(dv->base); dv->base = NULL; diff --git a/src/song.c b/src/song.c index 18f2bca21..aa6641020 100644 --- a/src/song.c +++ b/src/song.c @@ -87,7 +87,7 @@ ssize_t song_print_url(struct mpd_song *song, int fd) { if (song->parent && song->parent->path) return fdprintf(fd, "%s%s/%s\n", SONG_FILE, - getDirectoryPath(song->parent), song->url); + directory_get_path(song->parent), song->url); return fdprintf(fd, "%s%s\n", SONG_FILE, song->url); } @@ -244,7 +244,7 @@ char *song_get_url(struct mpd_song *song, char *path_max_tmp) strcpy(path_max_tmp, song->url); else pfx_dir(path_max_tmp, song->url, strlen(song->url), - getDirectoryPath(song->parent), - strlen(getDirectoryPath(song->parent))); + directory_get_path(song->parent), + strlen(directory_get_path(song->parent))); return path_max_tmp; } diff --git a/src/update.c b/src/update.c index 52e61167d..989b8f943 100644 --- a/src/update.c +++ b/src/update.c @@ -135,7 +135,7 @@ static int statDirectory(struct directory *dir) { struct stat st; - if (myStat(getDirectoryPath(dir), &st) < 0) + if (myStat(directory_get_path(dir), &st) < 0) return -1; directory_set_stat(dir, &st); @@ -168,11 +168,11 @@ addSubDirectoryToDirectory(struct directory *directory, if (inodeFoundInParent(directory, st->st_ino, st->st_dev)) return UPDATE_RETURN_NOUPDATE; - subDirectory = newDirectory(name, directory); + subDirectory = directory_new(name, directory); directory_set_stat(subDirectory, st); if (updateDirectory(subDirectory) != UPDATE_RETURN_UPDATED) { - freeDirectory(subDirectory); + directory_free(subDirectory); return UPDATE_RETURN_NOUPDATE; } @@ -254,7 +254,7 @@ enum update_return updateDirectory(struct directory *directory) { int was_empty = directory_is_empty(directory); DIR *dir; - const char *dirname = getDirectoryPath(directory); + const char *dirname = directory_get_path(directory); struct dirent *ent; char path_max_tmp[MPD_PATH_MAX]; enum update_return ret = UPDATE_RETURN_NOUPDATE; @@ -327,7 +327,7 @@ static struct directory * addDirectoryPathToDB(const char *utf8path) inodeFoundInParent(parentDirectory, st.st_ino, st.st_dev)) return NULL; else { - directory = newDirectory(utf8path, parentDirectory); + directory = directory_new(utf8path, parentDirectory); dirvec_add(&parentDirectory->children, directory); } } @@ -378,7 +378,7 @@ static enum update_return updatePath(const char *utf8path) /* if this update directory is successfull, we are done */ if ((ret = updateDirectory(directory)) >= 0) { - sortDirectory(directory); + directory_sort(directory); return ret; } /* we don't want to delete the root directory */ -- cgit v1.2.3 From b0364ba70de4d85d4d6ea510235982a024978305 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Tue, 7 Oct 2008 22:09:55 +0200 Subject: songvec: pass const pointers Pass const songvec pointers to songvec_find() and songvec_for_each(). [ew: already merged songvec_for_each() cosntification somewhere...] --- src/songvec.c | 2 +- src/songvec.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/songvec.c b/src/songvec.c index c306ab640..ce04a4373 100644 --- a/src/songvec.c +++ b/src/songvec.c @@ -24,7 +24,7 @@ void songvec_sort(struct songvec *sv) pthread_mutex_unlock(&nr_lock); } -struct mpd_song *songvec_find(struct songvec *sv, const char *url) +struct mpd_song *songvec_find(const struct songvec *sv, const char *url) { int i; struct mpd_song *ret = NULL; diff --git a/src/songvec.h b/src/songvec.h index 0779552ae..633cf8d66 100644 --- a/src/songvec.h +++ b/src/songvec.h @@ -11,7 +11,7 @@ struct songvec { void songvec_sort(struct songvec *sv); -struct mpd_song *songvec_find(struct songvec *sv, const char *url); +struct mpd_song *songvec_find(const struct songvec *sv, const char *url); int songvec_delete(struct songvec *sv, const struct mpd_song *del); -- cgit v1.2.3 From d32498dfec5f97275e6d769080a2a39c16f214c8 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Wed, 8 Oct 2008 11:08:04 +0200 Subject: directory: directory_get_path(NULL) is not allowed Also convert directory_get_path() to an inline function, which returns a constant string. --- src/directory.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/directory.h b/src/directory.h index a95e0d7db..5609e4ea4 100644 --- a/src/directory.h +++ b/src/directory.h @@ -61,7 +61,10 @@ static inline int directory_is_empty(struct directory *directory) return directory->children.nr == 0 && directory->songs.nr == 0; } -int printDirectoryInfo(int fd, const char *dirname); +static inline const char * directory_get_path(struct directory *dir) +{ + return dir->path ? dir->path : ""; +} void directory_prune_empty(struct directory *directory); @@ -86,6 +89,4 @@ int directory_walk(struct directory *directory, int (*forEachSong) (struct mpd_song *, void *), int (*forEachDir) (struct directory *, void *), void *data); -#define directory_get_path(dir) ((dir && dir->path) ? dir->path : "") - #endif -- cgit v1.2.3 From 313e8e3ecc15e65700e64252207227612d6d9195 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Wed, 8 Oct 2008 11:08:16 +0200 Subject: directory: path must not be NULL For the root directory, let's set path to an empty string. This saves a few checks. --- src/database.c | 4 ++-- src/directory.c | 14 +++++++------- src/directory.h | 2 +- 3 files changed, 10 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/database.c b/src/database.c index 98e50ad87..bd278a635 100644 --- a/src/database.c +++ b/src/database.c @@ -37,7 +37,7 @@ static time_t directory_dbModTime; void db_init(void) { - music_root = directory_new(NULL, NULL); + music_root = directory_new("", NULL); updateDirectory(music_root); stats.numberOfSongs = countSongsIn(NULL); stats.dbPlayTime = sumSongTimesIn(NULL); @@ -233,7 +233,7 @@ int db_load(void) struct stat st; if (!music_root) - music_root = directory_new(NULL, NULL); + music_root = directory_new("", NULL); while (!(fp = fopen(dbFile, "r")) && errno == EINTR) ; if (fp == NULL) { ERROR("unable to open db file \"%s\": %s\n", diff --git a/src/directory.c b/src/directory.c index f79cc2dbc..295fdd09a 100644 --- a/src/directory.c +++ b/src/directory.c @@ -30,10 +30,11 @@ struct directory * directory_new(const char *dirname, struct directory * parent) { struct directory *directory; - directory = xcalloc(1, sizeof(*directory)); + assert(dirname != NULL); + assert((*dirname == 0) == (parent == NULL)); - if (dirname && strlen(dirname)) - directory->path = xstrdup(dirname); + directory = xcalloc(1, sizeof(*directory)); + directory->path = xstrdup(dirname); directory->parent = parent; return directory; @@ -43,8 +44,7 @@ void directory_free(struct directory * directory) { dirvec_destroy(&directory->children); songvec_destroy(&directory->songs); - if (directory->path) - free(directory->path); + free(directory->path); free(directory); /* this resets last dir returned */ /*directory_get_path(NULL); */ @@ -140,7 +140,7 @@ int directory_save(int fd, struct directory * directory) struct dirvec *children = &directory->children; size_t i; - if (directory->path && + if (!isRootDirectory(directory->path) && fdprintf(fd, DIRECTORY_BEGIN "%s\n", directory_get_path(directory)) < 0) return -1; @@ -165,7 +165,7 @@ int directory_save(int fd, struct directory * directory) if (fdprintf(fd, SONG_END "\n") < 0) return -1; - if (directory->path && + if (!isRootDirectory(directory->path) && fdprintf(fd, DIRECTORY_END "%s\n", directory_get_path(directory)) < 0) return -1; diff --git a/src/directory.h b/src/directory.h index 5609e4ea4..17c218bfb 100644 --- a/src/directory.h +++ b/src/directory.h @@ -63,7 +63,7 @@ static inline int directory_is_empty(struct directory *directory) static inline const char * directory_get_path(struct directory *dir) { - return dir->path ? dir->path : ""; + return dir->path; } void directory_prune_empty(struct directory *directory); -- cgit v1.2.3 From 0c46207db41840ac70af7a5261969e865b748f1d Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Wed, 8 Oct 2008 11:55:52 +0200 Subject: directory: fix update in root directory Commit 0bfe7802 broke update for new files in the root directory, because music_root->path was an empty string and not NULL. There were some NULL tests missing. Change them to !isRootDirectory(path) instead of path!=NULL. --- src/dbUtils.c | 5 ++--- src/update.c | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/dbUtils.c b/src/dbUtils.c index aa7e639b7..9e307efc6 100644 --- a/src/dbUtils.c +++ b/src/dbUtils.c @@ -57,9 +57,8 @@ static int countSongsInDirectory(struct directory *directory, void *data) static int printDirectoryInDirectory(struct directory *directory, void *data) { int fd = (int)(size_t)data; - if (directory->path) { + if (!isRootDirectory(directory->path)) fdprintf(fd, "directory: %s\n", directory_get_path(directory)); - } return 0; } @@ -340,7 +339,7 @@ static int sumSavedFilenameMemoryInDirectory(struct directory *dir, void *data) { int *sum = data; - if (!dir->path) + if (!isRootDirectory(dir->path)) return 0; *sum += (strlen(directory_get_path(dir)) + 1 diff --git a/src/update.c b/src/update.c index 989b8f943..1cf6f3537 100644 --- a/src/update.c +++ b/src/update.c @@ -283,7 +283,7 @@ enum update_return updateDirectory(struct directory *directory) if (!utf8) continue; - if (directory->path) + if (!isRootDirectory(directory->path)) utf8 = pfx_dir(path_max_tmp, utf8, strlen(utf8), dirname, strlen(dirname)); if (was_empty) { -- cgit v1.2.3 From 064e2b83d8fb694813d451d667709dc1b33c2431 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Thu, 9 Oct 2008 15:21:18 +0200 Subject: database: simplify db_load() Removed a superfluous closure. --- src/database.c | 89 +++++++++++++++++++++++++++------------------------------- 1 file changed, 42 insertions(+), 47 deletions(-) (limited to 'src') diff --git a/src/database.c b/src/database.c index bd278a635..0fc340c3b 100644 --- a/src/database.c +++ b/src/database.c @@ -231,6 +231,10 @@ int db_load(void) FILE *fp = NULL; char *dbFile = db_get_file(); struct stat st; + char buffer[100]; + int bufferSize = 100; + int foundFsCharset = 0; + int foundVersion = 0; if (!music_root) music_root = directory_new("", NULL); @@ -242,54 +246,45 @@ int db_load(void) } /* get initial info */ - { - char buffer[100]; - int bufferSize = 100; - int foundFsCharset = 0; - int foundVersion = 0; - - if (!myFgets(buffer, bufferSize, fp)) - FATAL("Error reading db, fgets\n"); - if (0 == strcmp(DIRECTORY_INFO_BEGIN, buffer)) { - while (myFgets(buffer, bufferSize, fp) && - 0 != strcmp(DIRECTORY_INFO_END, buffer)) { - if (!prefixcmp(buffer, DIRECTORY_MPD_VERSION)) - { - if (foundVersion) - FATAL("already found version in db\n"); - foundVersion = 1; - } else if (!prefixcmp(buffer, - DIRECTORY_FS_CHARSET)) { - char *fsCharset; - char *tempCharset; - - if (foundFsCharset) - FATAL("already found fs charset in db\n"); - - foundFsCharset = 1; - - fsCharset = &(buffer[strlen(DIRECTORY_FS_CHARSET)]); - if ((tempCharset = getConfigParamValue(CONF_FS_CHARSET)) - && strcmp(fsCharset, tempCharset)) { - WARNING("Using \"%s\" for the " - "filesystem charset " - "instead of \"%s\"\n", - fsCharset, tempCharset); - WARNING("maybe you need to " - "recreate the db?\n"); - setFsCharset(fsCharset); - } - } else { - FATAL("directory: unknown line in db info: %s\n", - buffer); - } + if (!myFgets(buffer, bufferSize, fp)) + FATAL("Error reading db, fgets\n"); + + if (0 != strcmp(DIRECTORY_INFO_BEGIN, buffer)) { + ERROR("db info not found in db file\n"); + ERROR("you should recreate the db using --create-db\n"); + while (fclose(fp) && errno == EINTR) ; + return -1; + } + + while (myFgets(buffer, bufferSize, fp) && + 0 != strcmp(DIRECTORY_INFO_END, buffer)) { + if (!prefixcmp(buffer, DIRECTORY_MPD_VERSION)) { + if (foundVersion) + FATAL("already found version in db\n"); + foundVersion = 1; + } else if (!prefixcmp(buffer, DIRECTORY_FS_CHARSET)) { + char *fsCharset; + char *tempCharset; + + if (foundFsCharset) + FATAL("already found fs charset in db\n"); + + foundFsCharset = 1; + + fsCharset = &(buffer[strlen(DIRECTORY_FS_CHARSET)]); + if ((tempCharset = getConfigParamValue(CONF_FS_CHARSET)) + && strcmp(fsCharset, tempCharset)) { + WARNING("Using \"%s\" for the " + "filesystem charset " + "instead of \"%s\"\n", + fsCharset, tempCharset); + WARNING("maybe you need to " + "recreate the db?\n"); + setFsCharset(fsCharset); } - } else { - ERROR("db info not found in db file\n"); - ERROR("you should recreate the db using --create-db\n"); - while (fclose(fp) && errno == EINTR) ; - return -1; - } + } else + FATAL("directory: unknown line in db info: %s\n", + buffer); } DEBUG("reading DB\n"); -- cgit v1.2.3 From d296861ea05101450b3f3147f6cfcd134486a384 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Thu, 9 Oct 2008 15:21:23 +0200 Subject: database: removed local variable bufferSize Use sizeof(buffer) instead. --- src/database.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/database.c b/src/database.c index 0fc340c3b..6ed7a445d 100644 --- a/src/database.c +++ b/src/database.c @@ -232,7 +232,6 @@ int db_load(void) char *dbFile = db_get_file(); struct stat st; char buffer[100]; - int bufferSize = 100; int foundFsCharset = 0; int foundVersion = 0; @@ -246,7 +245,7 @@ int db_load(void) } /* get initial info */ - if (!myFgets(buffer, bufferSize, fp)) + if (!myFgets(buffer, sizeof(buffer), fp)) FATAL("Error reading db, fgets\n"); if (0 != strcmp(DIRECTORY_INFO_BEGIN, buffer)) { @@ -256,7 +255,7 @@ int db_load(void) return -1; } - while (myFgets(buffer, bufferSize, fp) && + while (myFgets(buffer, sizeof(buffer), fp) && 0 != strcmp(DIRECTORY_INFO_END, buffer)) { if (!prefixcmp(buffer, DIRECTORY_MPD_VERSION)) { if (foundVersion) -- cgit v1.2.3 From a24d3738e35d509aa180fffa127abac8057101cf Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Thu, 9 Oct 2008 15:23:37 +0200 Subject: diretory: moved code to directory_save.c, directory_print.c Remove clutter from directory.c. Everything which saves or loads to/from the hard disk goes to directory_save.c, and code which sends directory information to the client is moved into directory_print.c. --- src/Makefile.am | 4 ++ src/command.c | 1 + src/database.c | 1 + src/directory.c | 116 ------------------------------------------------- src/directory_print.c | 47 ++++++++++++++++++++ src/directory_print.h | 26 +++++++++++ src/directory_save.c | 117 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/directory_save.h | 30 +++++++++++++ 8 files changed, 226 insertions(+), 116 deletions(-) create mode 100644 src/directory_print.c create mode 100644 src/directory_print.h create mode 100644 src/directory_save.c create mode 100644 src/directory_save.h (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index e4cc17c3f..6a7497286 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -43,6 +43,8 @@ mpd_headers = \ dbUtils.h \ decode.h \ directory.h \ + directory_print.h \ + directory_save.h \ update.h \ dirvec.h \ gcc.h \ @@ -116,6 +118,8 @@ mpd_SOURCES = \ dbUtils.c \ decode.c \ directory.c \ + directory_print.c \ + directory_save.c \ dirvec.c \ update.c \ inputPlugin.c \ diff --git a/src/command.c b/src/command.c index 0f9852592..aafb88418 100644 --- a/src/command.c +++ b/src/command.c @@ -21,6 +21,7 @@ #include "ls.h" #include "database.h" #include "directory.h" +#include "directory_print.h" #include "update.h" #include "volume.h" #include "stats.h" diff --git a/src/database.c b/src/database.c index 6ed7a445d..11de15bcc 100644 --- a/src/database.c +++ b/src/database.c @@ -19,6 +19,7 @@ #include "database.h" #include "directory.h" +#include "directory_save.h" #include "song.h" #include "conf.h" #include "log.h" diff --git a/src/directory.c b/src/directory.c index 295fdd09a..305cd5fe3 100644 --- a/src/directory.c +++ b/src/directory.c @@ -17,10 +17,7 @@ */ #include "directory.h" -#include "database.h" -#include "log.h" -#include "path.h" #include "utils.h" #include "ack.h" #include "myfprintf.h" @@ -97,119 +94,6 @@ directory_get_subdir(struct directory * directory, const char *name) return found; } -static int dirvec_print(int fd, const struct dirvec *dv) -{ - size_t i; - - for (i = 0; i < dv->nr; ++i) { - if (fdprintf(fd, DIRECTORY_DIR "%s\n", - directory_get_path(dv->base[i])) < 0) - return -1; - } - - return 0; -} - -int directory_print(int fd, const struct directory *directory) -{ - if (dirvec_print(fd, &directory->children) < 0) - return -1; - if (songvec_for_each(&directory->songs, song_print_info_x, - (void *)(size_t)fd) < 0) - return -1; - return 0; -} - -static int directory_song_write(struct mpd_song *song, void *data) -{ - int fd = (int)(size_t)data; - - if (fdprintf(fd, SONG_KEY "%s\n", song->url) < 0) - return -1; - if (song_print_info(song, fd) < 0) - return -1; - if (fdprintf(fd, SONG_MTIME "%li\n", (long)song->mtime) < 0) - return -1; - - return 0; -} - -/* TODO error checking */ -int directory_save(int fd, struct directory * directory) -{ - struct dirvec *children = &directory->children; - size_t i; - - if (!isRootDirectory(directory->path) && - fdprintf(fd, DIRECTORY_BEGIN "%s\n", - directory_get_path(directory)) < 0) - return -1; - - for (i = 0; i < children->nr; ++i) { - struct directory *cur = children->base[i]; - const char *base = mpd_basename(cur->path); - - if (fdprintf(fd, DIRECTORY_DIR "%s\n", base) < 0) - return -1; - if (directory_save(fd, cur) < 0) - return -1; - } - - if (fdprintf(fd, SONG_BEGIN "\n") < 0) - return -1; - - if (songvec_for_each(&directory->songs, - directory_song_write, (void *)(size_t)fd) < 0) - return -1; - - if (fdprintf(fd, SONG_END "\n") < 0) - return -1; - - if (!isRootDirectory(directory->path) && - fdprintf(fd, DIRECTORY_END "%s\n", - directory_get_path(directory)) < 0) - return -1; - return 0; -} - -void directory_load(FILE * fp, struct directory * directory) -{ - char buffer[MPD_PATH_MAX * 2]; - int bufferSize = MPD_PATH_MAX * 2; - char key[MPD_PATH_MAX * 2]; - char *name; - - while (myFgets(buffer, bufferSize, fp) - && prefixcmp(buffer, DIRECTORY_END)) { - if (!prefixcmp(buffer, DIRECTORY_DIR)) { - struct directory *subdir; - - strcpy(key, &(buffer[strlen(DIRECTORY_DIR)])); - if (!myFgets(buffer, bufferSize, fp)) - FATAL("Error reading db, fgets\n"); - /* for compatibility with db's prior to 0.11 */ - if (!prefixcmp(buffer, DIRECTORY_MTIME)) { - if (!myFgets(buffer, bufferSize, fp)) - FATAL("Error reading db, fgets\n"); - } - if (prefixcmp(buffer, DIRECTORY_BEGIN)) - FATAL("Error reading db at line: %s\n", buffer); - name = &(buffer[strlen(DIRECTORY_BEGIN)]); - if ((subdir = db_get_directory(name))) { - assert(subdir->parent == directory); - } else { - subdir = directory_new(name, directory); - dirvec_add(&directory->children, subdir); - } - directory_load(fp, subdir); - } else if (!prefixcmp(buffer, SONG_BEGIN)) { - readSongInfoIntoList(fp, directory); - } else { - FATAL("Unknown line in db: %s\n", buffer); - } - } -} - void directory_sort(struct directory * directory) { int i; diff --git a/src/directory_print.c b/src/directory_print.c new file mode 100644 index 000000000..ebf9a472d --- /dev/null +++ b/src/directory_print.c @@ -0,0 +1,47 @@ +/* the Music Player Daemon (MPD) + * Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com) + * Copyright (C) 2008 Max Kellermann + * This project's homepage is: http://www.musicpd.org + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "directory_print.h" +#include "directory.h" +#include "dirvec.h" +#include "songvec.h" +#include "myfprintf.h" + +static int dirvec_print(int fd, const struct dirvec *dv) +{ + size_t i; + + for (i = 0; i < dv->nr; ++i) { + if (fdprintf(fd, DIRECTORY_DIR "%s\n", + directory_get_path(dv->base[i])) < 0) + return -1; + } + + return 0; +} + +int directory_print(int fd, const struct directory *directory) +{ + if (dirvec_print(fd, &directory->children) < 0) + return -1; + if (songvec_for_each(&directory->songs, song_print_info_x, + (void *)(size_t)fd) < 0) + return -1; + return 0; +} diff --git a/src/directory_print.h b/src/directory_print.h new file mode 100644 index 000000000..54089e58d --- /dev/null +++ b/src/directory_print.h @@ -0,0 +1,26 @@ +/* the Music Player Daemon (MPD) + * Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com) + * This project's homepage is: http://www.musicpd.org + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef DIRECTORY_PRINT_H +#define DIRECTORY_PRINT_H + +struct directory; + +int directory_print(int fd, const struct directory *directory); + +#endif diff --git a/src/directory_save.c b/src/directory_save.c new file mode 100644 index 000000000..27f7b14ce --- /dev/null +++ b/src/directory_save.c @@ -0,0 +1,117 @@ +/* the Music Player Daemon (MPD) + * Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com) + * This project's homepage is: http://www.musicpd.org + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "directory_save.h" +#include "directory.h" +#include "database.h" +#include "song.h" +#include "log.h" +#include "path.h" +#include "utils.h" +#include "dirvec.h" +#include "myfprintf.h" + +static int directory_song_write(struct mpd_song *song, void *data) +{ + int fd = (int)(size_t)data; + + if (fdprintf(fd, SONG_KEY "%s\n", song->url) < 0) + return -1; + if (song_print_info(song, fd) < 0) + return -1; + if (fdprintf(fd, SONG_MTIME "%li\n", (long)song->mtime) < 0) + return -1; + + return 0; +} + +/* TODO error checking */ +int directory_save(int fd, struct directory * directory) +{ + struct dirvec *children = &directory->children; + size_t i; + + if (!isRootDirectory(directory->path) && + fdprintf(fd, DIRECTORY_BEGIN "%s\n", + directory_get_path(directory)) < 0) + return -1; + + for (i = 0; i < children->nr; ++i) { + struct directory *cur = children->base[i]; + const char *base = mpd_basename(cur->path); + + if (fdprintf(fd, DIRECTORY_DIR "%s\n", base) < 0) + return -1; + if (directory_save(fd, cur) < 0) + return -1; + } + + if (fdprintf(fd, SONG_BEGIN "\n") < 0) + return -1; + + if (songvec_for_each(&directory->songs, + directory_song_write, (void *)(size_t)fd) < 0) + return -1; + + if (fdprintf(fd, SONG_END "\n") < 0) + return -1; + + if (!isRootDirectory(directory->path) && + fdprintf(fd, DIRECTORY_END "%s\n", + directory_get_path(directory)) < 0) + return -1; + return 0; +} + +void directory_load(FILE * fp, struct directory * directory) +{ + char buffer[MPD_PATH_MAX * 2]; + int bufferSize = MPD_PATH_MAX * 2; + char key[MPD_PATH_MAX * 2]; + char *name; + + while (myFgets(buffer, bufferSize, fp) + && prefixcmp(buffer, DIRECTORY_END)) { + if (!prefixcmp(buffer, DIRECTORY_DIR)) { + struct directory *subdir; + + strcpy(key, &(buffer[strlen(DIRECTORY_DIR)])); + if (!myFgets(buffer, bufferSize, fp)) + FATAL("Error reading db, fgets\n"); + /* for compatibility with db's prior to 0.11 */ + if (!prefixcmp(buffer, DIRECTORY_MTIME)) { + if (!myFgets(buffer, bufferSize, fp)) + FATAL("Error reading db, fgets\n"); + } + if (prefixcmp(buffer, DIRECTORY_BEGIN)) + FATAL("Error reading db at line: %s\n", buffer); + name = &(buffer[strlen(DIRECTORY_BEGIN)]); + if ((subdir = db_get_directory(name))) { + assert(subdir->parent == directory); + } else { + subdir = directory_new(name, directory); + dirvec_add(&directory->children, subdir); + } + directory_load(fp, subdir); + } else if (!prefixcmp(buffer, SONG_BEGIN)) { + readSongInfoIntoList(fp, directory); + } else { + FATAL("Unknown line in db: %s\n", buffer); + } + } +} diff --git a/src/directory_save.h b/src/directory_save.h new file mode 100644 index 000000000..211c73cca --- /dev/null +++ b/src/directory_save.h @@ -0,0 +1,30 @@ +/* the Music Player Daemon (MPD) + * Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com) + * This project's homepage is: http://www.musicpd.org + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef DIRECTORY_SAVE_H +#define DIRECTORY_SAVE_H + +#include "os_compat.h" + +struct directory; + +int directory_save(int fd, struct directory *directory); + +void directory_load(FILE *, struct directory *directory); + +#endif /* DIRECTORY_SAVE_H */ -- cgit v1.2.3 From 7f79b3c6fc21d687f116b3e2a2b7bad309a191c0 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Thu, 9 Oct 2008 15:24:05 +0200 Subject: directory: moved dirvec struct declaration to dirvec.h No idea why it was created in directory.h, but it should be in dirvec.h. --- src/directory.h | 6 +----- src/dirvec.h | 7 ++++++- src/update.c | 1 - 3 files changed, 7 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/directory.h b/src/directory.h index 17c218bfb..c767366a7 100644 --- a/src/directory.h +++ b/src/directory.h @@ -20,6 +20,7 @@ #define DIRECTORY_H #include "song.h" +#include "dirvec.h" #include "songvec.h" #define DIRECTORY_DIR "directory: " @@ -31,11 +32,6 @@ #define DIRECTORY_MPD_VERSION "mpd_version: " #define DIRECTORY_FS_CHARSET "fs_charset: " -struct dirvec { - struct directory **base; - size_t nr; -}; - struct directory { char *path; struct dirvec children; diff --git a/src/dirvec.h b/src/dirvec.h index 31719fcc8..24c960c2e 100644 --- a/src/dirvec.h +++ b/src/dirvec.h @@ -1,7 +1,12 @@ #ifndef DIRVEC_H #define DIRVEC_H -struct dirvec; +#include "os_compat.h" + +struct dirvec { + struct directory **base; + size_t nr; +}; void dirvec_sort(struct dirvec *dv); diff --git a/src/update.c b/src/update.c index 1cf6f3537..6e9f1572c 100644 --- a/src/update.c +++ b/src/update.c @@ -25,7 +25,6 @@ #include "playlist.h" #include "utils.h" #include "main_notify.h" -#include "dirvec.h" #include "condition.h" #include "update.h" -- cgit v1.2.3 From f2052e7e2ffb5b8ecd15d96a766b5a162a39b2af Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Thu, 9 Oct 2008 15:24:34 +0200 Subject: dirvec: constant pointers in dirvec_find() dirvec_find() does not modify the object, thus it should get a const pointer. --- src/dirvec.c | 2 +- src/dirvec.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/dirvec.c b/src/dirvec.c index 3ec5b7af1..fdfbb3434 100644 --- a/src/dirvec.c +++ b/src/dirvec.c @@ -21,7 +21,7 @@ void dirvec_sort(struct dirvec *dv) qsort(dv->base, dv->nr, sizeof(struct directory *), dirvec_cmp); } -struct directory *dirvec_find(struct dirvec *dv, const char *path) +struct directory *dirvec_find(const struct dirvec *dv, const char *path) { int i; diff --git a/src/dirvec.h b/src/dirvec.h index 24c960c2e..cc0b0d6c2 100644 --- a/src/dirvec.h +++ b/src/dirvec.h @@ -10,7 +10,7 @@ struct dirvec { void dirvec_sort(struct dirvec *dv); -struct directory *dirvec_find(struct dirvec *dv, const char *path); +struct directory *dirvec_find(const struct dirvec *dv, const char *path); int dirvec_delete(struct dirvec *dv, struct directory *del); -- cgit v1.2.3 From 4a13e19cebb8d72db6e2db9ffb9f9dbd7194ede9 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Thu, 9 Oct 2008 15:34:07 +0200 Subject: directory: added inline wrappers for accessing children Some tiny utilities... wrappers like these may become helpful when we introduce locking. --- src/directory.c | 2 +- src/directory.h | 14 ++++++++++++++ src/update.c | 10 ++++------ 3 files changed, 19 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/directory.c b/src/directory.c index 305cd5fe3..273515b91 100644 --- a/src/directory.c +++ b/src/directory.c @@ -79,7 +79,7 @@ directory_get_subdir(struct directory * directory, const char *name) while (1) { if (locate) *locate = '\0'; - if (!(found = dirvec_find(&cur->children, duplicated))) + if (!(found = directory_get_child(cur, duplicated))) break; assert(cur == found->parent); cur = found; diff --git a/src/directory.h b/src/directory.h index c767366a7..d8f86f50c 100644 --- a/src/directory.h +++ b/src/directory.h @@ -62,6 +62,20 @@ static inline const char * directory_get_path(struct directory *dir) return dir->path; } +static inline struct directory * +directory_get_child(const struct directory *directory, const char *name) +{ + return dirvec_find(&directory->children, name); +} + +static inline struct directory * +directory_new_child(struct directory *directory, const char *name) +{ + struct directory *subdir = directory_new(name, directory); + dirvec_add(&directory->children, subdir); + return subdir; +} + void directory_prune_empty(struct directory *directory); struct directory * diff --git a/src/update.c b/src/update.c index 6e9f1572c..b44d07075 100644 --- a/src/update.c +++ b/src/update.c @@ -230,7 +230,7 @@ updateInDirectory(struct directory *directory, const char *name) return UPDATE_RETURN_UPDATED; } } else if (S_ISDIR(st.st_mode)) { - struct directory *subdir = dirvec_find(&directory->children, name); + struct directory *subdir = directory_get_child(directory, name); if (subdir) { assert(directory == subdir->parent); directory_set_stat(subdir, &st); @@ -318,17 +318,15 @@ static struct directory * addDirectoryPathToDB(const char *utf8path) if (!parentDirectory) return NULL; - if ((directory = dirvec_find(&parentDirectory->children, utf8path))) { + if ((directory = directory_get_child(parentDirectory, utf8path))) { assert(parentDirectory == directory->parent); } else { struct stat st; if (myStat(utf8path, &st) < 0 || inodeFoundInParent(parentDirectory, st.st_ino, st.st_dev)) return NULL; - else { - directory = directory_new(utf8path, parentDirectory); - dirvec_add(&parentDirectory->children, directory); - } + + directory = directory_new_child(parentDirectory, utf8path); } /* if we're adding directory paths, make sure to delete filenames -- cgit v1.2.3 From 259f0fd80c9cf9eb06656dabcc6386a729d60127 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Thu, 9 Oct 2008 15:35:34 +0200 Subject: directory: check the absolute path of a subdirectory while loading A manipulated database could trigger an assertion failure, because the parent didn't match. Do a proper check if the new directory is within the parent's. This uses FATAL() to bail out, so MPD still dies, but it doesn't crash. --- src/directory_save.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src') diff --git a/src/directory_save.c b/src/directory_save.c index 27f7b14ce..cd79e178b 100644 --- a/src/directory_save.c +++ b/src/directory_save.c @@ -101,6 +101,10 @@ void directory_load(FILE * fp, struct directory * directory) if (prefixcmp(buffer, DIRECTORY_BEGIN)) FATAL("Error reading db at line: %s\n", buffer); name = &(buffer[strlen(DIRECTORY_BEGIN)]); + if (prefixcmp(name, directory->path) != 0) + FATAL("Wrong path in database: '%s' in '%s'\n", + name, directory->path); + if ((subdir = db_get_directory(name))) { assert(subdir->parent == directory); } else { -- cgit v1.2.3 From f5edfa1a93af9a8692d45d076a2f45cc25d33d94 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Thu, 9 Oct 2008 15:37:18 +0200 Subject: directory: don't query database during load Don't use db_get_directory() and traverse the full path with every directory being loaded. Just see if the current parent contains the entry. Everything else would be invalid anyway.. --- src/directory_save.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src') diff --git a/src/directory_save.c b/src/directory_save.c index cd79e178b..76eace90b 100644 --- a/src/directory_save.c +++ b/src/directory_save.c @@ -18,7 +18,6 @@ #include "directory_save.h" #include "directory.h" -#include "database.h" #include "song.h" #include "log.h" #include "path.h" @@ -105,7 +104,7 @@ void directory_load(FILE * fp, struct directory * directory) FATAL("Wrong path in database: '%s' in '%s'\n", name, directory->path); - if ((subdir = db_get_directory(name))) { + if ((subdir = directory_get_child(directory, name))) { assert(subdir->parent == directory); } else { subdir = directory_new(name, directory); -- cgit v1.2.3 From 8fabdfadaf2be72c5af9fd2b9804caf3cd0d14de Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Thu, 9 Oct 2008 15:37:21 +0200 Subject: update: removed addToDirectory() Use updateInDirectory() instead of addToDirectory(). Eliminate a duplicate stat() in updateInDirectory() by calling song_file_update() directly. --- src/update.c | 48 ++++++++++-------------------------------------- 1 file changed, 10 insertions(+), 38 deletions(-) (limited to 'src') diff --git a/src/update.c b/src/update.c index b44d07075..355821294 100644 --- a/src/update.c +++ b/src/update.c @@ -180,34 +180,6 @@ addSubDirectoryToDirectory(struct directory *directory, return UPDATE_RETURN_UPDATED; } -static enum update_return -addToDirectory(struct directory *directory, const char *name) -{ - struct stat st; - - if (myStat(name, &st)) { - DEBUG("failed to stat %s: %s\n", name, strerror(errno)); - return UPDATE_RETURN_ERROR; - } - if (S_ISREG(st.st_mode) && - hasMusicSuffix(name, 0) && isMusic(name, NULL, 0)) { - struct mpd_song *song; - const char *shortname = mpd_basename(name); - - if (!(song = song_file_load(shortname, directory))) - return -1; - songvec_add(&directory->songs, song); - LOG("added %s\n", name); - return UPDATE_RETURN_UPDATED; - } else if (S_ISDIR(st.st_mode)) { - return addSubDirectoryToDirectory(directory, name, &st); - } - - DEBUG("addToDirectory: %s is not a directory or music\n", name); - - return UPDATE_RETURN_ERROR; -} - static enum update_return updateInDirectory(struct directory *directory, const char *name) { @@ -221,7 +193,10 @@ updateInDirectory(struct directory *directory, const char *name) const char *shortname = mpd_basename(name); if (!(song = songvec_find(&directory->songs, shortname))) { - addToDirectory(directory, name); + if (!(song = song_file_load(shortname, directory))) + return -1; + songvec_add(&directory->songs, song); + LOG("added %s\n", name); return UPDATE_RETURN_UPDATED; } else if (st.st_mtime != song->mtime) { LOG("updating %s\n", name); @@ -240,6 +215,8 @@ updateInDirectory(struct directory *directory, const char *name) } } + DEBUG("update: %s is not a directory or music\n", name); + return UPDATE_RETURN_NOUPDATE; } @@ -285,14 +262,9 @@ enum update_return updateDirectory(struct directory *directory) if (!isRootDirectory(directory->path)) utf8 = pfx_dir(path_max_tmp, utf8, strlen(utf8), dirname, strlen(dirname)); - if (was_empty) { - if (addToDirectory(directory, path_max_tmp) == - UPDATE_RETURN_UPDATED) - ret = UPDATE_RETURN_UPDATED; - } else { - if (updateInDirectory(directory, path_max_tmp) > 0) - ret = UPDATE_RETURN_UPDATED; - } + if (updateInDirectory(directory, path_max_tmp) == + UPDATE_RETURN_UPDATED) + ret = UPDATE_RETURN_UPDATED; } closedir(dir); @@ -428,7 +400,7 @@ static enum update_return updatePath(const char *utf8path) } else if (0 == inodeFoundInParent(parentDirectory->parent, parentDirectory->inode, parentDirectory->device) - && addToDirectory(parentDirectory, utf8path) + && updateInDirectory(parentDirectory, utf8path) == UPDATE_RETURN_UPDATED) { ret = UPDATE_RETURN_UPDATED; } -- cgit v1.2.3 From 997d4c2ac9d6ea91cfcab8de195d3e7e40849a20 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Thu, 9 Oct 2008 15:37:41 +0200 Subject: dirvec: added dirvec_clear() --- src/dirvec.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src') diff --git a/src/dirvec.h b/src/dirvec.h index cc0b0d6c2..02496cd2b 100644 --- a/src/dirvec.h +++ b/src/dirvec.h @@ -16,6 +16,11 @@ int dirvec_delete(struct dirvec *dv, struct directory *del); void dirvec_add(struct dirvec *dv, struct directory *add); +static inline void dirvec_clear(struct dirvec *dv) +{ + dv->nr = 0; +} + void dirvec_destroy(struct dirvec *dv); #endif /* DIRVEC_H */ -- cgit v1.2.3 From 8aed358a9770618c93c0b33417f2b62fbb9a513e Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Thu, 9 Oct 2008 15:41:02 +0200 Subject: update: locked delete after update error When a directory failed to update, it was removed from the database, without freeing all children and songs (memory leak), and without locking (race condition). Introduce the functions clear_directory() and delete_directory(), which do both. --- src/update.c | 38 +++++++++++++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/update.c b/src/update.c index 355821294..6697a14c2 100644 --- a/src/update.c +++ b/src/update.c @@ -77,6 +77,42 @@ static void delete_song(struct directory *dir, struct mpd_song *del) song_free(del); } +static int delete_each_song(struct mpd_song *song, mpd_unused void *data) +{ + struct directory *directory = data; + assert(song->parent == directory); + delete_song(directory, song); + return 0; +} + +/** + * Recursively remove all sub directories and songs from a directory, + * leaving an empty directory. + */ +static void clear_directory(struct directory *directory) +{ + int i; + + for (i = directory->children.nr; --i >= 0;) + clear_directory(directory->children.base[i]); + dirvec_clear(&directory->children); + + songvec_for_each(&directory->songs, delete_each_song, directory); +} + +/** + * Recursively free a directory and all its contents. + */ +static void delete_directory(struct directory *directory) +{ + assert(directory->parent != NULL); + + clear_directory(directory); + + dirvec_delete(&directory->parent->children, directory); + directory_free(directory); +} + struct delete_data { char *tmp; struct directory *dir; @@ -357,7 +393,7 @@ static enum update_return updatePath(const char *utf8path) /* if updateDirectory fails, means we should delete it */ else { LOG("removing directory: %s\n", utf8path); - dirvec_delete(&parentDirectory->children, directory); + delete_directory(directory); ret = UPDATE_RETURN_UPDATED; /* don't return, path maybe a song now */ } -- cgit v1.2.3 From 017e2e4a4e8e8b60446cd90fe3d7ab1b3165572e Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Thu, 9 Oct 2008 15:42:30 +0200 Subject: update: clear root after error When the root directory fails to update, its contents are invalid. Clear it then. --- src/update.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/update.c b/src/update.c index 6697a14c2..564e691d0 100644 --- a/src/update.c +++ b/src/update.c @@ -388,6 +388,7 @@ static enum update_return updatePath(const char *utf8path) } /* we don't want to delete the root directory */ else if (directory == db_get_root()) { + clear_directory(directory); return UPDATE_RETURN_NOUPDATE; } /* if updateDirectory fails, means we should delete it */ -- cgit v1.2.3 From 189e7bbfe4ca060bc26bc917bd65b71a38851d13 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Thu, 9 Oct 2008 15:47:22 +0200 Subject: update: moved code to directory_make_child_checked() The branching looks a bit complicated in addDirectoryPathToDB() - improve its readability by moving code to a simplified separate function. --- src/update.c | 47 +++++++++++++++++++++++++---------------------- 1 file changed, 25 insertions(+), 22 deletions(-) (limited to 'src') diff --git a/src/update.c b/src/update.c index 564e691d0..73ab142c1 100644 --- a/src/update.c +++ b/src/update.c @@ -308,13 +308,34 @@ enum update_return updateDirectory(struct directory *directory) return ret; } -static struct directory * addDirectoryPathToDB(const char *utf8path) +static struct directory * +directory_make_child_checked(struct directory *parent, const char *path) +{ + struct directory *directory; + struct stat st; + struct mpd_song *conflicting; + + if ((directory = directory_get_child(parent, path))) + return directory; + + if (myStat(path, &st) < 0 || + inodeFoundInParent(parent, st.st_ino, st.st_dev)) + return NULL; + + /* if we're adding directory paths, make sure to delete filenames + with potentially the same name */ + if ((conflicting = songvec_find(&parent->songs, mpd_basename(path)))) + delete_song(parent, conflicting); + + return directory_new_child(parent, path); +} + +static struct directory * +addDirectoryPathToDB(const char *utf8path) { char path_max_tmp[MPD_PATH_MAX]; char *parent; struct directory *parentDirectory; - struct directory *directory; - struct mpd_song *conflicting; parent = parent_path(path_max_tmp, utf8path); @@ -326,25 +347,7 @@ static struct directory * addDirectoryPathToDB(const char *utf8path) if (!parentDirectory) return NULL; - if ((directory = directory_get_child(parentDirectory, utf8path))) { - assert(parentDirectory == directory->parent); - } else { - struct stat st; - if (myStat(utf8path, &st) < 0 || - inodeFoundInParent(parentDirectory, st.st_ino, st.st_dev)) - return NULL; - - directory = directory_new_child(parentDirectory, utf8path); - } - - /* if we're adding directory paths, make sure to delete filenames - with potentially the same name */ - conflicting = songvec_find(&parentDirectory->songs, - mpd_basename(directory->path)); - if (conflicting) - delete_song(parentDirectory, conflicting); - - return directory; + return directory_make_child_checked(parentDirectory, utf8path); } static struct directory * addParentPathToDB(const char *utf8path) -- cgit v1.2.3 From 50f1074c1b0b156e484401c6455e881cd830c2f7 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Thu, 9 Oct 2008 15:47:59 +0200 Subject: update: delete directory after failed update When a directory cannot be updated, there must be something wrong with it, and the database contains stale data. Remove it. --- src/update.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/update.c b/src/update.c index 73ab142c1..dd48bfe78 100644 --- a/src/update.c +++ b/src/update.c @@ -243,9 +243,16 @@ updateInDirectory(struct directory *directory, const char *name) } else if (S_ISDIR(st.st_mode)) { struct directory *subdir = directory_get_child(directory, name); if (subdir) { + enum update_return ret; + assert(directory == subdir->parent); directory_set_stat(subdir, &st); - return updateDirectory(subdir); + + ret = updateDirectory(subdir); + if (ret == UPDATE_RETURN_ERROR) + delete_directory(subdir); + + return ret; } else { return addSubDirectoryToDirectory(directory, name, &st); } -- cgit v1.2.3 From f2fd7be1d7b80da32611c57360e71fb777b95c7d Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Thu, 9 Oct 2008 15:48:07 +0200 Subject: update: make addDirectoryPathToDB() non-recursive This recursive function is very dangerous because it allocates a large buffer on the stack in every iteration. That may be misused to generate a stack overflow. --- src/update.c | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/update.c b/src/update.c index dd48bfe78..1415852e0 100644 --- a/src/update.c +++ b/src/update.c @@ -340,21 +340,23 @@ directory_make_child_checked(struct directory *parent, const char *path) static struct directory * addDirectoryPathToDB(const char *utf8path) { - char path_max_tmp[MPD_PATH_MAX]; - char *parent; - struct directory *parentDirectory; + struct directory *directory = db_get_root(); + char *duplicated = xstrdup(utf8path); + char *slash = duplicated; - parent = parent_path(path_max_tmp, utf8path); + while (1) { + if ((slash = strchr(slash, '/'))) + *slash = 0; - if (strlen(parent) == 0) - parentDirectory = db_get_root(); - else - parentDirectory = addDirectoryPathToDB(parent); + directory = directory_make_child_checked(directory, duplicated); + if (!directory || !slash) + break; - if (!parentDirectory) - return NULL; + *slash++ = '/'; + } - return directory_make_child_checked(parentDirectory, utf8path); + free(duplicated); + return directory; } static struct directory * addParentPathToDB(const char *utf8path) -- cgit v1.2.3 From 08ac9c4b05d51f79733b6ad27b7a79240c92fb03 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Thu, 9 Oct 2008 15:48:39 +0200 Subject: update: merged addDirectoryPathToDB() into addParentPathToDB() The algorithm in addDirectoryPathToDB() can be simplified further if it is combined with the function addParentPathToDB(). Since there is no other caller of addDirectoryPathToDB(), we can do that. This saves another large stack buffer. --- src/update.c | 26 +++----------------------- 1 file changed, 3 insertions(+), 23 deletions(-) (limited to 'src') diff --git a/src/update.c b/src/update.c index 1415852e0..c2f611e9e 100644 --- a/src/update.c +++ b/src/update.c @@ -338,15 +338,14 @@ directory_make_child_checked(struct directory *parent, const char *path) } static struct directory * -addDirectoryPathToDB(const char *utf8path) +addParentPathToDB(const char *utf8path) { struct directory *directory = db_get_root(); char *duplicated = xstrdup(utf8path); char *slash = duplicated; - while (1) { - if ((slash = strchr(slash, '/'))) - *slash = 0; + while ((slash = strchr(slash, '/'))) { + *slash = 0; directory = directory_make_child_checked(directory, duplicated); if (!directory || !slash) @@ -359,25 +358,6 @@ addDirectoryPathToDB(const char *utf8path) return directory; } -static struct directory * addParentPathToDB(const char *utf8path) -{ - char *parent; - char path_max_tmp[MPD_PATH_MAX]; - struct directory *parentDirectory; - - parent = parent_path(path_max_tmp, utf8path); - - if (strlen(parent) == 0) - parentDirectory = db_get_root(); - else - parentDirectory = addDirectoryPathToDB(parent); - - if (!parentDirectory) - return NULL; - - return (struct directory *) parentDirectory; -} - static enum update_return updatePath(const char *utf8path) { struct directory *directory; -- cgit v1.2.3 From e553fa4d36016cd4ba2162a64d8a770bef618608 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Thu, 9 Oct 2008 19:11:49 +0200 Subject: update: never pass root path to updatePath() update_task() already checks if it has got a root path. Extend this check and in turn remove a check in the inner function updatePath(). --- src/update.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'src') diff --git a/src/update.c b/src/update.c index c2f611e9e..e2afb7f81 100644 --- a/src/update.c +++ b/src/update.c @@ -378,11 +378,6 @@ static enum update_return updatePath(const char *utf8path) directory_sort(directory); return ret; } - /* we don't want to delete the root directory */ - else if (directory == db_get_root()) { - clear_directory(directory); - return UPDATE_RETURN_NOUPDATE; - } /* if updateDirectory fails, means we should delete it */ else { LOG("removing directory: %s\n", utf8path); @@ -442,7 +437,7 @@ static void * update_task(void *_path) { enum update_return ret = UPDATE_RETURN_NOUPDATE; - if (_path) { + if (_path != NULL && !isRootDirectory(_path)) { ret = updatePath((char *)_path); free(_path); } else { -- cgit v1.2.3 From 1f70121c5604be45e81c5a07d59efea2aaa1597b Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Thu, 9 Oct 2008 19:11:51 +0200 Subject: update: pass const pointer to addSubDirectoryToDirectory() The stat struct isn't going to be modified, make it const. --- src/update.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/update.c b/src/update.c index e2afb7f81..49850256c 100644 --- a/src/update.c +++ b/src/update.c @@ -196,7 +196,7 @@ inodeFoundInParent(struct directory *parent, ino_t inode, dev_t device) static enum update_return addSubDirectoryToDirectory(struct directory *directory, - const char *name, struct stat *st) + const char *name, const struct stat *st) { struct directory *subDirectory; -- cgit v1.2.3 From 6fd08bc8fad5d6c4be37ce751d53ef80b756b292 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Thu, 9 Oct 2008 19:11:54 +0200 Subject: update: don't export updateDirectory() If the user requests database update during startup, call directory_update_init(). This should be changed to fully asynchronous update later. For this to work, main_notify has to be initialized before db_init(). --- src/database.c | 10 +++++++++- src/main.c | 3 ++- src/update.c | 10 +++++++++- src/update.h | 10 ---------- 4 files changed, 20 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/database.c b/src/database.c index 11de15bcc..3a1667bb6 100644 --- a/src/database.c +++ b/src/database.c @@ -39,7 +39,15 @@ static time_t directory_dbModTime; void db_init(void) { music_root = directory_new("", NULL); - updateDirectory(music_root); + + if (directory_update_init(NULL) < 0) + FATAL("directory update failed\n"); + + do { + my_usleep(100000); + reap_update_task(); + } while (isUpdatingDB()); + stats.numberOfSongs = countSongsIn(NULL); stats.dbPlayTime = sumSongTimesIn(NULL); } diff --git a/src/main.c b/src/main.c index 07f0f528a..f1c288dd5 100644 --- a/src/main.c +++ b/src/main.c @@ -409,6 +409,8 @@ int main(int argc, char *argv[]) initPlaylist(); initInputPlugins(); + init_main_notify(); + openDB(&options, argv[0]); initCommands(); @@ -424,7 +426,6 @@ int main(int argc, char *argv[]) daemonize(&options); - init_main_notify(); init_output_buffer(); setup_log_output(options.stdOutput); diff --git a/src/update.c b/src/update.c index 49850256c..641b1d63b 100644 --- a/src/update.c +++ b/src/update.c @@ -28,6 +28,12 @@ #include "condition.h" #include "update.h" +enum update_return { + UPDATE_RETURN_ERROR = -1, + UPDATE_RETURN_NOUPDATE = 0, + UPDATE_RETURN_UPDATED = 1 +}; + enum update_progress { UPDATE_PROGRESS_IDLE = 0, UPDATE_PROGRESS_RUNNING = 1, @@ -194,6 +200,8 @@ inodeFoundInParent(struct directory *parent, ino_t inode, dev_t device) return 0; } +static enum update_return updateDirectory(struct directory *directory); + static enum update_return addSubDirectoryToDirectory(struct directory *directory, const char *name, const struct stat *st) @@ -269,7 +277,7 @@ static int skip_path(const char *path) return (path[0] == '.' || strchr(path, '\n')) ? 1 : 0; } -enum update_return updateDirectory(struct directory *directory) +static enum update_return updateDirectory(struct directory *directory) { int was_empty = directory_is_empty(directory); DIR *dir; diff --git a/src/update.h b/src/update.h index 65ffdc3bf..0c0d74416 100644 --- a/src/update.h +++ b/src/update.h @@ -20,18 +20,8 @@ #ifndef UPDATE_H #define UPDATE_H -struct directory; - -enum update_return { - UPDATE_RETURN_ERROR = -1, - UPDATE_RETURN_NOUPDATE = 0, - UPDATE_RETURN_UPDATED = 1 -}; - int isUpdatingDB(void); -enum update_return updateDirectory(struct directory *directory); - /* * returns the non-negative update job ID on success, * returns -1 if busy -- cgit v1.2.3 From 2d6a943bf0c84a2ece6014d7a74b25f819bc4510 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Thu, 9 Oct 2008 19:13:02 +0200 Subject: update: rewrote updatePath() using updateInDirectory() updatePath() duplicated a lot of code from the more generic updateInDirectory(). Eliminate most of updatePath() and call updateInDirectory(). --- src/update.c | 89 +++++++++++++----------------------------------------------- 1 file changed, 19 insertions(+), 70 deletions(-) (limited to 'src') diff --git a/src/update.c b/src/update.c index 641b1d63b..e1d0268a8 100644 --- a/src/update.c +++ b/src/update.c @@ -140,6 +140,21 @@ static int delete_song_if_removed(struct mpd_song *song, void *_data) return 0; } +static enum update_return delete_path(const char *path) +{ + struct directory *directory = db_get_directory(path); + struct mpd_song *song = db_get_song(path); + + if (directory) + delete_directory(directory); + if (song) + delete_song(song->parent, song); + + return directory == NULL && song == NULL + ? UPDATE_RETURN_NOUPDATE + : UPDATE_RETURN_UPDATED; +} + static enum update_return removeDeletedFromDirectory(char *path_max_tmp, struct directory *directory) { @@ -368,77 +383,11 @@ addParentPathToDB(const char *utf8path) static enum update_return updatePath(const char *utf8path) { - struct directory *directory; - struct directory *parentDirectory; - struct mpd_song *song; - time_t mtime; - enum update_return ret = UPDATE_RETURN_NOUPDATE; - char path_max_tmp[MPD_PATH_MAX]; - - assert(utf8path); - - /* if path is in the DB try to update it, or else delete it */ - if ((directory = db_get_directory(utf8path))) { - parentDirectory = directory->parent; - - /* if this update directory is successfull, we are done */ - if ((ret = updateDirectory(directory)) >= 0) { - directory_sort(directory); - return ret; - } - /* if updateDirectory fails, means we should delete it */ - else { - LOG("removing directory: %s\n", utf8path); - delete_directory(directory); - ret = UPDATE_RETURN_UPDATED; - /* don't return, path maybe a song now */ - } - } else if ((song = db_get_song(utf8path))) { - parentDirectory = song->parent; - if (!parentDirectory->stat - && statDirectory(parentDirectory) < 0) { - return UPDATE_RETURN_NOUPDATE; - } - /* if this song update is successful, we are done */ - else if (!inodeFoundInParent(parentDirectory->parent, - parentDirectory->inode, - parentDirectory->device) && - isMusic(song_get_url(song, path_max_tmp), &mtime, 0)) { - if (song->mtime == mtime) - return UPDATE_RETURN_NOUPDATE; - else if (song_file_update(song)) - return UPDATE_RETURN_UPDATED; - else { - delete_song(parentDirectory, song); - return UPDATE_RETURN_UPDATED; - } - } - /* if updateDirectory fails, means we should delete it */ - else { - delete_song(parentDirectory, song); - ret = UPDATE_RETURN_UPDATED; - /* don't return, path maybe a directory now */ - } - } - - /* path not found in the db, see if it actually exists on the fs. - * Also, if by chance a directory was replaced by a file of the same - * name or vice versa, we need to add it to the db - */ - if (isDir(utf8path) || isMusic(utf8path, NULL, 0)) { - parentDirectory = addParentPathToDB(utf8path); - if (!parentDirectory || (!parentDirectory->stat && - statDirectory(parentDirectory) < 0)) { - } else if (0 == inodeFoundInParent(parentDirectory->parent, - parentDirectory->inode, - parentDirectory->device) - && updateInDirectory(parentDirectory, utf8path) - == UPDATE_RETURN_UPDATED) { - ret = UPDATE_RETURN_UPDATED; - } - } + struct stat st; - return ret; + if (myStat(path, &st) < 0) + return delete_path(path); + return updateInDirectory(addParentPathToDB(path), path); } static void * update_task(void *_path) -- cgit v1.2.3 From e2d7fa53aa587b874709d441ecc782f745fd4b3e Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Thu, 9 Oct 2008 19:13:03 +0200 Subject: update: avoid duplicate stat() calls Pass a pointer to the stat struct to more functions. --- src/update.c | 66 ++++++++++++++++++++++++++++++++++-------------------------- 1 file changed, 38 insertions(+), 28 deletions(-) (limited to 'src') diff --git a/src/update.c b/src/update.c index e1d0268a8..410d906ff 100644 --- a/src/update.c +++ b/src/update.c @@ -215,7 +215,8 @@ inodeFoundInParent(struct directory *parent, ino_t inode, dev_t device) return 0; } -static enum update_return updateDirectory(struct directory *directory); +static enum update_return +updateDirectory(struct directory *directory, const struct stat *st); static enum update_return addSubDirectoryToDirectory(struct directory *directory, @@ -227,9 +228,7 @@ addSubDirectoryToDirectory(struct directory *directory, return UPDATE_RETURN_NOUPDATE; subDirectory = directory_new(name, directory); - directory_set_stat(subDirectory, st); - - if (updateDirectory(subDirectory) != UPDATE_RETURN_UPDATED) { + if (updateDirectory(subDirectory, st) != UPDATE_RETURN_UPDATED) { directory_free(subDirectory); return UPDATE_RETURN_NOUPDATE; } @@ -240,15 +239,12 @@ addSubDirectoryToDirectory(struct directory *directory, } static enum update_return -updateInDirectory(struct directory *directory, const char *name) +updateInDirectory(struct directory *directory, + const char *name, const struct stat *st) { struct mpd_song *song; - struct stat st; - if (myStat(name, &st)) - return UPDATE_RETURN_ERROR; - - if (S_ISREG(st.st_mode) && hasMusicSuffix(name, 0)) { + if (S_ISREG(st->st_mode) && hasMusicSuffix(name, 0)) { const char *shortname = mpd_basename(name); if (!(song = songvec_find(&directory->songs, shortname))) { @@ -257,27 +253,26 @@ updateInDirectory(struct directory *directory, const char *name) songvec_add(&directory->songs, song); LOG("added %s\n", name); return UPDATE_RETURN_UPDATED; - } else if (st.st_mtime != song->mtime) { + } else if (st->st_mtime != song->mtime) { LOG("updating %s\n", name); if (!song_file_update(song)) delete_song(directory, song); return UPDATE_RETURN_UPDATED; } - } else if (S_ISDIR(st.st_mode)) { + } else if (S_ISDIR(st->st_mode)) { struct directory *subdir = directory_get_child(directory, name); if (subdir) { enum update_return ret; assert(directory == subdir->parent); - directory_set_stat(subdir, &st); - ret = updateDirectory(subdir); + ret = updateDirectory(subdir, st); if (ret == UPDATE_RETURN_ERROR) delete_directory(subdir); return ret; } else { - return addSubDirectoryToDirectory(directory, name, &st); + return addSubDirectoryToDirectory(directory, name, st); } } @@ -292,7 +287,8 @@ static int skip_path(const char *path) return (path[0] == '.' || strchr(path, '\n')) ? 1 : 0; } -static enum update_return updateDirectory(struct directory *directory) +static enum update_return +updateDirectory(struct directory *directory, const struct stat *st) { int was_empty = directory_is_empty(directory); DIR *dir; @@ -300,12 +296,14 @@ static enum update_return updateDirectory(struct directory *directory) struct dirent *ent; char path_max_tmp[MPD_PATH_MAX]; enum update_return ret = UPDATE_RETURN_NOUPDATE; + enum update_return ret2; - if (!directory->stat && statDirectory(directory) < 0) - return UPDATE_RETURN_ERROR; - else if (inodeFoundInParent(directory->parent, - directory->inode, - directory->device)) + assert(S_ISDIR(st->st_mode)); + + directory_set_stat(directory, st); + + if (inodeFoundInParent(directory->parent, + directory->inode, directory->device)) return UPDATE_RETURN_ERROR; dir = opendir(opendir_path(path_max_tmp, dirname)); @@ -318,6 +316,8 @@ static enum update_return updateDirectory(struct directory *directory) while ((ent = readdir(dir))) { char *utf8; + struct stat st2; + if (skip_path(ent->d_name)) continue; @@ -328,9 +328,13 @@ static enum update_return updateDirectory(struct directory *directory) if (!isRootDirectory(directory->path)) utf8 = pfx_dir(path_max_tmp, utf8, strlen(utf8), dirname, strlen(dirname)); - if (updateInDirectory(directory, path_max_tmp) == - UPDATE_RETURN_UPDATED) - ret = UPDATE_RETURN_UPDATED; + + if (myStat(path_max_tmp, &st2) == 0) + ret2 = updateInDirectory(directory, path_max_tmp, &st2); + else + ret2 = delete_path(path_max_tmp); + if (ret == UPDATE_RETURN_NOUPDATE) + ret = ret2; } closedir(dir); @@ -385,9 +389,9 @@ static enum update_return updatePath(const char *utf8path) { struct stat st; - if (myStat(path, &st) < 0) - return delete_path(path); - return updateInDirectory(addParentPathToDB(path), path); + if (myStat(utf8path, &st) < 0) + return delete_path(utf8path); + return updateInDirectory(addParentPathToDB(utf8path), utf8path, &st); } static void * update_task(void *_path) @@ -398,7 +402,13 @@ static void * update_task(void *_path) ret = updatePath((char *)_path); free(_path); } else { - ret = updateDirectory(db_get_root()); + struct directory *directory = db_get_root(); + struct stat st; + + if (myStat(directory_get_path(directory), &st) == 0) + ret = updateDirectory(directory, &st); + else + ret = UPDATE_RETURN_ERROR; } if (ret == UPDATE_RETURN_UPDATED && db_save() < 0) -- cgit v1.2.3 From 120aa4bfb5c0b6962ee50559c0263f8e850f2c88 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Thu, 9 Oct 2008 19:14:04 +0200 Subject: update: copy stat to new directory When reading a new directory, copy the stat data (which we have anyway) to the directory struct. This may save a stat() in the future. --- src/update.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/update.c b/src/update.c index 410d906ff..c8eb33b6d 100644 --- a/src/update.c +++ b/src/update.c @@ -361,7 +361,9 @@ directory_make_child_checked(struct directory *parent, const char *path) if ((conflicting = songvec_find(&parent->songs, mpd_basename(path)))) delete_song(parent, conflicting); - return directory_new_child(parent, path); + directory = directory_new_child(parent, path); + directory_set_stat(directory, &st); + return directory; } static struct directory * -- cgit v1.2.3 From 01bf8687f27db7d4ddec019a606670d43ec14680 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Thu, 9 Oct 2008 19:15:56 +0200 Subject: update: do the recursive directory check only once The recursive checks were performed in several functions, and sometimes a directory was checked twice. --- src/update.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/update.c b/src/update.c index c8eb33b6d..5b2721cdb 100644 --- a/src/update.c +++ b/src/update.c @@ -224,9 +224,6 @@ addSubDirectoryToDirectory(struct directory *directory, { struct directory *subDirectory; - if (inodeFoundInParent(directory, st->st_ino, st->st_dev)) - return UPDATE_RETURN_NOUPDATE; - subDirectory = directory_new(name, directory); if (updateDirectory(subDirectory, st) != UPDATE_RETURN_UPDATED) { directory_free(subDirectory); @@ -260,8 +257,12 @@ updateInDirectory(struct directory *directory, return UPDATE_RETURN_UPDATED; } } else if (S_ISDIR(st->st_mode)) { - struct directory *subdir = directory_get_child(directory, name); - if (subdir) { + struct directory *subdir; + + if (inodeFoundInParent(directory, st->st_ino, st->st_dev)) + return UPDATE_RETURN_ERROR; + + if ((subdir = directory_get_child(directory, name))) { enum update_return ret; assert(directory == subdir->parent); @@ -302,10 +303,6 @@ updateDirectory(struct directory *directory, const struct stat *st) directory_set_stat(directory, st); - if (inodeFoundInParent(directory->parent, - directory->inode, directory->device)) - return UPDATE_RETURN_ERROR; - dir = opendir(opendir_path(path_max_tmp, dirname)); if (!dir) return UPDATE_RETURN_ERROR; -- cgit v1.2.3 From 7945d695e5ebcfea8e41e0c3b2dc5b72f8b0a0b9 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Thu, 9 Oct 2008 19:16:21 +0200 Subject: update: make the "song" variable more local --- src/update.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src') diff --git a/src/update.c b/src/update.c index 5b2721cdb..a1e33ba22 100644 --- a/src/update.c +++ b/src/update.c @@ -239,10 +239,9 @@ static enum update_return updateInDirectory(struct directory *directory, const char *name, const struct stat *st) { - struct mpd_song *song; - if (S_ISREG(st->st_mode) && hasMusicSuffix(name, 0)) { const char *shortname = mpd_basename(name); + struct mpd_song *song; if (!(song = songvec_find(&directory->songs, shortname))) { if (!(song = song_file_load(shortname, directory))) -- cgit v1.2.3 From 516540ba565d47c79ac18f8bfe395e0d38598fea Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Thu, 9 Oct 2008 19:17:25 +0200 Subject: update: eliminated addSubDirectoryToDirectory() In updateInDirectory(), add new directories immediately and delete them when they turn out to be empty. This simplifies the code and allows us to eliminate addSubDirectoryToDirectory(). --- src/update.c | 35 ++++++++--------------------------- 1 file changed, 8 insertions(+), 27 deletions(-) (limited to 'src') diff --git a/src/update.c b/src/update.c index a1e33ba22..69ae9794d 100644 --- a/src/update.c +++ b/src/update.c @@ -218,23 +218,6 @@ inodeFoundInParent(struct directory *parent, ino_t inode, dev_t device) static enum update_return updateDirectory(struct directory *directory, const struct stat *st); -static enum update_return -addSubDirectoryToDirectory(struct directory *directory, - const char *name, const struct stat *st) -{ - struct directory *subDirectory; - - subDirectory = directory_new(name, directory); - if (updateDirectory(subDirectory, st) != UPDATE_RETURN_UPDATED) { - directory_free(subDirectory); - return UPDATE_RETURN_NOUPDATE; - } - - dirvec_add(&directory->children, subDirectory); - - return UPDATE_RETURN_UPDATED; -} - static enum update_return updateInDirectory(struct directory *directory, const char *name, const struct stat *st) @@ -257,23 +240,21 @@ updateInDirectory(struct directory *directory, } } else if (S_ISDIR(st->st_mode)) { struct directory *subdir; + enum update_return ret; if (inodeFoundInParent(directory, st->st_ino, st->st_dev)) return UPDATE_RETURN_ERROR; - if ((subdir = directory_get_child(directory, name))) { - enum update_return ret; + if (!(subdir = directory_get_child(directory, name))) + subdir = directory_new_child(directory, name); - assert(directory == subdir->parent); + assert(directory == subdir->parent); - ret = updateDirectory(subdir, st); - if (ret == UPDATE_RETURN_ERROR) - delete_directory(subdir); + ret = updateDirectory(subdir, st); + if (ret == UPDATE_RETURN_ERROR || directory_is_empty(subdir)) + delete_directory(subdir); - return ret; - } else { - return addSubDirectoryToDirectory(directory, name, st); - } + return ret; } DEBUG("update: %s is not a directory or music\n", name); -- cgit v1.2.3 From 0d4cc41ae07ca3f2e079fced38d9bd244c787df8 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Thu, 9 Oct 2008 19:17:26 +0200 Subject: updated: always call removeDeletedFromDirectory() Removed the local variable "was_empty": don't remember if the directory is new. Always call removeDeletedFromDirectory(). --- src/update.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'src') diff --git a/src/update.c b/src/update.c index 69ae9794d..4498449bd 100644 --- a/src/update.c +++ b/src/update.c @@ -271,7 +271,6 @@ static int skip_path(const char *path) static enum update_return updateDirectory(struct directory *directory, const struct stat *st) { - int was_empty = directory_is_empty(directory); DIR *dir; const char *dirname = directory_get_path(directory); struct dirent *ent; @@ -287,8 +286,7 @@ updateDirectory(struct directory *directory, const struct stat *st) if (!dir) return UPDATE_RETURN_ERROR; - if (!was_empty && - removeDeletedFromDirectory(path_max_tmp, directory) > 0) + if (removeDeletedFromDirectory(path_max_tmp, directory) > 0) ret = UPDATE_RETURN_UPDATED; while ((ent = readdir(dir))) { -- cgit v1.2.3 From 0775237e40087ee328888eb2b16953dc0cb332e0 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Thu, 9 Oct 2008 19:17:33 +0200 Subject: update: fixed stack corruption due to pthread_join() call pthread_join() expects a "pointer to a pointer" parameter, but it got a "pointer to an enum". On AMD64, an enum is smaller than a pointer, leading to a buffer overflow. --- src/update.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/update.c b/src/update.c index 4498449bd..34ec1ba77 100644 --- a/src/update.c +++ b/src/update.c @@ -433,6 +433,7 @@ int directory_update_init(char *path) void reap_update_task(void) { + void *thread_return; enum update_return ret; assert(pthread_equal(pthread_self(), main_task)); @@ -449,8 +450,9 @@ void reap_update_task(void) if (progress != UPDATE_PROGRESS_DONE) return; - if (pthread_join(update_thr, (void **)&ret)) + if (pthread_join(update_thr, &thread_return)) FATAL("error joining update thread: %s\n", strerror(errno)); + ret = (enum update_return)(size_t)thread_return; if (ret == UPDATE_RETURN_UPDATED) playlistVersionChange(); -- cgit v1.2.3 From e5c747982adfae06c51b60819ec6a4ef5a34ffe2 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Thu, 9 Oct 2008 19:17:38 +0200 Subject: update: check progress!=IDLE in reap_update_task() When the update task is idle, there is no need to check for deleted songs. Return early from reap_update_task(). --- src/update.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src') diff --git a/src/update.c b/src/update.c index 34ec1ba77..f5619a1d4 100644 --- a/src/update.c +++ b/src/update.c @@ -438,6 +438,9 @@ void reap_update_task(void) assert(pthread_equal(pthread_self(), main_task)); + if (progress == UPDATE_PROGRESS_IDLE) + return; + cond_enter(&delete_cond); if (delete) { char tmp[MPD_PATH_MAX]; -- cgit v1.2.3 From 1d59716731f3ed8569d60ae84c291bd93eb7d582 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Thu, 9 Oct 2008 19:17:44 +0200 Subject: update: job ID must be positive The documentation for directory_update_init() was incorrect: a job ID must be positive, not non-negative. If the update queue is full and no job was created, it makes more sense to return 0 instead of -1, because it is more consistent with the return value of isUpdatingDB(). --- src/command.c | 8 +++----- src/database.c | 2 +- src/update.c | 4 ++-- src/update.h | 4 ++-- 4 files changed, 8 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/command.c b/src/command.c index aafb88418..541a71a50 100644 --- a/src/command.c +++ b/src/command.c @@ -788,14 +788,12 @@ static int handlePlaylistMove(int fd, mpd_unused int *permission, static int print_update_result(int fd, int ret) { - if (ret >= 0) { + if (ret > 0) { fdprintf(fd, "updating_db: %i\n", ret); return 0; } - if (ret == -2) - commandError(fd, ACK_ERROR_ARG, "invalid path"); - else - commandError(fd, ACK_ERROR_UPDATE_ALREADY, "already updating"); + assert(!ret); + commandError(fd, ACK_ERROR_UPDATE_ALREADY, "already updating"); return -1; } diff --git a/src/database.c b/src/database.c index 3a1667bb6..ea78940f8 100644 --- a/src/database.c +++ b/src/database.c @@ -40,7 +40,7 @@ void db_init(void) { music_root = directory_new("", NULL); - if (directory_update_init(NULL) < 0) + if (!directory_update_init(NULL)) FATAL("directory update failed\n"); do { diff --git a/src/update.c b/src/update.c index f5619a1d4..7dc50b5aa 100644 --- a/src/update.c +++ b/src/update.c @@ -418,9 +418,9 @@ int directory_update_init(char *path) int next_task_id; if (!path) - return -1; + return 0; if (update_paths_nr == ARRAY_SIZE(update_paths)) - return -1; + return 0; assert(update_paths_nr < ARRAY_SIZE(update_paths)); update_paths[update_paths_nr++] = path; next_task_id = update_task_id + update_paths_nr; diff --git a/src/update.h b/src/update.h index 0c0d74416..5c7277e32 100644 --- a/src/update.h +++ b/src/update.h @@ -23,8 +23,8 @@ int isUpdatingDB(void); /* - * returns the non-negative update job ID on success, - * returns -1 if busy + * returns the positive update job ID on success, + * returns 0 if busy * @path will be freed by this function and should not be reused */ int directory_update_init(char *path); -- cgit v1.2.3 From e3ac6a123a442cf9d1f9147b122f21a1f3f1ebb2 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Thu, 9 Oct 2008 19:20:05 +0200 Subject: update: make the job id unsigned Since the return value cannot be -1 anymore, we can make it unsigned. --- src/update.c | 10 +++++----- src/update.h | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/update.c b/src/update.c index 7dc50b5aa..68e030b78 100644 --- a/src/update.c +++ b/src/update.c @@ -46,15 +46,15 @@ static size_t update_paths_nr; static pthread_t update_thr; -static const int update_task_id_max = 1 << 15; +static const unsigned update_task_id_max = 1 << 15; -static int update_task_id; +static unsigned update_task_id; static struct mpd_song *delete; static struct condition delete_cond; -int isUpdatingDB(void) +unsigned isUpdatingDB(void) { return (progress != UPDATE_PROGRESS_IDLE) ? update_task_id : 0; } @@ -410,12 +410,12 @@ static void spawn_update_task(char *path) DEBUG("spawned thread for update job id %i\n", update_task_id); } -int directory_update_init(char *path) +unsigned directory_update_init(char *path) { assert(pthread_equal(pthread_self(), main_task)); if (progress != UPDATE_PROGRESS_IDLE) { - int next_task_id; + unsigned next_task_id; if (!path) return 0; diff --git a/src/update.h b/src/update.h index 5c7277e32..0842c0df0 100644 --- a/src/update.h +++ b/src/update.h @@ -20,14 +20,14 @@ #ifndef UPDATE_H #define UPDATE_H -int isUpdatingDB(void); +unsigned isUpdatingDB(void); /* * returns the positive update job ID on success, * returns 0 if busy * @path will be freed by this function and should not be reused */ -int directory_update_init(char *path); +unsigned directory_update_init(char *path); void reap_update_task(void); -- cgit v1.2.3 From ab7e9dd283abdea1ec94c75b94e450ba39fa3835 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Thu, 9 Oct 2008 19:20:54 +0200 Subject: update: fix memory leak in directory_update_init() When the update queue is full, directory_update_init() did not free the path argument. --- src/update.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/update.c b/src/update.c index 68e030b78..b910486e0 100644 --- a/src/update.c +++ b/src/update.c @@ -419,8 +419,11 @@ unsigned directory_update_init(char *path) if (!path) return 0; - if (update_paths_nr == ARRAY_SIZE(update_paths)) + if (update_paths_nr == ARRAY_SIZE(update_paths)) { + free(path); return 0; + } + assert(update_paths_nr < ARRAY_SIZE(update_paths)); update_paths[update_paths_nr++] = path; next_task_id = update_task_id + update_paths_nr; -- cgit v1.2.3 From 04c4ea74f7d633d262ab2c54751cae29d4995621 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Thu, 9 Oct 2008 19:20:59 +0200 Subject: update: don't print debug message when song was not modified When a song file was not modified, MPD printed the debug message "not a directory or music", because the first "if" branch did not return. --- src/update.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/update.c b/src/update.c index b910486e0..40f47a26a 100644 --- a/src/update.c +++ b/src/update.c @@ -238,6 +238,8 @@ updateInDirectory(struct directory *directory, delete_song(directory, song); return UPDATE_RETURN_UPDATED; } + + return UPDATE_RETURN_NOUPDATE; } else if (S_ISDIR(st->st_mode)) { struct directory *subdir; enum update_return ret; @@ -255,11 +257,10 @@ updateInDirectory(struct directory *directory, delete_directory(subdir); return ret; + } else { + DEBUG("update: %s is not a directory or music\n", name); + return UPDATE_RETURN_NOUPDATE; } - - DEBUG("update: %s is not a directory or music\n", name); - - return UPDATE_RETURN_NOUPDATE; } /* we don't look at hidden files nor files with newlines in them */ -- cgit v1.2.3 From 9ae9c1f8cff904cdc2451ddbee88a30e0570d2f5 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Thu, 9 Oct 2008 19:31:31 +0200 Subject: update: make the variable "progress" static --- src/update.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/update.c b/src/update.c index 40f47a26a..f0905b5db 100644 --- a/src/update.c +++ b/src/update.c @@ -34,7 +34,7 @@ enum update_return { UPDATE_RETURN_UPDATED = 1 }; -enum update_progress { +static enum update_progress { UPDATE_PROGRESS_IDLE = 0, UPDATE_PROGRESS_RUNNING = 1, UPDATE_PROGRESS_DONE = 2 -- cgit v1.2.3 From e71207440ebdf492e00fd5ac73b0833c82366ac6 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Thu, 9 Oct 2008 19:41:58 +0200 Subject: update: replaced update_return with global "modified" flag There is only once update thread at a time. Make the "modified" flag global and remove the return values of most functions. Propagating an error is only useful for updateDirectory(), since updateInDirectory() will delete failed subdirectories. --- src/update.c | 107 ++++++++++++++++++++++------------------------------------- 1 file changed, 39 insertions(+), 68 deletions(-) (limited to 'src') diff --git a/src/update.c b/src/update.c index f0905b5db..928aac5c5 100644 --- a/src/update.c +++ b/src/update.c @@ -28,18 +28,14 @@ #include "condition.h" #include "update.h" -enum update_return { - UPDATE_RETURN_ERROR = -1, - UPDATE_RETURN_NOUPDATE = 0, - UPDATE_RETURN_UPDATED = 1 -}; - static enum update_progress { UPDATE_PROGRESS_IDLE = 0, UPDATE_PROGRESS_RUNNING = 1, UPDATE_PROGRESS_DONE = 2 } progress; +static int modified; + /* make this dynamic?, or maybe this is big enough... */ static char *update_paths[32]; static size_t update_paths_nr; @@ -122,7 +118,6 @@ static void delete_directory(struct directory *directory) struct delete_data { char *tmp; struct directory *dir; - enum update_return ret; }; /* passed to songvec_for_each */ @@ -135,30 +130,29 @@ static int delete_song_if_removed(struct mpd_song *song, void *_data) if (!isFile(data->tmp, NULL)) { delete_song(data->dir, song); - data->ret = UPDATE_RETURN_UPDATED; + modified = 1; } return 0; } -static enum update_return delete_path(const char *path) +static void delete_path(const char *path) { struct directory *directory = db_get_directory(path); struct mpd_song *song = db_get_song(path); - if (directory) + if (directory) { delete_directory(directory); - if (song) + modified = 1; + } + if (song) { delete_song(song->parent, song); - - return directory == NULL && song == NULL - ? UPDATE_RETURN_NOUPDATE - : UPDATE_RETURN_UPDATED; + modified = 1; + } } -static enum update_return +static void removeDeletedFromDirectory(char *path_max_tmp, struct directory *directory) { - enum update_return ret = UPDATE_RETURN_NOUPDATE; int i; struct dirvec *dv = &directory->children; struct delete_data data; @@ -168,15 +162,12 @@ removeDeletedFromDirectory(char *path_max_tmp, struct directory *directory) continue; LOG("removing directory: %s\n", dv->base[i]->path); dirvec_delete(dv, dv->base[i]); - ret = UPDATE_RETURN_UPDATED; + modified = 1; } data.dir = directory; data.tmp = path_max_tmp; - data.ret = ret; songvec_for_each(&directory->songs, delete_song_if_removed, &data); - - return data.ret; } static const char *opendir_path(char *path_max_tmp, const char *dirname) @@ -215,10 +206,9 @@ inodeFoundInParent(struct directory *parent, ino_t inode, dev_t device) return 0; } -static enum update_return -updateDirectory(struct directory *directory, const struct stat *st); +static int updateDirectory(struct directory *directory, const struct stat *st); -static enum update_return +static void updateInDirectory(struct directory *directory, const char *name, const struct stat *st) { @@ -228,38 +218,31 @@ updateInDirectory(struct directory *directory, if (!(song = songvec_find(&directory->songs, shortname))) { if (!(song = song_file_load(shortname, directory))) - return -1; + return; songvec_add(&directory->songs, song); + modified = 1; LOG("added %s\n", name); - return UPDATE_RETURN_UPDATED; } else if (st->st_mtime != song->mtime) { LOG("updating %s\n", name); if (!song_file_update(song)) delete_song(directory, song); - return UPDATE_RETURN_UPDATED; + modified = 1; } - - return UPDATE_RETURN_NOUPDATE; } else if (S_ISDIR(st->st_mode)) { struct directory *subdir; - enum update_return ret; if (inodeFoundInParent(directory, st->st_ino, st->st_dev)) - return UPDATE_RETURN_ERROR; + return; if (!(subdir = directory_get_child(directory, name))) subdir = directory_new_child(directory, name); assert(directory == subdir->parent); - ret = updateDirectory(subdir, st); - if (ret == UPDATE_RETURN_ERROR || directory_is_empty(subdir)) + if (!updateDirectory(subdir, st)) delete_directory(subdir); - - return ret; } else { DEBUG("update: %s is not a directory or music\n", name); - return UPDATE_RETURN_NOUPDATE; } } @@ -269,26 +252,21 @@ static int skip_path(const char *path) return (path[0] == '.' || strchr(path, '\n')) ? 1 : 0; } -static enum update_return -updateDirectory(struct directory *directory, const struct stat *st) +static int updateDirectory(struct directory *directory, const struct stat *st) { DIR *dir; const char *dirname = directory_get_path(directory); struct dirent *ent; char path_max_tmp[MPD_PATH_MAX]; - enum update_return ret = UPDATE_RETURN_NOUPDATE; - enum update_return ret2; assert(S_ISDIR(st->st_mode)); directory_set_stat(directory, st); - dir = opendir(opendir_path(path_max_tmp, dirname)); - if (!dir) - return UPDATE_RETURN_ERROR; + if (!(dir = opendir(opendir_path(path_max_tmp, dirname)))) + return 0; - if (removeDeletedFromDirectory(path_max_tmp, directory) > 0) - ret = UPDATE_RETURN_UPDATED; + removeDeletedFromDirectory(path_max_tmp, directory); while ((ent = readdir(dir))) { char *utf8; @@ -306,16 +284,14 @@ updateDirectory(struct directory *directory, const struct stat *st) dirname, strlen(dirname)); if (myStat(path_max_tmp, &st2) == 0) - ret2 = updateInDirectory(directory, path_max_tmp, &st2); + updateInDirectory(directory, path_max_tmp, &st2); else - ret2 = delete_path(path_max_tmp); - if (ret == UPDATE_RETURN_NOUPDATE) - ret = ret2; + delete_path(path_max_tmp); } closedir(dir); - return ret; + return 1; } static struct directory * @@ -363,37 +339,34 @@ addParentPathToDB(const char *utf8path) return directory; } -static enum update_return updatePath(const char *utf8path) +static void updatePath(const char *utf8path) { struct stat st; if (myStat(utf8path, &st) < 0) - return delete_path(utf8path); - return updateInDirectory(addParentPathToDB(utf8path), utf8path, &st); + delete_path(utf8path); + else + updateInDirectory(addParentPathToDB(utf8path), utf8path, &st); } static void * update_task(void *_path) { - enum update_return ret = UPDATE_RETURN_NOUPDATE; - if (_path != NULL && !isRootDirectory(_path)) { - ret = updatePath((char *)_path); + updatePath((char *)_path); free(_path); } else { struct directory *directory = db_get_root(); struct stat st; if (myStat(directory_get_path(directory), &st) == 0) - ret = updateDirectory(directory, &st); - else - ret = UPDATE_RETURN_ERROR; + updateDirectory(directory, &st); } - if (ret == UPDATE_RETURN_UPDATED && db_save() < 0) - ret = UPDATE_RETURN_ERROR; + if (modified) + db_save(); progress = UPDATE_PROGRESS_DONE; wakeup_main_task(); - return (void *)ret; + return NULL; } static void spawn_update_task(char *path) @@ -403,6 +376,7 @@ static void spawn_update_task(char *path) assert(pthread_equal(pthread_self(), main_task)); progress = UPDATE_PROGRESS_RUNNING; + modified = 0; pthread_attr_init(&attr); if (pthread_create(&update_thr, &attr, update_task, path)) FATAL("Failed to spawn update task: %s\n", strerror(errno)); @@ -437,9 +411,6 @@ unsigned directory_update_init(char *path) void reap_update_task(void) { - void *thread_return; - enum update_return ret; - assert(pthread_equal(pthread_self(), main_task)); if (progress == UPDATE_PROGRESS_IDLE) @@ -457,10 +428,10 @@ void reap_update_task(void) if (progress != UPDATE_PROGRESS_DONE) return; - if (pthread_join(update_thr, &thread_return)) + if (pthread_join(update_thr, NULL)) FATAL("error joining update thread: %s\n", strerror(errno)); - ret = (enum update_return)(size_t)thread_return; - if (ret == UPDATE_RETURN_UPDATED) + + if (modified) playlistVersionChange(); if (update_paths_nr) { -- cgit v1.2.3 From 6e2b0ca9edaed200f250ef487701ad161aa4a168 Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Sat, 11 Oct 2008 19:49:14 -0700 Subject: directory: don't use identical struct and variable names Duplicated tokens in close proximity takes too long for my head to parse; and "dir" is an easy and common abbreviation for "directory". --- src/command.c | 6 +-- src/database.c | 19 +++++---- src/dbUtils.c | 10 ++--- src/directory.c | 44 ++++++++++----------- src/directory.h | 30 +++++++------- src/directory_print.c | 6 +-- src/directory_print.h | 2 +- src/directory_save.c | 30 +++++++------- src/directory_save.h | 4 +- src/update.c | 107 +++++++++++++++++++++++++------------------------- 10 files changed, 128 insertions(+), 130 deletions(-) (limited to 'src') diff --git a/src/command.c b/src/command.c index 541a71a50..e542683d8 100644 --- a/src/command.c +++ b/src/command.c @@ -560,17 +560,17 @@ static int handleLsInfo(int fd, mpd_unused int *permission, int argc, char *argv[]) { const char *path = ""; - const struct directory *directory; + const struct directory *dir; if (argc == 2) path = argv[1]; - if (!(directory = db_get_directory(path))) { + if (!(dir = db_get_directory(path))) { commandError(fd, ACK_ERROR_NO_EXIST, "directory not found"); return -1; } - directory_print(fd, directory); + directory_print(fd, dir); if (isRootDirectory(path)) return lsPlaylists(fd, path); diff --git a/src/database.c b/src/database.c index ea78940f8..dde57ce6a 100644 --- a/src/database.c +++ b/src/database.c @@ -75,8 +75,8 @@ struct directory * db_get_directory(const char *name) struct mpd_song *db_get_song(const char *file) { struct mpd_song *song = NULL; - struct directory *directory; - char *dir = NULL; + struct directory *dir; + char *dirpath = NULL; char *duplicated = xstrdup(file); char *shortname = strrchr(duplicated, '/'); @@ -87,14 +87,14 @@ struct mpd_song *db_get_song(const char *file) } else { *shortname = '\0'; ++shortname; - dir = duplicated; + dirpath = duplicated; } - if (!(directory = db_get_directory(dir))) + if (!(dir = db_get_directory(dirpath))) goto out; - if (!(song = songvec_find(&directory->songs, shortname))) + if (!(song = songvec_find(&dir->songs, shortname))) goto out; - assert(song->parent == directory); + assert(song->parent == dir); out: free(duplicated); @@ -105,9 +105,9 @@ int db_walk(const char *name, int (*forEachSong) (struct mpd_song *, void *), int (*forEachDir) (struct directory *, void *), void *data) { - struct directory *directory; + struct directory *dir; - if ((directory = db_get_directory(name)) == NULL) { + if ((dir = db_get_directory(name)) == NULL) { struct mpd_song *song; if ((song = db_get_song(name)) && forEachSong) { return forEachSong(song, data); @@ -115,8 +115,7 @@ int db_walk(const char *name, return -1; } - return directory_walk(directory, forEachSong, forEachDir, - data); + return directory_walk(dir, forEachSong, forEachDir, data); } static char *db_get_file(void) diff --git a/src/dbUtils.c b/src/dbUtils.c index 9e307efc6..1fadb232e 100644 --- a/src/dbUtils.c +++ b/src/dbUtils.c @@ -45,20 +45,20 @@ typedef struct _SearchStats { unsigned long playTime; } SearchStats; -static int countSongsInDirectory(struct directory *directory, void *data) +static int countSongsInDirectory(struct directory *dir, void *data) { int *count = (int *)data; - *count += directory->songs.nr; + *count += dir->songs.nr; return 0; } -static int printDirectoryInDirectory(struct directory *directory, void *data) +static int printDirectoryInDirectory(struct directory *dir, void *data) { int fd = (int)(size_t)data; - if (!isRootDirectory(directory->path)) - fdprintf(fd, "directory: %s\n", directory_get_path(directory)); + if (!isRootDirectory(dir->path)) + fdprintf(fd, "directory: %s\n", directory_get_path(dir)); return 0; } diff --git a/src/directory.c b/src/directory.c index 273515b91..b90b477fd 100644 --- a/src/directory.c +++ b/src/directory.c @@ -25,32 +25,32 @@ struct directory * directory_new(const char *dirname, struct directory * parent) { - struct directory *directory; + struct directory *dir; assert(dirname != NULL); assert((*dirname == 0) == (parent == NULL)); - directory = xcalloc(1, sizeof(*directory)); - directory->path = xstrdup(dirname); - directory->parent = parent; + dir = xcalloc(1, sizeof(struct directory)); + dir->path = xstrdup(dirname); + dir->parent = parent; - return directory; + return dir; } -void directory_free(struct directory * directory) +void directory_free(struct directory *dir) { - dirvec_destroy(&directory->children); - songvec_destroy(&directory->songs); - free(directory->path); - free(directory); + dirvec_destroy(&dir->children); + songvec_destroy(&dir->songs); + free(dir->path); + free(dir); /* this resets last dir returned */ /*directory_get_path(NULL); */ } -void directory_prune_empty(struct directory * directory) +void directory_prune_empty(struct directory *dir) { int i; - struct dirvec *dv = &directory->children; + struct dirvec *dv = &dir->children; for (i = dv->nr; --i >= 0; ) { directory_prune_empty(dv->base[i]); @@ -62,9 +62,9 @@ void directory_prune_empty(struct directory * directory) } struct directory * -directory_get_subdir(struct directory * directory, const char *name) +directory_get_subdir(struct directory *dir, const char *name) { - struct directory *cur = directory; + struct directory *cur = dir; struct directory *found = NULL; char *duplicated; char *locate; @@ -72,7 +72,7 @@ directory_get_subdir(struct directory * directory, const char *name) assert(name != NULL); if (isRootDirectory(name)) - return directory; + return dir; duplicated = xstrdup(name); locate = strchr(duplicated, '/'); @@ -94,33 +94,33 @@ directory_get_subdir(struct directory * directory, const char *name) return found; } -void directory_sort(struct directory * directory) +void directory_sort(struct directory *dir) { int i; - struct dirvec *dv = &directory->children; + struct dirvec *dv = &dir->children; dirvec_sort(dv); - songvec_sort(&directory->songs); + songvec_sort(&dir->songs); for (i = dv->nr; --i >= 0; ) directory_sort(dv->base[i]); } int -directory_walk(struct directory * directory, +directory_walk(struct directory *dir, int (*forEachSong) (struct mpd_song *, void *), int (*forEachDir) (struct directory *, void *), void *data) { - struct dirvec *dv = &directory->children; + struct dirvec *dv = &dir->children; int err = 0; size_t j; - if (forEachDir && (err = forEachDir(directory, data)) < 0) + if (forEachDir && (err = forEachDir(dir, data)) < 0) return err; if (forEachSong) { - err = songvec_for_each(&directory->songs, forEachSong, data); + err = songvec_for_each(&dir->songs, forEachSong, data); if (err < 0) return err; } diff --git a/src/directory.h b/src/directory.h index d8f86f50c..949df0c0e 100644 --- a/src/directory.h +++ b/src/directory.h @@ -50,11 +50,11 @@ static inline int isRootDirectory(const char *name) struct directory * directory_new(const char *dirname, struct directory *parent); -void directory_free(struct directory *directory); +void directory_free(struct directory *dir); -static inline int directory_is_empty(struct directory *directory) +static inline int directory_is_empty(struct directory *dir) { - return directory->children.nr == 0 && directory->songs.nr == 0; + return dir->children.nr == 0 && dir->songs.nr == 0; } static inline const char * directory_get_path(struct directory *dir) @@ -63,39 +63,39 @@ static inline const char * directory_get_path(struct directory *dir) } static inline struct directory * -directory_get_child(const struct directory *directory, const char *name) +directory_get_child(const struct directory *dir, const char *name) { - return dirvec_find(&directory->children, name); + return dirvec_find(&dir->children, name); } static inline struct directory * -directory_new_child(struct directory *directory, const char *name) +directory_new_child(struct directory *dir, const char *name) { - struct directory *subdir = directory_new(name, directory); - dirvec_add(&directory->children, subdir); + struct directory *subdir = directory_new(name, dir); + dirvec_add(&dir->children, subdir); return subdir; } -void directory_prune_empty(struct directory *directory); +void directory_prune_empty(struct directory *dir); struct directory * -directory_get_subdir(struct directory *directory, const char *name); +directory_get_subdir(struct directory *dir, const char *name); -int directory_print(int fd, const struct directory *directory); +int directory_print(int fd, const struct directory *dir); struct mpd_song *db_get_song(const char *file); -int directory_save(int fd, struct directory *directory); +int directory_save(int fd, struct directory *dir); -void directory_load(FILE *fp, struct directory *directory); +void directory_load(FILE *fp, struct directory *dir); -void directory_sort(struct directory * directory); +void directory_sort(struct directory *dir); int db_walk(const char *name, int (*forEachSong) (struct mpd_song *, void *), int (*forEachDir) (struct directory *, void *), void *data); -int directory_walk(struct directory *directory, +int directory_walk(struct directory *dir, int (*forEachSong) (struct mpd_song *, void *), int (*forEachDir) (struct directory *, void *), void *data); diff --git a/src/directory_print.c b/src/directory_print.c index ebf9a472d..1c30f1608 100644 --- a/src/directory_print.c +++ b/src/directory_print.c @@ -36,11 +36,11 @@ static int dirvec_print(int fd, const struct dirvec *dv) return 0; } -int directory_print(int fd, const struct directory *directory) +int directory_print(int fd, const struct directory *dir) { - if (dirvec_print(fd, &directory->children) < 0) + if (dirvec_print(fd, &dir->children) < 0) return -1; - if (songvec_for_each(&directory->songs, song_print_info_x, + if (songvec_for_each(&dir->songs, song_print_info_x, (void *)(size_t)fd) < 0) return -1; return 0; diff --git a/src/directory_print.h b/src/directory_print.h index 54089e58d..a55c3672d 100644 --- a/src/directory_print.h +++ b/src/directory_print.h @@ -21,6 +21,6 @@ struct directory; -int directory_print(int fd, const struct directory *directory); +int directory_print(int fd, const struct directory *dir); #endif diff --git a/src/directory_save.c b/src/directory_save.c index 76eace90b..c39ece58a 100644 --- a/src/directory_save.c +++ b/src/directory_save.c @@ -40,14 +40,14 @@ static int directory_song_write(struct mpd_song *song, void *data) } /* TODO error checking */ -int directory_save(int fd, struct directory * directory) +int directory_save(int fd, struct directory *dir) { - struct dirvec *children = &directory->children; + struct dirvec *children = &dir->children; size_t i; - if (!isRootDirectory(directory->path) && + if (!isRootDirectory(dir->path) && fdprintf(fd, DIRECTORY_BEGIN "%s\n", - directory_get_path(directory)) < 0) + directory_get_path(dir)) < 0) return -1; for (i = 0; i < children->nr; ++i) { @@ -63,21 +63,21 @@ int directory_save(int fd, struct directory * directory) if (fdprintf(fd, SONG_BEGIN "\n") < 0) return -1; - if (songvec_for_each(&directory->songs, + if (songvec_for_each(&dir->songs, directory_song_write, (void *)(size_t)fd) < 0) return -1; if (fdprintf(fd, SONG_END "\n") < 0) return -1; - if (!isRootDirectory(directory->path) && + if (!isRootDirectory(dir->path) && fdprintf(fd, DIRECTORY_END "%s\n", - directory_get_path(directory)) < 0) + directory_get_path(dir)) < 0) return -1; return 0; } -void directory_load(FILE * fp, struct directory * directory) +void directory_load(FILE * fp, struct directory *dir) { char buffer[MPD_PATH_MAX * 2]; int bufferSize = MPD_PATH_MAX * 2; @@ -100,19 +100,19 @@ void directory_load(FILE * fp, struct directory * directory) if (prefixcmp(buffer, DIRECTORY_BEGIN)) FATAL("Error reading db at line: %s\n", buffer); name = &(buffer[strlen(DIRECTORY_BEGIN)]); - if (prefixcmp(name, directory->path) != 0) + if (prefixcmp(name, dir->path) != 0) FATAL("Wrong path in database: '%s' in '%s'\n", - name, directory->path); + name, dir->path); - if ((subdir = directory_get_child(directory, name))) { - assert(subdir->parent == directory); + if ((subdir = directory_get_child(dir, name))) { + assert(subdir->parent == dir); } else { - subdir = directory_new(name, directory); - dirvec_add(&directory->children, subdir); + subdir = directory_new(name, dir); + dirvec_add(&dir->children, subdir); } directory_load(fp, subdir); } else if (!prefixcmp(buffer, SONG_BEGIN)) { - readSongInfoIntoList(fp, directory); + readSongInfoIntoList(fp, dir); } else { FATAL("Unknown line in db: %s\n", buffer); } diff --git a/src/directory_save.h b/src/directory_save.h index 211c73cca..64364d82d 100644 --- a/src/directory_save.h +++ b/src/directory_save.h @@ -23,8 +23,8 @@ struct directory; -int directory_save(int fd, struct directory *directory); +int directory_save(int fd, struct directory *dir); -void directory_load(FILE *, struct directory *directory); +void directory_load(FILE *, struct directory *dir); #endif /* DIRECTORY_SAVE_H */ diff --git a/src/update.c b/src/update.c index 928aac5c5..ca3640b73 100644 --- a/src/update.c +++ b/src/update.c @@ -81,9 +81,9 @@ static void delete_song(struct directory *dir, struct mpd_song *del) static int delete_each_song(struct mpd_song *song, mpd_unused void *data) { - struct directory *directory = data; - assert(song->parent == directory); - delete_song(directory, song); + struct directory *dir = data; + assert(song->parent == dir); + delete_song(dir, song); return 0; } @@ -91,28 +91,27 @@ static int delete_each_song(struct mpd_song *song, mpd_unused void *data) * Recursively remove all sub directories and songs from a directory, * leaving an empty directory. */ -static void clear_directory(struct directory *directory) +static void clear_directory(struct directory *dir) { int i; - for (i = directory->children.nr; --i >= 0;) - clear_directory(directory->children.base[i]); - dirvec_clear(&directory->children); + for (i = dir->children.nr; --i >= 0;) + clear_directory(dir->children.base[i]); + dirvec_clear(&dir->children); - songvec_for_each(&directory->songs, delete_each_song, directory); + songvec_for_each(&dir->songs, delete_each_song, dir); } /** * Recursively free a directory and all its contents. */ -static void delete_directory(struct directory *directory) +static void delete_directory(struct directory *dir) { - assert(directory->parent != NULL); + assert(dir->parent != NULL); - clear_directory(directory); - - dirvec_delete(&directory->parent->children, directory); - directory_free(directory); + clear_directory(dir); + dirvec_delete(&dir->parent->children, dir); + directory_free(dir); } struct delete_data { @@ -137,11 +136,11 @@ static int delete_song_if_removed(struct mpd_song *song, void *_data) static void delete_path(const char *path) { - struct directory *directory = db_get_directory(path); + struct directory *dir = db_get_directory(path); struct mpd_song *song = db_get_song(path); - if (directory) { - delete_directory(directory); + if (dir) { + delete_directory(dir); modified = 1; } if (song) { @@ -151,10 +150,10 @@ static void delete_path(const char *path) } static void -removeDeletedFromDirectory(char *path_max_tmp, struct directory *directory) +removeDeletedFromDirectory(char *path_max_tmp, struct directory *dir) { int i; - struct dirvec *dv = &directory->children; + struct dirvec *dv = &dir->children; struct delete_data data; for (i = dv->nr; --i >= 0; ) { @@ -165,9 +164,9 @@ removeDeletedFromDirectory(char *path_max_tmp, struct directory *directory) modified = 1; } - data.dir = directory; + data.dir = dir; data.tmp = path_max_tmp; - songvec_for_each(&directory->songs, delete_song_if_removed, &data); + songvec_for_each(&dir->songs, delete_song_if_removed, &data); } static const char *opendir_path(char *path_max_tmp, const char *dirname) @@ -206,38 +205,38 @@ inodeFoundInParent(struct directory *parent, ino_t inode, dev_t device) return 0; } -static int updateDirectory(struct directory *directory, const struct stat *st); +static int updateDirectory(struct directory *dir, const struct stat *st); static void -updateInDirectory(struct directory *directory, +updateInDirectory(struct directory *dir, const char *name, const struct stat *st) { if (S_ISREG(st->st_mode) && hasMusicSuffix(name, 0)) { const char *shortname = mpd_basename(name); struct mpd_song *song; - if (!(song = songvec_find(&directory->songs, shortname))) { - if (!(song = song_file_load(shortname, directory))) + if (!(song = songvec_find(&dir->songs, shortname))) { + if (!(song = song_file_load(shortname, dir))) return; - songvec_add(&directory->songs, song); + songvec_add(&dir->songs, song); modified = 1; LOG("added %s\n", name); } else if (st->st_mtime != song->mtime) { LOG("updating %s\n", name); if (!song_file_update(song)) - delete_song(directory, song); + delete_song(dir, song); modified = 1; } } else if (S_ISDIR(st->st_mode)) { struct directory *subdir; - if (inodeFoundInParent(directory, st->st_ino, st->st_dev)) + if (inodeFoundInParent(dir, st->st_ino, st->st_dev)) return; - if (!(subdir = directory_get_child(directory, name))) - subdir = directory_new_child(directory, name); + if (!(subdir = directory_get_child(dir, name))) + subdir = directory_new_child(dir, name); - assert(directory == subdir->parent); + assert(dir == subdir->parent); if (!updateDirectory(subdir, st)) delete_directory(subdir); @@ -252,23 +251,23 @@ static int skip_path(const char *path) return (path[0] == '.' || strchr(path, '\n')) ? 1 : 0; } -static int updateDirectory(struct directory *directory, const struct stat *st) +static int updateDirectory(struct directory *dir, const struct stat *st) { - DIR *dir; - const char *dirname = directory_get_path(directory); + DIR *fs_dir; + const char *dirname = directory_get_path(dir); struct dirent *ent; char path_max_tmp[MPD_PATH_MAX]; assert(S_ISDIR(st->st_mode)); - directory_set_stat(directory, st); + directory_set_stat(dir, st); - if (!(dir = opendir(opendir_path(path_max_tmp, dirname)))) + if (!(fs_dir = opendir(opendir_path(path_max_tmp, dirname)))) return 0; - removeDeletedFromDirectory(path_max_tmp, directory); + removeDeletedFromDirectory(path_max_tmp, dir); - while ((ent = readdir(dir))) { + while ((ent = readdir(fs_dir))) { char *utf8; struct stat st2; @@ -279,17 +278,17 @@ static int updateDirectory(struct directory *directory, const struct stat *st) if (!utf8) continue; - if (!isRootDirectory(directory->path)) + if (!isRootDirectory(dir->path)) utf8 = pfx_dir(path_max_tmp, utf8, strlen(utf8), dirname, strlen(dirname)); if (myStat(path_max_tmp, &st2) == 0) - updateInDirectory(directory, path_max_tmp, &st2); + updateInDirectory(dir, path_max_tmp, &st2); else delete_path(path_max_tmp); } - closedir(dir); + closedir(fs_dir); return 1; } @@ -297,12 +296,12 @@ static int updateDirectory(struct directory *directory, const struct stat *st) static struct directory * directory_make_child_checked(struct directory *parent, const char *path) { - struct directory *directory; + struct directory *dir; struct stat st; struct mpd_song *conflicting; - if ((directory = directory_get_child(parent, path))) - return directory; + if ((dir = directory_get_child(parent, path))) + return dir; if (myStat(path, &st) < 0 || inodeFoundInParent(parent, st.st_ino, st.st_dev)) @@ -313,30 +312,30 @@ directory_make_child_checked(struct directory *parent, const char *path) if ((conflicting = songvec_find(&parent->songs, mpd_basename(path)))) delete_song(parent, conflicting); - directory = directory_new_child(parent, path); - directory_set_stat(directory, &st); - return directory; + dir = directory_new_child(parent, path); + directory_set_stat(dir, &st); + return dir; } static struct directory * addParentPathToDB(const char *utf8path) { - struct directory *directory = db_get_root(); + struct directory *dir = db_get_root(); char *duplicated = xstrdup(utf8path); char *slash = duplicated; while ((slash = strchr(slash, '/'))) { *slash = 0; - directory = directory_make_child_checked(directory, duplicated); - if (!directory || !slash) + dir = directory_make_child_checked(dir, duplicated); + if (!dir || !slash) break; *slash++ = '/'; } free(duplicated); - return directory; + return dir; } static void updatePath(const char *utf8path) @@ -355,11 +354,11 @@ static void * update_task(void *_path) updatePath((char *)_path); free(_path); } else { - struct directory *directory = db_get_root(); + struct directory *dir = db_get_root(); struct stat st; - if (myStat(directory_get_path(directory), &st) == 0) - updateDirectory(directory, &st); + if (myStat(directory_get_path(dir), &st) == 0) + updateDirectory(dir, &st); } if (modified) -- cgit v1.2.3