@@ -48,6 +48,7 @@ static gboolean flag_help = FALSE;
48
48
static gchar sock_path [1024 ];
49
49
static gchar line [65536 ];
50
50
static gboolean flag_color = FALSE;
51
+ static gboolean flag_json = FALSE;
51
52
52
53
#define BOOL (i ) (i?1:0)
53
54
@@ -275,6 +276,62 @@ dump_as_is(FILE *in_stream, void *udata)
275
276
fflush (stdout );
276
277
}
277
278
279
+
280
+ static void
281
+ print_as_json (gchar * status , gchar * start , gchar * error )
282
+ {
283
+ gchar header [] = " {\n" ;
284
+ gchar footer [] = " }" ;
285
+ gchar tab [] = " " ;
286
+
287
+ fprintf (stdout , "%s" , header );
288
+ fprintf (stdout , "%s\"status\": \"%s\",\n" , tab , status );
289
+ fprintf (stdout , "%s\"start\": \"%s\",\n" , tab , start );
290
+ fprintf (stdout , "%s\"error\": \"%s\",\n" , tab , error );
291
+ fprintf (stdout , "%s" , footer );
292
+ }
293
+
294
+ static void
295
+ dump_as_json (FILE * in_stream , void * udata )
296
+ {
297
+ gchar * start , * status ;
298
+ int code , first = 1 ;
299
+ gchar head [] = "[\n" ;
300
+ gchar footer [] = "\n]\n" ;
301
+ struct keyword_set_s * kw ;
302
+ struct dump_as_is_arg_s * dump_args ;
303
+
304
+ kw = flag_color ? & KEYWORDS_COLOR : & KEYWORDS_NORMAL ;
305
+
306
+ dump_args = udata ;
307
+ fprintf (stdout , "%s" , head );
308
+ while (!feof (in_stream ) && !ferror (in_stream )) {
309
+ bzero (line , sizeof (line ));
310
+ if (NULL != fgets (line , sizeof (line ), in_stream )) {
311
+ start = NULL ;
312
+ (void )unpack_line (line , & start , & code );
313
+
314
+ if (dump_args ) {
315
+ if (code == 0 || code == EALREADY )
316
+ dump_args -> count_success ++ ;
317
+ else
318
+ dump_args -> count_errors ++ ;
319
+ }
320
+ if (!first )
321
+ fprintf (stdout , ",\n" );
322
+ first = 0 ;
323
+ status = (gchar * )(code == 0 ? kw -> done : (code == EALREADY ?kw -> already :kw -> failed ));
324
+ print_as_json (status , start , strerror (code ));
325
+ }
326
+ }
327
+ fprintf (stdout , "%s" , footer );
328
+ fflush (stdout );
329
+ }
330
+
331
+
332
+
333
+
334
+
278
335
static FILE *
279
336
open_cnx (void )
280
337
{
@@ -483,29 +540,143 @@ command_status(int lvl, int argc, char **args)
483
540
return rc ;
484
541
}
485
542
543
+
544
+ static int
545
+ command_status_json (int lvl , int argc , char * * args )
546
+ {
547
+ char fmt_line [256 ];
548
+
549
+ int * counters = alloca (sizeof (int ) * (argc + 1 ));
550
+ memset (counters , 0 , sizeof (int ) * (argc + 1 ));
551
+
552
+ GList * all_jobs = _fetch_services ();
553
+ GList * jobs = _filter_services (all_jobs , args , counters );
554
+
555
+ fprintf (stdout , "[\n" );
556
+ char fmt_str []= " \"%s\": \"%s\",\n" ;
557
+ char fmt_int []= " \"%s\": \"%d\",\n" ;
558
+ char fmt_lint []= " \"%s\": \"%ld\",\n" ;
559
+ switch (lvl ) {
560
+ case 0 :
561
+ g_snprintf (fmt_line , sizeof (fmt_line ),
562
+ " {\n%s%s%s%s\n }" ,
563
+ fmt_str , fmt_str , fmt_int , fmt_str );
564
+ break ;
565
+ case 1 :
566
+ g_snprintf (fmt_line , sizeof (fmt_line ),
567
+ " {\n%s%s%s%s%s%s%s%s\n }" ,
568
+ fmt_str , fmt_str , fmt_int , fmt_int ,
569
+ fmt_int , fmt_str , fmt_str , fmt_str );
570
+ break ;
571
+ default :
572
+ g_snprintf (fmt_line , sizeof (fmt_line ),
573
+ " {\n%s%s%s%s%s%s%s%s%s%s%s\n }" ,
574
+ fmt_str , fmt_str , fmt_int , fmt_int , fmt_int ,
575
+ fmt_lint ,fmt_lint ,fmt_lint ,fmt_str , fmt_str ,
576
+ fmt_str
577
+ );
578
+ break ;
579
+ }
580
+
581
+ int count_faulty = 0 , count_all = 0 , count_misses = 0 ;
582
+
583
+ /* iterate on the lines */
584
+ for (GList * l = jobs ; l ;l = l -> next ) {
585
+ char str_time [20 ] = "---------- --------" ;
586
+ const char * str_status = "-" ;
587
+ struct child_info_s * ci = NULL ;
588
+ gboolean faulty = FALSE;
589
+ ci = l -> data ;
590
+
591
+ /* Prepare some fields */
592
+ if (ci -> pid > 0 )
593
+ strftime (str_time , sizeof (str_time ), "%Y-%m-%d %H:%M:%S" ,
594
+ gmtime (& (ci -> last_start_attempt )));
595
+ str_status = get_child_status (ci , & faulty );
596
+
597
+ /* Manage counters */
598
+ if (faulty )
599
+ count_faulty ++ ;
600
+ count_all ++ ;
601
+
602
+ /* Print now! */
603
+ if (count_all - 1 )
604
+ fprintf (stdout , ",\n" );
605
+
606
+ switch (lvl ) {
607
+ case 0 :
608
+
609
+ fprintf (stdout , fmt_line ,
610
+ "key" , ci -> key , "status" , str_status ,
611
+ "pid" , ci -> pid ,"group" , ci -> group );
612
+ break ;
613
+ case 1 :
614
+ fprintf (stdout , fmt_line ,
615
+ "key" , ci -> key , "status" , str_status ,
616
+ "pid" , ci -> pid , "#start" , ci -> counter_started ,
617
+ "#died" , ci -> counter_died , "since" , str_time ,
618
+ "group" , ci -> group , "cmd" , ci -> cmd );
619
+ break ;
620
+ default :
621
+ fprintf (stdout , fmt_line ,
622
+ "key" , ci -> key , "status" , str_status ,
623
+ "pid" , ci -> pid , "#start" , ci -> counter_started ,
624
+ "#died" , ci -> counter_died , "csz" , ci -> rlimits .core_size ,
625
+ "ssz" , ci -> rlimits .stack_size , "mfd" , ci -> rlimits .nb_files ,
626
+ "since" , str_time , "group" , ci -> group ,
627
+ "cmd" , ci -> cmd );
628
+ break ;
629
+ }
630
+ }
631
+
632
+ fprintf (stdout , "\n]\n" );
633
+ fflush (stdout );
634
+
635
+ /* If patterns have been specified, we must find items (the user
636
+ * expects something to show up */
637
+ for (int i = 0 ; i < argc ;i ++ ) {
638
+ if (!counters [i ])
639
+ count_misses ++ ;
640
+ }
641
+
642
+ g_list_free_full (all_jobs , (GDestroyNotify )child_info_free );
643
+ g_list_free (jobs );
644
+
645
+ return !(!count_misses && !count_faulty && (!argc || count_all > 0 ));
646
+ }
647
+
486
648
static int
487
649
command_status0 (int argc , char * * args )
488
650
{
651
+ if (flag_json )
652
+ return command_status_json (0 , argc , args );
489
653
return command_status (0 , argc , args );
490
654
}
491
655
492
656
static int
493
657
command_status1 (int argc , char * * args )
494
658
{
659
+ if (flag_json )
660
+ return command_status_json (1 , argc , args );
495
661
return command_status (1 , argc , args );
496
662
}
497
663
498
664
static int
499
665
command_status2 (int argc , char * * args )
500
666
{
667
+ if (flag_json )
668
+ return command_status_json (2 , argc , args );
501
669
return command_status (2 , argc , args );
502
670
}
503
671
504
672
static int
505
673
command_start (int argc , char * * args )
506
674
{
507
675
struct dump_as_is_arg_s dump_args = {};
508
- int rc = send_commandv (dump_as_is , & dump_args , "start" , argc , args );
676
+ void * dumper = dump_as_is ;
677
+
678
+ if (flag_json ) dumper = dump_as_json ;
679
+ int rc = send_commandv (dumper , & dump_args , "start" , argc , args );
509
680
return !rc
510
681
|| dump_args .count_errors != 0
511
682
|| dump_args .count_success == 0 ;
@@ -515,7 +686,10 @@ static int
515
686
command_kill (int argc , char * * args )
516
687
{
517
688
struct dump_as_is_arg_s dump_args = {};
518
- int rc = send_commandv (dump_as_is , & dump_args , "stop" , argc , args );
689
+ void * dumper = dump_as_is ;
690
+
691
+ if (flag_json ) dumper = dump_as_json ;
692
+ int rc = send_commandv (dumper , & dump_args , "stop" , argc , args );
519
693
return !rc
520
694
|| dump_args .count_errors != 0
521
695
|| dump_args .count_success == 0 ;
@@ -539,7 +713,8 @@ command_stop(int argc, char **args)
539
713
}
540
714
541
715
while (!_all_down ()) {
542
- g_print ("# Stopping...\n" );
716
+ if (!flag_json )
717
+ g_print ("# Stopping...\n" );
543
718
int rc = command_kill (argc , args );
544
719
if (rc != 0 )
545
720
return rc ;
@@ -552,7 +727,10 @@ static int
552
727
command_restart (int argc , char * * args )
553
728
{
554
729
struct dump_as_is_arg_s dump_args = {};
555
- int rc = send_commandv (dump_as_is , & dump_args , "restart" , argc , args );
730
+ void * dumper = dump_as_is ;
731
+
732
+ if (flag_json ) dumper = dump_as_json ;
733
+ int rc = send_commandv (dumper , & dump_args , "restart" , argc , args );
556
734
return !rc
557
735
|| dump_args .count_errors != 0
558
736
|| dump_args .count_success == 0 ;
@@ -562,7 +740,10 @@ static int
562
740
command_repair (int argc , char * * args )
563
741
{
564
742
struct dump_as_is_arg_s dump_args = {};
565
- int rc = send_commandv (dump_as_is , & dump_args , "repair" , argc , args );
743
+ void * dumper = dump_as_is ;
744
+
745
+ if (flag_json ) dumper = dump_as_json ;
746
+ int rc = send_commandv (dumper , & dump_args , "repair" , argc , args );
566
747
return !rc
567
748
|| dump_args .count_errors != 0
568
749
|| dump_args .count_success == 0 ;
@@ -572,8 +753,11 @@ static int
572
753
command_reload (int argc , char * * args )
573
754
{
574
755
struct dump_as_is_arg_s dump_args = {};
756
+ void * dumper = dump_as_is ;
575
757
(void ) argc , (void ) args ;
576
- int rc = send_commandv (dump_as_is , & dump_args , "reload" , 0 , (char * []){NULL });
758
+
759
+ if (flag_json ) dumper = dump_as_json ;
760
+ int rc = send_commandv (dumper , & dump_args , "reload" , 0 , (char * []){NULL });
577
761
return !rc
578
762
|| dump_args .count_errors != 0
579
763
|| dump_args .count_success == 0 ;
@@ -605,7 +789,7 @@ main_options(int argc, char **args)
605
789
606
790
g_strlcpy (sock_path , GRIDINIT_SOCK_PATH , sizeof (sock_path ));
607
791
608
- while ((opt = getopt (argc , args , "chS :" )) != -1 ) {
792
+ while ((opt = getopt (argc , args , "chjS :" )) != -1 ) {
609
793
switch (opt ) {
610
794
case 'c' :
611
795
flag_color = TRUE;
@@ -617,6 +801,9 @@ main_options(int argc, char **args)
617
801
case 'h' :
618
802
flag_help = TRUE;
619
803
break ;
804
+ case 'j' :
805
+ flag_json = TRUE;
806
+ break ;
620
807
}
621
808
}
622
809
@@ -627,11 +814,12 @@ static void
627
814
help (char * * args )
628
815
{
629
816
close (2 );
630
- g_print ("Usage: %s [-h|-c|-S SOCK]... (status{,2,3}|start|stop|reload|repair) [ID...]\n" , args [0 ]);
817
+ g_print ("Usage: %s [-h|-c|-j|- S SOCK]... (status{,2,3}|start|stop|reload|repair) [ID...]\n" , args [0 ]);
631
818
g_print ("\n OPTIONS:\n" );
632
819
g_print (" -c : coloured display\n" );
633
820
g_print (" -h : displays a little help section\n" );
634
821
g_print (" -S SOCK : explicit unix socket path\n" );
822
+ g_print (" -j : output result by json\n" );
635
823
g_print ("\n COMMANDS:\n" );
636
824
g_print (" status* : Displays the status of the given processes or groups\n" );
637
825
g_print (" start : Starts the given processes or groups, even if broken\n" );
0 commit comments