|
1 | 1 | /*
|
2 | 2 | gridinit, a monitor for non-daemon processes.
|
3 | 3 | Copyright (C) 2013 AtoS Worldline, original work aside of Redcurrant
|
4 |
| -Copyright (C) 2015-2018 OpenIO SAS |
| 4 | +Copyright (C) 2015-2020 OpenIO SAS |
5 | 5 |
|
6 | 6 | This program is free software: you can redistribute it and/or modify
|
7 | 7 | it under the terms of the GNU Affero General Public License as
|
@@ -291,6 +291,59 @@ read_services_list(FILE *in_stream)
|
291 | 291 | return g_list_sort(all_jobs, compare_child_info);
|
292 | 292 | }
|
293 | 293 |
|
| 294 | +static const gchar json_basic_translations[] = |
| 295 | +{ |
| 296 | + 0, 0, 0, 0, 0, 0, 0, 0, |
| 297 | + 'b', 't', 'n', 0, 'f', 'r', 0, 0, |
| 298 | +}; |
| 299 | + |
| 300 | +static gchar * str_to_json_str(const char *s0) { |
| 301 | + GString *json_str = g_string_new(""); |
| 302 | + int len = strlen(s0); |
| 303 | + for (const char *s = s0; (len < 0 && *s) || (s - s0) < len ;) { |
| 304 | + if (*s & (const char)0x80) { // (part of a) unicode character |
| 305 | + gunichar c = g_utf8_get_char_validated(s, -1); |
| 306 | + if (c == (gunichar)-1) { |
| 307 | + // something wrong happened, let the client deal with it |
| 308 | + g_string_append_c(json_str, *(s++)); |
| 309 | + } else if (c == (gunichar)-2) { |
| 310 | + // middle of a unicode character |
| 311 | + char *end = g_utf8_next_char(s); |
| 312 | + while (s < end && *s) |
| 313 | + g_string_append_c(json_str, *(s++)); |
| 314 | + } else { |
| 315 | + g_string_append_unichar(json_str, c); |
| 316 | + s = g_utf8_next_char(s); |
| 317 | + } |
| 318 | + } else if (*s < ' ') { // control character |
| 319 | + g_string_append_c(json_str, '\\'); |
| 320 | + switch (*s) { |
| 321 | + case '\b': |
| 322 | + case '\t': |
| 323 | + case '\n': |
| 324 | + case '\f': |
| 325 | + case '\r': |
| 326 | + g_string_append_c(json_str, json_basic_translations[(int)*(s++)]); |
| 327 | + break; |
| 328 | + default: |
| 329 | + g_string_append_printf(json_str, "u%04x", *(s++)); |
| 330 | + break; |
| 331 | + } |
| 332 | + } else { // printable ASCII character |
| 333 | + switch (*s) { |
| 334 | + case '"': |
| 335 | + case '\\': |
| 336 | + case '/': |
| 337 | + g_string_append_c(json_str, '\\'); |
| 338 | + /* FALLTHROUGH */ |
| 339 | + default: |
| 340 | + g_string_append_c(json_str, *(s++)); |
| 341 | + break; |
| 342 | + } |
| 343 | + } |
| 344 | + } |
| 345 | + return g_string_free(json_str, FALSE); |
| 346 | +} |
294 | 347 |
|
295 | 348 | static void
|
296 | 349 | dump_as_is(FILE *in_stream, void *udata)
|
@@ -342,7 +395,14 @@ dump_as_is(FILE *in_stream, void *udata)
|
342 | 395 | case JSON:
|
343 | 396 | if(!first)
|
344 | 397 | fprintf(stdout, ",\n");
|
345 |
| - fprintf(stdout, "{\"status\": \"%s\",\"start\": \"%s\",\"error\": \"%s\"}\n", status, start, error); |
| 398 | + gchar *json_str_status = str_to_json_str(status); |
| 399 | + gchar *json_str_start = str_to_json_str(start); |
| 400 | + gchar *json_str_error = str_to_json_str(error); |
| 401 | + fprintf(stdout, "{\"status\": \"%s\",\"start\": \"%s\",\"error\": \"%s\"}\n", |
| 402 | + json_str_status, json_str_start, json_str_error); |
| 403 | + g_free(json_str_status); |
| 404 | + g_free(json_str_start); |
| 405 | + g_free(json_str_error); |
346 | 406 | break;
|
347 | 407 | case CSV:
|
348 | 408 | fprintf(stdout, "%s,%s,%s\n", status, start, error);
|
@@ -548,10 +608,30 @@ command_status(int lvl, int argc, char **args)
|
548 | 608 | if (format_t == JSON && count_all > 1)
|
549 | 609 | fputs(",", stdout);
|
550 | 610 |
|
551 |
| - fprintf(stdout, fmt_line, ci->key, str_status, ci->pid, |
552 |
| - ci->counter_started, ci->counter_died, |
553 |
| - ci->rlimits.core_size, ci->rlimits.stack_size, |
554 |
| - ci->rlimits.nb_files, str_time, ci->group, ci->cmd); |
| 611 | + gchar *json_str_key = NULL; |
| 612 | + gchar *json_str_status = NULL; |
| 613 | + gchar *json_str_time = NULL; |
| 614 | + gchar *json_str_group = NULL; |
| 615 | + gchar *json_str_cmd = NULL; |
| 616 | + if (format_t == JSON) { |
| 617 | + json_str_key = str_to_json_str(ci->key); |
| 618 | + json_str_status = str_to_json_str(str_status); |
| 619 | + json_str_time = str_to_json_str(str_time); |
| 620 | + json_str_group = str_to_json_str(ci->group); |
| 621 | + json_str_cmd = str_to_json_str(ci->cmd); |
| 622 | + } |
| 623 | + |
| 624 | + fprintf(stdout, fmt_line, json_str_key?:ci->key, |
| 625 | + json_str_status?:str_status, ci->pid, ci->counter_started, |
| 626 | + ci->counter_died, ci->rlimits.core_size, ci->rlimits.stack_size, |
| 627 | + ci->rlimits.nb_files, json_str_time?:str_time, |
| 628 | + json_str_group?:ci->group, json_str_cmd?:ci->cmd); |
| 629 | + |
| 630 | + g_free(json_str_key); |
| 631 | + g_free(json_str_status); |
| 632 | + g_free(json_str_time); |
| 633 | + g_free(json_str_group); |
| 634 | + g_free(json_str_cmd); |
555 | 635 | } else {
|
556 | 636 | switch (lvl) {
|
557 | 637 | case 0:
|
|
0 commit comments