Commit 96019f4a authored by Denis Krjuchkov's avatar Denis Krjuchkov

UpdateWalk, ExcludeList: use Path, file system API, DirectoryReader, log in UTF8

parent 896015bf
...@@ -63,14 +63,14 @@ ExcludeList::LoadFile(const Path &path_fs) ...@@ -63,14 +63,14 @@ ExcludeList::LoadFile(const Path &path_fs)
} }
bool bool
ExcludeList::Check(const char *name_fs) const ExcludeList::Check(const Path &name_fs) const
{ {
assert(name_fs != NULL); assert(!name_fs.IsNull());
/* XXX include full path name in check */ /* XXX include full path name in check */
for (const auto &i : patterns) for (const auto &i : patterns)
if (i.Check(name_fs)) if (i.Check(name_fs.c_str()))
return true; return true;
return false; return false;
......
...@@ -73,7 +73,7 @@ public: ...@@ -73,7 +73,7 @@ public:
* Checks whether one of the patterns in the .mpdignore file matches * Checks whether one of the patterns in the .mpdignore file matches
* the specified file name. * the specified file name.
*/ */
bool Check(const char *name_fs) const; bool Check(const Path &name_fs) const;
}; };
......
...@@ -34,6 +34,7 @@ ...@@ -34,6 +34,7 @@
#include "conf.h" #include "conf.h"
#include "fs/Path.hxx" #include "fs/Path.hxx"
#include "fs/FileSystem.hxx" #include "fs/FileSystem.hxx"
#include "fs/DirectoryReader.hxx"
#include "util/UriUtil.hxx" #include "util/UriUtil.hxx"
#include <glib.h> #include <glib.h>
...@@ -102,7 +103,7 @@ remove_excluded_from_directory(Directory *directory, ...@@ -102,7 +103,7 @@ remove_excluded_from_directory(Directory *directory,
directory_for_each_child_safe(child, n, directory) { directory_for_each_child_safe(child, n, directory) {
const Path name_fs = Path::FromUTF8(child->GetName()); const Path name_fs = Path::FromUTF8(child->GetName());
if (name_fs.IsNull() || exclude_list.Check(name_fs.c_str())) { if (name_fs.IsNull() || exclude_list.Check(name_fs)) {
delete_directory(child); delete_directory(child);
modified = true; modified = true;
} }
...@@ -113,7 +114,7 @@ remove_excluded_from_directory(Directory *directory, ...@@ -113,7 +114,7 @@ remove_excluded_from_directory(Directory *directory,
assert(song->parent == directory); assert(song->parent == directory);
const Path name_fs = Path::FromUTF8(song->uri); const Path name_fs = Path::FromUTF8(song->uri);
if (name_fs.IsNull() || exclude_list.Check(name_fs.c_str())) { if (name_fs.IsNull() || exclude_list.Check(name_fs)) {
delete_song(directory, song); delete_song(directory, song);
modified = true; modified = true;
} }
...@@ -261,8 +262,9 @@ update_directory_child(Directory *directory, ...@@ -261,8 +262,9 @@ update_directory_child(Directory *directory,
/* we don't look at "." / ".." nor files with newlines in their name */ /* we don't look at "." / ".." nor files with newlines in their name */
G_GNUC_PURE G_GNUC_PURE
static bool skip_path(const char *path) static bool skip_path(const Path &path_fs)
{ {
const char *path = path_fs.c_str();
return (path[0] == '.' && path[1] == 0) || return (path[0] == '.' && path[1] == 0) ||
(path[0] == '.' && path[1] == '.' && path[2] == 0) || (path[0] == '.' && path[1] == '.' && path[2] == 0) ||
strchr(path, '\n') != NULL; strchr(path, '\n') != NULL;
...@@ -277,20 +279,11 @@ skip_symlink(const Directory *directory, const char *utf8_name) ...@@ -277,20 +279,11 @@ skip_symlink(const Directory *directory, const char *utf8_name)
if (path_fs.IsNull()) if (path_fs.IsNull())
return true; return true;
char buffer[MPD_PATH_MAX]; const Path target = ReadLink(path_fs);
ssize_t length = readlink(path_fs.c_str(), buffer, sizeof(buffer)); if (target.IsNull())
if (length < 0)
/* don't skip if this is not a symlink */ /* don't skip if this is not a symlink */
return errno != EINVAL; return errno != EINVAL;
if ((size_t)length >= sizeof(buffer))
/* skip symlinks when the buffer is too small for the
link target */
return true;
/* null-terminate the buffer, because readlink() will not */
buffer[length] = 0;
if (!follow_inside_symlinks && !follow_outside_symlinks) { if (!follow_inside_symlinks && !follow_outside_symlinks) {
/* ignore all symlinks */ /* ignore all symlinks */
return true; return true;
...@@ -299,16 +292,18 @@ skip_symlink(const Directory *directory, const char *utf8_name) ...@@ -299,16 +292,18 @@ skip_symlink(const Directory *directory, const char *utf8_name)
return false; return false;
} }
if (g_path_is_absolute(buffer)) { const char *target_str = target.c_str();
if (g_path_is_absolute(target_str)) {
/* if the symlink points to an absolute path, see if /* if the symlink points to an absolute path, see if
that path is inside the music directory */ that path is inside the music directory */
const char *relative = map_to_relative_path(buffer); const char *relative = map_to_relative_path(target_str);
return relative > buffer return relative > target_str
? !follow_inside_symlinks ? !follow_inside_symlinks
: !follow_outside_symlinks; : !follow_outside_symlinks;
} }
const char *p = buffer; const char *p = target_str;
while (*p == '.') { while (*p == '.') {
if (p[1] == '.' && G_IS_DIR_SEPARATOR(p[2])) { if (p[1] == '.' && G_IS_DIR_SEPARATOR(p[2])) {
/* "../" moves to parent directory */ /* "../" moves to parent directory */
...@@ -352,10 +347,12 @@ update_directory(Directory *directory, const struct stat *st) ...@@ -352,10 +347,12 @@ update_directory(Directory *directory, const struct stat *st)
if (path_fs.IsNull()) if (path_fs.IsNull())
return false; return false;
DIR *dir = opendir(path_fs.c_str()); DirectoryReader reader(path_fs);
if (!dir) { if (reader.HasFailed()) {
int error = errno;
const auto path_utf8 = path_fs.ToUTF8();
g_warning("Failed to open directory %s: %s", g_warning("Failed to open directory %s: %s",
path_fs.c_str(), g_strerror(errno)); path_utf8.c_str(), g_strerror(error));
return false; return false;
} }
...@@ -367,15 +364,16 @@ update_directory(Directory *directory, const struct stat *st) ...@@ -367,15 +364,16 @@ update_directory(Directory *directory, const struct stat *st)
purge_deleted_from_directory(directory); purge_deleted_from_directory(directory);
struct dirent *ent; while (reader.ReadEntry()) {
while ((ent = readdir(dir))) {
std::string utf8; std::string utf8;
struct stat st2; struct stat st2;
if (skip_path(ent->d_name) || exclude_list.Check(ent->d_name)) const Path entry = reader.GetEntry();
if (skip_path(entry) || exclude_list.Check(entry))
continue; continue;
utf8 = Path::ToUTF8(ent->d_name); utf8 = entry.ToUTF8();
if (utf8.empty()) if (utf8.empty())
continue; continue;
...@@ -390,8 +388,6 @@ update_directory(Directory *directory, const struct stat *st) ...@@ -390,8 +388,6 @@ update_directory(Directory *directory, const struct stat *st)
modified |= delete_name_in(directory, utf8.c_str()); modified |= delete_name_in(directory, utf8.c_str());
} }
closedir(dir);
directory->mtime = st->st_mtime; directory->mtime = st->st_mtime;
return true; return true;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment