diff options
Diffstat (limited to 'src/directory.c')
-rw-r--r-- | src/directory.c | 318 |
1 files changed, 10 insertions, 308 deletions
diff --git a/src/directory.c b/src/directory.c index b8e6fa1f0..c2fa229f5 100644 --- a/src/directory.c +++ b/src/directory.c @@ -17,44 +17,15 @@ */ #include "directory.h" +#include "database.h" #include "song.h" -#include "conf.h" #include "log.h" -#include "ls.h" #include "path.h" -#include "stats.h" #include "utils.h" #include "client.h" -#include "dbUtils.h" #include "song_print.h" #include "song_save.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) @@ -82,7 +53,8 @@ freeDirectory(struct directory * directory) /*getDirectoryPath(NULL); */ } -static void deleteEmptyDirectoriesInDirectory(struct directory * directory) +void +deleteEmptyDirectoriesInDirectory(struct directory *directory) { int i; struct dirvec *dv = &directory->children; @@ -96,20 +68,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 * getSubDirectory(struct directory * directory, const char *name) { struct directory *cur = directory; @@ -142,16 +101,8 @@ 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(struct client *client, struct dirvec *dv) +static int +printDirectoryList(struct client *client, const struct dirvec *dv) { size_t i; @@ -163,13 +114,9 @@ static int printDirectoryList(struct client *client, struct dirvec *dv) return 0; } -int printDirectoryInfo(struct client *client, const char *name) +int +directory_print(struct client *client, const struct directory *directory) { - struct directory *directory; - - if ((directory = getDirectory(name)) == NULL) - return -1; - printDirectoryList(client, &directory->children); songvec_print(client, &directory->songs); @@ -177,7 +124,7 @@ int printDirectoryInfo(struct client *client, const char *name) } /* TODO error checking */ -static int +int writeDirectoryInfo(FILE * fp, struct directory * directory) { struct dirvec *children = &directory->children; @@ -211,7 +158,7 @@ writeDirectoryInfo(FILE * fp, struct directory * directory) return 0; } -static void +void readDirectoryInfo(FILE * fp, struct directory * directory) { char buffer[MPD_PATH_MAX * 2]; @@ -263,190 +210,7 @@ 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) -{ - FILE *fp; - 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"); - - fp = fopen(dbFile, "w"); - if (!fp) { - ERROR("unable to write to db file \"%s\": %s\n", - dbFile, strerror(errno)); - return -1; - } - - /* block signals when writing the db so we don't get a corrupted db */ - fprintf(fp, "%s\n", DIRECTORY_INFO_BEGIN); - fprintf(fp, "%s%s\n", DIRECTORY_MPD_VERSION, VERSION); - fprintf(fp, "%s%s\n", DIRECTORY_FS_CHARSET, getFsCharset()); - fprintf(fp, "%s\n", DIRECTORY_INFO_END); - - if (writeDirectoryInfo(fp, music_root) < 0) { - ERROR("Failed to write to database file: %s\n", - strerror(errno)); - while (fclose(fp) && errno == EINTR); - return -1; - } - - while (fclose(fp) && errno == EINTR); - - 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 song *, void *), int (*forEachDir) (struct directory *, void *), @@ -471,65 +235,3 @@ traverseAllInSubDirectory(struct directory * directory, return err; } - -int -traverseAllIn(const char *name, - int (*forEachSong) (struct song *, void *), - int (*forEachDir) (struct directory *, void *), void *data) -{ - struct directory *directory; - - if ((directory = getDirectory(name)) == NULL) { - struct 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 song * -getSongFromDB(const char *file) -{ - struct 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; -} |