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