This commit is contained in:
		
							
								
								
									
										235
									
								
								bin/main-c.c
									
									
									
									
									
								
							
							
						
						
									
										235
									
								
								bin/main-c.c
									
									
									
									
									
								
							@ -452,232 +452,26 @@ static int handle_logopt (hcl_client_t* client, const hcl_bch_t* str)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
/* ========================================================================= */
 | 
					/* ========================================================================= */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct proto_xtn_t
 | 
					static int client_on_packet (hcl_xproto_t* proto, hcl_xpkt_type_t type, const void* data, hcl_oow_t len)
 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	int x;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
typedef struct proto_xtn_t proto_xtn_t;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static int handle_packet (hcl_xproto_t* proto, hcl_xpkt_type_t type, const void* data, hcl_oow_t len)
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if (type == HCL_XPKT_STDOUT)
 | 
						if (type == HCL_XPKT_STDOUT)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		/*if (len > 0) fwrite (data, 1, len, stdout); */
 | 
							/*if (len > 0) fwrite (data, 1, len, stdout); */
 | 
				
			||||||
		if (len > 0) fprintf (stdout, "%.*s", (int)len, data);
 | 
							if (len > 0) fprintf (stdout, "%.*s", (int)len, data);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						else if (type == HCL_XPKT_STDERR)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							if (len > 0) fprintf (stderr, "%.*s", (int)len, data);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						else if (type == HCL_XPKT_ERROR)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							/* error notification */
 | 
				
			||||||
 | 
							if (len > 0) fprintf (stderr, "ERROR: %.*s\n", (int)len, data);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	return 1;
 | 
						return 1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int handle_request (hcl_client_t* client, const char* ipaddr, const char* script, int reuse_addr, int shut_wr_after_req)
 | 
					/* ========================================================================= */
 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	hcl_sckaddr_t sckaddr;
 | 
					 | 
				
			||||||
	hcl_scklen_t scklen;
 | 
					 | 
				
			||||||
	int sckfam;
 | 
					 | 
				
			||||||
	int sck = -1;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	hcl_oow_t used, avail;
 | 
					 | 
				
			||||||
	int x;
 | 
					 | 
				
			||||||
	hcl_bch_t buf[256];
 | 
					 | 
				
			||||||
	ssize_t n;
 | 
					 | 
				
			||||||
	const char* scptr;
 | 
					 | 
				
			||||||
	const char* sccur;
 | 
					 | 
				
			||||||
	hcl_xproto_t* proto = HCL_NULL;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	client_xtn_t* client_xtn;
 | 
					 | 
				
			||||||
	proto_xtn_t* proto_xtn;
 | 
					 | 
				
			||||||
	hcl_xproto_cb_t proto_cb;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	client_xtn = hcl_client_getxtn(client);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	sckfam = hcl_bchars_to_sckaddr(ipaddr, strlen(ipaddr), &sckaddr, &scklen);
 | 
					 | 
				
			||||||
	if (sckfam <= -1)
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		fprintf (stderr, "cannot convert ip address - %s\n", ipaddr);
 | 
					 | 
				
			||||||
		goto oops;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	sck = socket(sckfam, SOCK_STREAM, 0);
 | 
					 | 
				
			||||||
	if (sck <= -1)
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		fprintf (stderr, "cannot create a socket for %s - %s\n", ipaddr, strerror(errno));
 | 
					 | 
				
			||||||
		goto oops;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (reuse_addr)
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		if (sckfam == AF_INET)
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			struct sockaddr_in anyaddr;
 | 
					 | 
				
			||||||
			int opt = 1;
 | 
					 | 
				
			||||||
			setsockopt(sck, SOL_SOCKET, SO_REUSEADDR, (char *)&opt, sizeof(opt));
 | 
					 | 
				
			||||||
			memset (&anyaddr, 0, HCL_SIZEOF(anyaddr));
 | 
					 | 
				
			||||||
			anyaddr.sin_family = sckfam;
 | 
					 | 
				
			||||||
			bind(sck, (struct sockaddr *)&anyaddr, scklen);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		else if (sckfam == AF_INET6)
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			struct sockaddr_in6 anyaddr;
 | 
					 | 
				
			||||||
			int opt = 1;
 | 
					 | 
				
			||||||
			setsockopt(sck, SOL_SOCKET, SO_REUSEADDR, (char *)&opt, sizeof(opt));
 | 
					 | 
				
			||||||
			memset (&anyaddr, 0, HCL_SIZEOF(anyaddr));
 | 
					 | 
				
			||||||
			anyaddr.sin6_family = sckfam;
 | 
					 | 
				
			||||||
			bind(sck, (struct sockaddr *)&anyaddr, scklen);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (connect(sck, (struct sockaddr*)&sckaddr, scklen) <= -1)
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		fprintf (stderr, "cannot connect to %s - %s\n", ipaddr, strerror(errno));
 | 
					 | 
				
			||||||
		goto oops;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	memset (&proto, 0, HCL_SIZEOF(proto_cb));
 | 
					 | 
				
			||||||
	proto_cb.on_packet = handle_packet;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	proto = hcl_xproto_open(hcl_client_getmmgr(client), &proto_cb, HCL_SIZEOF(*proto_xtn));
 | 
					 | 
				
			||||||
	if (HCL_UNLIKELY(!proto))
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		fprintf (stderr, "cannot open protocol to %s\n", ipaddr);
 | 
					 | 
				
			||||||
		goto oops;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	proto_xtn = hcl_xproto_getxtn(proto);
 | 
					 | 
				
			||||||
	//proto_xtn->client = client;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	scptr = sccur = script;
 | 
					 | 
				
			||||||
	while (1)
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		struct pollfd pfd;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		pfd.fd = sck;
 | 
					 | 
				
			||||||
		pfd.events = POLLIN;
 | 
					 | 
				
			||||||
		if (*sccur != '\0') pfd.events |= POLLOUT;
 | 
					 | 
				
			||||||
		pfd.revents = 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		n = poll(&pfd, 1, 1000);
 | 
					 | 
				
			||||||
		if (n <= -1)
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			fprintf (stderr, "poll error on %d - %s\n", sck, strerror(n));
 | 
					 | 
				
			||||||
			goto oops;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if (n == 0)
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			/* TODO: proper timeout handling */
 | 
					 | 
				
			||||||
			continue;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if (pfd.revents & POLLERR)
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			fprintf (stderr, "error condition detected on %d\n", sck);
 | 
					 | 
				
			||||||
			goto oops;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if (pfd.revents & POLLOUT)
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			hcl_xpkt_hdr_t hdr;
 | 
					 | 
				
			||||||
			struct iovec iov[2];
 | 
					 | 
				
			||||||
			hcl_uint16_t seglen;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			while (*sccur != '\0' && sccur - scptr < HCL_XPKT_MAX_PLD_LEN) sccur++;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			seglen = sccur - scptr;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			hdr.id = 1; /* TODO: */
 | 
					 | 
				
			||||||
			hdr.type = HCL_XPKT_CODE | (((seglen >> 8) & 0x0F) << 4);
 | 
					 | 
				
			||||||
			hdr.len = seglen & 0xFF;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			iov[0].iov_base = &hdr;
 | 
					 | 
				
			||||||
			iov[0].iov_len = HCL_SIZEOF(hdr);
 | 
					 | 
				
			||||||
			iov[1].iov_base = scptr;
 | 
					 | 
				
			||||||
			iov[1].iov_len = seglen;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			hcl_sys_send_iov (sck, iov, 2); /* TODO: error check */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			scptr = sccur;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			if (*sccur == '\0')
 | 
					 | 
				
			||||||
			{
 | 
					 | 
				
			||||||
				hdr.id = 1; /* TODO: */
 | 
					 | 
				
			||||||
				hdr.type = HCL_XPKT_EXECUTE;
 | 
					 | 
				
			||||||
				hdr.len = 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
				iov[0].iov_base = &hdr;
 | 
					 | 
				
			||||||
				iov[0].iov_len = HCL_SIZEOF(hdr);
 | 
					 | 
				
			||||||
				hcl_sys_send_iov (sck, iov, 1);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
				if (shut_wr_after_req)
 | 
					 | 
				
			||||||
				{
 | 
					 | 
				
			||||||
					shutdown (sck, SHUT_WR);
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
				else
 | 
					 | 
				
			||||||
				{
 | 
					 | 
				
			||||||
					hdr.type = HCL_XPKT_DISCONNECT;
 | 
					 | 
				
			||||||
					hdr.id = 1; /* TODO: */
 | 
					 | 
				
			||||||
					hdr.len = 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
					iov[0].iov_base = &hdr;
 | 
					 | 
				
			||||||
					iov[0].iov_len = HCL_SIZEOF(hdr);
 | 
					 | 
				
			||||||
					hcl_sys_send_iov (sck, iov, 1);
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if (pfd.revents & POLLIN)
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			hcl_oow_t bcap;
 | 
					 | 
				
			||||||
			hcl_uint8_t* bptr;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			bptr = hcl_xproto_getbuf(proto, &bcap);;
 | 
					 | 
				
			||||||
			x = recv(sck, bptr, bcap, 0);
 | 
					 | 
				
			||||||
			if (x <= -1)
 | 
					 | 
				
			||||||
			{
 | 
					 | 
				
			||||||
				if (errno == EINTR) goto carry_on; /* didn't read read */
 | 
					 | 
				
			||||||
				/*hcl_seterrwithsyserr (hcl, 0, errno); */
 | 
					 | 
				
			||||||
				/* TODO: error info set... */
 | 
					 | 
				
			||||||
				return -1;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			if (x == 0) hcl_xproto_seteof(proto, 1);
 | 
					 | 
				
			||||||
			hcl_xproto_advbuf (proto, x);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	carry_on:
 | 
					 | 
				
			||||||
		while (hcl_xproto_ready(proto))
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			if ((n = hcl_xproto_process(proto)) <= -1)
 | 
					 | 
				
			||||||
			{
 | 
					 | 
				
			||||||
				/* TODO: proper error message */
 | 
					 | 
				
			||||||
				return -1;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			if (n == 0)
 | 
					 | 
				
			||||||
			{
 | 
					 | 
				
			||||||
				/* TODO: chceck if there is remaining data in the buffer...?? */
 | 
					 | 
				
			||||||
				printf ("NO MORE DATA. EXITING...\n");
 | 
					 | 
				
			||||||
				goto done;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if (hcl_xproto_geteof(proto)) break;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
done:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* TODO: we can check if the buffer has all been consumed. if not, there is trailing garbage.. */
 | 
					 | 
				
			||||||
	/*{
 | 
					 | 
				
			||||||
		struct linger linger;
 | 
					 | 
				
			||||||
		linger.l_onoff = 1;
 | 
					 | 
				
			||||||
		linger.l_linger = 0;
 | 
					 | 
				
			||||||
		setsockopt (sck, SOL_SOCKET, SO_LINGER, (char *) &linger, sizeof(linger));
 | 
					 | 
				
			||||||
	}*/
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	hcl_xproto_close (proto);
 | 
					 | 
				
			||||||
	close (sck);
 | 
					 | 
				
			||||||
	return 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
oops:
 | 
					 | 
				
			||||||
	if (proto) hcl_xproto_close (proto);
 | 
					 | 
				
			||||||
	if (sck >= 0) close (sck);
 | 
					 | 
				
			||||||
	return -1;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
int main (int argc, char* argv[])
 | 
					int main (int argc, char* argv[])
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@ -753,6 +547,7 @@ int main (int argc, char* argv[])
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	memset (&client_prim, 0, HCL_SIZEOF(client_prim));
 | 
						memset (&client_prim, 0, HCL_SIZEOF(client_prim));
 | 
				
			||||||
	client_prim.log_write = log_write;
 | 
						client_prim.log_write = log_write;
 | 
				
			||||||
 | 
						client_prim.on_packet = client_on_packet;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	client = hcl_client_open(&sys_mmgr, HCL_SIZEOF(client_xtn_t), &client_prim, HCL_NULL);
 | 
						client = hcl_client_open(&sys_mmgr, HCL_SIZEOF(client_xtn_t), &client_prim, HCL_NULL);
 | 
				
			||||||
	if (!client)
 | 
						if (!client)
 | 
				
			||||||
@ -779,16 +574,12 @@ int main (int argc, char* argv[])
 | 
				
			|||||||
	set_signal (SIGINT, handle_sigint);
 | 
						set_signal (SIGINT, handle_sigint);
 | 
				
			||||||
	set_signal_to_ignore (SIGPIPE);
 | 
						set_signal_to_ignore (SIGPIPE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if 0
 | 
						n = hcl_client_start(client, argv[opt.ind], argv[opt.ind + 1], reuse_addr, shut_wr_after_req);
 | 
				
			||||||
	n = hcl_client_connect(client, argv[opt.ind], reuse_addr);
 | 
					 | 
				
			||||||
	if (n <= -1)
 | 
						if (n <= -1)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		fprintf (stderr, "ERROR: %s\n", hcl_client_geterrbmsg(client));
 | 
							fprintf (stderr, "ERROR: %s\n", hcl_client_geterrbmsg(client));
 | 
				
			||||||
		goto oops;
 | 
							goto oops;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
#else
 | 
					 | 
				
			||||||
	n = handle_request(client, argv[opt.ind], argv[opt.ind + 1], reuse_addr, shut_wr_after_req);
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	set_signal_to_default (SIGINT);
 | 
						set_signal_to_default (SIGINT);
 | 
				
			||||||
	set_signal_to_default (SIGPIPE);
 | 
						set_signal_to_default (SIGPIPE);
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										21
									
								
								lib/hcl-x.h
									
									
									
									
									
								
							
							
						
						
									
										21
									
								
								lib/hcl-x.h
									
									
									
									
									
								
							@ -63,8 +63,8 @@ typedef struct hcl_xpkt_hdr_t hcl_xpkt_hdr_t;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#define HCL_XPKT_HDR_LEN (HCL_SIZEOF(hcl_xpkt_hdr_t))
 | 
					#define HCL_XPKT_HDR_LEN (HCL_SIZEOF(hcl_xpkt_hdr_t))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* the actual length field is 12 bits long. so the maximum payload length allowed per packet is 2^12 */
 | 
					/* the actual length field is 12 bits long. so the maximum payload length allowed per packet is 2^12 - 1 */
 | 
				
			||||||
#define HCL_XPKT_MAX_PLD_LEN (4096)
 | 
					#define HCL_XPKT_MAX_PLD_LEN (4095)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* ---------------------------------------------------------------------- */
 | 
					/* ---------------------------------------------------------------------- */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -162,12 +162,21 @@ typedef void (*hcl_client_log_write_t) (
 | 
				
			|||||||
	hcl_oow_t         len
 | 
						hcl_oow_t         len
 | 
				
			||||||
);
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef int (*hcl_client_on_packet_t) (
 | 
				
			||||||
 | 
						hcl_xproto_t*   proto,
 | 
				
			||||||
 | 
						hcl_xpkt_type_t type,
 | 
				
			||||||
 | 
						const void*     data,
 | 
				
			||||||
 | 
						hcl_oow_t       len
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct hcl_client_prim_t
 | 
					struct hcl_client_prim_t
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	hcl_client_log_write_t     log_write;
 | 
						hcl_client_log_write_t     log_write;
 | 
				
			||||||
 | 
						hcl_client_on_packet_t     on_packet;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
typedef struct hcl_client_prim_t hcl_client_prim_t;
 | 
					typedef struct hcl_client_prim_t hcl_client_prim_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* ---------------------------------------------------------------------- */
 | 
					/* ---------------------------------------------------------------------- */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if defined(__cplusplus)
 | 
					#if defined(__cplusplus)
 | 
				
			||||||
@ -306,10 +315,12 @@ HCL_EXPORT void hcl_client_close (
 | 
				
			|||||||
	hcl_client_t* client
 | 
						hcl_client_t* client
 | 
				
			||||||
);
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
HCL_EXPORT int hcl_client_connnect (
 | 
					HCL_EXPORT int hcl_client_start (
 | 
				
			||||||
	hcl_client_t* client,
 | 
						hcl_client_t* client,
 | 
				
			||||||
	const char*   ptr,
 | 
						const char*   ipaddr,
 | 
				
			||||||
	int           reuse_addr
 | 
						const char*   script,
 | 
				
			||||||
 | 
						int           reuse_addr,
 | 
				
			||||||
 | 
						int           shut_wr_after_req
 | 
				
			||||||
);
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
HCL_EXPORT int hcl_client_setoption (
 | 
					HCL_EXPORT int hcl_client_setoption (
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										330
									
								
								lib/x-client.c
									
									
									
									
									
								
							
							
						
						
									
										330
									
								
								lib/x-client.c
									
									
									
									
									
								
							@ -388,169 +388,7 @@ struct proto_xtn_t
 | 
				
			|||||||
};
 | 
					};
 | 
				
			||||||
typedef struct proto_xtn_t proto_xtn_t;
 | 
					typedef struct proto_xtn_t proto_xtn_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int handle_packet (hcl_xproto_t* proto, hcl_xpkt_type_t type, const void* data, hcl_oow_t len)
 | 
					static int client_connect (hcl_client_t* client, const char* ipaddr, int reuse_addr)
 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	if (type == HCL_XPKT_STDOUT)
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		/*if (len > 0) fwrite (data, 1, len, stdout); */
 | 
					 | 
				
			||||||
		if (len > 0) fprintf (stdout, "%.*s", (int)len, data);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return 1;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#if 0
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int hcl_client_process (hcl_client_t* client, const char* ipaddr, const char* script, int reuse_addr, int shut_wr_after_req)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	hcl_oow_t used, avail;
 | 
					 | 
				
			||||||
	int x;
 | 
					 | 
				
			||||||
	hcl_bch_t buf[256];
 | 
					 | 
				
			||||||
	ssize_t n;
 | 
					 | 
				
			||||||
	const char* scptr;
 | 
					 | 
				
			||||||
	const char* sccur;
 | 
					 | 
				
			||||||
	hcl_xproto_t* proto = HCL_NULL;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	proto_xtn_t* proto_xtn;
 | 
					 | 
				
			||||||
	hcl_xproto_cb_t proto_cb;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	scptr = sccur = script;
 | 
					 | 
				
			||||||
	while (1)
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		struct pollfd pfd;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		pfd.fd = sck;
 | 
					 | 
				
			||||||
		pfd.events = POLLIN;
 | 
					 | 
				
			||||||
		if (*sccur != '\0') pfd.events |= POLLOUT;
 | 
					 | 
				
			||||||
		pfd.revents = 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		n = poll(&pfd, 1, 1000);
 | 
					 | 
				
			||||||
		if (n <= -1)
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			fprintf (stderr, "poll error on %d - %s\n", sck, strerror(n));
 | 
					 | 
				
			||||||
			goto oops;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if (n == 0)
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			/* TODO: proper timeout handling */
 | 
					 | 
				
			||||||
			continue;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if (pfd.revents & POLLERR)
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			fprintf (stderr, "error condition detected on %d\n", sck);
 | 
					 | 
				
			||||||
			goto oops;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if (pfd.revents & POLLOUT)
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			hcl_xpkt_hdr_t hdr;
 | 
					 | 
				
			||||||
			struct iovec iov[2];
 | 
					 | 
				
			||||||
			hcl_uint16_t seglen;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			while (*sccur != '\0' && sccur - scptr < HCL_XPKT_MAX_PLD_LEN) sccur++;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			seglen = sccur - scptr;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			hdr.id = 1; /* TODO: */
 | 
					 | 
				
			||||||
			hdr.type = HCL_XPKT_CODE | (((seglen >> 8) & 0x0F) << 4);
 | 
					 | 
				
			||||||
			hdr.len = seglen & 0xFF;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			iov[0].iov_base = &hdr;
 | 
					 | 
				
			||||||
			iov[0].iov_len = HCL_SIZEOF(hdr);
 | 
					 | 
				
			||||||
			iov[1].iov_base = scptr;
 | 
					 | 
				
			||||||
			iov[1].iov_len = seglen;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			hcl_sys_send_iov (sck, iov, 2); /* TODO: error check */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			scptr = sccur;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			if (*sccur == '\0')
 | 
					 | 
				
			||||||
			{
 | 
					 | 
				
			||||||
				hdr.id = 1; /* TODO: */
 | 
					 | 
				
			||||||
				hdr.type = HCL_XPKT_EXECUTE;
 | 
					 | 
				
			||||||
				hdr.len = 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
				iov[0].iov_base = &hdr;
 | 
					 | 
				
			||||||
				iov[0].iov_len = HCL_SIZEOF(hdr);
 | 
					 | 
				
			||||||
				hcl_sys_send_iov (sck, iov, 1);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
				if (shut_wr_after_req)
 | 
					 | 
				
			||||||
				{
 | 
					 | 
				
			||||||
					shutdown (sck, SHUT_WR);
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
				else
 | 
					 | 
				
			||||||
				{
 | 
					 | 
				
			||||||
					hdr.type = HCL_XPKT_DISCONNECT;
 | 
					 | 
				
			||||||
					hdr.id = 1; /* TODO: */
 | 
					 | 
				
			||||||
					hdr.len = 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
					iov[0].iov_base = &hdr;
 | 
					 | 
				
			||||||
					iov[0].iov_len = HCL_SIZEOF(hdr);
 | 
					 | 
				
			||||||
					hcl_sys_send_iov (sck, iov, 1);
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if (pfd.revents & POLLIN)
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			hcl_oow_t bcap;
 | 
					 | 
				
			||||||
			hcl_uint8_t* bptr;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			bptr = hcl_xproto_getbuf(proto, &bcap);;
 | 
					 | 
				
			||||||
			x = recv(sck, bptr, bcap, 0);
 | 
					 | 
				
			||||||
			if (x <= -1)
 | 
					 | 
				
			||||||
			{
 | 
					 | 
				
			||||||
				if (errno == EINTR) goto carry_on; /* didn't read read */
 | 
					 | 
				
			||||||
				/*hcl_seterrwithsyserr (hcl, 0, errno); */
 | 
					 | 
				
			||||||
				/* TODO: error info set... */
 | 
					 | 
				
			||||||
				return -1;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			if (x == 0) hcl_xproto_seteof(proto, 1);
 | 
					 | 
				
			||||||
			hcl_xproto_advbuf (proto, x);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	carry_on:
 | 
					 | 
				
			||||||
		while (hcl_xproto_ready(proto))
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			if ((n = hcl_xproto_process(proto)) <= -1)
 | 
					 | 
				
			||||||
			{
 | 
					 | 
				
			||||||
				/* TODO: proper error message */
 | 
					 | 
				
			||||||
				return -1;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			if (n == 0)
 | 
					 | 
				
			||||||
			{
 | 
					 | 
				
			||||||
				/* TODO: chceck if there is remaining data in the buffer...?? */
 | 
					 | 
				
			||||||
				printf ("NO MORE DATA. EXITING...\n");
 | 
					 | 
				
			||||||
				goto done;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if (hcl_xproto_geteof(proto)) break;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
done:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* TODO: we can check if the buffer has all been consumed. if not, there is trailing garbage.. */
 | 
					 | 
				
			||||||
	/*{
 | 
					 | 
				
			||||||
		struct linger linger;
 | 
					 | 
				
			||||||
		linger.l_onoff = 1;
 | 
					 | 
				
			||||||
		linger.l_linger = 0;
 | 
					 | 
				
			||||||
		setsockopt (sck, SOL_SOCKET, SO_LINGER, (char *) &linger, sizeof(linger));
 | 
					 | 
				
			||||||
	}*/
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	hcl_xproto_close (proto);
 | 
					 | 
				
			||||||
	close (sck);
 | 
					 | 
				
			||||||
	return 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
oops:
 | 
					 | 
				
			||||||
	if (proto) hcl_xproto_close (proto);
 | 
					 | 
				
			||||||
	if (sck >= 0) close (sck);
 | 
					 | 
				
			||||||
	return -1;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int hcl_client_connect (hcl_client_t* client, const char* ipaddr, int reuse_addr)
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	hcl_sckaddr_t sckaddr;
 | 
						hcl_sckaddr_t sckaddr;
 | 
				
			||||||
	hcl_scklen_t scklen;
 | 
						hcl_scklen_t scklen;
 | 
				
			||||||
@ -607,6 +445,8 @@ int hcl_client_connect (hcl_client_t* client, const char* ipaddr, int reuse_addr
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* TODO: async connect? */
 | 
				
			||||||
 | 
					/* TODO: connect timeout */
 | 
				
			||||||
	if (connect(sck, (struct sockaddr*)&sckaddr, scklen) <= -1)
 | 
						if (connect(sck, (struct sockaddr*)&sckaddr, scklen) <= -1)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		hcl_client_seterrbfmt (client, HCL_ESYSERR,
 | 
							hcl_client_seterrbfmt (client, HCL_ESYSERR,
 | 
				
			||||||
@ -616,12 +456,12 @@ int hcl_client_connect (hcl_client_t* client, const char* ipaddr, int reuse_addr
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	memset (&proto, 0, HCL_SIZEOF(proto_cb));
 | 
						memset (&proto, 0, HCL_SIZEOF(proto_cb));
 | 
				
			||||||
	proto_cb.on_packet = handle_packet;
 | 
						proto_cb.on_packet = client->prim.on_packet;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	proto = hcl_xproto_open(hcl_client_getmmgr(client), &proto_cb, HCL_SIZEOF(*proto_xtn));
 | 
						proto = hcl_xproto_open(hcl_client_getmmgr(client), &proto_cb, HCL_SIZEOF(*proto_xtn));
 | 
				
			||||||
	if (HCL_UNLIKELY(!proto))
 | 
						if (HCL_UNLIKELY(!proto))
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		fprintf (stderr, "cannot open protocol to %s\n", ipaddr);
 | 
							hcl_client_seterrbfmt (client, HCL_ESYSERR, "cannot open protocol to %s", ipaddr);
 | 
				
			||||||
		goto oops;
 | 
							goto oops;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	proto_xtn = hcl_xproto_getxtn(proto);
 | 
						proto_xtn = hcl_xproto_getxtn(proto);
 | 
				
			||||||
@ -636,3 +476,163 @@ oops:
 | 
				
			|||||||
	if (sck >= 0) close (sck);
 | 
						if (sck >= 0) close (sck);
 | 
				
			||||||
	return -1;
 | 
						return -1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void client_close (hcl_client_t* client)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (client->proto)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							hcl_xproto_close (client->proto);
 | 
				
			||||||
 | 
							client->proto = HCL_NULL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (client->sck >= 0)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							close (client->sck);
 | 
				
			||||||
 | 
							client->sck = -1;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int hcl_client_start (hcl_client_t* client, const char* ipaddr, const char* script, int reuse_addr, int shut_wr_after_req)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int x;
 | 
				
			||||||
 | 
						ssize_t n;
 | 
				
			||||||
 | 
						const char* scptr, * sccur;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (client_connect(client, ipaddr, reuse_addr) <= -1) return -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						scptr = sccur = script;
 | 
				
			||||||
 | 
						while (1)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							struct pollfd pfd;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							pfd.fd = client->sck;
 | 
				
			||||||
 | 
							pfd.events = POLLIN;
 | 
				
			||||||
 | 
							if (*sccur != '\0') pfd.events |= POLLOUT;
 | 
				
			||||||
 | 
							pfd.revents = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							n = poll(&pfd, 1, 1000);
 | 
				
			||||||
 | 
							if (n <= -1)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								hcl_client_seterrbfmt (client, HCL_ESYSERR, "poll error on %d - %hs", client->sck, strerror(n));
 | 
				
			||||||
 | 
								goto oops;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (n == 0)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								/* TODO: proper timeout handling */
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (pfd.revents & POLLERR)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								hcl_client_seterrbfmt (client, HCL_ESYSERR, "error condition detected on %d", client->sck);
 | 
				
			||||||
 | 
								goto oops;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (pfd.revents & POLLOUT)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								hcl_xpkt_hdr_t hdr;
 | 
				
			||||||
 | 
								struct iovec iov[2];
 | 
				
			||||||
 | 
								hcl_uint16_t seglen;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								while (*sccur != '\0' && sccur - scptr < HCL_XPKT_MAX_PLD_LEN) sccur++;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								seglen = sccur - scptr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								hdr.id = 1; /* TODO: */
 | 
				
			||||||
 | 
								hdr.type = HCL_XPKT_CODE | (((seglen >> 8) & 0x0F) << 4);
 | 
				
			||||||
 | 
								hdr.len = seglen & 0xFF;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								iov[0].iov_base = &hdr;
 | 
				
			||||||
 | 
								iov[0].iov_len = HCL_SIZEOF(hdr);
 | 
				
			||||||
 | 
								iov[1].iov_base = scptr;
 | 
				
			||||||
 | 
								iov[1].iov_len = seglen;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								hcl_sys_send_iov (client->sck, iov, 2); /* TODO: error check */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								scptr = sccur;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if (*sccur == '\0')
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									hdr.id = 1; /* TODO: */
 | 
				
			||||||
 | 
									hdr.type = HCL_XPKT_EXECUTE;
 | 
				
			||||||
 | 
									hdr.len = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									iov[0].iov_base = &hdr;
 | 
				
			||||||
 | 
									iov[0].iov_len = HCL_SIZEOF(hdr);
 | 
				
			||||||
 | 
									hcl_sys_send_iov (client->sck, iov, 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									if (shut_wr_after_req)
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										shutdown (client->sck, SHUT_WR);
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									else
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										hdr.type = HCL_XPKT_DISCONNECT;
 | 
				
			||||||
 | 
										hdr.id = 1; /* TODO: */
 | 
				
			||||||
 | 
										hdr.len = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
										iov[0].iov_base = &hdr;
 | 
				
			||||||
 | 
										iov[0].iov_len = HCL_SIZEOF(hdr);
 | 
				
			||||||
 | 
										hcl_sys_send_iov (client->sck, iov, 1);
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (pfd.revents & POLLIN)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								hcl_oow_t bcap;
 | 
				
			||||||
 | 
								hcl_uint8_t* bptr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								bptr = hcl_xproto_getbuf(client->proto, &bcap);;
 | 
				
			||||||
 | 
								x = recv(client->sck, bptr, bcap, 0);
 | 
				
			||||||
 | 
								if (x <= -1)
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									if (errno == EINTR) goto carry_on; /* didn't read read */
 | 
				
			||||||
 | 
									/*hcl_seterrwithsyserr (hcl, 0, errno); */
 | 
				
			||||||
 | 
									/* TODO: error info set... */
 | 
				
			||||||
 | 
									return -1;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								if (x == 0) hcl_xproto_seteof(client->proto, 1);
 | 
				
			||||||
 | 
								hcl_xproto_advbuf (client->proto, x);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						carry_on:
 | 
				
			||||||
 | 
							while (hcl_xproto_ready(client->proto))
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								if ((n = hcl_xproto_process(client->proto)) <= -1)
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									/* TODO: proper error message */
 | 
				
			||||||
 | 
									return -1;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								if (n == 0)
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									/* TODO: chceck if there is remaining data in the buffer...?? */
 | 
				
			||||||
 | 
									printf ("NO MORE DATA. EXITING...\n");
 | 
				
			||||||
 | 
									goto done;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (hcl_xproto_geteof(client->proto)) break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					done:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* TODO: we can check if the buffer has all been consumed. if not, there is trailing garbage.. */
 | 
				
			||||||
 | 
						/*{
 | 
				
			||||||
 | 
							struct linger linger;
 | 
				
			||||||
 | 
							linger.l_onoff = 1;
 | 
				
			||||||
 | 
							linger.l_linger = 0;
 | 
				
			||||||
 | 
							setsockopt (client->sck, SOL_SOCKET, SO_LINGER, (char *) &linger, sizeof(linger));
 | 
				
			||||||
 | 
						}*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						client_close (client);
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					oops:
 | 
				
			||||||
 | 
						client_close (client);
 | 
				
			||||||
 | 
						return -1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -244,12 +244,12 @@ struct hcl_server_t
 | 
				
			|||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* ========================================================================= */
 | 
					/* ========================================================================= */
 | 
				
			||||||
static int send_stdout_bytes (hcl_xproto_t* proto, const hcl_bch_t* data, hcl_oow_t len);
 | 
					static int send_stdout_bytes (hcl_xproto_t* proto, int xpkt_code, const hcl_bch_t* data, hcl_oow_t len);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if defined(HCL_OOCH_IS_UCH)
 | 
					#if defined(HCL_OOCH_IS_UCH)
 | 
				
			||||||
static int send_stdout_chars (hcl_xproto_t* proto, const hcl_ooch_t* data, hcl_oow_t len);
 | 
					static int send_stdout_chars (hcl_xproto_t* proto, int xpkt_code, const hcl_ooch_t* data, hcl_oow_t len);
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
#define send_stdout_chars(proto,data,len) send_stdout_bytes(proto,data,len)
 | 
					#define send_stdout_chars(proto,xpkt_code,data,len) send_stdout_bytes(proto,xpkt_code,data,len)
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* ========================================================================= */
 | 
					/* ========================================================================= */
 | 
				
			||||||
@ -558,7 +558,7 @@ printf ("IO CLOSE SOMETHING...........\n");
 | 
				
			|||||||
			hcl_io_udoarg_t* outarg = (hcl_io_udoarg_t*)arg;
 | 
								hcl_io_udoarg_t* outarg = (hcl_io_udoarg_t*)arg;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
printf ("IO WRITE SOMETHING...........\n");
 | 
					printf ("IO WRITE SOMETHING...........\n");
 | 
				
			||||||
			if (send_stdout_chars(xtn->worker->proto, outarg->ptr, outarg->len) <= -1)
 | 
								if (send_stdout_chars(xtn->worker->proto, HCL_XPKT_STDOUT, outarg->ptr, outarg->len) <= -1)
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				/* TODO: change error code and message. propagage the errormessage from proto */
 | 
									/* TODO: change error code and message. propagage the errormessage from proto */
 | 
				
			||||||
				hcl_seterrbfmt (hcl, HCL_EIOERR, "failed to write message via proto");
 | 
									hcl_seterrbfmt (hcl, HCL_EIOERR, "failed to write message via proto");
 | 
				
			||||||
@ -578,7 +578,7 @@ printf ("IO WRITE SOMETHING...........\n");
 | 
				
			|||||||
			hcl_io_udoarg_t* outarg = (hcl_io_udoarg_t*)arg;
 | 
								hcl_io_udoarg_t* outarg = (hcl_io_udoarg_t*)arg;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
printf ("IO WRITE SOMETHING BYTES...........\n");
 | 
					printf ("IO WRITE SOMETHING BYTES...........\n");
 | 
				
			||||||
			if (send_stdout_bytes(xtn->worker->proto, outarg->ptr, outarg->len) <= -1)
 | 
								if (send_stdout_bytes(xtn->worker->proto, HCL_XPKT_STDOUT, outarg->ptr, outarg->len) <= -1)
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				/* TODO: change error code and message. propagage the errormessage from proto */
 | 
									/* TODO: change error code and message. propagage the errormessage from proto */
 | 
				
			||||||
				hcl_seterrbfmt (hcl, HCL_EIOERR, "failed to write message via proto");
 | 
									hcl_seterrbfmt (hcl, HCL_EIOERR, "failed to write message via proto");
 | 
				
			||||||
@ -671,26 +671,26 @@ static hcl_server_worker_t* proto_to_worker (hcl_xproto_t* proto)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
static int on_fed_cnode (hcl_t* hcl, hcl_cnode_t* obj)
 | 
					static int on_fed_cnode (hcl_t* hcl, hcl_cnode_t* obj)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	/*worker_hcl_xtn_t* xtn = (worker_hcl_xtn_t*)hcl_getxtn(hcl);*/
 | 
						worker_hcl_xtn_t* hcl_xtn = (worker_hcl_xtn_t*)hcl_getxtn(hcl);
 | 
				
			||||||
	/*hcl_xproto_t* proto = xtn->proto;*/
 | 
						hcl_server_worker_t* worker;
 | 
				
			||||||
 | 
						hcl_xproto_t* proto;
 | 
				
			||||||
	int flags = 0;
 | 
						int flags = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
printf ("on_fed_cnode......\n");
 | 
						hcl_xtn = (worker_hcl_xtn_t*)hcl_getxtn(hcl);
 | 
				
			||||||
 | 
						worker = hcl_xtn->worker;
 | 
				
			||||||
 | 
						proto = worker->proto;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* the compile error must not break the input loop.
 | 
						/* the compile error must not break the input loop.
 | 
				
			||||||
	 * this function returns 0 to go on despite a compile-time error.
 | 
						 * this function returns 0 to go on despite a compile-time error.
 | 
				
			||||||
	 *
 | 
						 *
 | 
				
			||||||
	 * if a single line or continued lines contain multiple expressions,
 | 
						 * if a single line or continued lines contain multiple expressions,
 | 
				
			||||||
	 * execution is delayed until the last expression is compiled. */
 | 
						 * execution is delayed until the last expression is compiled. */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
printf ("COMPILING hcl_copingll......\n");
 | 
					 | 
				
			||||||
	if (hcl_compile(hcl, obj, flags) <= -1)
 | 
						if (hcl_compile(hcl, obj, flags) <= -1)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
hcl_logbfmt (hcl, HCL_LOG_STDERR, "COMPILER ERROR - %js\n", hcl_geterrmsg(hcl));
 | 
							const hcl_bch_t* errmsg = hcl_geterrbmsg(hcl);
 | 
				
			||||||
#if 0
 | 
							send_stdout_bytes(proto, HCL_XPKT_ERROR, errmsg, hcl_count_bcstr(errmsg));
 | 
				
			||||||
		print_error(hcl, "failed to compile");
 | 
					/* TODO: ignore the whole line??? */
 | 
				
			||||||
		xtn->feed.pos = xtn->feed.len; /* arrange to discard the rest of the line */
 | 
					 | 
				
			||||||
		show_prompt (hcl, 0);
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
@ -928,7 +928,7 @@ static int kill_server_worker (hcl_xproto_t* proto, hcl_oow_t wid)
 | 
				
			|||||||
	return xret;
 | 
						return xret;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int handle_packet (hcl_xproto_t* proto, hcl_xpkt_type_t type, const void* data, hcl_oow_t len)
 | 
					static int server_on_packet (hcl_xproto_t* proto, hcl_xpkt_type_t type, const void* data, hcl_oow_t len)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	hcl_server_worker_t* worker;
 | 
						hcl_server_worker_t* worker;
 | 
				
			||||||
	hcl_t* hcl;
 | 
						hcl_t* hcl;
 | 
				
			||||||
@ -994,7 +994,7 @@ oops:
 | 
				
			|||||||
	return -1;
 | 
						return -1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int send_stdout_bytes (hcl_xproto_t* proto, const hcl_bch_t* data, hcl_oow_t len)
 | 
					static int send_stdout_bytes (hcl_xproto_t* proto, int xpkt_code, const hcl_bch_t* data, hcl_oow_t len)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	hcl_server_worker_t* worker;
 | 
						hcl_server_worker_t* worker;
 | 
				
			||||||
	hcl_xpkt_hdr_t hdr;
 | 
						hcl_xpkt_hdr_t hdr;
 | 
				
			||||||
@ -1003,6 +1003,7 @@ static int send_stdout_bytes (hcl_xproto_t* proto, const hcl_bch_t* data, hcl_oo
 | 
				
			|||||||
	hcl_uint16_t seglen;
 | 
						hcl_uint16_t seglen;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	worker = proto_to_worker(proto);
 | 
						worker = proto_to_worker(proto);
 | 
				
			||||||
 | 
						HCL_ASSERT (worker->hcl, xpkt_code == HCL_XPKT_STDOUT || xpkt_code == HCL_XPKT_STDERR || xpkt_code == HCL_XPKT_ERROR);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ptr = cur = data;
 | 
						ptr = cur = data;
 | 
				
			||||||
	end = data + len;
 | 
						end = data + len;
 | 
				
			||||||
@ -1015,7 +1016,7 @@ printf ("SENDING BYTES [%.*s]\n", (int)len, data);
 | 
				
			|||||||
		seglen = cur - ptr;
 | 
							seglen = cur - ptr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		hdr.id = 1; /* TODO: */
 | 
							hdr.id = 1; /* TODO: */
 | 
				
			||||||
		hdr.type = HCL_XPKT_STDOUT | (((seglen >> 8) & 0x0F) << 4);
 | 
							hdr.type = xpkt_code | (((seglen >> 8) & 0x0F) << 4);
 | 
				
			||||||
		hdr.len = seglen & 0xFF;
 | 
							hdr.len = seglen & 0xFF;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		iov[0].iov_base = &hdr;
 | 
							iov[0].iov_base = &hdr;
 | 
				
			||||||
@ -1037,7 +1038,7 @@ printf ("SENDING BYTES [%.*s]\n", (int)len, data);
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if defined(HCL_OOCH_IS_UCH)
 | 
					#if defined(HCL_OOCH_IS_UCH)
 | 
				
			||||||
static int send_stdout_chars (hcl_xproto_t* proto, const hcl_ooch_t* data, hcl_oow_t len)
 | 
					static int send_stdout_chars (hcl_xproto_t* proto, int xpkt_code, const hcl_ooch_t* data, hcl_oow_t len)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	hcl_server_worker_t* worker;
 | 
						hcl_server_worker_t* worker;
 | 
				
			||||||
	const hcl_ooch_t* ptr, * end;
 | 
						const hcl_ooch_t* ptr, * end;
 | 
				
			||||||
@ -1057,7 +1058,7 @@ static int send_stdout_chars (hcl_xproto_t* proto, const hcl_ooch_t* data, hcl_o
 | 
				
			|||||||
		n = hcl_convutobchars(worker->hcl, ptr, &pln, tmp, &tln);
 | 
							n = hcl_convutobchars(worker->hcl, ptr, &pln, tmp, &tln);
 | 
				
			||||||
		if (n <= -1 && n != -2) return -1;
 | 
							if (n <= -1 && n != -2) return -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (send_stdout_bytes(proto, tmp, tln) <= -1) return -1;
 | 
							if (send_stdout_bytes(proto, xpkt_code, tmp, tln) <= -1) return -1;
 | 
				
			||||||
		ptr += pln;
 | 
							ptr += pln;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -1560,7 +1561,7 @@ static int init_worker_proto (hcl_server_worker_t* worker)
 | 
				
			|||||||
	hcl_xproto_cb_t cb;
 | 
						hcl_xproto_cb_t cb;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	HCL_MEMSET (&cb, 0, HCL_SIZEOF(cb));
 | 
						HCL_MEMSET (&cb, 0, HCL_SIZEOF(cb));
 | 
				
			||||||
	cb.on_packet = handle_packet;
 | 
						cb.on_packet = server_on_packet;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	proto = hcl_xproto_open(hcl_server_getmmgr(worker->server), &cb, HCL_SIZEOF(*xtn));
 | 
						proto = hcl_xproto_open(hcl_server_getmmgr(worker->server), &cb, HCL_SIZEOF(*xtn));
 | 
				
			||||||
	if (HCL_UNLIKELY(!proto)) return -1;
 | 
						if (HCL_UNLIKELY(!proto)) return -1;
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user