37 static struct iconv *iconv_get(
void)
    42 static int iconv_convpath(
struct iconv *ic, 
const char *path, 
char **newpathp,
    58         pathlen = strlen(path);
    59         newpathlen = pathlen * 4;
    60         newpath = malloc(newpathlen + 1);
    66         pthread_mutex_lock(&ic->lock);
    68                 res = iconv(fromfs ? ic->fromfs : ic->tofs, (
char **) &path,
    70                 if (res == (
size_t) -1) {
    78                         inc = (pathlen + 1) * 4;
    80                         tmp = realloc(newpath, newpathlen + 1);
    85                         p = tmp + (p - newpath);
    89         } 
while (res == (
size_t) -1);
    90         pthread_mutex_unlock(&ic->lock);
    96         iconv(fromfs ? ic->fromfs : ic->tofs, NULL, NULL, NULL, NULL);
    97         pthread_mutex_unlock(&ic->lock);
   102 static int iconv_getattr(
const char *path, 
struct stat *stbuf,
   105         struct iconv *ic = iconv_get();
   107         int err = iconv_convpath(ic, path, &newpath, 0);
   109                 err = fuse_fs_getattr(ic->next, newpath, stbuf, fi);
   115 static int iconv_access(
const char *path, 
int mask)
   117         struct iconv *ic = iconv_get();
   119         int err = iconv_convpath(ic, path, &newpath, 0);
   121                 err = fuse_fs_access(ic->next, newpath, mask);
   127 static int iconv_readlink(
const char *path, 
char *buf, 
size_t size)
   129         struct iconv *ic = iconv_get();
   131         int err = iconv_convpath(ic, path, &newpath, 0);
   133                 err = fuse_fs_readlink(ic->next, newpath, buf, size);
   136                         err = iconv_convpath(ic, buf, &newlink, 1);
   138                                 strncpy(buf, newlink, size - 1);
   139                                 buf[size - 1] = 
'\0';
   148 static int iconv_opendir(
const char *path, 
struct fuse_file_info *fi)
   150         struct iconv *ic = iconv_get();
   152         int err = iconv_convpath(ic, path, &newpath, 0);
   154                 err = fuse_fs_opendir(ic->next, newpath, fi);
   160 static int iconv_dir_fill(
void *buf, 
const char *name,
   161                           const struct stat *stbuf, off_t off,
   164         struct iconv_dh *dh = buf;
   167         if (iconv_convpath(dh->ic, name, &newname, 1) == 0) {
   168                 res = dh->prev_filler(dh->prev_buf, newname, stbuf, off, flags);
   174 static int iconv_readdir(
const char *path, 
void *buf, 
fuse_fill_dir_t filler,
   178         struct iconv *ic = iconv_get();
   180         int err = iconv_convpath(ic, path, &newpath, 0);
   185                 dh.prev_filler = filler;
   186                 err = fuse_fs_readdir(ic->next, newpath, &dh, iconv_dir_fill,
   193 static int iconv_releasedir(
const char *path, 
struct fuse_file_info *fi)
   195         struct iconv *ic = iconv_get();
   197         int err = iconv_convpath(ic, path, &newpath, 0);
   199                 err = fuse_fs_releasedir(ic->next, newpath, fi);
   205 static int iconv_mknod(
const char *path, mode_t mode, dev_t rdev)
   207         struct iconv *ic = iconv_get();
   209         int err = iconv_convpath(ic, path, &newpath, 0);
   211                 err = fuse_fs_mknod(ic->next, newpath, mode, rdev);
   217 static int iconv_mkdir(
const char *path, mode_t mode)
   219         struct iconv *ic = iconv_get();
   221         int err = iconv_convpath(ic, path, &newpath, 0);
   223                 err = fuse_fs_mkdir(ic->next, newpath, mode);
   229 static int iconv_unlink(
const char *path)
   231         struct iconv *ic = iconv_get();
   233         int err = iconv_convpath(ic, path, &newpath, 0);
   235                 err = fuse_fs_unlink(ic->next, newpath);
   241 static int iconv_rmdir(
const char *path)
   243         struct iconv *ic = iconv_get();
   245         int err = iconv_convpath(ic, path, &newpath, 0);
   247                 err = fuse_fs_rmdir(ic->next, newpath);
   253 static int iconv_symlink(
const char *from, 
const char *to)
   255         struct iconv *ic = iconv_get();
   258         int err = iconv_convpath(ic, from, &newfrom, 0);
   260                 err = iconv_convpath(ic, to, &newto, 0);
   262                         err = fuse_fs_symlink(ic->next, newfrom, newto);
   270 static int iconv_rename(
const char *from, 
const char *to, 
unsigned int flags)
   272         struct iconv *ic = iconv_get();
   275         int err = iconv_convpath(ic, from, &newfrom, 0);
   277                 err = iconv_convpath(ic, to, &newto, 0);
   279                         err = fuse_fs_rename(ic->next, newfrom, newto, flags);
   287 static int iconv_link(
const char *from, 
const char *to)
   289         struct iconv *ic = iconv_get();
   292         int err = iconv_convpath(ic, from, &newfrom, 0);
   294                 err = iconv_convpath(ic, to, &newto, 0);
   296                         err = fuse_fs_link(ic->next, newfrom, newto);
   304 static int iconv_chmod(
const char *path, mode_t mode,
   307         struct iconv *ic = iconv_get();
   309         int err = iconv_convpath(ic, path, &newpath, 0);
   311                 err = fuse_fs_chmod(ic->next, newpath, mode, fi);
   317 static int iconv_chown(
const char *path, uid_t uid, gid_t gid,
   320         struct iconv *ic = iconv_get();
   322         int err = iconv_convpath(ic, path, &newpath, 0);
   324                 err = fuse_fs_chown(ic->next, newpath, uid, gid, fi);
   330 static int iconv_truncate(
const char *path, off_t size,
   333         struct iconv *ic = iconv_get();
   335         int err = iconv_convpath(ic, path, &newpath, 0);
   337                 err = fuse_fs_truncate(ic->next, newpath, size, fi);
   343 static int iconv_utimens(
const char *path, 
const struct timespec ts[2],
   346         struct iconv *ic = iconv_get();
   348         int err = iconv_convpath(ic, path, &newpath, 0);
   350                 err = fuse_fs_utimens(ic->next, newpath, ts, fi);
   356 static int iconv_create(
const char *path, mode_t mode,
   359         struct iconv *ic = iconv_get();
   361         int err = iconv_convpath(ic, path, &newpath, 0);
   363                 err = fuse_fs_create(ic->next, newpath, mode, fi);
   369 static int iconv_open_file(
const char *path, 
struct fuse_file_info *fi)
   371         struct iconv *ic = iconv_get();
   373         int err = iconv_convpath(ic, path, &newpath, 0);
   375                 err = fuse_fs_open(ic->next, newpath, fi);
   381 static int iconv_read_buf(
const char *path, 
struct fuse_bufvec **bufp,
   384         struct iconv *ic = iconv_get();
   386         int err = iconv_convpath(ic, path, &newpath, 0);
   388                 err = fuse_fs_read_buf(ic->next, newpath, bufp, size, offset, fi);
   394 static int iconv_write_buf(
const char *path, 
struct fuse_bufvec *buf,
   397         struct iconv *ic = iconv_get();
   399         int err = iconv_convpath(ic, path, &newpath, 0);
   401                 err = fuse_fs_write_buf(ic->next, newpath, buf, offset, fi);
   407 static int iconv_statfs(
const char *path, 
struct statvfs *stbuf)
   409         struct iconv *ic = iconv_get();
   411         int err = iconv_convpath(ic, path, &newpath, 0);
   413                 err = fuse_fs_statfs(ic->next, newpath, stbuf);
   419 static int iconv_flush(
const char *path, 
struct fuse_file_info *fi)
   421         struct iconv *ic = iconv_get();
   423         int err = iconv_convpath(ic, path, &newpath, 0);
   425                 err = fuse_fs_flush(ic->next, newpath, fi);
   431 static int iconv_release(
const char *path, 
struct fuse_file_info *fi)
   433         struct iconv *ic = iconv_get();
   435         int err = iconv_convpath(ic, path, &newpath, 0);
   437                 err = fuse_fs_release(ic->next, newpath, fi);
   443 static int iconv_fsync(
const char *path, 
int isdatasync,
   446         struct iconv *ic = iconv_get();
   448         int err = iconv_convpath(ic, path, &newpath, 0);
   450                 err = fuse_fs_fsync(ic->next, newpath, isdatasync, fi);
   456 static int iconv_fsyncdir(
const char *path, 
int isdatasync,
   459         struct iconv *ic = iconv_get();
   461         int err = iconv_convpath(ic, path, &newpath, 0);
   463                 err = fuse_fs_fsyncdir(ic->next, newpath, isdatasync, fi);
   469 static int iconv_setxattr(
const char *path, 
const char *name,
   470                           const char *value, 
size_t size, 
int flags)
   472         struct iconv *ic = iconv_get();
   474         int err = iconv_convpath(ic, path, &newpath, 0);
   476                 err = fuse_fs_setxattr(ic->next, newpath, name, value, size,
   483 static int iconv_getxattr(
const char *path, 
const char *name, 
char *value,
   486         struct iconv *ic = iconv_get();
   488         int err = iconv_convpath(ic, path, &newpath, 0);
   490                 err = fuse_fs_getxattr(ic->next, newpath, name, value, size);
   496 static int iconv_listxattr(
const char *path, 
char *list, 
size_t size)
   498         struct iconv *ic = iconv_get();
   500         int err = iconv_convpath(ic, path, &newpath, 0);
   502                 err = fuse_fs_listxattr(ic->next, newpath, list, size);
   508 static int iconv_removexattr(
const char *path, 
const char *name)
   510         struct iconv *ic = iconv_get();
   512         int err = iconv_convpath(ic, path, &newpath, 0);
   514                 err = fuse_fs_removexattr(ic->next, newpath, name);
   520 static int iconv_lock(
const char *path, 
struct fuse_file_info *fi, 
int cmd,
   523         struct iconv *ic = iconv_get();
   525         int err = iconv_convpath(ic, path, &newpath, 0);
   527                 err = fuse_fs_lock(ic->next, newpath, fi, cmd, lock);
   533 static int iconv_flock(
const char *path, 
struct fuse_file_info *fi, 
int op)
   535         struct iconv *ic = iconv_get();
   537         int err = iconv_convpath(ic, path, &newpath, 0);
   539                 err = fuse_fs_flock(ic->next, newpath, fi, op);
   545 static int iconv_bmap(
const char *path, 
size_t blocksize, uint64_t *idx)
   547         struct iconv *ic = iconv_get();
   549         int err = iconv_convpath(ic, path, &newpath, 0);
   551                 err = fuse_fs_bmap(ic->next, newpath, blocksize, idx);
   557 static off_t iconv_lseek(
const char *path, off_t off, 
int whence,
   560         struct iconv *ic = iconv_get();
   562         int res = iconv_convpath(ic, path, &newpath, 0);
   564                 res = fuse_fs_lseek(ic->next, newpath, off, whence, fi);
   573         struct iconv *ic = iconv_get();
   574         fuse_fs_init(ic->next, conn, cfg);
   580 static void iconv_destroy(
void *data)
   582         struct iconv *ic = data;
   583         fuse_fs_destroy(ic->next);
   584         iconv_close(ic->tofs);
   585         iconv_close(ic->fromfs);
   586         pthread_mutex_destroy(&ic->lock);
   595         .getattr        = iconv_getattr,
   596         .access         = iconv_access,
   597         .readlink       = iconv_readlink,
   598         .opendir        = iconv_opendir,
   599         .readdir        = iconv_readdir,
   600         .releasedir     = iconv_releasedir,
   601         .mknod          = iconv_mknod,
   602         .mkdir          = iconv_mkdir,
   603         .symlink        = iconv_symlink,
   604         .unlink         = iconv_unlink,
   605         .rmdir          = iconv_rmdir,
   606         .rename         = iconv_rename,
   608         .chmod          = iconv_chmod,
   609         .chown          = iconv_chown,
   610         .truncate       = iconv_truncate,
   611         .utimens        = iconv_utimens,
   612         .create         = iconv_create,
   613         .open           = iconv_open_file,
   614         .read_buf       = iconv_read_buf,
   615         .write_buf      = iconv_write_buf,
   616         .statfs         = iconv_statfs,
   617         .flush          = iconv_flush,
   618         .release        = iconv_release,
   619         .fsync          = iconv_fsync,
   620         .fsyncdir       = iconv_fsyncdir,
   621         .setxattr       = iconv_setxattr,
   622         .getxattr       = iconv_getxattr,
   623         .listxattr      = iconv_listxattr,
   624         .removexattr    = iconv_removexattr,
   626         .flock          = iconv_flock,
   628         .lseek          = iconv_lseek,
   631 static const struct fuse_opt iconv_opts[] = {
   634         { 
"from_code=%s", offsetof(
struct iconv, from_code), 0 },
   635         { 
"to_code=%s", offsetof(
struct iconv, to_code), 1 },
   639 static void iconv_help(
void)
   642         const char *old = setlocale(LC_CTYPE, 
"");
   644         charmap = strdup(nl_langinfo(CODESET));
   646                 setlocale(LC_CTYPE, old);
   651 "    -o from_code=CHARSET   original encoding of file names (default: UTF-8)\n"   652 "    -o to_code=CHARSET     new encoding of the file names (default: %s)\n",
   657 static int iconv_opt_proc(
void *data, 
const char *arg, 
int key,
   660         (void) data; (void) arg; (void) outargs;
   670 static struct fuse_fs *iconv_new(
struct fuse_args *args,
   671                                  struct fuse_fs *next[])
   679         ic = calloc(1, 
sizeof(
struct iconv));
   681                 fuse_log(FUSE_LOG_ERR, 
"fuse-iconv: memory allocation failed\n");
   688         if (!next[0] || next[1]) {
   689                 fuse_log(FUSE_LOG_ERR, 
"fuse-iconv: exactly one next filesystem required\n");
   693         from = ic->from_code ? ic->from_code : 
"UTF-8";
   694         to = ic->to_code ? ic->to_code : 
"";
   697                 old = strdup(setlocale(LC_CTYPE, 
""));
   698         ic->tofs = iconv_open(from, to);
   699         if (ic->tofs == (iconv_t) -1) {
   700                 fuse_log(FUSE_LOG_ERR, 
"fuse-iconv: cannot convert from %s to %s\n",
   704         ic->fromfs = iconv_open(to, from);
   705         if (ic->tofs == (iconv_t) -1) {
   706                 fuse_log(FUSE_LOG_ERR, 
"fuse-iconv: cannot convert from %s to %s\n",
   708                 goto out_iconv_close_to;
   711                 setlocale(LC_CTYPE, old);
   717         fs = 
fuse_fs_new(&iconv_oper, 
sizeof(iconv_oper), ic);
   719                 goto out_iconv_close_from;
   723 out_iconv_close_from:
   724         iconv_close(ic->fromfs);
   726         iconv_close(ic->tofs);
   732                 setlocale(LC_CTYPE, old);
 int fuse_opt_parse(struct fuse_args *args, void *data, const struct fuse_opt opts[], fuse_opt_proc_t proc)
#define FUSE_REGISTER_MODULE(name_, factory_)
void(* destroy)(void *private_data)
struct fuse_fs * fuse_fs_new(const struct fuse_operations *op, size_t op_size, void *private_data)
struct fuse_context * fuse_get_context(void)
#define FUSE_OPT_KEY(templ, key)
int(* fuse_fill_dir_t)(void *buf, const char *name, const struct stat *stbuf, off_t off, enum fuse_fill_dir_flags flags)
void fuse_log(enum fuse_log_level level, const char *fmt,...)