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

📄 iconv.c

📁 FUSE文件系统开发工具,将内核层面的文件系统开发过程平移到应用层面上来。
💻 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 LGPLv2.  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 + -