Net-LibNFS

 view release on metacpan or  search on metacpan

libnfs/lib/nfs_v4.c  view on Meta::CPAN

nfs4_op_open_confirm(struct nfs_context *nfs, nfs_argop4 *op, struct nfsfh *fh)
{
        OPEN_CONFIRM4args *ocargs;

        op[0].argop = OP_OPEN_CONFIRM;
        ocargs = &op[0].nfs_argop4_u.opopen_confirm;
        ocargs->open_stateid.seqid = fh->stateid.seqid;
        memcpy(&ocargs->open_stateid.other, fh->stateid.other, 12);
        ocargs->seqid = fh->open_seqid;

        return 1;
}

static int
nfs4_op_truncate(struct nfs_context *nfs, nfs_argop4 *op, struct nfsfh *fh,
                 void *sabuf)
{
        SETATTR4args *saargs;
        static uint32_t mask[2] = {1 << (FATTR4_SIZE),
                                   1 << (FATTR4_TIME_MODIFY_SET - 32)};

        op[0].argop = OP_SETATTR;
        saargs = &op[0].nfs_argop4_u.opsetattr;
        saargs->stateid.seqid = fh->stateid.seqid;
        memcpy(saargs->stateid.other, fh->stateid.other, 12);

        saargs->obj_attributes.attrmask.bitmap4_len = 2;
        saargs->obj_attributes.attrmask.bitmap4_val = mask;

        saargs->obj_attributes.attr_vals.attrlist4_len = 12;
        saargs->obj_attributes.attr_vals.attrlist4_val = sabuf;

        return 1;
}

static int
nfs4_op_chmod(struct nfs_context *nfs, nfs_argop4 *op, struct nfsfh *fh,
              void *sabuf)
{
        SETATTR4args *saargs;
        static uint32_t mask[2] = {0,
                                   1 << (FATTR4_MODE - 32)};

        op[0].argop = OP_SETATTR;
        saargs = &op[0].nfs_argop4_u.opsetattr;
        if (fh) {
                saargs->stateid.seqid = fh->stateid.seqid;
                memcpy(saargs->stateid.other, fh->stateid.other, 12);
        }

        saargs->obj_attributes.attrmask.bitmap4_len = 2;
        saargs->obj_attributes.attrmask.bitmap4_val = mask;

        saargs->obj_attributes.attr_vals.attrlist4_len = 4;
        saargs->obj_attributes.attr_vals.attrlist4_val = sabuf;

        return 1;
}

static int
nfs4_op_chown(struct nfs_context *nfs, nfs_argop4 *op, struct nfsfh *fh,
              void *sabuf, int len)
{
        SETATTR4args *saargs;
        static uint32_t mask[2] = {0,
                                   1 << (FATTR4_OWNER - 32) |
                                   1 << (FATTR4_OWNER_GROUP - 32)};

        op[0].argop = OP_SETATTR;
        saargs = &op[0].nfs_argop4_u.opsetattr;
        if (fh) {
                saargs->stateid.seqid = fh->stateid.seqid;
                memcpy(saargs->stateid.other, fh->stateid.other, 12);
        }

        saargs->obj_attributes.attrmask.bitmap4_len = 2;
        saargs->obj_attributes.attrmask.bitmap4_val = mask;

        saargs->obj_attributes.attr_vals.attrlist4_len = len;
        saargs->obj_attributes.attr_vals.attrlist4_val = sabuf;

        return 1;
}

static int
nfs4_op_utimes(struct nfs_context *nfs, nfs_argop4 *op, struct nfsfh *fh,
               void *sabuf, int len)
{
        SETATTR4args *saargs;
        static uint32_t mask[2] = {0,
                                   1 << (FATTR4_TIME_ACCESS_SET - 32) |
                                   1 << (FATTR4_TIME_MODIFY_SET - 32)};

        op[0].argop = OP_SETATTR;
        saargs = &op[0].nfs_argop4_u.opsetattr;
        if (fh) {
                saargs->stateid.seqid = fh->stateid.seqid;
                memcpy(saargs->stateid.other, fh->stateid.other, 12);
        }

        saargs->obj_attributes.attrmask.bitmap4_len = 2;
        saargs->obj_attributes.attrmask.bitmap4_val = mask;

        saargs->obj_attributes.attr_vals.attrlist4_len = len;
        saargs->obj_attributes.attr_vals.attrlist4_val = sabuf;

        return 1;
}

static int
nfs4_op_readdir(struct nfs_context *nfs, nfs_argop4 *op, uint64_t cookie)
{
        READDIR4args *rdargs;

        op[0].argop = OP_READDIR;
        rdargs = &op[0].nfs_argop4_u.opreaddir;
        memset(rdargs, 0, sizeof(*rdargs));

        rdargs->cookie = cookie;
        rdargs->dircount = nfs->nfsi->readdir_dircount;
        rdargs->maxcount = nfs->nfsi->readdir_maxcount;

libnfs/lib/nfs_v4.c  view on Meta::CPAN

        if (nfs4_lookup_path_async(nfs, data, nfs4_chmod_cb) < 0) {
                return -1;
        }

        return 0;
}

int
nfs4_fchmod_async(struct nfs_context *nfs, struct nfsfh *fh, int mode,
                  nfs_cb cb, void *private_data)
{
        COMPOUND4args args;
        nfs_argop4 op[2];
        struct nfs4_cb_data *data;
        uint32_t m;
        int i;

        data = malloc(sizeof(*data));
        if (data == NULL) {
                nfs_set_error(nfs, "Out of memory.");
                return -1;
        }
        memset(data, 0, sizeof(*data));

        data->nfs          = nfs;
        data->cb           = cb;
        data->private_data = private_data;

        data->filler.blob3.val = malloc(sizeof(uint32_t));
        if (data->filler.blob3.val == NULL) {
                nfs_set_error(nfs, "Out of memory");
                free_nfs4_cb_data(data);
                return -1;
        }
        data->filler.blob3.free = free;

        m = htonl(mode);
        memcpy(data->filler.blob3.val, &m, sizeof(uint32_t));
        
        memset(op, 0, sizeof(op));

        i = nfs4_op_putfh(nfs, &op[0], fh);
        i += nfs4_op_chmod(nfs, &op[i], fh, data->filler.blob3.val);

        memset(&args, 0, sizeof(args));
        args.argarray.argarray_len = i;
        args.argarray.argarray_val = op;

        if (rpc_nfs4_compound_async(nfs->rpc, nfs4_fsync_cb, &args,
                                    data) != 0) {
                data->filler.blob0.val = NULL;
                free_nfs4_cb_data(data);
                return -1;
        }

        return 0;
}

#define CHOWN_BLOB_SIZE 64
static int
nfs4_create_chown_buffer(struct nfs_context *nfs, struct nfs4_cb_data *data,
                         int uid, int gid)
{
        char *str;
        int i, l;
        uint32_t len;

        data->filler.blob3.val = malloc(CHOWN_BLOB_SIZE);
        if (data->filler.blob3.val == NULL) {
                nfs_set_error(nfs, "Out of memory");
                return -1;
        }
        data->filler.blob3.free = free;
        memset(data->filler.blob3.val, 0, CHOWN_BLOB_SIZE);
        
        i = 0;
        str = data->filler.blob3.val;
        /* UID */
        l = snprintf(&str[i + 4], CHOWN_BLOB_SIZE - 4 - i,
                     "%d", uid);
        if (l < 0) {
                nfs_set_error(nfs, "snprintf failed");
                return -1;
        }
        len = htonl(l);
        /* UID length prefix */
        memcpy(&str[i], &len, sizeof(uint32_t));
        i += 4 + l;
        i = (i + 3) & ~0x03;

        /* GID */
        l = snprintf(&str[i + 4], CHOWN_BLOB_SIZE - 4 - i,
                     "%d", gid);
        if (l < 0) {
                nfs_set_error(nfs, "snprintf failed");
                return -1;
        }
        len = htonl(l);
        /* GID length prefix */
        memcpy(&str[i], &len, sizeof(uint32_t));
        i += 4 + l;
        i = (i + 3) & ~0x03;

        data->filler.blob3.len = i;

        return 0;
}

static void
nfs4_chown_cb(struct rpc_context *rpc, int status, void *command_data,
                   void *private_data)
{
        struct nfs4_cb_data *data = private_data;
        struct nfs_context *nfs = data->nfs;
        COMPOUND4res *res = command_data;

        if (check_nfs4_error(nfs, status, data, res, "OPEN")) {
                return;
        }

        data->cb(0, nfs, NULL, data->private_data);
        free_nfs4_cb_data(data);
}

static int
nfs4_populate_chown(struct nfs4_cb_data *data, nfs_argop4 *op)
{
        return nfs4_op_chown(data->nfs, op, NULL, data->filler.blob3.val,
                           data->filler.blob3.len);
}

int
nfs4_chown_async_internal(struct nfs_context *nfs, const char *path,
                          int no_follow, int uid, int gid,
                          nfs_cb cb, void *private_data)
{
        struct nfs4_cb_data *data;

        data = init_cb_data_split_path(nfs, path);
        if (data == NULL) {
                return -1;
        }

        data->cb           = cb;
        data->private_data = private_data;
        data->filler.func = nfs4_populate_chown;
        data->filler.max_op = 1;

        if (no_follow) {
                data->flags |= LOOKUP_FLAG_NO_FOLLOW;
        }

        if (nfs4_create_chown_buffer(nfs, data, uid, gid) < 0) {
                free_nfs4_cb_data(data);
                return -1;
        }

        if (nfs4_lookup_path_async(nfs, data, nfs4_chown_cb) < 0) {
                return -1;
        }

        return 0;
}

int
nfs4_fchown_async(struct nfs_context *nfs, struct nfsfh *fh, int uid, int gid,
                  nfs_cb cb, void *private_data)
{
        COMPOUND4args args;
        nfs_argop4 op[2];
        struct nfs4_cb_data *data;
        int i;

        data = malloc(sizeof(*data));
        if (data == NULL) {
                nfs_set_error(nfs, "Out of memory.");
                return -1;
        }
        memset(data, 0, sizeof(*data));

        data->nfs          = nfs;
        data->cb           = cb;
        data->private_data = private_data;

        if (nfs4_create_chown_buffer(nfs, data, uid, gid) < 0) {
                free_nfs4_cb_data(data);
                return -1;
        }
        
        memset(op, 0, sizeof(op));

        i = nfs4_op_putfh(nfs, &op[0], fh);
        i += nfs4_op_chown(nfs, &op[i], fh, data->filler.blob3.val,
                           data->filler.blob3.len);

        memset(&args, 0, sizeof(args));
        args.argarray.argarray_len = i;
        args.argarray.argarray_val = op;

        if (rpc_nfs4_compound_async(nfs->rpc, nfs4_fsync_cb, &args,
                                    data) != 0) {
                data->filler.blob0.val = NULL;
                free_nfs4_cb_data(data);
                return -1;
        }

        return 0;
}

static void
nfs4_access_cb(struct rpc_context *rpc, int status, void *command_data,
               void *private_data)
{
        struct nfs4_cb_data *data = private_data;
        struct nfs_context *nfs = data->nfs;
        COMPOUND4res *res = command_data;
        ACCESS4resok *aresok;
        int i;

        assert(rpc->magic == RPC_CONTEXT_MAGIC);

        if (check_nfs4_error(nfs, status, data, res, "ACCESS")) {
                return;
        }

        if ((i = nfs4_find_op(nfs, data, res, OP_ACCESS, "ACCESS")) < 0) {
                return;
        }

        aresok = &res->resarray.resarray_val[i].nfs_resop4_u.opaccess.ACCESS4res_u.resok4;

        /* access2 */
        if (data->filler.flags) {
                int mode = 0;

                if (aresok->access & ACCESS4_READ) {
                        mode |= R_OK;
                }
                if (aresok->access & ACCESS4_MODIFY) {
                        mode |= W_OK;
                }
                if (aresok->access & ACCESS4_EXECUTE) {
                        mode |= X_OK;
                }
                data->cb(mode, nfs, NULL, data->private_data);
                free_nfs4_cb_data(data);
                return;
        }

        if (aresok->supported != aresok->access) {
                data->cb(-EACCES, nfs, NULL, data->private_data);
                free_nfs4_cb_data(data);
                return;



( run in 0.399 second using v1.01-cache-2.11-cpan-5511b514fd6 )