20
20
#include <langinfo.h>
34
fuse_fill_dir_t prev_filler;
34
fuse_fill_dir_t prev_filler;
37
37
static struct iconv *iconv_get(void)
39
return fuse_get_context()->private_data;
39
return fuse_get_context()->private_data;
42
42
static int iconv_convpath(struct iconv *ic, const char *path, char **newpathp,
45
size_t pathlen = strlen(path);
46
size_t newpathlen = pathlen * 4;
47
char *newpath = malloc(newpathlen + 1);
48
size_t plen = newpathlen;
56
pthread_mutex_lock(&ic->lock);
58
res = iconv(fromfs ? ic->fromfs : ic->tofs, (char **) &path, &pathlen,
60
if (res == (size_t) -1) {
68
inc = (pathlen + 1) * 4;
70
tmp = realloc(newpath, newpathlen + 1);
75
p = tmp + (p - newpath);
79
} while (res == (size_t) -1);
80
pthread_mutex_unlock(&ic->lock);
86
iconv(fromfs ? ic->fromfs : ic->tofs, NULL, NULL, NULL, NULL);
87
pthread_mutex_unlock(&ic->lock);
45
size_t pathlen = strlen(path);
46
size_t newpathlen = pathlen * 4;
47
char *newpath = malloc(newpathlen + 1);
48
size_t plen = newpathlen;
56
pthread_mutex_lock(&ic->lock);
58
res = iconv(fromfs ? ic->fromfs : ic->tofs, (char **) &path,
60
if (res == (size_t) -1) {
68
inc = (pathlen + 1) * 4;
70
tmp = realloc(newpath, newpathlen + 1);
75
p = tmp + (p - newpath);
79
} while (res == (size_t) -1);
80
pthread_mutex_unlock(&ic->lock);
86
iconv(fromfs ? ic->fromfs : ic->tofs, NULL, NULL, NULL, NULL);
87
pthread_mutex_unlock(&ic->lock);
92
92
static int iconv_getattr(const char *path, struct stat *stbuf)
94
struct iconv *ic = iconv_get();
96
int err = iconv_convpath(ic, path, &newpath, 0);
98
err = fuse_fs_getattr(ic->next, newpath, stbuf);
94
struct iconv *ic = iconv_get();
96
int err = iconv_convpath(ic, path, &newpath, 0);
98
err = fuse_fs_getattr(ic->next, newpath, stbuf);
104
104
static int iconv_fgetattr(const char *path, struct stat *stbuf,
105
struct fuse_file_info *fi)
105
struct fuse_file_info *fi)
107
struct iconv *ic = iconv_get();
109
int err = iconv_convpath(ic, path, &newpath, 0);
111
err = fuse_fs_fgetattr(ic->next, newpath, stbuf, fi);
107
struct iconv *ic = iconv_get();
109
int err = iconv_convpath(ic, path, &newpath, 0);
111
err = fuse_fs_fgetattr(ic->next, newpath, stbuf, fi);
117
117
static int iconv_access(const char *path, int mask)
119
struct iconv *ic = iconv_get();
121
int err = iconv_convpath(ic, path, &newpath, 0);
123
err = fuse_fs_access(ic->next, newpath, mask);
119
struct iconv *ic = iconv_get();
121
int err = iconv_convpath(ic, path, &newpath, 0);
123
err = fuse_fs_access(ic->next, newpath, mask);
129
129
static int iconv_readlink(const char *path, char *buf, size_t size)
131
struct iconv *ic = iconv_get();
133
int err = iconv_convpath(ic, path, &newpath, 0);
135
err = fuse_fs_readlink(ic->next, newpath, buf, size);
138
err = iconv_convpath(ic, buf, &newlink, 1);
140
strncpy(buf, newlink, size - 1);
141
buf[size - 1] = '\0';
131
struct iconv *ic = iconv_get();
133
int err = iconv_convpath(ic, path, &newpath, 0);
135
err = fuse_fs_readlink(ic->next, newpath, buf, size);
138
err = iconv_convpath(ic, buf, &newlink, 1);
140
strncpy(buf, newlink, size - 1);
141
buf[size - 1] = '\0';
150
150
static int iconv_opendir(const char *path, struct fuse_file_info *fi)
152
struct iconv *ic = iconv_get();
154
int err = iconv_convpath(ic, path, &newpath, 0);
156
err = fuse_fs_opendir(ic->next, newpath, fi);
152
struct iconv *ic = iconv_get();
154
int err = iconv_convpath(ic, path, &newpath, 0);
156
err = fuse_fs_opendir(ic->next, newpath, fi);
162
162
static int iconv_dir_fill(void *buf, const char *name,
163
const struct stat *stbuf, off_t off)
163
const struct stat *stbuf, off_t off)
165
struct iconv_dh *dh = buf;
168
if (iconv_convpath(dh->ic, name, &newname, 1) == 0) {
169
res = dh->prev_filler(dh->prev_buf, newname, stbuf, off);
165
struct iconv_dh *dh = buf;
168
if (iconv_convpath(dh->ic, name, &newname, 1) == 0) {
169
res = dh->prev_filler(dh->prev_buf, newname, stbuf, off);
175
175
static int iconv_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
176
off_t offset, struct fuse_file_info *fi)
176
off_t offset, struct fuse_file_info *fi)
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, offset,
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
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);
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
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);
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
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);
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
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);
231
struct iconv *ic = iconv_get();
233
int err = iconv_convpath(ic, path, &newpath, 0);
235
err = fuse_fs_unlink(ic->next, newpath);
241
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);
243
struct iconv *ic = iconv_get();
245
int err = iconv_convpath(ic, path, &newpath, 0);
247
err = fuse_fs_rmdir(ic->next, newpath);
253
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);
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
270
static int iconv_rename(const char *from, const char *to)
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);
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);
287
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);
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
304
static int iconv_chmod(const char *path, mode_t mode)
306
struct iconv *ic = iconv_get();
308
int err = iconv_convpath(ic, path, &newpath, 0);
310
err = fuse_fs_chmod(ic->next, newpath, mode);
306
struct iconv *ic = iconv_get();
308
int err = iconv_convpath(ic, path, &newpath, 0);
310
err = fuse_fs_chmod(ic->next, newpath, mode);
316
316
static int iconv_chown(const char *path, uid_t uid, gid_t gid)
318
struct iconv *ic = iconv_get();
320
int err = iconv_convpath(ic, path, &newpath, 0);
322
err = fuse_fs_chown(ic->next, newpath, uid, gid);
318
struct iconv *ic = iconv_get();
320
int err = iconv_convpath(ic, path, &newpath, 0);
322
err = fuse_fs_chown(ic->next, newpath, uid, gid);
328
328
static int iconv_truncate(const char *path, off_t size)
330
struct iconv *ic = iconv_get();
332
int err = iconv_convpath(ic, path, &newpath, 0);
334
err = fuse_fs_truncate(ic->next, newpath, size);
330
struct iconv *ic = iconv_get();
332
int err = iconv_convpath(ic, path, &newpath, 0);
334
err = fuse_fs_truncate(ic->next, newpath, size);
340
340
static int iconv_ftruncate(const char *path, off_t size,
341
struct fuse_file_info *fi)
341
struct fuse_file_info *fi)
343
struct iconv *ic = iconv_get();
345
int err = iconv_convpath(ic, path, &newpath, 0);
347
err = fuse_fs_ftruncate(ic->next, newpath, size, fi);
343
struct iconv *ic = iconv_get();
345
int err = iconv_convpath(ic, path, &newpath, 0);
347
err = fuse_fs_ftruncate(ic->next, newpath, size, fi);
353
353
static int iconv_utimens(const char *path, const struct timespec ts[2])
355
struct iconv *ic = iconv_get();
357
int err = iconv_convpath(ic, path, &newpath, 0);
359
err = fuse_fs_utimens(ic->next, newpath, ts);
355
struct iconv *ic = iconv_get();
357
int err = iconv_convpath(ic, path, &newpath, 0);
359
err = fuse_fs_utimens(ic->next, newpath, ts);
365
365
static int iconv_create(const char *path, mode_t mode,
366
struct fuse_file_info *fi)
366
struct fuse_file_info *fi)
368
struct iconv *ic = iconv_get();
370
int err = iconv_convpath(ic, path, &newpath, 0);
372
err = fuse_fs_create(ic->next, newpath, mode, fi);
368
struct iconv *ic = iconv_get();
370
int err = iconv_convpath(ic, path, &newpath, 0);
372
err = fuse_fs_create(ic->next, newpath, mode, fi);
378
378
static int iconv_open_file(const char *path, struct fuse_file_info *fi)
380
struct iconv *ic = iconv_get();
382
int err = iconv_convpath(ic, path, &newpath, 0);
384
err = fuse_fs_open(ic->next, newpath, fi);
380
struct iconv *ic = iconv_get();
382
int err = iconv_convpath(ic, path, &newpath, 0);
384
err = fuse_fs_open(ic->next, newpath, fi);
390
390
static int iconv_read(const char *path, char *buf, size_t size, off_t offset,
391
struct fuse_file_info *fi)
391
struct fuse_file_info *fi)
393
struct iconv *ic = iconv_get();
395
int err = iconv_convpath(ic, path, &newpath, 0);
397
err = fuse_fs_read(ic->next, newpath, buf, size, offset, fi);
393
struct iconv *ic = iconv_get();
395
int err = iconv_convpath(ic, path, &newpath, 0);
397
err = fuse_fs_read(ic->next, newpath, buf, size, offset, fi);
403
403
static int iconv_write(const char *path, const char *buf, size_t size,
404
off_t offset, struct fuse_file_info *fi)
404
off_t offset, struct fuse_file_info *fi)
406
struct iconv *ic = iconv_get();
408
int err = iconv_convpath(ic, path, &newpath, 0);
410
err = fuse_fs_write(ic->next, newpath, buf, size, offset, fi);
406
struct iconv *ic = iconv_get();
408
int err = iconv_convpath(ic, path, &newpath, 0);
410
err = fuse_fs_write(ic->next, newpath, buf, size, offset, fi);
416
416
static int iconv_statfs(const char *path, struct statvfs *stbuf)
418
struct iconv *ic = iconv_get();
420
int err = iconv_convpath(ic, path, &newpath, 0);
422
err = fuse_fs_statfs(ic->next, newpath, stbuf);
418
struct iconv *ic = iconv_get();
420
int err = iconv_convpath(ic, path, &newpath, 0);
422
err = fuse_fs_statfs(ic->next, newpath, stbuf);
428
428
static int iconv_flush(const char *path, struct fuse_file_info *fi)
430
struct iconv *ic = iconv_get();
432
int err = iconv_convpath(ic, path, &newpath, 0);
434
err = fuse_fs_flush(ic->next, newpath, fi);
430
struct iconv *ic = iconv_get();
432
int err = iconv_convpath(ic, path, &newpath, 0);
434
err = fuse_fs_flush(ic->next, newpath, fi);
440
440
static int iconv_release(const char *path, struct fuse_file_info *fi)
442
struct iconv *ic = iconv_get();
444
int err = iconv_convpath(ic, path, &newpath, 0);
446
err = fuse_fs_release(ic->next, newpath, fi);
442
struct iconv *ic = iconv_get();
444
int err = iconv_convpath(ic, path, &newpath, 0);
446
err = fuse_fs_release(ic->next, newpath, fi);
452
452
static int iconv_fsync(const char *path, int isdatasync,
453
struct fuse_file_info *fi)
453
struct fuse_file_info *fi)
455
struct iconv *ic = iconv_get();
457
int err = iconv_convpath(ic, path, &newpath, 0);
459
err = fuse_fs_fsync(ic->next, newpath, isdatasync, fi);
455
struct iconv *ic = iconv_get();
457
int err = iconv_convpath(ic, path, &newpath, 0);
459
err = fuse_fs_fsync(ic->next, newpath, isdatasync, fi);
465
465
static int iconv_fsyncdir(const char *path, int isdatasync,
466
struct fuse_file_info *fi)
466
struct fuse_file_info *fi)
468
struct iconv *ic = iconv_get();
470
int err = iconv_convpath(ic, path, &newpath, 0);
472
err = fuse_fs_fsyncdir(ic->next, newpath, isdatasync, fi);
468
struct iconv *ic = iconv_get();
470
int err = iconv_convpath(ic, path, &newpath, 0);
472
err = fuse_fs_fsyncdir(ic->next, newpath, isdatasync, fi);
478
478
static int iconv_setxattr(const char *path, const char *name,
479
const char *value, size_t size, int flags)
479
const char *value, size_t size, int flags)
481
struct iconv *ic = iconv_get();
483
int err = iconv_convpath(ic, path, &newpath, 0);
485
err = fuse_fs_setxattr(ic->next, newpath, name, value, size, flags);
481
struct iconv *ic = iconv_get();
483
int err = iconv_convpath(ic, path, &newpath, 0);
485
err = fuse_fs_setxattr(ic->next, newpath, name, value, size,
491
492
static int iconv_getxattr(const char *path, const char *name, char *value,
494
struct iconv *ic = iconv_get();
496
int err = iconv_convpath(ic, path, &newpath, 0);
498
err = fuse_fs_getxattr(ic->next, newpath, name, value, size);
495
struct iconv *ic = iconv_get();
497
int err = iconv_convpath(ic, path, &newpath, 0);
499
err = fuse_fs_getxattr(ic->next, newpath, name, value, size);
504
505
static int iconv_listxattr(const char *path, char *list, size_t size)
506
struct iconv *ic = iconv_get();
508
int err = iconv_convpath(ic, path, &newpath, 0);
510
err = fuse_fs_listxattr(ic->next, newpath, list, size);
507
struct iconv *ic = iconv_get();
509
int err = iconv_convpath(ic, path, &newpath, 0);
511
err = fuse_fs_listxattr(ic->next, newpath, list, size);
516
517
static int iconv_removexattr(const char *path, const char *name)
518
struct iconv *ic = iconv_get();
520
int err = iconv_convpath(ic, path, &newpath, 0);
522
err = fuse_fs_removexattr(ic->next, newpath, name);
519
struct iconv *ic = iconv_get();
521
int err = iconv_convpath(ic, path, &newpath, 0);
523
err = fuse_fs_removexattr(ic->next, newpath, name);
528
529
static int iconv_lock(const char *path, struct fuse_file_info *fi, int cmd,
531
struct iconv *ic = iconv_get();
533
int err = iconv_convpath(ic, path, &newpath, 0);
535
err = fuse_fs_lock(ic->next, newpath, fi, cmd, lock);
532
struct iconv *ic = iconv_get();
534
int err = iconv_convpath(ic, path, &newpath, 0);
536
err = fuse_fs_lock(ic->next, newpath, fi, cmd, lock);
541
542
static int iconv_bmap(const char *path, size_t blocksize, uint64_t *idx)
543
struct iconv *ic = iconv_get();
545
int err = iconv_convpath(ic, path, &newpath, 0);
547
err = fuse_fs_bmap(ic->next, newpath, blocksize, idx);
544
struct iconv *ic = iconv_get();
546
int err = iconv_convpath(ic, path, &newpath, 0);
548
err = fuse_fs_bmap(ic->next, newpath, blocksize, idx);
553
554
static void *iconv_init(struct fuse_conn_info *conn)
555
struct iconv *ic = iconv_get();
556
fuse_fs_init(ic->next, conn);
556
struct iconv *ic = iconv_get();
557
fuse_fs_init(ic->next, conn);
560
561
static void iconv_destroy(void *data)
562
struct iconv *ic = data;
563
fuse_fs_destroy(ic->next);
564
iconv_close(ic->tofs);
565
iconv_close(ic->fromfs);
566
pthread_mutex_destroy(&ic->lock);
563
struct iconv *ic = data;
564
fuse_fs_destroy(ic->next);
565
iconv_close(ic->tofs);
566
iconv_close(ic->fromfs);
567
pthread_mutex_destroy(&ic->lock);
572
573
static struct fuse_operations iconv_oper = {
573
.destroy = iconv_destroy,
575
.getattr = iconv_getattr,
576
.fgetattr = iconv_fgetattr,
577
.access = iconv_access,
578
.readlink = iconv_readlink,
579
.opendir = iconv_opendir,
580
.readdir = iconv_readdir,
581
.releasedir = iconv_releasedir,
582
.mknod = iconv_mknod,
583
.mkdir = iconv_mkdir,
584
.symlink = iconv_symlink,
585
.unlink = iconv_unlink,
586
.rmdir = iconv_rmdir,
587
.rename = iconv_rename,
589
.chmod = iconv_chmod,
590
.chown = iconv_chown,
591
.truncate = iconv_truncate,
592
.ftruncate = iconv_ftruncate,
593
.utimens = iconv_utimens,
594
.create = iconv_create,
595
.open = iconv_open_file,
597
.write = iconv_write,
598
.statfs = iconv_statfs,
599
.flush = iconv_flush,
600
.release = iconv_release,
601
.fsync = iconv_fsync,
602
.fsyncdir = iconv_fsyncdir,
603
.setxattr = iconv_setxattr,
604
.getxattr = iconv_getxattr,
605
.listxattr = iconv_listxattr,
606
.removexattr= iconv_removexattr,
574
.destroy = iconv_destroy,
576
.getattr = iconv_getattr,
577
.fgetattr = iconv_fgetattr,
578
.access = iconv_access,
579
.readlink = iconv_readlink,
580
.opendir = iconv_opendir,
581
.readdir = iconv_readdir,
582
.releasedir = iconv_releasedir,
583
.mknod = iconv_mknod,
584
.mkdir = iconv_mkdir,
585
.symlink = iconv_symlink,
586
.unlink = iconv_unlink,
587
.rmdir = iconv_rmdir,
588
.rename = iconv_rename,
590
.chmod = iconv_chmod,
591
.chown = iconv_chown,
592
.truncate = iconv_truncate,
593
.ftruncate = iconv_ftruncate,
594
.utimens = iconv_utimens,
595
.create = iconv_create,
596
.open = iconv_open_file,
598
.write = iconv_write,
599
.statfs = iconv_statfs,
600
.flush = iconv_flush,
601
.release = iconv_release,
602
.fsync = iconv_fsync,
603
.fsyncdir = iconv_fsyncdir,
604
.setxattr = iconv_setxattr,
605
.getxattr = iconv_getxattr,
606
.listxattr = iconv_listxattr,
607
.removexattr = iconv_removexattr,
611
612
static struct fuse_opt iconv_opts[] = {
612
FUSE_OPT_KEY("-h", 0),
613
FUSE_OPT_KEY("--help", 0),
614
{ "from_code=%s", offsetof(struct iconv, from_code), 0 },
615
{ "to_code=%s", offsetof(struct iconv, to_code), 1 },
613
FUSE_OPT_KEY("-h", 0),
614
FUSE_OPT_KEY("--help", 0),
615
{ "from_code=%s", offsetof(struct iconv, from_code), 0 },
616
{ "to_code=%s", offsetof(struct iconv, to_code), 1 },
619
620
static void iconv_help(void)
621
char *old = strdup(setlocale(LC_CTYPE, ""));
622
char *charmap = strdup(nl_langinfo(CODESET));
623
setlocale(LC_CTYPE, old);
622
char *old = strdup(setlocale(LC_CTYPE, ""));
623
char *charmap = strdup(nl_langinfo(CODESET));
624
setlocale(LC_CTYPE, old);
626
627
" -o from_code=CHARSET original encoding of file names (default: UTF-8)\n"
627
" -o to_code=CHARSET new encoding of the file names (default: %s)\n",
628
" -o to_code=CHARSET new encoding of the file names (default: %s)\n",
632
633
static int iconv_opt_proc(void *data, const char *arg, int key,
633
struct fuse_args *outargs)
634
struct fuse_args *outargs)
635
(void) data; (void) arg; (void) outargs;
636
(void) data; (void) arg; (void) outargs;
645
646
static struct fuse_fs *iconv_new(struct fuse_args *args,
646
struct fuse_fs *next[])
647
struct fuse_fs *next[])
654
ic = calloc(1, sizeof(struct iconv));
656
fprintf(stderr, "fuse-iconv: memory allocation failed\n");
660
if (fuse_opt_parse(args, ic, iconv_opts, iconv_opt_proc) == -1)
663
if (!next[0] || next[1]) {
664
fprintf(stderr, "fuse-iconv: exactly one next filesystem required\n");
668
from = ic->from_code ? ic->from_code : "UTF-8";
669
to = ic->to_code ? ic->to_code : "";
670
/* FIXME: detect charset equivalence? */
672
old = strdup(setlocale(LC_CTYPE, ""));
673
ic->tofs = iconv_open(from, to);
674
if (ic->tofs == (iconv_t) -1) {
675
fprintf(stderr, "fuse-iconv: cannot convert from %s to %s\n",
679
ic->fromfs = iconv_open(to, from);
680
if (ic->tofs == (iconv_t) -1) {
681
fprintf(stderr, "fuse-iconv: cannot convert from %s to %s\n",
683
goto out_iconv_close_to;
686
setlocale(LC_CTYPE, old);
691
fs = fuse_fs_new(&iconv_oper, sizeof(iconv_oper), ic);
693
goto out_iconv_close_from;
697
out_iconv_close_from:
698
iconv_close(ic->fromfs);
700
iconv_close(ic->tofs);
655
ic = calloc(1, sizeof(struct iconv));
657
fprintf(stderr, "fuse-iconv: memory allocation failed\n");
661
if (fuse_opt_parse(args, ic, iconv_opts, iconv_opt_proc) == -1)
664
if (!next[0] || next[1]) {
665
fprintf(stderr, "fuse-iconv: exactly one next filesystem required\n");
669
from = ic->from_code ? ic->from_code : "UTF-8";
670
to = ic->to_code ? ic->to_code : "";
671
/* FIXME: detect charset equivalence? */
673
old = strdup(setlocale(LC_CTYPE, ""));
674
ic->tofs = iconv_open(from, to);
675
if (ic->tofs == (iconv_t) -1) {
676
fprintf(stderr, "fuse-iconv: cannot convert from %s to %s\n",
680
ic->fromfs = iconv_open(to, from);
681
if (ic->tofs == (iconv_t) -1) {
682
fprintf(stderr, "fuse-iconv: cannot convert from %s to %s\n",
684
goto out_iconv_close_to;
687
setlocale(LC_CTYPE, old);
692
fs = fuse_fs_new(&iconv_oper, sizeof(iconv_oper), ic);
694
goto out_iconv_close_from;
698
out_iconv_close_from:
699
iconv_close(ic->fromfs);
701
iconv_close(ic->tofs);
708
709
FUSE_REGISTER_MODULE(iconv, iconv_new);