Beispiel #1
0
static telf_status
defaultfs_readdir(void *ctx_hdl,
                  const char *path,
                  void *data,
                  fuse_fill_dir_t fill)
{
        telf_ctx *ctx = ctx_hdl;
        telf_obj *obj = NULL;
        telf_status ret;
        int rc;
        telf_dir_hdl *dir_hdl = NULL;
        telf_dirent dirent;
        int locked = 0;

        DEBUG("%s", path);

        elf_ctx_lock(ctx);

        rc = elf_namei(ctx, path, &obj);
        if (ELF_SUCCESS != rc) {
                ERR("can't find object with key '%s': %s",
                    path, elf_status_to_str(rc));
                ret = ELF_ENOENT;
                goto end;
        }

        elf_obj_lock(obj);
        locked = 1;

        dir_hdl = alloca(sizeof *dir_hdl);
        if (! dir_hdl) {
                ERR("alloca: %s", strerror(errno));
                ret = ELF_ENOMEM;
                goto end;
        }

        memset(&dirent, 0, sizeof dirent);

        dir_ctor(obj->ctx, obj, dir_hdl);

        while (0 == readdir_getdirent(dir_hdl, &dirent)) {
                if (fill(data, dirent.name, NULL, 0))
                        break;
        }

        ret = ELF_SUCCESS;

  end:
        if (locked)
                elf_obj_unlock(obj);

        elf_ctx_unlock(ctx);

        return ret;
}
Beispiel #2
0
static telf_status
defaultfs_read(void *ctx_hdl,
               const char *path,
               char *buf,
               size_t size,
               off_t offset,
               ssize_t *sizep)
{
        telf_ctx *ctx = ctx_hdl;
        telf_obj *obj = NULL;
        telf_default_content *content = NULL;
        telf_status ret;
        telf_status rc;
        int locked = 0;

        DEBUG("path=%s", path);

        elf_ctx_lock(ctx);

        rc = elf_namei(ctx, path, &obj);
        if (ELF_SUCCESS != rc) {
                ERR("namei(%s) failed: %d", path, rc);
                ret = ELF_ENOENT;
                goto end;
        }

        elf_obj_lock(obj);
        locked = 1;

        DEBUG("name:%s data=%p", obj->name, obj->data);

        content = obj->data;

        if (content->buf) {

                if (size > content->buf_len - offset)
                        size = content->buf_len - offset;

                memcpy(buf, content->buf + offset, size);
        }

        ret = ELF_SUCCESS;
  end:
        if (sizep)
                *sizep = size;

        if (locked)
                elf_obj_unlock(obj);

        elf_ctx_unlock(ctx);

        DEBUG("path=%s, ret=%s (%d)", path, elf_status_to_str(ret), ret);
        return ret;
}
Beispiel #3
0
static telf_status
defaultfs_getattr(void *ctx_hdl,
                  const char *path,
                  telf_stat *st)
{
        telf_ctx *ctx = ctx_hdl;
        telf_status ret;
        telf_status rc;
        telf_obj *obj = NULL;
        int locked = 0;

        DEBUG("path=%s", path);

        elf_ctx_lock(ctx);

        rc = elf_namei(ctx, path, &obj);
        if (ELF_SUCCESS != rc) {
                ERR("namei(%s) failed: %d", path, rc);
                ret = ELF_ENOENT;
                goto end;
        }

        elf_obj_lock(obj);
        locked = 1;

        DEBUG("name:%s data=%p", obj->name, obj->data);

        memcpy(st, &obj->st, sizeof *st);
        st->mode |= ELF_S_IRUSR|ELF_S_IWUSR | ELF_S_IRGRP | ELF_S_IROTH;
        st->nlink = 1;
        st->atime = st->mtime = st->ctime = time(NULL);

        if (ELF_S_ISREG(obj->st.mode)) {
                if (obj->fill_func) {
                        rc = obj->fill_func(obj, NULL, &st->size);
                        if (ELF_SUCCESS != rc) {
                                ret = rc;
                                goto end;
                        }
                }
        }

        ret = ELF_SUCCESS;
  end:

        if (locked)
                elf_obj_unlock(obj);

        elf_ctx_unlock(ctx);

        DEBUG("path=%s, ret=%s (%d)", path, elf_status_to_str(ret), ret);
        return ret;
}
Beispiel #4
0
static telf_status
defaultfs_release(void *ctx_hdl,
                  const char *path)
{
        telf_ctx *ctx = ctx_hdl;
        telf_obj *obj = NULL;
        telf_status ret;
        telf_status rc;
        int locked = 0;

        DEBUG("path=%s", path);

        elf_ctx_lock(ctx);

        rc = elf_namei(ctx, path, &obj);
        if (ELF_SUCCESS != rc) {
                ERR("namei(%s) failed: %d", path, rc);
                ret = ELF_ENOENT;
                goto end;
        }

        elf_obj_lock(obj);
        locked = 1;

        elf_obj_unref_nolock(obj);

        DEBUG("name:%s data=%p", obj->name, obj->data);

        if (0 == obj->refcount) {
                if (obj->free_func) {
                        obj->free_func(obj->data);
                        obj->data = NULL;
                }
        }

        ret = ELF_SUCCESS;
  end:

        if (locked)
                elf_obj_unlock(obj);

        elf_ctx_unlock(ctx);

        DEBUG("path=%s, ret=%s (%d)", path, elf_status_to_str(ret), ret);

        return ELF_SUCCESS;
}
Beispiel #5
0
telf_status
headerfs_build(telf_ctx *ctx)
{
        telf_obj *header_obj = NULL;
        telf_status ret;
        telf_status rc;

        rc = elf_namei(ctx, "/header", &header_obj);
        if (ELF_SUCCESS != rc) {
                ERR("can't find '/header' object: %s",
                    elf_status_to_str(rc));
                ret = rc;
                goto end;
        }

        /* now add the pseudo files */
        for (size_t i = 0; i < N_ELEMS(headerfs_fcb); i++) {
                telf_obj *entry = NULL;
                telf_fcb *fcb = headerfs_fcb + i;

                entry = elf_obj_new(ctx, fcb->str, header_obj,
                                    ELF_HEADER_ENTRY,
                                    ELF_S_IFREG);
                if (! entry) {
                        ERR("can't build entry '%s'", fcb->str);
                        continue;
                }

                headerfs_override_driver(entry->driver);
                entry->free_func = fcb->freecontent_func;
                entry->fill_func = fcb->fillcontent_func;

                list_add(header_obj->entries, entry);
        }

        ret = ELF_SUCCESS;
  end:
        return ret;
}
Beispiel #6
0
static telf_status
headerfs_release(void *ctx_hdl,
                 const char *path)
{
        telf_ctx *ctx = ctx_hdl;
        telf_obj *obj = NULL;
        telf_fcb *fcb = NULL;
        telf_status ret;
        telf_status rc;
        int locked = 0;

        elf_ctx_lock(ctx);

        rc = elf_namei(ctx, path, &obj);
        if (ELF_SUCCESS != rc) {
                ERR("namei(%s) failed: %d", path, rc);
                ret = -ENOENT;
                goto end;
        }

        elf_obj_lock(obj);
        locked = 1;

        elf_obj_unref_nolock(obj);

        DEBUG("name:%s data=%p", obj->name, obj->data);

        fcb = elf_get_fcb(headerfs_fcb, N_ELEMS(headerfs_fcb), obj->name);
        if (! fcb) {
                ERR("no fcb matching obj '%s'", obj->name);
                ret = ELF_ENOENT;
                goto end;
        }

        if (fcb->release_func) {
                rc = fcb->release_func(obj);
                if (ELF_SUCCESS != rc) {
                        ERR("release ('%s') failed: %s",
                            obj->name, elf_status_to_str(rc));
                        ret = rc;
                        goto end;
                }
        }

        if (0 == obj->refcount) {
                if (obj->free_func) {
                        obj->free_func(obj->data);
                        obj->data = NULL;
                }
        }

        ret = ELF_SUCCESS;
  end:

        if (locked)
                elf_obj_unlock(obj);

        elf_ctx_unlock(ctx);

        return ret;
}
Beispiel #7
0
static telf_status
defaultfs_open(void *ctx_hdl,
               const char *path,
               void **obj_hdlp)
{
        telf_ctx *ctx = ctx_hdl;
        telf_obj *obj = NULL;
        telf_status ret;
        telf_status rc;
        telf_default_content *content;
        int locked = 0;

        DEBUG("path=%s", path);

        elf_ctx_lock(ctx);

        rc = elf_namei(ctx, path, &obj);
        if (ELF_SUCCESS != rc) {
                ERR("namei(%s) failed: %d", path, rc);
                ret = ELF_ENOENT;
                goto end;
        }

        elf_obj_lock(obj);
        locked = 1;

        elf_obj_ref_nolock(obj);

        content = malloc(sizeof *content);
        if (! content) {
                ERR("malloc: %s", strerror(errno));
                ret = ELF_ENOMEM;
                goto end;
        }

        if (obj->fill_func) {
                rc = obj->fill_func(obj, &content->buf, &content->buf_len);
                if (ELF_SUCCESS != rc) {
                        ret = rc;
                        goto end;
                }
        }

        if (obj->data && obj->free_func)
                obj->free_func(obj->data);

        obj->data = content;

        ret = ELF_SUCCESS;
  end:
        if (obj_hdlp)
                *obj_hdlp = obj;

        if (locked)
                elf_obj_unlock(obj);

        elf_ctx_unlock(ctx);

        DEBUG("path=%s, ret=%s (%d)", path, elf_status_to_str(ret), ret);
        return ret;
}
Beispiel #8
0
telf_status
libfs_build(telf_ctx *ctx)
{
        telf_status ret;
        telf_status rc;
        telf_obj *libfs_obj = NULL;
        telf_obj *entry = NULL;
        int i;
        Elf64_Shdr *shdr = NULL;
        Elf64_Dyn *dyn = NULL;

        /* sanity check */
        rc = elf_namei(ctx, "/libs", &libfs_obj);
        if (ELF_SUCCESS != rc) {
                ERR("can't find '/libfs' object: %s", elf_status_to_str(rc));
                ret = rc;
                goto end;
        }

        shdr = elf_getsectionbytype(ctx, SHT_DYNAMIC);
        if (! shdr) {
                ERR("can't find any SHT_DYNAMIC section");
                ret = ELF_ENOENT;
                goto end;
        }

        /* get all DT_NEEDED strings. */
        for (i = 0; i < shdr->sh_size / sizeof(Elf64_Dyn); i++) {
                telf_obj *entry = NULL;
                char *libname = NULL;

                dyn = (Elf64_Dyn *) (ctx->addr + shdr->sh_offset) + i;

                if (DT_NEEDED != dyn->d_tag)
                        continue;

                libname = strdup(ctx->dstrtab + dyn->d_un.d_val);
                if (! libname) {
                        ERR("strdup(%s): %s", libname, strerror(errno));
                        ret = ELF_ENOMEM;
                        goto end;
                }

                entry = elf_obj_new(ctx, libname, libfs_obj,
                                    ELF_LIBS_ENTRY,
                                    ELF_S_IFLNK);
                if (! entry) {
                        ERR("can't build entry '%s'", libname);
                        continue;
                }

                libfs_override_driver(entry->driver);
                list_add(libfs_obj->entries, entry);
        }

        rc = elf_set_default_libpath(ctx);
        if (ELF_SUCCESS != rc) {
                ERR("Can't set libpath list");
                ret = rc;
                goto end;
        }

        ret = ELF_SUCCESS;
  end:
        return ret;
}