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

📄 iconv.c

📁 UNIX/LINUX下面的用户文件系统
💻 C
📖 第 1 页 / 共 2 页
字号:
/*    fuse iconv module: file name charset conversion    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>#include <iconv.h>#include <pthread.h>#include <locale.h>#include <langinfo.h>struct iconv {    struct fuse_fs *next;    pthread_mutex_t lock;    char *from_code;    char *to_code;    iconv_t tofs;    iconv_t fromfs;};struct iconv_dh {    struct iconv *ic;    void *prev_buf;    fuse_fill_dir_t prev_filler;};static struct iconv *iconv_get(void){    return fuse_get_context()->private_data;}static int iconv_convpath(struct iconv *ic, const char *path, char **newpathp,                          int fromfs){    size_t pathlen = strlen(path);    size_t newpathlen = pathlen * 4;    char *newpath = malloc(newpathlen + 1);    size_t plen = newpathlen;    char *p = newpath;    size_t res;    int err;    if (!newpath)        return -ENOMEM;    pthread_mutex_lock(&ic->lock);    do {        res = iconv(fromfs ? ic->fromfs : ic->tofs, (char **) &path, &pathlen,                    &p, &plen);        if (res == (size_t) -1) {            char *tmp;            size_t inc;            err = -EILSEQ;            if (errno != E2BIG)                goto err;            inc = (pathlen + 1) * 4;            newpathlen += inc;            tmp = realloc(newpath, newpathlen + 1);            err = -ENOMEM;            if (!tmp)                goto err;            p = tmp + (p - newpath);            plen += inc;            newpath = tmp;        }    } while (res == (size_t) -1);    pthread_mutex_unlock(&ic->lock);    *p = '\0';    *newpathp = newpath;    return 0; err:    iconv(fromfs ? ic->fromfs : ic->tofs, NULL, NULL, NULL, NULL);    pthread_mutex_unlock(&ic->lock);    free(newpath);    return err;}static int iconv_getattr(const char *path, struct stat *stbuf){    struct iconv *ic = iconv_get();    char *newpath;    int err = iconv_convpath(ic, path, &newpath, 0);    if (!err) {        err = fuse_fs_getattr(ic->next, newpath, stbuf);        free(newpath);    }    return err;}static int iconv_fgetattr(const char *path, struct stat *stbuf,                          struct fuse_file_info *fi){    struct iconv *ic = iconv_get();    char *newpath;    int err = iconv_convpath(ic, path, &newpath, 0);    if (!err) {        err = fuse_fs_fgetattr(ic->next, newpath, stbuf, fi);        free(newpath);    }    return err;}static int iconv_access(const char *path, int mask){    struct iconv *ic = iconv_get();    char *newpath;    int err = iconv_convpath(ic, path, &newpath, 0);    if (!err) {        err = fuse_fs_access(ic->next, newpath, mask);        free(newpath);    }    return err;}static int iconv_readlink(const char *path, char *buf, size_t size){    struct iconv *ic = iconv_get();    char *newpath;    int err = iconv_convpath(ic, path, &newpath, 0);    if (!err) {        err = fuse_fs_readlink(ic->next, newpath, buf, size);        if (!err) {            char *newlink;            err = iconv_convpath(ic, buf, &newlink, 1);            if (!err) {                strncpy(buf, newlink, size - 1);                buf[size - 1] = '\0';                free(newlink);            }        }        free(newpath);    }    return err;}static int iconv_opendir(const char *path, struct fuse_file_info *fi){    struct iconv *ic = iconv_get();    char *newpath;    int err = iconv_convpath(ic, path, &newpath, 0);    if (!err) {        err = fuse_fs_opendir(ic->next, newpath, fi);        free(newpath);    }    return err;}static int iconv_dir_fill(void *buf, const char *name,                          const struct stat *stbuf, off_t off){    struct iconv_dh *dh = buf;    char *newname;    int res = 0;    if (iconv_convpath(dh->ic, name, &newname, 1) == 0) {        res = dh->prev_filler(dh->prev_buf, newname, stbuf, off);        free(newname);    }    return res;}static int iconv_readdir(const char *path, void *buf, fuse_fill_dir_t filler,                         off_t offset, struct fuse_file_info *fi){    struct iconv *ic = iconv_get();    char *newpath;    int err = iconv_convpath(ic, path, &newpath, 0);    if (!err) {        struct iconv_dh dh;        dh.ic = ic;        dh.prev_buf = buf;        dh.prev_filler = filler;        err = fuse_fs_readdir(ic->next, newpath, &dh, iconv_dir_fill, offset,                              fi);        free(newpath);    }    return err;}static int iconv_releasedir(const char *path, struct fuse_file_info *fi){    struct iconv *ic = iconv_get();    char *newpath;    int err = iconv_convpath(ic, path, &newpath, 0);    if (!err) {        err = fuse_fs_releasedir(ic->next, newpath, fi);        free(newpath);    }    return err;}static int iconv_mknod(const char *path, mode_t mode, dev_t rdev){    struct iconv *ic = iconv_get();    char *newpath;    int err = iconv_convpath(ic, path, &newpath, 0);    if (!err) {        err = fuse_fs_mknod(ic->next, newpath, mode, rdev);        free(newpath);    }    return err;}static int iconv_mkdir(const char *path, mode_t mode){    struct iconv *ic = iconv_get();    char *newpath;    int err = iconv_convpath(ic, path, &newpath, 0);    if (!err) {        err = fuse_fs_mkdir(ic->next, newpath, mode);        free(newpath);    }    return err;}static int iconv_unlink(const char *path){    struct iconv *ic = iconv_get();    char *newpath;    int err = iconv_convpath(ic, path, &newpath, 0);    if (!err) {        err = fuse_fs_unlink(ic->next, newpath);        free(newpath);    }    return err;}static int iconv_rmdir(const char *path){    struct iconv *ic = iconv_get();    char *newpath;    int err = iconv_convpath(ic, path, &newpath, 0);    if (!err) {        err = fuse_fs_rmdir(ic->next, newpath);        free(newpath);    }    return err;}static int iconv_symlink(const char *from, const char *to){    struct iconv *ic = iconv_get();    char *newfrom;    char *newto;    int err = iconv_convpath(ic, from, &newfrom, 0);    if (!err) {        err = iconv_convpath(ic, to, &newto, 0);        if (!err) {            err = fuse_fs_symlink(ic->next, newfrom, newto);            free(newto);        }        free(newfrom);    }    return err;}static int iconv_rename(const char *from, const char *to){    struct iconv *ic = iconv_get();    char *newfrom;    char *newto;    int err = iconv_convpath(ic, from, &newfrom, 0);    if (!err) {        err = iconv_convpath(ic, to, &newto, 0);        if (!err) {            err = fuse_fs_rename(ic->next, newfrom, newto);            free(newto);        }        free(newfrom);    }    return err;}static int iconv_link(const char *from, const char *to){    struct iconv *ic = iconv_get();    char *newfrom;    char *newto;    int err = iconv_convpath(ic, from, &newfrom, 0);    if (!err) {        err = iconv_convpath(ic, to, &newto, 0);        if (!err) {            err = fuse_fs_link(ic->next, newfrom, newto);            free(newto);        }        free(newfrom);    }    return err;}static int iconv_chmod(const char *path, mode_t mode){    struct iconv *ic = iconv_get();    char *newpath;    int err = iconv_convpath(ic, path, &newpath, 0);    if (!err) {        err = fuse_fs_chmod(ic->next, newpath, mode);        free(newpath);    }    return err;}static int iconv_chown(const char *path, uid_t uid, gid_t gid){    struct iconv *ic = iconv_get();    char *newpath;    int err = iconv_convpath(ic, path, &newpath, 0);    if (!err) {        err = fuse_fs_chown(ic->next, newpath, uid, gid);        free(newpath);    }    return err;}static int iconv_truncate(const char *path, off_t size){    struct iconv *ic = iconv_get();    char *newpath;    int err = iconv_convpath(ic, path, &newpath, 0);    if (!err) {        err = fuse_fs_truncate(ic->next, newpath, size);        free(newpath);    }    return err;}static int iconv_ftruncate(const char *path, off_t size,                           struct fuse_file_info *fi){    struct iconv *ic = iconv_get();    char *newpath;    int err = iconv_convpath(ic, path, &newpath, 0);    if (!err) {        err = fuse_fs_ftruncate(ic->next, newpath, size, fi);        free(newpath);    }    return err;}static int iconv_utimens(const char *path, const struct timespec ts[2]){    struct iconv *ic = iconv_get();

⌨️ 快捷键说明

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