aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/update.c66
1 files changed, 38 insertions, 28 deletions
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)