📄 subdir.c
字号:
/* fuse subdir module: offset paths with a base directory Copyright (C) 2007 Miklos Szeredi <miklos@szeredi.hu> This program can be distributed under the terms of the GNU LGPL. See the file COPYING.LIB*/#define FUSE_USE_VERSION 26#include <fuse.h>#include <stdio.h>#include <stdlib.h>#include <stddef.h>#include <string.h>#include <errno.h>struct subdir { char *base; size_t baselen; int rellinks; struct fuse_fs *next;};static struct subdir *subdir_get(void){ return fuse_get_context()->private_data;}static char *subdir_addpath(struct subdir *d, const char *path){ unsigned newlen = d->baselen + strlen(path); char *newpath = malloc(newlen + 2); if (newpath) { if (path[0] == '/') path++; strcpy(newpath, d->base); strcpy(newpath + d->baselen, path); if (!newpath[0]) strcpy(newpath, "."); } return newpath;}static int subdir_getattr(const char *path, struct stat *stbuf){ struct subdir *d = subdir_get(); char *newpath = subdir_addpath(d, path); int err = -ENOMEM; if (newpath) { err = fuse_fs_getattr(d->next, newpath, stbuf); free(newpath); } return err;}static int subdir_fgetattr(const char *path, struct stat *stbuf, struct fuse_file_info *fi){ struct subdir *d = subdir_get(); char *newpath = subdir_addpath(d, path); int err = -ENOMEM; if (newpath) { err = fuse_fs_fgetattr(d->next, newpath, stbuf, fi); free(newpath); } return err;}static int subdir_access(const char *path, int mask){ struct subdir *d = subdir_get(); char *newpath = subdir_addpath(d, path); int err = -ENOMEM; if (newpath) { err = fuse_fs_access(d->next, newpath, mask); free(newpath); } return err;}static int count_components(const char *p){ int ctr; for (; *p == '/'; p++); for (ctr = 0; *p; ctr++) { for (; *p && *p != '/'; p++); for (; *p == '/'; p++); } return ctr;}static void strip_common(const char **sp, const char **tp){ const char *s = *sp; const char *t = *tp; do { for (; *s == '/'; s++); for (; *t == '/'; t++); *tp = t; *sp = s; for (; *s == *t && *s && *s != '/'; s++, t++); } while ((*s == *t && *s) || (!*s && *t == '/') || (*s == '/' && !*t));}static void transform_symlink(struct subdir *d, const char *path, char *buf, size_t size){ const char *l = buf; size_t llen; char *s; int dotdots; int i; if (l[0] != '/' || d->base[0] != '/') return; strip_common(&l, &path); if (l - buf < (long) d->baselen) return; dotdots = count_components(path); if (!dotdots) return; dotdots--; llen = strlen(l); if (dotdots * 3 + llen + 2 > size) return; s = buf + dotdots * 3; if (llen) memmove(s, l, llen + 1); else if (!dotdots) strcpy(s, "."); else *s = '\0'; for (s = buf, i = 0; i < dotdots; i++, s += 3) memcpy(s, "../", 3);}static int subdir_readlink(const char *path, char *buf, size_t size){ struct subdir *d = subdir_get(); char *newpath = subdir_addpath(d, path); int err = -ENOMEM; if (newpath) { err = fuse_fs_readlink(d->next, newpath, buf, size); if (!err && d->rellinks) transform_symlink(d, newpath, buf, size); free(newpath); } return err;}static int subdir_opendir(const char *path, struct fuse_file_info *fi){ struct subdir *d = subdir_get(); char *newpath = subdir_addpath(d, path); int err = -ENOMEM; if (newpath) { err = fuse_fs_opendir(d->next, newpath, fi); free(newpath); } return err;}static int subdir_readdir(const char *path, void *buf, fuse_fill_dir_t filler, off_t offset, struct fuse_file_info *fi){ struct subdir *d = subdir_get(); char *newpath = subdir_addpath(d, path); int err = -ENOMEM; if (newpath) { err = fuse_fs_readdir(d->next, newpath, buf, filler, offset, fi); free(newpath); } return err;}static int subdir_releasedir(const char *path, struct fuse_file_info *fi){ struct subdir *d = subdir_get(); char *newpath = subdir_addpath(d, path); int err = -ENOMEM; if (newpath) { err = fuse_fs_releasedir(d->next, newpath, fi); free(newpath); } return err;}static int subdir_mknod(const char *path, mode_t mode, dev_t rdev){ struct subdir *d = subdir_get(); char *newpath = subdir_addpath(d, path); int err = -ENOMEM; if (newpath) { err = fuse_fs_mknod(d->next, newpath, mode, rdev); free(newpath); } return err;}static int subdir_mkdir(const char *path, mode_t mode){ struct subdir *d = subdir_get(); char *newpath = subdir_addpath(d, path); int err = -ENOMEM; if (newpath) { err = fuse_fs_mkdir(d->next, newpath, mode); free(newpath); } return err;}static int subdir_unlink(const char *path){ struct subdir *d = subdir_get(); char *newpath = subdir_addpath(d, path); int err = -ENOMEM; if (newpath) { err = fuse_fs_unlink(d->next, newpath); free(newpath); } return err;}static int subdir_rmdir(const char *path){ struct subdir *d = subdir_get(); char *newpath = subdir_addpath(d, path); int err = -ENOMEM; if (newpath) { err = fuse_fs_rmdir(d->next, newpath); free(newpath); } return err;}static int subdir_symlink(const char *from, const char *path){ struct subdir *d = subdir_get(); char *newpath = subdir_addpath(d, path); int err = -ENOMEM; if (newpath) { err = fuse_fs_symlink(d->next, from, newpath); free(newpath); } return err;}static int subdir_rename(const char *from, const char *to){ struct subdir *d = subdir_get(); char *newfrom = subdir_addpath(d, from); char *newto = subdir_addpath(d, to); int err = -ENOMEM; if (newfrom && newto) err = fuse_fs_rename(d->next, newfrom, newto); free(newfrom); free(newto); return err;}static int subdir_link(const char *from, const char *to){ struct subdir *d = subdir_get(); char *newfrom = subdir_addpath(d, from); char *newto = subdir_addpath(d, to); int err = -ENOMEM; if (newfrom && newto) err = fuse_fs_link(d->next, newfrom, newto); free(newfrom); free(newto); return err;}static int subdir_chmod(const char *path, mode_t mode){ struct subdir *d = subdir_get(); char *newpath = subdir_addpath(d, path); int err = -ENOMEM; if (newpath) { err = fuse_fs_chmod(d->next, newpath, mode); free(newpath); } return err;}static int subdir_chown(const char *path, uid_t uid, gid_t gid){ struct subdir *d = subdir_get(); char *newpath = subdir_addpath(d, path); int err = -ENOMEM; if (newpath) { err = fuse_fs_chown(d->next, newpath, uid, gid); free(newpath); } return err;}static int subdir_truncate(const char *path, off_t size){ struct subdir *d = subdir_get(); char *newpath = subdir_addpath(d, path); int err = -ENOMEM; if (newpath) { err = fuse_fs_truncate(d->next, newpath, size); free(newpath); } return err;}static int subdir_ftruncate(const char *path, off_t size, struct fuse_file_info *fi){ struct subdir *d = subdir_get(); char *newpath = subdir_addpath(d, path); int err = -ENOMEM; if (newpath) { err = fuse_fs_ftruncate(d->next, newpath, size, fi); free(newpath); } return err;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -