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[])
 
  675         const char *old = NULL;
 
  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 = 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);
 
  716         fs = 
fuse_fs_new(&iconv_oper, 
sizeof(iconv_oper), ic);
 
  718                 goto out_iconv_close_from;
 
  722 out_iconv_close_from:
 
  723         iconv_close(ic->fromfs);
 
  725         iconv_close(ic->tofs);
 
  731                 setlocale(LC_CTYPE, old);
 
struct fuse_fs * fuse_fs_new(const struct fuse_operations *op, size_t op_size, void *private_data)
int(* fuse_fill_dir_t)(void *buf, const char *name, const struct stat *stbuf, off_t off, enum fuse_fill_dir_flags flags)
struct fuse_context * fuse_get_context(void)
#define FUSE_REGISTER_MODULE(name_, factory_)
void fuse_log(enum fuse_log_level level, const char *fmt,...)
#define FUSE_OPT_KEY(templ, key)
int fuse_opt_parse(struct fuse_args *args, void *data, const struct fuse_opt opts[], fuse_opt_proc_t proc)
void(* destroy)(void *private_data)