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/directory.c | 570 +------------------------------------------------------- 1 file changed, 10 insertions(+), 560 deletions(-) (limited to 'src/directory.c') 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; -- 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 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/directory.c') 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) -- 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 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/directory.c') 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); } -- 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/directory.c | 57 ++++++++++++++++++++++++++++++--------------------------- 1 file changed, 30 insertions(+), 27 deletions(-) (limited to 'src/directory.c') 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, '/'); -- 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/directory.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'src/directory.c') 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); -- 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 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/directory.c') 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); -- 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 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'src/directory.c') 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); } -- 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/directory.c | 324 +++----------------------------------------------------- 1 file changed, 12 insertions(+), 312 deletions(-) (limited to 'src/directory.c') 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; -} -- 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/directory.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/directory.c') 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); -- 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/directory.c | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) (limited to 'src/directory.c') 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; -- 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/directory.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'src/directory.c') 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; -- 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/directory.c | 116 -------------------------------------------------------- 1 file changed, 116 deletions(-) (limited to 'src/directory.c') 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; -- 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 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/directory.c') 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; -- 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/directory.c | 44 ++++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 22 deletions(-) (limited to 'src/directory.c') 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; } -- cgit v1.2.3