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 )