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

📄 fuse.c

📁 LINUX下读写NTFS分区的工具。 已经集成了通过LIBCONV库支持中文的代码。
💻 C
📖 第 1 页 / 共 5 页
字号:
    pthread_cond_t cond;    int finished;};static void fuse_interrupt(fuse_req_t req, void *d_){    struct fuse_intr_data *d = d_;    struct fuse *f = req_fuse(req);    if (d->id == pthread_self())        return;    pthread_mutex_lock(&f->lock);    while (!d->finished) {        struct timeval now;        struct timespec timeout;        pthread_kill(d->id, f->conf.intr_signal);        gettimeofday(&now, NULL);        timeout.tv_sec = now.tv_sec + 1;        timeout.tv_nsec = now.tv_usec * 1000;        pthread_cond_timedwait(&d->cond, &f->lock, &timeout);    }    pthread_mutex_unlock(&f->lock);}static void fuse_do_finish_interrupt(struct fuse *f, fuse_req_t req,                                     struct fuse_intr_data *d){    pthread_mutex_lock(&f->lock);    d->finished = 1;    pthread_cond_broadcast(&d->cond);    pthread_mutex_unlock(&f->lock);    fuse_req_interrupt_func(req, NULL, NULL);    pthread_cond_destroy(&d->cond);}static void fuse_do_prepare_interrupt(fuse_req_t req, struct fuse_intr_data *d){    d->id = pthread_self();    pthread_cond_init(&d->cond, NULL);    d->finished = 0;    fuse_req_interrupt_func(req, fuse_interrupt, d);}static inline void fuse_finish_interrupt(struct fuse *f, fuse_req_t req,                                         struct fuse_intr_data *d){    if (f->conf.intr)        fuse_do_finish_interrupt(f, req, d);}static inline void fuse_prepare_interrupt(struct fuse *f, fuse_req_t req,                                          struct fuse_intr_data *d){    if (f->conf.intr)        fuse_do_prepare_interrupt(req, d);}int fuse_fs_getattr(struct fuse_fs *fs, const char *path, struct stat *buf){    fuse_get_context()->private_data = fs->user_data;    if (fs->op.getattr)        return fs->op.getattr(path, buf);    else        return -ENOSYS;}int fuse_fs_fgetattr(struct fuse_fs *fs, const char *path, struct stat *buf,                     struct fuse_file_info *fi){    fuse_get_context()->private_data = fs->user_data;    if (fs->op.fgetattr)        return fs->op.fgetattr(path, buf, fi);    else if (fs->op.getattr)        return fs->op.getattr(path, buf);    else        return -ENOSYS;}int fuse_fs_rename(struct fuse_fs *fs, const char *oldpath,                   const char *newpath){    fuse_get_context()->private_data = fs->user_data;    if (fs->op.rename)        return fs->op.rename(oldpath, newpath);    else        return -ENOSYS;}int fuse_fs_unlink(struct fuse_fs *fs, const char *path){    fuse_get_context()->private_data = fs->user_data;    if (fs->op.unlink)        return fs->op.unlink(path);    else        return -ENOSYS;}int fuse_fs_rmdir(struct fuse_fs *fs, const char *path){    fuse_get_context()->private_data = fs->user_data;    if (fs->op.rmdir)        return fs->op.rmdir(path);    else        return -ENOSYS;}int fuse_fs_symlink(struct fuse_fs *fs, const char *linkname, const char *path){    fuse_get_context()->private_data = fs->user_data;    if (fs->op.symlink)        return fs->op.symlink(linkname, path);    else        return -ENOSYS;}int fuse_fs_link(struct fuse_fs *fs, const char *oldpath, const char *newpath){    fuse_get_context()->private_data = fs->user_data;    if (fs->op.link)        return fs->op.link(oldpath, newpath);    else        return -ENOSYS;}int fuse_fs_release(struct fuse_fs *fs,  const char *path,                    struct fuse_file_info *fi){    fuse_get_context()->private_data = fs->user_data;    if (fs->op.release)        return fs->op.release(path, fi);    else        return 0;}int fuse_fs_opendir(struct fuse_fs *fs, const char *path,                    struct fuse_file_info *fi){    fuse_get_context()->private_data = fs->user_data;    if (fs->op.opendir)        return fs->op.opendir(path, fi);    else        return 0;}int fuse_fs_open(struct fuse_fs *fs, const char *path,                 struct fuse_file_info *fi){    fuse_get_context()->private_data = fs->user_data;    if (fs->op.open)        return fs->op.open(path, fi);    else        return 0;}int fuse_fs_read(struct fuse_fs *fs, const char *path, char *buf, size_t size,                 off_t off, struct fuse_file_info *fi){    fuse_get_context()->private_data = fs->user_data;    if (fs->op.read)        return fs->op.read(path, buf, size, off, fi);    else        return -ENOSYS;}int fuse_fs_write(struct fuse_fs *fs, const char *path, const char *buf,                  size_t size, off_t off, struct fuse_file_info *fi){    fuse_get_context()->private_data = fs->user_data;    if (fs->op.write)        return fs->op.write(path, buf, size, off, fi);    else        return -ENOSYS;}int fuse_fs_fsync(struct fuse_fs *fs, const char *path, int datasync,                  struct fuse_file_info *fi){    fuse_get_context()->private_data = fs->user_data;    if (fs->op.fsync)        return fs->op.fsync(path, datasync, fi);    else        return -ENOSYS;}int fuse_fs_fsyncdir(struct fuse_fs *fs, const char *path, int datasync,                     struct fuse_file_info *fi){    fuse_get_context()->private_data = fs->user_data;    if (fs->op.fsyncdir)        return fs->op.fsyncdir(path, datasync, fi);    else        return -ENOSYS;}int fuse_fs_flush(struct fuse_fs *fs, const char *path,                  struct fuse_file_info *fi){    fuse_get_context()->private_data = fs->user_data;    if (fs->op.flush)        return fs->op.flush(path, fi);    else        return -ENOSYS;}int fuse_fs_statfs(struct fuse_fs *fs, const char *path, struct statvfs *buf){    fuse_get_context()->private_data = fs->user_data;    if (fs->op.statfs)        return fs->op.statfs(path, buf);    else {        buf->f_namemax = 255;        buf->f_bsize = 512;        return 0;    }}int fuse_fs_releasedir(struct fuse_fs *fs, const char *path,                       struct fuse_file_info *fi){    fuse_get_context()->private_data = fs->user_data;    if (fs->op.releasedir)        return fs->op.releasedir(path, fi);    else        return 0;}int fuse_fs_readdir(struct fuse_fs *fs, const char *path, void *buf,                    fuse_fill_dir_t filler, off_t off,                    struct fuse_file_info *fi){    fuse_get_context()->private_data = fs->user_data;    if (fs->op.readdir)        return fs->op.readdir(path, buf, filler, off, fi);    else        return -ENOSYS;}int fuse_fs_create(struct fuse_fs *fs, const char *path, mode_t mode,                   struct fuse_file_info *fi){    fuse_get_context()->private_data = fs->user_data;    if (fs->op.create)        return fs->op.create(path, mode, fi);    else        return -ENOSYS;}int fuse_fs_lock(struct fuse_fs *fs, const char *path,                 struct fuse_file_info *fi, int cmd, struct flock *lock){    fuse_get_context()->private_data = fs->user_data;    if (fs->op.lock)        return fs->op.lock(path, fi, cmd, lock);    else        return -ENOSYS;}int fuse_fs_chown(struct fuse_fs *fs, const char *path, uid_t uid, gid_t gid){    fuse_get_context()->private_data = fs->user_data;    if (fs->op.chown)        return fs->op.chown(path, uid, gid);    else        return -ENOSYS;}int fuse_fs_truncate(struct fuse_fs *fs, const char *path, off_t size){    fuse_get_context()->private_data = fs->user_data;    if (fs->op.truncate)        return fs->op.truncate(path, size);    else        return -ENOSYS;}int fuse_fs_ftruncate(struct fuse_fs *fs, const char *path, off_t size,                      struct fuse_file_info *fi){    fuse_get_context()->private_data = fs->user_data;    if (fs->op.ftruncate)        return fs->op.ftruncate(path, size, fi);    else if (fs->op.truncate)        return fs->op.truncate(path, size);    else        return -ENOSYS;}int fuse_fs_utimens(struct fuse_fs *fs, const char *path,                    const struct timespec tv[2]){    fuse_get_context()->private_data = fs->user_data;    if (fs->op.utimens)        return fs->op.utimens(path, tv);    else if(fs->op.utime) {        struct utimbuf buf;        buf.actime = tv[0].tv_sec;        buf.modtime = tv[1].tv_sec;        return fs->op.utime(path, &buf);    } else        return -ENOSYS;}int fuse_fs_access(struct fuse_fs *fs, const char *path, int mask){    fuse_get_context()->private_data = fs->user_data;    if (fs->op.access)        return fs->op.access(path, mask);    else        return -ENOSYS;}int fuse_fs_readlink(struct fuse_fs *fs, const char *path, char *buf,                     size_t len){    fuse_get_context()->private_data = fs->user_data;    if (fs->op.readlink)        return fs->op.readlink(path, buf, len);    else        return -ENOSYS;}int fuse_fs_mknod(struct fuse_fs *fs, const char *path, mode_t mode,                  dev_t rdev){    fuse_get_context()->private_data = fs->user_data;    if (fs->op.mknod)        return fs->op.mknod(path, mode, rdev);    else        return -ENOSYS;}int fuse_fs_mkdir(struct fuse_fs *fs, const char *path, mode_t mode){    fuse_get_context()->private_data = fs->user_data;    if (fs->op.mkdir)        return fs->op.mkdir(path, mode);    else        return -ENOSYS;}int fuse_fs_setxattr(struct fuse_fs *fs, const char *path, const char *name,                     const char *value, size_t size, int flags){    fuse_get_context()->private_data = fs->user_data;    if (fs->op.setxattr)        return fs->op.setxattr(path, name, value, size, flags);    else        return -ENOSYS;}int fuse_fs_getxattr(struct fuse_fs *fs, const char *path, const char *name,                     char *value, size_t size){    fuse_get_context()->private_data = fs->user_data;    if (fs->op.getxattr)        return fs->op.getxattr(path, name, value, size);    else        return -ENOSYS;}int fuse_fs_listxattr(struct fuse_fs *fs, const char *path, char *list,                      size_t size){    fuse_get_context()->private_data = fs->user_data;    if (fs->op.listxattr)        return fs->op.listxattr(path, list, size);    else        return -ENOSYS;}int fuse_fs_bmap(struct fuse_fs *fs, const char *path, size_t blocksize,                 uint64_t *idx){    fuse_get_context()->private_data = fs->user_data;    if (fs->op.bmap)        return fs->op.bmap(path, blocksize, idx);    else        return -ENOSYS;}int fuse_fs_removexattr(struct fuse_fs *fs, const char *path, const char *name){    fuse_get_context()->private_data = fs->user_data;    if (fs->op.removexattr)        return fs->op.removexattr(path, name);    else        return -ENOSYS;}static int is_open(struct fuse *f, fuse_ino_t dir, const char *name){    struct node *node;    int isopen = 0;    pthread_mutex_lock(&f->lock);    node = lookup_node(f, dir, name);    if (node && node->open_count > 0)        isopen = 1;    pthread_mutex_unlock(&f->lock);    return isopen;}static char *hidden_name(struct fuse *f, fuse_ino_t dir, const char *oldname,                         char *newname, size_t bufsize){    struct stat buf;    struct node *node;    struct node *newnode;    char *newpath;    int res;    int failctr = 10;    do {        pthread_mutex_lock(&f->lock);        node = lookup_node(f, dir, oldname);        if (node == NULL) {            pthread_mutex_unlock(&f->lock);            return NULL;        }        do {            f->hidectr ++;            snprintf(newname, bufsize, ".fuse_hidden%08x%08x",                     (unsigned int) node->nodeid, f->hidectr);            newnode = lookup_node(f, dir, newname);        } while(newnode);        pthread_mutex_unlock(&f->lock);        newpath = get_path_name(f, dir, newname);        if (!newpath)            break;        res = fuse_fs_getattr(f->fs, newpath, &buf);        if (res == -ENOENT)            break;        free(newpath);        newpath = NULL;    } while(res == 0 && --failctr);    return newpath;}static int hide_node(struct fuse *f, const char *oldpath,                     fuse_ino_t dir, const char *oldname){    char newname[64];    char *newpath;    int err = -EBUSY;    newpath = hidden_name(f, dir, oldname, newname, sizeof(newname));    if (newpath) {        err = fuse_fs_rename(f->fs, oldpath, newpath);        if (!err)            err = rename_node(f, dir, oldname, dir, newname, 1);        free(newpath);    }    return err;}static int mtime_eq(const struct stat *stbuf, const struct timespec *ts){    return stbuf->st_mtime == ts->tv_sec && ST_MTIM_NSEC(stbuf) == ts->tv_nsec;}#ifndef CLOCK_MONOTONIC#define CLOCK_MONOTONIC CLOCK_REALTIME#endifstatic void curr_time(struct timespec *now){    static clockid_t clockid = CLOCK_MONOTONIC;    int res = clock_gettime(clockid, now);    if (res == -1 && errno == EINVAL) {        clockid = CLOCK_REALTIME;        res = clock_gettime(clockid, now);    }    if (res == -1) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -