⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 subdir.c

📁 UNIX/LINUX下面的用户文件系统
💻 C
📖 第 1 页 / 共 2 页
字号:
/*    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 + -