Net-LibNFS

 view release on metacpan or  search on metacpan

libnfs/examples/nfs4-cat.c  view on Meta::CPAN

        struct client *client = private_data;
        struct server *server;
        int revents = 0;

        if (events & EV_READ) {
                revents |= POLLIN;
        }
        if (events & EV_WRITE) {
                revents |= POLLOUT;
        }

        if (rpc_service(client->rpc, revents) < 0) {
                fprintf(stderr, "rpc_service failed\n");
                exit(10);
        }
        update_events(client->rpc, client->read_event, client->write_event);

        if (client->is_finished) {
                /*
                 * Stop listening for new connections.
                 */
                event_free(client->listen_event);
                client->listen_event = NULL;

                /*
                 * Stop listening for events on the client context.
                 */
                event_free(client->read_event);
                client->read_event = NULL;
                event_free(client->write_event);
                client->write_event = NULL;

                /*
                 * Stop listening to server connections.
                 */
                for (server = server_list; server; server = server->next) {
                        if (server->read_event) {
                                event_free(server->read_event);
                                server->read_event = NULL;
                        }
                        if (server->write_event) {
                                event_free(server->write_event);
                                server->write_event = NULL;
                        }
                }
        }
}

/*
 * Helper functions to send client RPC requests.
 */
static void send_setclientid_confirm(struct rpc_context *rpc,
                                     rpc_cb cb, void *private_data)
{
	struct client *client = private_data;
        COMPOUND4args args;
        nfs_argop4 op[1];

        memset(op, 0, sizeof(op));
        op[0].argop = OP_SETCLIENTID_CONFIRM;
        op[0].nfs_argop4_u.opsetclientid_confirm.clientid = client->clientid;
        memcpy(op[0].nfs_argop4_u.opsetclientid_confirm.setclientid_confirm, client->setclientid_confirm, NFS4_VERIFIER_SIZE);
               
        memset(&args, 0, sizeof(args));
        args.argarray.argarray_len = sizeof(op) / sizeof(nfs_argop4);
        args.argarray.argarray_val = op;

        if (rpc_nfs4_compound_async(rpc, cb, &args, private_data) != 0) {
                fprintf(stderr, "Failed to send nfs4 SETCLIENTID_CONFIRM request\n");
                exit(10);
        }
}

static void send_setclientid(struct rpc_context *rpc,
                             rpc_cb cb, void *private_data)
{
	struct client *client = private_data;
        COMPOUND4args args;
        nfs_argop4 op[1];
        struct sockaddr_storage ss;
        socklen_t len = sizeof(ss);
        struct sockaddr_in *in;
        struct sockaddr_in6 *in6;
        char *netid;
        char str[240], addr[256];
        unsigned short port;

        if (getsockname(client->callback_fd, (struct sockaddr *)&ss, &len) < 0) {
                fprintf(stderr, "getsockaddr failed\n");
                exit(10);
        }
        
        switch (ss.ss_family) {
        case AF_INET:
                netid = "tcp";
                in = (struct sockaddr_in *)&ss;
                inet_ntop(AF_INET, &in->sin_addr, str, sizeof(str));
                port = ntohs(in->sin_port);
                break;
        case AF_INET6:
                netid = "tcp6";
                in6 = (struct sockaddr_in6 *)&ss;
                inet_ntop(AF_INET6, &in6->sin6_addr, str, sizeof(str));
                port = ntohs(in6->sin6_port);
                break;
        }
        sprintf(addr, "%s.%d.%d", str, port >> 8, port & 0xff);
        
        memset(op, 0, sizeof(op));
        op[0].argop = OP_SETCLIENTID;
        memcpy(op[0].nfs_argop4_u.opsetclientid.client.verifier, client->verifier, sizeof(verifier4));
        op[0].nfs_argop4_u.opsetclientid.client.id.id_len = strlen(client->id);
        op[0].nfs_argop4_u.opsetclientid.client.id.id_val = client->id;
                
        op[0].nfs_argop4_u.opsetclientid.callback.cb_program = NFS4_CALLBACK;

        op[0].nfs_argop4_u.opsetclientid.callback.cb_location.r_netid = netid;
        op[0].nfs_argop4_u.opsetclientid.callback.cb_location.r_addr = addr;

        op[0].nfs_argop4_u.opsetclientid.callback_ident = 0x00000001;
        
        memset(&args, 0, sizeof(args));
        args.argarray.argarray_len = sizeof(op) / sizeof(nfs_argop4);
        args.argarray.argarray_val = op;

        if (rpc_nfs4_compound_async(rpc, cb, &args, private_data) != 0) {
                fprintf(stderr, "Failed to send nfs4 SETCLIENTID request\n");
                exit(10);
        }
}

static void send_getrootfh(struct rpc_context *rpc,
                           rpc_cb cb, void *private_data)
{
        COMPOUND4args args;
        nfs_argop4 op[2];

        memset(op, 0, sizeof(op));
        op[0].argop = OP_PUTROOTFH;
        op[1].argop = OP_GETFH;

        memset(&args, 0, sizeof(args));
        args.argarray.argarray_len = sizeof(op) / sizeof(nfs_argop4);
        args.argarray.argarray_val = op;
	if (rpc_nfs4_compound_async(rpc, cb, &args, private_data) != 0) {
		fprintf(stderr, "Failed to send nfs4 GETROOTFH request\n");
		exit(10);
	}
}

static void send_open(struct rpc_context *rpc, nfs_fh4 dir, char *path,
                        rpc_cb cb, void *private_data)
{
	struct client *client = private_data;
        COMPOUND4args args;
        nfs_argop4 *op;
        int i = 0, idx = 0;
        char *tmp;
        
        printf("OPEN called\n");
        /*
         * Count how many directories we have in the path.
         */
        tmp = path;
        while (tmp = strchr(tmp, '/')) {
                i++;
                tmp++;
        }

        op = malloc(sizeof(nfs_argop4) * (4 + i));
        memset(op, 0, sizeof(nfs_argop4) * (4 + i));

        op[idx].argop = OP_PUTFH;
        op[idx].nfs_argop4_u.opputfh.object = dir;
        idx++;

        while (i-- > 0) {
                tmp = strchr(path, '/');
                *tmp++ = '\0';

libnfs/examples/nfs4-cat.c  view on Meta::CPAN

{
	struct client *client = private_data;
        COMPOUND4res *res = data;

	if (status != RPC_STATUS_SUCCESS) {
		fprintf(stderr, "Failed to get root filehandle of server %s\n",
                        client->server);
		exit(10);
	}

        if (res->status != NFS4_OK) {
		fprintf(stderr, "Failed to get root filehandle of server %s\n",
                        client->server);
		exit(10);
        }

        send_open(rpc, res->resarray.resarray_val[1].nfs_resop4_u.opgetfh.GETFH4res_u.resok4.object, client->path, open_cb, client);
}


void setclientid_confirm_cb(struct rpc_context *rpc, int status, void *data,
                            void *private_data)
{
	struct client *client = private_data;
        COMPOUND4res *res = data;
        char *path;

	if (status != RPC_STATUS_SUCCESS) {
		fprintf(stderr, "Failed to set client id of server %s\n",
                        client->server);
		exit(10);
	}

        if (res->status != NFS4_OK) {
		fprintf(stderr, "Failed to set client id of server %s\n",
                        client->server);
		exit(10);
        }

        send_getrootfh(rpc, getrootfh_cb, client);
}

void setclientid_cb(struct rpc_context *rpc, int status, void *data,
                void *private_data)
{
	struct client *client = private_data;
        COMPOUND4res *res = data;

	if (status != RPC_STATUS_SUCCESS) {
		fprintf(stderr, "Failed to set client id on server %s\n",
                        client->server);
		exit(10);
	}

        if (res->status != NFS4_OK) {
		fprintf(stderr, "Failed to set client id on server %s\n",
                        client->server);
		exit(10);
        }

        client->clientid = res->resarray.resarray_val[0].nfs_resop4_u.opsetclientid.SETCLIENTID4res_u.resok4.clientid;
        memcpy(client->setclientid_confirm, res->resarray.resarray_val[0].nfs_resop4_u.opsetclientid.SETCLIENTID4res_u.resok4.setclientid_confirm, NFS4_VERIFIER_SIZE);

        send_setclientid_confirm(rpc, setclientid_confirm_cb, client);
}

/*
 * NULL procedure for the callback protocol.
 */
static int cb_null_proc(struct rpc_context *rpc, struct rpc_msg *call, void *opaque)
{
        rpc_send_reply(rpc, call, NULL, (zdrproc_t)zdr_void, 0);

        return 0;
}

/*
 * CB_COMPOUND procedure for the callback protocol.
 * This is where the server will inform us about lease breaks and similar.
 */
static int cb_compound_proc(struct rpc_context *rpc, struct rpc_msg *call, void *opaque)
{
        CB_COMPOUND4args *args = call->body.cbody.args;

        fprintf(stderr, "cb_compund_cb. Do something here.\n");
        return 0;
}

struct service_proc pt[] = {
        {CB_NULL, cb_null_proc,
            (zdrproc_t)zdr_void, 0},
        {CB_COMPOUND, cb_compound_proc,
         (zdrproc_t)zdr_CB_COMPOUND4args, sizeof(CB_COMPOUND4args)},
};

/*
 * This callback is invoked when others (the nfsv4 server) initiates a
 * NFSv4 CALLBACK sessions to us.
 * We accept() the connection and create a local rpc server context
 * for the callback protocol.
 */
static void client_accept(evutil_socket_t s, short events, void *private_data)
{
	struct client *client = private_data;
        struct server *server;
        struct sockaddr_storage ss;
        socklen_t len = sizeof(ss);
        int fd;
        
        server = malloc(sizeof(struct server));
        if (server == NULL) {
                fprintf(stderr, "failed to malloc server structure\n");
                exit(10);
        }
        memset(server, 0, sizeof(*server));
        server->next = server_list;
        server_list = server;

        if ((fd = accept(s, (struct sockaddr *)&ss, &len)) < 0) {
                free_server(server);
                fprintf(stderr, "accept failed\n");
                exit(10);



( run in 0.521 second using v1.01-cache-2.11-cpan-71847e10f99 )