static struct fuse_fs *subdir_new(struct fuse_args *args, struct fuse_fs *next[]) { struct fuse_fs *fs; struct subdir *d; d = calloc(1, sizeof(struct subdir)); if (d == NULL) { fprintf(stderr, "fuse-subdir: memory allocation failed\n"); return NULL; } if (fuse_opt_parse(args, d, subdir_opts, subdir_opt_proc) == -1) goto out_free; if (!next[0] || next[1]) { fprintf(stderr, "fuse-subdir: exactly one next filesystem required\n"); goto out_free; } if (!d->base) { fprintf(stderr, "fuse-subdir: missing 'subdir' option\n"); goto out_free; } if (d->base[0] && d->base[strlen(d->base)-1] != '/') { char *tmp = realloc(d->base, strlen(d->base) + 2); if (!tmp) { fprintf(stderr, "fuse-subdir: memory allocation failed\n"); goto out_free; } d->base = tmp; strcat(d->base, "/"); } d->baselen = strlen(d->base); d->next = next[0]; fs = fuse_fs_new(&subdir_oper, sizeof(subdir_oper), d); if (!fs) goto out_free; return fs; out_free: free(d->base); free(d); return NULL; }
static struct fuse_fs *iconv_new(struct fuse_args *args, struct fuse_fs *next[]) { struct fuse_fs *fs; struct iconv *ic; char *old = NULL; const char *from; const char *to; ic = calloc(1, sizeof(struct iconv)); if (ic == NULL) { fprintf(stderr, "fuse-iconv: memory allocation failed\n"); return NULL; } if (fuse_opt_parse(args, ic, iconv_opts, iconv_opt_proc) == -1) goto out_free; if (!next[0] || next[1]) { fprintf(stderr, "fuse-iconv: exactly one next filesystem required\n"); goto out_free; } from = ic->from_code ? ic->from_code : "UTF-8"; to = ic->to_code ? ic->to_code : ""; /* FIXME: detect charset equivalence? */ if (!to[0]) old = strdup(setlocale(LC_CTYPE, "")); ic->tofs = iconv_open(from, to); if (ic->tofs == (iconv_t) -1) { fprintf(stderr, "fuse-iconv: cannot convert from %s to %s\n", to, from); goto out_free; } ic->fromfs = iconv_open(to, from); if (ic->tofs == (iconv_t) -1) { fprintf(stderr, "fuse-iconv: cannot convert from %s to %s\n", from, to); goto out_iconv_close_to; } if (old) { setlocale(LC_CTYPE, old); free(old); } ic->next = next[0]; fs = fuse_fs_new(&iconv_oper, sizeof(iconv_oper), ic); if (!fs) goto out_iconv_close_from; return fs; out_iconv_close_from: iconv_close(ic->fromfs); out_iconv_close_to: iconv_close(ic->tofs); out_free: free(ic->from_code); free(ic->to_code); free(ic); return NULL; }
static struct fuse_fs * volicon_new(struct fuse_args *args, struct fuse_fs *next[]) { int ret; int voliconfd = -1; struct stat sb; struct fuse_fs *fs; struct volicon *d; d = calloc(1, sizeof(*d)); if (d == NULL) { fprintf(stderr, "volicon: memory allocation failed\n"); return NULL; } if (fuse_opt_parse(args, d, volicon_opts, volicon_opt_proc) == -1) { goto out_free; } if (!next[0] || next[1]) { fprintf(stderr, "volicon: exactly one next filesystem required\n"); goto out_free; } if (!d->volicon) { fprintf(stderr, "volicon: missing 'iconpath' option\n"); goto out_free; } voliconfd = open(d->volicon, O_RDONLY); if (voliconfd < 0) { fprintf(stderr, "volicon: failed to access volume icon file (%d)\n", errno); goto out_free; } ret = fstat(voliconfd, &sb); if (ret) { fprintf(stderr, "volicon: failed to stat volume icon file (%d)\n", errno); goto out_free; } if (sb.st_size > (VOLICON_ICON_MAXSIZE)) { fprintf(stderr, "volicon: size limit exceeded for volume icon file\n"); goto out_free; } d->volicon_data = malloc(sb.st_size); if (!d->volicon_data) { fprintf(stderr, "volicon: failed to allocate memory for volume icon data\n"); goto out_free; } ret = read(voliconfd, d->volicon_data, sb.st_size); if (ret != sb.st_size) { fprintf(stderr, "volicon: failed to read data from volume icon file\n"); goto out_free; } close(voliconfd); voliconfd = -1; d->volicon_size = sb.st_size; d->volicon_uid = getuid(); d->next = next[0]; fs = fuse_fs_new(&volicon_oper, sizeof(volicon_oper), d); if (!fs) { goto out_free; } return fs; out_free: if (d->volicon_data) { free(d->volicon_data); } if (voliconfd >= 0) { close(voliconfd); } if (d->volicon) { free(d->volicon); } free(d); return NULL; }