Esempio n. 1
0
/* returns: -1 on error, number of bytes written on success */
static int send_binrpc_cmd(int s, struct binrpc_cmd* cmd, int cookie)
{
	struct iovec v[IOVEC_CNT];
	int r;
	unsigned char msg_body[MAX_BODY_SIZE];
	unsigned char msg_hdr[BINRPC_MAX_HDR_SIZE];
	struct binrpc_pkt body;
	int ret;
	int n;

	ret=binrpc_init_pkt(&body, msg_body, MAX_BODY_SIZE);
	if (ret<0) goto binrpc_err;
	ret=binrpc_addstr(&body, cmd->method, strlen(cmd->method));
	if (ret<0) goto binrpc_err;
	for (r=0; r<cmd->argc; r++){
		switch(cmd->argv[r].type){
			case BINRPC_T_STR:
				ret=binrpc_addstr(&body, cmd->argv[r].u.strval.s,
										cmd->argv[r].u.strval.len);
				break;
			case BINRPC_T_INT:
				ret=binrpc_addint(&body, cmd->argv[r].u.intval);
				break;
			case BINRPC_T_DOUBLE:
				ret=binrpc_adddouble(&body, cmd->argv[r].u.fval);
				break;
			default:
				fprintf(stderr, "ERROR: unsupported type %d\n",
								cmd->argv[r].type);
		}
		if (ret<0) goto binrpc_err;
	}
	ret=binrpc_build_hdr(BINRPC_REQ, binrpc_pkt_len(&body), cookie, msg_hdr,
							BINRPC_MAX_HDR_SIZE);
	if (ret<0) goto binrpc_err;
	v[0].iov_base=msg_hdr;
	v[0].iov_len=ret;
	v[1].iov_base=msg_body;
	v[1].iov_len=binrpc_pkt_len(&body);
write_again:
	if ((n=writev(s, v, 2))<0){
		if (errno==EINTR)
			goto write_again;
		goto error_send;
	}

	return n;
error_send:
	return -1;
binrpc_err:
	return -2;
}
Esempio n. 2
0
static struct rpc_struct_l* new_rpc_struct()
{
	struct rpc_struct_l* rs;
	
	/* alloc everything in one chunk */
	rs=ctl_malloc(sizeof(struct rpc_struct_l)+STRUCT_MAX_BODY);
	if (rs==0)
		goto error;
	memset(rs, 0, sizeof(struct rpc_struct_l));
	clist_init(&rs->substructs, next, prev);
	if (binrpc_init_pkt(&rs->pkt,
				(unsigned char*)rs+sizeof(struct rpc_struct_l),
				STRUCT_MAX_BODY)<0){
		ctl_free(rs);
		goto error;
	}
	return rs;
error:
	return 0;
}
Esempio n. 3
0
/* parse the body into a malloc allocated,  binrpc_val array */
int binrpc_send_command(
	struct binrpc_handle* handle, char* method, char** args, int arg_count,
	struct binrpc_response_handle *resp_handle)
{
	struct binrpc_pkt req_pkt;
	struct binrpc_val v;
	int i, size, res = FATAL_ERROR, ret = 0;
	unsigned char *req_buf = NULL;

	memset(&resp_handle->in_pkt, 0, sizeof(resp_handle->in_pkt));	
	if (!method || strlen(method) == 0) {
		snprintf(binrpc_last_errs, sizeof(binrpc_last_errs)-1,
			"send_command: method name not specified");
		goto fail;
	
	}
	size = BINRPC_MIN_RECORD_SIZE + 8 + strlen(method) + 1; /*max.possible optional value len */	
	for (i=0; i<arg_count; i++) {
		if (parse_arg(&v, args[i]) < 0)
			goto fail;
		switch (v.type) {
			case BINRPC_T_STR:
				size += v.u.strval.len + 1;
				break;
			case BINRPC_T_INT:
			case BINRPC_T_DOUBLE:
				size += sizeof(int);
				break;
			default:
				snprintf(binrpc_last_errs, sizeof(binrpc_last_errs)-1,
					"BUG: send_command: unexpected value type");
				goto fail;
		}
		size +=  BINRPC_MIN_RECORD_SIZE + 8;
	}
	req_buf = binrpc_malloc(size);
	if (!req_buf) {
		snprintf(binrpc_last_errs, sizeof(binrpc_last_errs)-1,
			"send_command: not enough memory to allocate buffer. Needed %d bytes", size);
		goto fail;
	}
	if ((ret = binrpc_init_pkt(&req_pkt, req_buf, size)) < 0) goto fail2;

	if ((ret = binrpc_addstr(&req_pkt, method, strlen(method))) < 0) goto fail2;

	for (i=0; i<arg_count; i++) {
		if (parse_arg(&v, args[i]) < 0)
			goto fail;
		switch (v.type) {
			case BINRPC_T_STR:
				if ((ret = binrpc_addstr(&req_pkt,  v.u.strval.s,  v.u.strval.len)) < 0) goto fail2;
				break;
			case BINRPC_T_INT:
				if ((ret = binrpc_addint(&req_pkt, v.u.intval)) < 0) goto fail2;
				break;
			case BINRPC_T_DOUBLE:
				if ((ret = binrpc_adddouble(&req_pkt, v.u.fval)) < 0) goto fail2;
				break;
			default:
				break;
		}
	}

	if (binrpc_send_command_ex(handle, &req_pkt, resp_handle) < 0) {
		goto fail;
	}
	res = 0;
fail:	
	if (req_buf) binrpc_free(req_buf);
	return res;	
fail2:
	snprintf(binrpc_last_errs, sizeof(binrpc_last_errs)-1,
		"send_command: error when preparing params: %s", binrpc_error(ret));
	goto fail;
}