X-Git-Url: http://git.openwrt.org//?a=blobdiff_plain;f=libfstools%2Foverlay.c;h=db80798a53620896c46bb4cb40004be43a3c6622;hb=532a5568104449777d24c4f83f24b9c9581d54ab;hp=0677c34ed3588bbc32a52c72c446ac4cd84f9626;hpb=a5fa5b6144253726dcd7e769197eed787a723f5f;p=project%2Ffstools.git diff --git a/libfstools/overlay.c b/libfstools/overlay.c index 0677c34..db80798 100644 --- a/libfstools/overlay.c +++ b/libfstools/overlay.c @@ -14,7 +14,6 @@ #include #include #include -#include #include @@ -35,18 +34,6 @@ static bool keep_sysupgrade; -static ssize_t -fs_getxattr(const char *path, const char *name, void *value, size_t size) -{ - return syscall(__NR_getxattr, path, name, value, size); -} - -static ssize_t -fs_setxattr(const char *path, const char *name, const void *value, size_t size, int flags) -{ - return syscall(__NR_setxattr, path, name, value, size, flags); -} - static int handle_rmdir(const char *dir) { @@ -80,6 +67,7 @@ handle_rmdir(const char *dir) void foreachdir(const char *dir, int (*cb)(const char*)) { + struct stat s = { 0 }; char globdir[256]; glob_t gl; int j; @@ -90,9 +78,16 @@ foreachdir(const char *dir, int (*cb)(const char*)) snprintf(globdir, 256, "%s/*", dir); /**/ if (!glob(globdir, GLOB_NOESCAPE | GLOB_MARK | GLOB_ONLYDIR, NULL, &gl)) - for (j = 0; j < gl.gl_pathc; j++) - foreachdir(gl.gl_pathv[j], cb); + for (j = 0; j < gl.gl_pathc; j++) { + char *dir = gl.gl_pathv[j]; + int len = strlen(gl.gl_pathv[j]); + + if (len > 1 && dir[len - 1] == '/') + dir[len - 1] = '\0'; + if (!lstat(gl.gl_pathv[j], &s) && !S_ISLNK(s.st_mode)) + foreachdir(gl.gl_pathv[j], cb); + } cb(dir); } @@ -285,16 +280,25 @@ static int overlay_mount_fs(struct volume *v) return -1; } - return -1; + return 0; } enum fs_state fs_state_get(const char *dir) { + char *path; + char valstr[16]; uint32_t val; + ssize_t len; - if (fs_getxattr(dir, "user.fs_state", &val, sizeof(val)) != sizeof(val)) + path = alloca(strlen(dir) + 1 + sizeof("/.fs_state")); + sprintf(path, "%s/.fs_state", dir); + len = readlink(path, valstr, sizeof(valstr) - 1); + if (len < 0) return FS_STATE_UNKNOWN; + valstr[len] = 0; + val = atoi(valstr); + if (val > __FS_STATE_LAST) return FS_STATE_UNKNOWN; @@ -304,9 +308,18 @@ enum fs_state fs_state_get(const char *dir) int fs_state_set(const char *dir, enum fs_state state) { - uint32_t val = state; + char valstr[16]; + char *path; + + if (fs_state_get(dir) == state) + return 0; + + path = alloca(strlen(dir) + 1 + sizeof("/.fs_state")); + sprintf(path, "%s/.fs_state", dir); + unlink(path); + snprintf(valstr, sizeof(valstr), "%d", state); - return fs_setxattr(dir, "user.fs_state", &val, sizeof(val), 0); + return symlink(valstr, path); }