Fix: liblttng-ctl: unreported truncations when copying strings
[lttng-tools.git] / src / lib / lttng-ctl / load.c
1 /*
2 * Copyright (C) 2014 - David Goulet <dgoulet@efficios.com>
3 *
4 * This library is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU Lesser General Public License, version 2.1 only,
6 * as published by the Free Software Foundation.
7 *
8 * This library is distributed in the hope that it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
11 * for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this library; if not, write to the Free Software Foundation,
15 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16 */
17
18 #define _LGPL_SOURCE
19 #include <assert.h>
20 #include <string.h>
21 #include <limits.h>
22
23 #include <lttng/lttng-error.h>
24 #include <lttng/load.h>
25 #include <lttng/load-internal.h>
26 #include <common/sessiond-comm/sessiond-comm.h>
27 #include <common/config/session-config.h>
28 #include <common/uri.h>
29 #include <common/macros.h>
30 #include <common/compat/string.h>
31
32 #include "lttng-ctl-helper.h"
33
34 struct lttng_load_session_attr *lttng_load_session_attr_create(void)
35 {
36 return zmalloc(sizeof(struct lttng_load_session_attr));
37 }
38
39 static
40 void reset_load_session_attr_urls(struct lttng_load_session_attr *attr)
41 {
42 free(attr->raw_override_url);
43 free(attr->raw_override_path_url);
44 free(attr->raw_override_ctrl_url);
45 free(attr->raw_override_data_url);
46 if (attr->override_attr) {
47 free(attr->override_attr->path_url);
48 free(attr->override_attr->ctrl_url);
49 free(attr->override_attr->data_url);
50 free(attr->override_attr->session_name);
51 }
52 }
53
54 void lttng_load_session_attr_destroy(struct lttng_load_session_attr *attr)
55 {
56 if (attr) {
57 reset_load_session_attr_urls(attr);
58 free(attr->override_attr);
59 free(attr);
60 }
61 }
62
63 static int validate_attr(const struct lttng_load_session_attr *attr)
64 {
65 int ret = 0;
66
67 if (!attr) {
68 ret = -LTTNG_ERR_INVALID;
69 goto end;
70 }
71
72 if (!attr->override_attr) {
73 goto end;
74 }
75
76 /*
77 * Refuse override name if the objective is to load multiple session
78 * since this operation is ambiguous while loading multiple session.
79 */
80 if (attr->override_attr->session_name
81 && attr->session_name[0] == '\0') {
82 ret = -LTTNG_ERR_INVALID;
83 goto end;
84 }
85 end:
86 return ret;
87 }
88
89 const char *lttng_load_session_attr_get_session_name(
90 struct lttng_load_session_attr *attr)
91 {
92 const char *ret = NULL;
93
94 if (attr && attr->session_name[0]) {
95 ret = attr->session_name;
96 }
97
98 return ret;
99 }
100
101 const char *lttng_load_session_attr_get_input_url(
102 struct lttng_load_session_attr *attr)
103 {
104 const char *ret = NULL;
105
106 if (attr && attr->input_url[0]) {
107 ret = attr->input_url;
108 }
109
110 return ret;
111 }
112
113 int lttng_load_session_attr_get_overwrite(
114 struct lttng_load_session_attr *attr)
115 {
116 return attr ? attr->overwrite : -LTTNG_ERR_INVALID;
117 }
118
119 const char *lttng_load_session_attr_get_override_ctrl_url(
120 struct lttng_load_session_attr *attr)
121 {
122 const char *ret = NULL;
123
124 if (!attr || !attr->override_attr) {
125 goto end;
126 }
127
128 ret = attr->raw_override_ctrl_url;
129 end:
130 return ret;
131 }
132
133 const char *lttng_load_session_attr_get_override_data_url(
134 struct lttng_load_session_attr *attr)
135 {
136 const char *ret = NULL;
137
138 if (!attr || !attr->override_attr) {
139 goto end;
140 }
141
142 ret = attr->raw_override_data_url;
143 end:
144 return ret;
145 }
146
147 const char *lttng_load_session_attr_get_override_url(
148 struct lttng_load_session_attr *attr)
149 {
150 const char *ret = NULL;
151
152 if (!attr || !attr->override_attr) {
153 goto end;
154 }
155
156 if ((attr->override_attr->path_url ||
157 (attr->override_attr->ctrl_url &&
158 attr->override_attr->data_url))) {
159 ret = attr->raw_override_url;
160 }
161 end:
162 return ret;
163 }
164
165 const char *lttng_load_session_attr_get_override_session_name(
166 struct lttng_load_session_attr *attr)
167 {
168 const char *ret = NULL;
169
170 if (!attr || !attr->override_attr) {
171 goto end;
172 }
173
174 ret = attr->override_attr->session_name;
175 end:
176 return ret;
177 }
178
179 int lttng_load_session_attr_set_session_name(
180 struct lttng_load_session_attr *attr, const char *session_name)
181 {
182 int ret = 0;
183
184 if (!attr) {
185 ret = -LTTNG_ERR_INVALID;
186 goto error;
187 }
188
189 if (session_name) {
190 size_t len;
191
192 len = strlen(session_name);
193 if (len >= LTTNG_NAME_MAX) {
194 ret = -LTTNG_ERR_INVALID;
195 goto error;
196 }
197
198 ret = lttng_strncpy(attr->session_name, session_name,
199 sizeof(attr->session_name));
200 if (ret) {
201 ret = -LTTNG_ERR_INVALID;
202 goto error;
203 }
204 } else {
205 attr->session_name[0] = '\0';
206 }
207 error:
208 return ret;
209 }
210
211 int lttng_load_session_attr_set_input_url(
212 struct lttng_load_session_attr *attr, const char *url)
213 {
214 int ret = 0;
215 size_t len;
216 ssize_t size;
217 struct lttng_uri *uris = NULL;
218
219 if (!attr) {
220 ret = -LTTNG_ERR_INVALID;
221 goto error;
222 }
223
224 if (!url) {
225 attr->input_url[0] = '\0';
226 ret = 0;
227 goto end;
228 }
229
230 len = strlen(url);
231 if (len >= PATH_MAX) {
232 ret = -LTTNG_ERR_INVALID;
233 goto error;
234 }
235
236 size = uri_parse_str_urls(url, NULL, &uris);
237 if (size <= 0 || uris[0].dtype != LTTNG_DST_PATH) {
238 ret = -LTTNG_ERR_INVALID;
239 goto error;
240 }
241
242 /* Copy string plus the NULL terminated byte. */
243 ret = lttng_strncpy(attr->input_url, uris[0].dst.path,
244 sizeof(attr->input_url));
245 if (ret) {
246 ret = -LTTNG_ERR_INVALID;
247 goto error;
248 }
249
250 end:
251 error:
252 free(uris);
253 return ret;
254 }
255
256 int lttng_load_session_attr_set_overwrite(
257 struct lttng_load_session_attr *attr, int overwrite)
258 {
259 int ret = 0;
260
261 if (!attr) {
262 ret = -LTTNG_ERR_INVALID;
263 goto end;
264 }
265
266 attr->overwrite = !!overwrite;
267 end:
268 return ret;
269 }
270
271 int lttng_load_session_attr_set_override_ctrl_url(
272 struct lttng_load_session_attr *attr, const char *url)
273 {
274 int ret = 0;
275 ssize_t ret_size;
276 struct lttng_uri *uri = NULL;
277 char *url_str = NULL;
278 char *raw_str = NULL;
279
280 if (!attr) {
281 ret = -LTTNG_ERR_INVALID;
282 goto end;
283 }
284
285 if (!attr->override_attr) {
286 attr->override_attr = zmalloc(
287 sizeof(struct config_load_session_override_attr));
288 if (!attr->override_attr) {
289 ret = -LTTNG_ERR_NOMEM;
290 goto end;
291 }
292 }
293
294 if (attr->override_attr->path_url) {
295 /*
296 * Setting a ctrl override after a path override makes no sense.
297 */
298 ret = -LTTNG_ERR_INVALID;
299 goto end;
300 }
301
302 /*
303 * FIXME: uri_parse should be able to take as parameter the protocol
304 * type to validate "url". For now only check the parsing goes through;
305 * it will fail later on.
306 */
307 ret_size = uri_parse(url, &uri);
308 if (ret_size < 0) {
309 ret = -LTTNG_ERR_INVALID;
310 goto end;
311 }
312
313 if (uri[0].port == 0) {
314 uri[0].port = DEFAULT_NETWORK_CONTROL_PORT;
315 }
316
317 url_str = zmalloc(PATH_MAX);
318 if (!url_str) {
319 /* FIXME: return valid error */
320 ret = -LTTNG_ERR_NOMEM;
321 goto end;
322 }
323
324 ret = uri_to_str_url(&uri[0], url_str, PATH_MAX);
325 if (ret < 0) {
326 ret = -LTTNG_ERR_INVALID;
327 goto end;
328 }
329 ret = 0;
330
331 raw_str = lttng_strndup(url, PATH_MAX);
332 if (!raw_str) {
333 ret = -LTTNG_ERR_NOMEM;
334 goto end;
335 }
336
337 /* Squash old value if any */
338 free(attr->override_attr->ctrl_url);
339 free(attr->raw_override_ctrl_url);
340
341 /* Populate the object */
342 attr->override_attr->ctrl_url = url_str;
343 attr->raw_override_ctrl_url = raw_str;
344
345 /* Ownership passed to attr. */
346 url_str = NULL;
347 raw_str = NULL;
348
349 end:
350 free(raw_str);
351 free(url_str);
352 free(uri);
353 return ret;
354 }
355
356 int lttng_load_session_attr_set_override_data_url(
357 struct lttng_load_session_attr *attr, const char *url)
358 {
359 int ret = 0;
360 ssize_t ret_size;
361 struct lttng_uri *uri = NULL;
362 char *url_str = NULL;
363 char *raw_str = NULL;
364
365 if (!attr) {
366 ret = -LTTNG_ERR_INVALID;
367 goto end;
368 }
369
370 if (!attr->override_attr) {
371 attr->override_attr = zmalloc(
372 sizeof(struct config_load_session_override_attr));
373 if (!attr->override_attr) {
374 ret = -LTTNG_ERR_NOMEM;
375 goto end;
376 }
377 }
378
379 if (attr->override_attr->path_url) {
380 /*
381 * Setting a data override after a path override makes no sense.
382 */
383 ret = -LTTNG_ERR_INVALID;
384 goto end;
385 }
386
387 /*
388 * FIXME: uri_parse should be able to take as parameter the protocol
389 * type to validate "url". For now only check the parsing goes through;
390 * it will fail later on.
391 */
392 ret_size = uri_parse(url, &uri);
393 if (ret_size < 0) {
394 ret = -LTTNG_ERR_INVALID;
395 goto end;
396 }
397
398 if (uri[0].port == 0) {
399 uri[0].port = DEFAULT_NETWORK_DATA_PORT;
400 }
401
402 url_str = zmalloc(PATH_MAX);
403 if (!url_str) {
404 ret = -LTTNG_ERR_NOMEM;
405 goto end;
406 }
407
408 ret = uri_to_str_url(&uri[0], url_str, PATH_MAX);
409 if (ret < 0) {
410 ret = -LTTNG_ERR_INVALID;
411 goto end;
412 }
413 ret = 0;
414
415 raw_str = lttng_strndup(url, PATH_MAX);
416 if (!raw_str) {
417 ret = -LTTNG_ERR_NOMEM;
418 goto end;
419 }
420
421 /* Squash old value if any */
422 free(attr->override_attr->data_url);
423 free(attr->raw_override_data_url);
424
425 /* Populate the object */
426 attr->override_attr->data_url = url_str;
427 attr->raw_override_data_url = raw_str;
428
429 /* Ownership passed to attr. */
430 url_str = NULL;
431 raw_str = NULL;
432 end:
433 free(raw_str);
434 free(url_str);
435 free(uri);
436 return ret;
437 }
438
439 int lttng_load_session_attr_set_override_url(
440 struct lttng_load_session_attr *attr, const char *url)
441 {
442 int ret = 0;
443 ssize_t ret_size;
444 struct lttng_uri *uri = NULL;
445 char *raw_url_str = NULL;
446 char *raw_path_str = NULL;
447 char *path_str = NULL;
448 char *raw_ctrl_str = NULL;
449 char *ctrl_str = NULL;
450 char *raw_data_str = NULL;
451 char *data_str = NULL;
452 char buffer[PATH_MAX];
453
454 if (!attr || !url || strlen(url) >= PATH_MAX) {
455 ret = -LTTNG_ERR_INVALID;
456 goto end;
457 }
458
459 if (!attr->override_attr) {
460 attr->override_attr = zmalloc(
461 sizeof(struct config_load_session_override_attr));
462 if (!attr->override_attr) {
463 ret = -LTTNG_ERR_NOMEM;
464 goto end;
465 }
466 }
467
468 /*
469 * FIXME: uri_parse should be able to take as parameter the protocol
470 * type to validate "url". For now only check the parsing goes through;
471 * it will fail later on.
472 */
473 ret_size = uri_parse_str_urls(url, NULL, &uri);
474 if (ret_size < 0 || ret_size > 2) {
475 /* Unexpected URL format. */
476 ret = -LTTNG_ERR_INVALID;
477 goto end;
478 }
479
480 raw_url_str = lttng_strndup(url, PATH_MAX);
481 if (!raw_url_str) {
482 ret = -LTTNG_ERR_NOMEM;
483 goto end;
484 }
485
486 /* Get path | ctrl && data string URL. */
487 ret = uri_to_str_url(&uri[0], buffer, sizeof(buffer));
488 if (ret < 0 || ret >= PATH_MAX) {
489 ret = -LTTNG_ERR_INVALID;
490 goto end;
491 }
492 ret = 0;
493
494 switch (uri[0].dtype) {
495 case LTTNG_DST_PATH:
496 raw_path_str = lttng_strndup(buffer, PATH_MAX);
497 if (!raw_path_str) {
498 ret = -LTTNG_ERR_NOMEM;
499 goto end;
500 }
501
502 path_str = lttng_strndup(raw_path_str, PATH_MAX);
503 if (!path_str) {
504 ret = -LTTNG_ERR_NOMEM;
505 goto end;
506 }
507 break;
508 case LTTNG_DST_IPV4:
509 case LTTNG_DST_IPV6:
510 if (ret_size != 2) {
511 ret = -LTTNG_ERR_INVALID;
512 goto end;
513 }
514
515 raw_ctrl_str = lttng_strndup(buffer, PATH_MAX);
516 if (!raw_ctrl_str) {
517 ret = -LTTNG_ERR_NOMEM;
518 goto end;
519 }
520
521 ctrl_str = lttng_strndup(raw_ctrl_str, PATH_MAX);
522 if (!ctrl_str) {
523 ret = -LTTNG_ERR_NOMEM;
524 goto end;
525 }
526
527 /* Get the data uri. */
528 ret = uri_to_str_url(&uri[1], buffer, sizeof(buffer));
529 if (ret < 0) {
530 ret = -LTTNG_ERR_INVALID;
531 goto end;
532 }
533 ret = 0;
534
535 raw_data_str = lttng_strndup(buffer, PATH_MAX);
536 if (!raw_data_str) {
537 ret = -LTTNG_ERR_NOMEM;
538 goto end;
539 }
540
541 data_str = lttng_strndup(raw_data_str, PATH_MAX);
542 if (!data_str) {
543 ret = -LTTNG_ERR_NOMEM;
544 goto end;
545 }
546
547 break;
548 default:
549 ret = -LTTNG_ERR_INVALID;
550 goto end;
551 }
552
553 reset_load_session_attr_urls(attr);
554
555 attr->override_attr->path_url = path_str;
556 attr->override_attr->ctrl_url = ctrl_str;
557 attr->override_attr->data_url = data_str;
558
559 attr->raw_override_url = raw_url_str;
560 attr->raw_override_path_url = raw_path_str;
561 attr->raw_override_ctrl_url = raw_ctrl_str;
562 attr->raw_override_data_url = raw_data_str;
563
564 /* Pass data ownership to attr. */
565 raw_url_str = NULL;
566 raw_path_str = NULL;
567 path_str = NULL;
568 raw_ctrl_str = NULL;
569 ctrl_str = NULL;
570 raw_data_str = NULL;
571 data_str = NULL;
572
573 end:
574 free(raw_path_str);
575 free(path_str);
576 free(raw_ctrl_str);
577 free(ctrl_str);
578 free(raw_data_str);
579 free(data_str);
580 free(raw_url_str);
581 free(uri);
582 return ret;
583 }
584
585 int lttng_load_session_attr_set_override_session_name(
586 struct lttng_load_session_attr *attr, const char *session_name)
587 {
588 int ret = 0;
589 size_t len;
590
591 if (!attr ||!session_name) {
592 ret = -LTTNG_ERR_INVALID;
593 goto end;
594 }
595
596 if (!attr->override_attr) {
597 attr->override_attr = zmalloc(
598 sizeof(struct config_load_session_override_attr));
599 if (!attr->override_attr) {
600 ret = -LTTNG_ERR_NOMEM;
601 goto end;
602 }
603 }
604
605 len = strlen(session_name);
606 if (len >= LTTNG_NAME_MAX) {
607 ret = -LTTNG_ERR_INVALID;
608 goto end;
609 }
610
611 attr->override_attr->session_name = lttng_strndup(session_name,
612 len);
613 if (!attr->override_attr->session_name) {
614 ret = -LTTNG_ERR_NOMEM;
615 goto end;
616 }
617 end:
618 return ret;
619 }
620
621 int lttng_load_session(struct lttng_load_session_attr *attr)
622 {
623 int ret;
624 const char *url, *session_name;
625
626 if (!attr) {
627 ret = -LTTNG_ERR_INVALID;
628 goto end;
629 }
630
631 ret = validate_attr(attr);
632 if (ret) {
633 goto end;
634 }
635
636 url = attr->input_url[0] != '\0' ? attr->input_url : NULL;
637 session_name = attr->session_name[0] != '\0' ?
638 attr->session_name : NULL;
639
640 ret = config_load_session(url, session_name, attr->overwrite, 0,
641 attr->override_attr);
642
643 end:
644 return ret;
645 }
This page took 0.041191 seconds and 4 git commands to generate.