예제 #1
0
bool_t libnfs_zdr_array(ZDR *zdrs, char **arrp, uint32_t *size, uint32_t maxsize, uint32_t elsize, zdrproc_t proc)
{
	int  i;

	if (!libnfs_zdr_u_int(zdrs, size)) {
		return FALSE;
	}

	if (zdrs->pos + *size * elsize > zdrs->size) {
		return FALSE;
	}

	if (zdrs->x_op == ZDR_DECODE) {
		*arrp = zdr_malloc(zdrs, *size * elsize);
		if (*arrp == NULL) {
			return FALSE;
		}
		memset(*arrp, 0, *size * elsize);
	}

	for (i = 0; i < *size; i++) {
		if (!proc(zdrs, *arrp + i * elsize)) {
			return FALSE;
		}
	}
	return TRUE;
}
예제 #2
0
bool_t libnfs_zdr_string(ZDR *zdrs, char **strp, uint32_t maxsize)
{
	uint32_t size;

	if (zdrs->x_op == ZDR_ENCODE) {
		size = strlen(*strp);
	}

	if (!libnfs_zdr_u_int(zdrs, &size)) {
		return FALSE;
	}

	if (zdrs->pos + size > zdrs->size) {
		return FALSE;
	}

	switch (zdrs->x_op) {
	case ZDR_ENCODE:
		return libnfs_zdr_opaque(zdrs, *strp, size);
	case ZDR_DECODE:
		*strp = zdr_malloc(zdrs, size + 1);
		if (*strp == NULL) {
			return FALSE;
		}
		(*strp)[size] = 0;
		return libnfs_zdr_opaque(zdrs, *strp, size);
	}

	return FALSE;
}
예제 #3
0
bool_t libnfs_zdr_bytes(ZDR *zdrs, char **bufp, uint32_t *size, uint32_t maxsize)
{
	if (!libnfs_zdr_u_int(zdrs, size)) {
		return FALSE;
	}

	if (zdrs->pos + *size > zdrs->size) {
		return FALSE;
	}

	switch (zdrs->x_op) {
	case ZDR_ENCODE:
		memcpy(&zdrs->buf[zdrs->pos], *bufp, *size);
		zdrs->pos += *size;
		zdrs->pos = (zdrs->pos + 3) & ~3;
		return TRUE;
	case ZDR_DECODE:
		if (*bufp == NULL) {
			*bufp = zdr_malloc(zdrs, *size);
		}
		memcpy(*bufp, &zdrs->buf[zdrs->pos], *size);
		zdrs->pos += *size;
		zdrs->pos = (zdrs->pos + 3) & ~3;
		return TRUE;
	}

	return FALSE;
}
예제 #4
0
파일: pdu.c 프로젝트: sahlberg/libnfs
static int rpc_process_call(struct rpc_context *rpc, ZDR *zdr)
{
	struct rpc_msg call;
        struct rpc_endpoint *endpoint;
        int i, min_version = 0, max_version = 0, found_program = 0;

	assert(rpc->magic == RPC_CONTEXT_MAGIC);

	memset(&call, 0, sizeof(struct rpc_msg));
	if (zdr_callmsg(rpc, zdr, &call) == 0) {
		rpc_set_error(rpc, "Failed to decode CALL message. %s",
                              rpc_get_error(rpc));
                return rpc_send_error_reply(rpc, &call, GARBAGE_ARGS, 0, 0);
        }
        for (endpoint = rpc->endpoints; endpoint; endpoint = endpoint->next) {
                if (call.body.cbody.prog == endpoint->program) {
                        if (!found_program) {
                                min_version = max_version = endpoint->version;
                        }
                        if (endpoint->version < min_version) {
                                min_version = endpoint->version;
                        }
                        if (endpoint->version > max_version) {
                                max_version = endpoint->version;
                        }
                        found_program = 1;
                        if (call.body.cbody.vers == endpoint->version) {
                                break;
                        }
                }
        }
        if (endpoint == NULL) {
		rpc_set_error(rpc, "No endpoint found for CALL "
                              "program:0x%08x version:%d\n",
                              call.body.cbody.prog, call.body.cbody.vers);
                if (!found_program) {
                        return rpc_send_error_reply(rpc, &call, PROG_UNAVAIL,
                                                    0, 0);
                }
                return rpc_send_error_reply(rpc, &call, PROG_MISMATCH,
                                            min_version, max_version);
        }
        for (i = 0; i < endpoint->num_procs; i++) {
                if (endpoint->procs[i].proc == call.body.cbody.proc) {
                        if (endpoint->procs[i].decode_buf_size) {
                                call.body.cbody.args = zdr_malloc(zdr, endpoint->procs[i].decode_buf_size);
                        }
                        if (!endpoint->procs[i].decode_fn(zdr, call.body.cbody.args)) {
                                rpc_set_error(rpc, "Failed to unmarshall "
                                              "call payload");
                                return rpc_send_error_reply(rpc, &call, GARBAGE_ARGS, 0 ,0);
                        }
                        return endpoint->procs[i].func(rpc, &call);
                }
        }

        return rpc_send_error_reply(rpc, &call, PROC_UNAVAIL, 0 ,0);
}
예제 #5
0
bool_t libnfs_zdr_string(ZDR *zdrs, char **strp, uint32_t maxsize)
{
	uint32_t size;

	if (zdrs->x_op == ZDR_ENCODE) {
		size = strlen(*strp);
	}

	if (!libnfs_zdr_u_int(zdrs, &size)) {
		return FALSE;
	}

	if (zdrs->pos + size > zdrs->size) {
		return FALSE;
	}

	switch (zdrs->x_op) {
	case ZDR_ENCODE:
		return libnfs_zdr_opaque(zdrs, *strp, size);
	case ZDR_DECODE:
		/* If the we string is null terminated we can just return it
		 * in place.
		 */
		if (zdrs->size > zdrs->pos + size && zdrs->buf[zdrs->pos + size] == 0) {
			if (*strp == NULL) {
				*strp = &zdrs->buf[zdrs->pos];
                                (*strp)[size] = 0;
                                zdrs->pos += size;
                                zdrs->pos = (zdrs->pos + 3) & ~3;
                                return TRUE;
			}
			(*strp)[size] = 0;
			return libnfs_zdr_opaque(zdrs, *strp, size);
		}

		/* Crap. The string is not null terminated in the rx buffer.
		 * we have to allocate a buffer so we can add the null byte.
		 */
		*strp = zdr_malloc(zdrs, size + 1);
		if (*strp == NULL) {
			return FALSE;
		}
		(*strp)[size] = 0;
		return libnfs_zdr_opaque(zdrs, *strp, size);
	}

	return FALSE;
}
예제 #6
0
bool_t libnfs_zdr_pointer(ZDR *zdrs, char **objp, uint32_t size, zdrproc_t proc)
{
	bool_t more_data;

	more_data = (*objp != NULL);

	if (!libnfs_zdr_bool(zdrs, &more_data)) {
		return FALSE;
	}
	if (more_data == 0) {
		*objp = NULL;
		return TRUE;
	}

	if (zdrs->x_op == ZDR_DECODE) {
		*objp = zdr_malloc(zdrs, size);
		if (*objp == NULL) {
			return FALSE;
		}
		memset(*objp, 0, size);
	}
	return proc(zdrs, *objp);
}