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