📄 iconv.c
字号:
/* 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 + -