1 /*
2  *   LASH
3  *
4  *   Copyright (C) 2002, 2003 Robert Ham <rah@bash.sh>
5  *
6  *   This program is free software; you can redistribute it and/or modify
7  *   it under the terms of the GNU General Public License as published by
8  *   the Free Software Foundation; either version 2 of the License, or
9  *   (at your option) any later version.
10  *
11  *   This program is distributed in the hope that it will be useful,
12  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *   GNU General Public License for more details.
15  *
16  *   You should have received a copy of the GNU General Public License
17  *   along with this program; if not, write to the Free Software
18  *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19  */
20 
21 #define _GNU_SOURCE /* strdup */
22 
23 #include <stdint.h>
24 #include <string.h>
25 #include <stdlib.h>
26 #include <stdio.h>
27 #include <netinet/in.h>
28 
29 #include <lash/lash.h>
30 #include <lash/internal_headers.h>
31 
32 void
lash_buffer_from_comm_event_connect(char ** buf_ptr,size_t * buf_size_ptr,lash_connect_params_t * params)33 lash_buffer_from_comm_event_connect(char **buf_ptr, size_t * buf_size_ptr,
34 									lash_connect_params_t * params)
35 {
36 	size_t buf_size;
37 	char *buf;
38 	size_t proj_name_size;
39 	size_t working_dir_size;
40 	size_t class_size;
41 	size_t arg_size;
42 	int i;
43 	uint32_t *iptr;
44 	char *ptr;
45 	char id_str[37];
46 
47 	if (!buf_ptr)
48 		return;
49 
50 	buf_size = sizeof(uint32_t) * 5;
51 	buf_size += proj_name_size =
52 		(params->project ? strlen(params->project) : 0) + 1;
53 	buf_size += working_dir_size = strlen(params->working_dir) + 1;
54 	buf_size += class_size = strlen(params->class) + 1;
55 	buf_size += sizeof(id_str);
56 
57 	for (i = 0; i < params->argc; i++)
58 		buf_size += strlen(params->argv[i]) + 1;
59 
60 	buf = lash_malloc(buf_size);
61 
62 	iptr = (uint32_t *) buf;
63 	*iptr = htonl(LASH_Comm_Event_Connect);
64 	iptr++;
65 
66 	*iptr = htonl(LASH_COMM_PROTOCOL_VERSION);
67 	iptr++;
68 
69 	*iptr = htonl(params->protocol_version);
70 	iptr++;
71 
72 	*iptr = htonl(params->flags);
73 	iptr++;
74 
75 	ptr = (char *)iptr;
76 	if (params->project)
77 		memcpy(ptr, params->project, proj_name_size);
78 	else
79 		*ptr = 0;
80 	ptr += proj_name_size;
81 
82 	memcpy(ptr, params->working_dir, working_dir_size);
83 	ptr += working_dir_size;
84 
85 	memcpy(ptr, params->class, class_size);
86 	ptr += class_size;
87 
88 	uuid_unparse(params->id, id_str);
89 	memcpy(ptr, id_str, sizeof(id_str));
90 	ptr += sizeof(id_str);
91 
92 	iptr = (uint32_t *) ptr;
93 	*iptr = htonl(params->argc);
94 	iptr++;
95 
96 	ptr = (char *)iptr;
97 	for (i = 0; i < params->argc; i++) {
98 		arg_size = strlen(params->argv[i]) + 1;
99 		memcpy(ptr, params->argv[i], arg_size);
100 		ptr += arg_size;
101 	}
102 
103 	*buf_ptr = buf;
104 	*buf_size_ptr = buf_size;
105 }
106 
107 int
lash_comm_event_from_buffer_connect(char * buf,size_t buf_size,lash_comm_event_t * event)108 lash_comm_event_from_buffer_connect(char *buf, size_t buf_size,
109 									lash_comm_event_t * event)
110 {
111 	lash_connect_params_t *params;
112 	uint32_t *iptr;
113 	char *ptr;
114 	int i;
115 
116 	LASH_DEBUGARGS("buf_size: %d", buf_size);
117 
118 	iptr = (uint32_t *) buf;
119 	event->type = ntohl(*iptr);
120 	iptr++;
121 
122 	if (ntohl(*iptr) != LASH_COMM_PROTOCOL_VERSION)
123 		return -1;
124 	iptr++;
125 
126 	params = lash_connect_params_new();
127 
128 	params->protocol_version = ntohl(*iptr);
129 	iptr++;
130 
131 	params->flags = ntohl(*iptr);
132 	iptr++;
133 
134 	ptr = (char *)iptr;
135 	if (*ptr)
136 		lash_connect_params_set_project(params, ptr);
137 	ptr += strlen(ptr) + 1;
138 
139 	lash_connect_params_set_working_dir(params, ptr);
140 	ptr += strlen(ptr) + 1;
141 
142 	lash_connect_params_set_class(params, ptr);
143 	ptr += strlen(ptr) + 1;
144 
145 	uuid_parse(ptr, params->id);
146 	ptr += sizeof(char[37]);
147 
148 	iptr = (uint32_t *) ptr;
149 	params->argc = ntohl(*iptr);
150 	iptr++;
151 
152 	params->argv = lash_malloc(params->argc * sizeof(char *));
153 
154 	/* set the argv array */
155 	ptr = (char *)iptr;
156 	for (i = 0; i < params->argc; i++) {
157 		LASH_DEBUGARGS("recieving argv[%d] == '%s'", i, ptr);
158 		params->argv[i] = strdup(ptr);
159 		ptr += strlen(ptr) + 1;
160 	}
161 
162 	event->event_data.connect = params;
163 
164 	return 0;
165 }
166 
167 void
lash_buffer_from_comm_event_event(char ** buf_ptr,size_t * buf_size_ptr,lash_event_t * event)168 lash_buffer_from_comm_event_event(char **buf_ptr, size_t * buf_size_ptr,
169 								  lash_event_t * event)
170 {
171 	size_t buf_size;
172 	char *buf;
173 	size_t string_size = 0;
174 	size_t project_size = 0;
175 	uint32_t *iptr;
176 	char *ptr;
177 
178 	buf_size = sizeof(uint32_t) * 2;
179 	buf_size += sizeof(char[37]);
180 
181 	if (event->string)
182 		buf_size += string_size = strlen(event->string) + 1;
183 	else
184 		buf_size += 1;
185 
186 	if (event->project)
187 		buf_size += project_size = strlen(event->project) + 1;
188 	else
189 		buf_size += 1;
190 
191 	buf = lash_malloc(buf_size);
192 
193 	iptr = (uint32_t *) buf;
194 	*iptr = htonl(LASH_Comm_Event_Event);
195 	iptr++;
196 
197 	*iptr = htonl(event->type);
198 	iptr++;
199 
200 	ptr = (char *)iptr;
201 	uuid_unparse(event->client_id, ptr);
202 	ptr += sizeof(char[37]);
203 
204 	if (event->string) {
205 		memcpy(ptr, event->string, string_size);
206 		ptr += string_size;
207 	} else {
208 		*ptr = '\0';
209 		ptr++;
210 	}
211 
212 	if (event->project) {
213 		memcpy(ptr, event->project, project_size);
214 		ptr += project_size;
215 	} else {
216 		*ptr = '\0';
217 	}
218 
219 	*buf_ptr = buf;
220 	*buf_size_ptr = buf_size;
221 }
222 
223 void
lash_comm_event_from_buffer_event(char * buf,size_t buf_size,lash_comm_event_t * comm_event)224 lash_comm_event_from_buffer_event(char *buf, size_t buf_size,
225 								  lash_comm_event_t * comm_event)
226 {
227 	uint32_t *iptr;
228 	char *ptr;
229 	lash_event_t *event;
230 
231 	comm_event->type = LASH_Comm_Event_Event;
232 	iptr = (uint32_t *) buf;
233 	iptr++;
234 
235 	event = lash_event_new();
236 
237 	lash_event_set_type(event, ntohl(*iptr));
238 	iptr++;
239 
240 	ptr = (char *)iptr;
241 	uuid_parse(ptr, event->client_id);
242 	ptr += sizeof(char[37]);
243 
244 	if (*ptr == '\0')
245 		ptr++;
246 	else {
247 		lash_event_set_string(event, ptr);
248 		ptr += strlen(event->string) + 1;
249 	}
250 
251 	if (*ptr != '\0')
252 		lash_event_set_project(event, ptr);
253 
254 	comm_event->event_data.event = event;
255 }
256 
257 void
lash_buffer_from_comm_event_config(char ** buf_ptr,size_t * buf_size_ptr,lash_config_t * config)258 lash_buffer_from_comm_event_config(char **buf_ptr, size_t * buf_size_ptr,
259 								   lash_config_t * config)
260 {
261 	size_t buf_size = sizeof(uint32_t);
262 	char *buf;
263 	size_t key_size;
264 	uint32_t *iptr;
265 	char *ptr;
266 
267 	buf_size += key_size = strlen(config->key) + 1;
268 	if (config->value) {
269 		buf_size += sizeof(uint32_t);
270 		buf_size += config->value_size;
271 	}
272 
273 	buf = lash_malloc(buf_size);
274 
275 	iptr = (uint32_t *) buf;
276 	*iptr = htonl(LASH_Comm_Event_Config);
277 	iptr++;
278 
279 	memcpy(iptr, config->key, key_size);
280 	ptr = (char *)iptr;
281 	ptr += key_size;
282 
283 	if (config->value) {
284 		iptr = (uint32_t *) ptr;
285 		*iptr = htonl(config->value_size);
286 		iptr++;
287 
288 		memcpy(iptr, config->value, config->value_size);
289 	}
290 
291 	*buf_ptr = buf;
292 	*buf_size_ptr = buf_size;
293 }
294 
295 void
lash_comm_event_from_buffer_config(char * buf,size_t buf_size,lash_comm_event_t * event)296 lash_comm_event_from_buffer_config(char *buf, size_t buf_size,
297 								   lash_comm_event_t * event)
298 {
299 	uint32_t *iptr;
300 	char *ptr;
301 	lash_config_t *config;
302 	size_t key_size;
303 	size_t value_size;
304 
305 	event->type = LASH_Comm_Event_Config;
306 	iptr = (uint32_t *) buf;
307 	iptr++;
308 
309 	config = lash_config_new();
310 
311 	ptr = (char *)iptr;
312 	lash_config_set_key(config, ptr);
313 
314 	key_size = strlen(ptr) + 1;
315 	if (buf_size > key_size + sizeof(uint32_t)) {
316 		ptr += key_size;
317 
318 		iptr = (uint32_t *) ptr;
319 		value_size = ntohl(*iptr);
320 		iptr++;
321 
322 		lash_config_set_value(config, iptr, value_size);
323 	}
324 
325 	event->event_data.config = config;
326 }
327 
328 void
lash_buffer_from_comm_event_protocol_mismatch(char ** buf_ptr,size_t * buf_size_ptr,lash_protocol_t protocol)329 lash_buffer_from_comm_event_protocol_mismatch(char **buf_ptr,
330 											  size_t * buf_size_ptr,
331 											  lash_protocol_t protocol)
332 {
333 	size_t buf_size = sizeof(uint32_t) + sizeof(lash_protocol_t);
334 	char *buf;
335 	uint32_t *iptr;
336 
337 	buf = lash_malloc(buf_size);
338 
339 	iptr = (uint32_t *) buf;
340 	*iptr = htonl(LASH_Comm_Event_Protocol_Mismatch);
341 	iptr++;
342 
343 	*iptr = htonl(protocol);
344 	/* iptr++ */
345 
346 	*buf_ptr = buf;
347 	*buf_size_ptr = buf_size;
348 }
349 
350 void
lash_comm_event_from_buffer_protocol_mismatch(char * buf,size_t buf_size,lash_comm_event_t * event)351 lash_comm_event_from_buffer_protocol_mismatch(char *buf, size_t buf_size,
352 											  lash_comm_event_t * event)
353 {
354 	uint32_t *iptr;
355 
356 	iptr = (uint32_t *) buf;
357 	iptr++;
358 
359 	lash_comm_event_set_protocol_mismatch(event, ntohl(*iptr));
360 }
361 
362 void
lash_buffer_from_comm_event_exec(char ** buf_ptr,size_t * buf_size_ptr,lash_exec_params_t * params)363 lash_buffer_from_comm_event_exec(char **buf_ptr, size_t * buf_size_ptr,
364 								 lash_exec_params_t * params)
365 {
366 	uint32_t *iptr;
367 	char *ptr;
368 	char *buf;
369 	size_t working_dir_size;
370 	size_t server_size;
371 	size_t project_size;
372 	size_t argv_size;
373 	size_t buf_size;
374 	int i;
375 
376 	/* see how big our buffer will be */
377 	buf_size = sizeof(uint32_t) * 3;
378 	buf_size += sizeof(char[37]);
379 	buf_size += working_dir_size = strlen(params->working_dir) + 1;
380 	buf_size += server_size = strlen(params->server) + 1;
381 	buf_size += project_size = strlen(params->project) + 1;
382 
383 	for (i = 0; i < params->argc; i++)
384 		buf_size += strlen(params->argv[i]) + 1;
385 
386 	/* create it */
387 
388 	buf = lash_malloc(buf_size);
389 
390 	iptr = (uint32_t *) buf;
391 	*iptr = htonl(LASH_Comm_Event_Exec);
392 	iptr++;
393 
394 	*iptr = htonl(params->flags);
395 	iptr++;
396 
397 	*iptr = htonl(params->argc);
398 	iptr++;
399 
400 	ptr = (char *)iptr;
401 	uuid_unparse(params->id, ptr);
402 	ptr += 37;
403 
404 	memcpy(ptr, params->working_dir, working_dir_size);
405 	ptr += working_dir_size;
406 
407 	memcpy(ptr, params->server, server_size);
408 	ptr += server_size;
409 
410 	memcpy(ptr, params->project, project_size);
411 	ptr += project_size;
412 
413 	for (i = 0; i < params->argc; i++) {
414 		argv_size = strlen(params->argv[i]) + 1;
415 		memcpy(ptr, params->argv[i], argv_size);
416 		ptr += argv_size;
417 	}
418 
419 	/* done */
420 
421 	*buf_ptr = buf;
422 	*buf_size_ptr = buf_size;
423 }
424 
425 void
lash_comm_event_from_buffer_exec(char * buf,size_t buf_size,lash_comm_event_t * event)426 lash_comm_event_from_buffer_exec(char *buf, size_t buf_size,
427 								 lash_comm_event_t * event)
428 {
429 	uint32_t *iptr;
430 	char *ptr;
431 	lash_exec_params_t *params;
432 	int i;
433 
434 	iptr = (uint32_t *) buf;
435 	event->type = LASH_Comm_Event_Exec;
436 	iptr++;
437 
438 	params = lash_exec_params_new();
439 
440 	params->flags = ntohl(*iptr);
441 	iptr++;
442 
443 	params->argc = ntohl(*iptr);
444 	iptr++;
445 
446 	ptr = (char *)iptr;
447 	uuid_parse(ptr, params->id);
448 	ptr += 37;
449 
450 	lash_exec_params_set_working_dir(params, ptr);
451 	ptr += strlen(ptr) + 1;
452 
453 	lash_exec_params_set_server(params, ptr);
454 	ptr += strlen(ptr) + 1;
455 
456 	lash_exec_params_set_project(params, ptr);
457 	ptr += strlen(ptr) + 1;
458 
459 	params->argv = lash_malloc(sizeof(char *) * params->argc);
460 	for (i = 0; i < params->argc; i++) {
461 		params->argv[i] = lash_strdup(ptr);
462 		ptr += strlen(ptr) + 1;
463 	}
464 
465 #ifdef LASH_DEBUG
466 	LASH_DEBUGARGS
467 		("created exec comm event with: flags=%d, working_dir=%s, server=%s, project=%s, argc=%d, args:",
468 		 params->flags, params->working_dir, params->server, params->project,
469 		 params->argc);
470 	for (i = 0; i < params->argc; i++) {
471 		LASH_DEBUGARGS("  argv[%d]: '%s'", i, params->argv[i]);
472 	}
473 #endif
474 
475 	lash_comm_event_set_exec(event, params);
476 }
477 
478 /* for ping, pong and close */
479 void
lash_buffer_from_comm_event(char ** buf_ptr,size_t * buf_size_ptr,lash_comm_event_t * event)480 lash_buffer_from_comm_event(char **buf_ptr, size_t * buf_size_ptr,
481 							lash_comm_event_t * event)
482 {
483 	size_t buf_size = sizeof(uint32_t);
484 	char *buf;
485 	uint32_t *iptr;
486 
487 	buf = lash_malloc(buf_size);
488 
489 	iptr = (uint32_t *) buf;
490 	*iptr = htonl(event->type);
491 	iptr++;
492 
493 	*buf_ptr = buf;
494 	*buf_size_ptr = buf_size;
495 }
496 
497 void
lash_comm_event_from_buffer(char * buf,size_t buf_size,lash_comm_event_t * event)498 lash_comm_event_from_buffer(char *buf, size_t buf_size,
499 							lash_comm_event_t * event)
500 {
501 	event->type = ntohl(*((uint32_t *) buf));
502 }
503 
504 /* EOF */
505