]> granicus.if.org Git - sysstat/blob - sadf_misc.c
sar/sadc: Get rid of volatile activities
[sysstat] / sadf_misc.c
1 /*
2  * sadf_misc.c: Funtions used by sadf to display special records
3  * (C) 2011-2017 by Sebastien GODARD (sysstat <at> orange.fr)
4  *
5  ***************************************************************************
6  * This program is free software; you can redistribute it and/or modify it *
7  * under the terms of the GNU General Public License as published  by  the *
8  * Free Software Foundation; either version 2 of the License, or (at  your *
9  * option) any later version.                                              *
10  *                                                                         *
11  * This program is distributed in the hope that it  will  be  useful,  but *
12  * WITHOUT ANY WARRANTY; without the implied warranty  of  MERCHANTABILITY *
13  * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License *
14  * for more details.                                                       *
15  *                                                                         *
16  * You should have received a copy of the GNU General Public License along *
17  * with this program; if not, write to the Free Software Foundation, Inc., *
18  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA              *
19  ***************************************************************************
20  */
21
22 #include <stdio.h>
23 #include <string.h>
24
25 #include "sadf.h"
26 #include "sa.h"
27
28 #ifdef USE_NLS
29 #include <locale.h>
30 #include <libintl.h>
31 #define _(string) gettext(string)
32 #else
33 #define _(string) (string)
34 #endif
35
36 extern unsigned int flags;
37 extern char *seps[];
38
39 /*
40  ***************************************************************************
41  * Display restart messages (database and ppc formats).
42  *
43  * IN:
44  * @cur_date    Date string of current restart message.
45  * @cur_time    Time string of current restart message.
46  * @utc         True if @cur_time is expressed in UTC.
47  * @sep         Character used as separator.
48  * @file_hdr    System activity file standard header.
49  ***************************************************************************
50  */
51 void print_dbppc_restart(char *cur_date, char *cur_time, int utc, char sep,
52                          struct file_header *file_hdr)
53 {
54         printf("%s%c-1%c", file_hdr->sa_nodename, sep, sep);
55         if (strlen(cur_date)) {
56                 printf("%s ", cur_date);
57         }
58         printf("%s", cur_time);
59         if (strlen(cur_date) && utc) {
60                 printf(" UTC");
61         }
62         printf("%cLINUX-RESTART\t(%d CPU)\n",
63                sep, file_hdr->sa_cpu_nr > 1 ? file_hdr->sa_cpu_nr - 1 : 1);
64 }
65
66 /*
67  ***************************************************************************
68  * Display restart messages (ppc format).
69  *
70  * IN:
71  * @tab         Number of tabulations (unused here).
72  * @action      Action expected from current function.
73  * @cur_date    Date string of current restart message.
74  * @cur_time    Time string of current restart message.
75  * @utc         True if @cur_time is expressed in UTC.
76  * @file_hdr    System activity file standard header.
77  ***************************************************************************
78  */
79 __printf_funct_t print_db_restart(int *tab, int action, char *cur_date,
80                                   char *cur_time, int utc, struct file_header *file_hdr)
81 {
82         /* Actions F_BEGIN and F_END ignored */
83         if (action == F_MAIN) {
84                 print_dbppc_restart(cur_date, cur_time, utc, ';', file_hdr);
85         }
86 }
87
88 /*
89  ***************************************************************************
90  * Display restart messages (database format).
91  *
92  * IN:
93  * @tab         Number of tabulations (unused here).
94  * @action      Action expected from current function.
95  * @cur_date    Date string of current restart message.
96  * @cur_time    Time string of current restart message.
97  * @utc         True if @cur_time is expressed in UTC.
98  * @file_hdr    System activity file standard header.
99  ***************************************************************************
100  */
101 __printf_funct_t print_ppc_restart(int *tab, int action, char *cur_date,
102                                    char *cur_time, int utc, struct file_header *file_hdr)
103 {
104         /* Actions F_BEGIN and F_END ignored */
105         if (action == F_MAIN) {
106                 print_dbppc_restart(cur_date, cur_time, utc, '\t', file_hdr);
107         }
108 }
109
110 /*
111  ***************************************************************************
112  * Display restart messages (XML format).
113  *
114  * IN:
115  * @tab         Number of tabulations.
116  * @action      Action expected from current function.
117  * @cur_date    Date string of current restart message.
118  * @cur_time    Time string of current restart message.
119  * @utc         True if @cur_time is expressed in UTC.
120  * @file_hdr    System activity file standard header (unused here).
121  *
122  * OUT:
123  * @tab         Number of tabulations.
124  ***************************************************************************
125  */
126 __printf_funct_t print_xml_restart(int *tab, int action, char *cur_date,
127                                    char *cur_time, int utc, struct file_header *file_hdr)
128 {
129         if (action & F_BEGIN) {
130                 xprintf((*tab)++, "<restarts>");
131         }
132         if (action & F_MAIN) {
133                 xprintf(*tab, "<boot date=\"%s\" time=\"%s\" utc=\"%d\" cpu_count=\"%d\"/>",
134                         cur_date, cur_time, utc ? 1 : 0,
135                         file_hdr->sa_cpu_nr > 1 ? file_hdr->sa_cpu_nr - 1 : 1);
136         }
137         if (action & F_END) {
138                 xprintf(--(*tab), "</restarts>");
139         }
140 }
141
142 /*
143  ***************************************************************************
144  * Display restart messages (JSON format).
145  *
146  * IN:
147  * @tab         Number of tabulations.
148  * @action      Action expected from current function.
149  * @cur_date    Date string of current restart message.
150  * @cur_time    Time string of current restart message.
151  * @utc         True if @cur_time is expressed in UTC.
152  * @file_hdr    System activity file standard header (unused here).
153  *
154  * OUT:
155  * @tab         Number of tabulations.
156  ***************************************************************************
157  */
158 __printf_funct_t print_json_restart(int *tab, int action, char *cur_date,
159                                     char *cur_time, int utc, struct file_header *file_hdr)
160 {
161         static int sep = FALSE;
162
163         if (action & F_BEGIN) {
164                 printf(",\n");
165                 xprintf((*tab)++, "\"restarts\": [");
166         }
167         if (action & F_MAIN) {
168                 if (sep) {
169                         printf(",\n");
170                 }
171                 xprintf((*tab)++, "{");
172                 xprintf(*tab, "\"boot\": {\"date\": \"%s\", \"time\": \"%s\", \"utc\": %d, \"cpu_count\": %d}",
173                         cur_date, cur_time, utc ? 1 : 0,
174                         file_hdr->sa_cpu_nr > 1 ? file_hdr->sa_cpu_nr - 1 : 1);
175                 xprintf0(--(*tab), "}");
176                 sep = TRUE;
177         }
178         if (action & F_END) {
179                 if (sep) {
180                         printf("\n");
181                         sep = FALSE;
182                 }
183                 xprintf0(--(*tab), "]");
184         }
185 }
186
187 /*
188  ***************************************************************************
189  * Display restart messages (raw format).
190  *
191  * IN:
192  * @tab         Number of tabulations (unused here).
193  * @action      Action expected from current function.
194  * @cur_date    Date string of current restart message.
195  * @cur_time    Time string of current restart message.
196  * @utc         True if @cur_time is expressed in UTC.
197  * @file_hdr    System activity file standard header (unused here).
198  ***************************************************************************
199  */
200 __printf_funct_t print_raw_restart(int *tab, int action, char *cur_date,
201                                    char *cur_time, int utc, struct file_header *file_hdr)
202 {
203         /* Actions F_BEGIN and F_END ignored */
204         if (action == F_MAIN) {
205                 printf("%s", cur_time);
206                 if (strlen(cur_date) && utc) {
207                         printf(" UTC");
208                 }
209                 printf("\tLINUX-RESTART\t(%d CPU)\n",
210                        file_hdr->sa_cpu_nr > 1 ? file_hdr->sa_cpu_nr - 1 : 1);
211         }
212 }
213
214 /*
215  ***************************************************************************
216  * Display comments (database and ppc formats).
217  *
218  * IN:
219  * @cur_date    Date string of current restart message.
220  * @cur_time    Time string of current restart message.
221  * @utc         True if @cur_time is expressed in UTC.
222  * @comment     Comment to display.
223  * @sep         Character used as separator.
224  * @file_hdr    System activity file standard header.
225  ***************************************************************************
226  */
227 void print_dbppc_comment(char *cur_date, char *cur_time, int utc,
228                          char *comment, char sep, struct file_header *file_hdr)
229 {
230         printf("%s%c-1%c", file_hdr->sa_nodename, sep, sep);
231         if (strlen(cur_date)) {
232                 printf("%s ", cur_date);
233         }
234         printf("%s", cur_time);
235         if (strlen(cur_date) && utc) {
236                 printf(" UTC");
237         }
238         printf("%cCOM %s\n", sep, comment);
239 }
240
241 /*
242  ***************************************************************************
243  * Display comments (database format).
244  *
245  * IN:
246  * @tab         Number of tabulations (unused here).
247  * @action      Action expected from current function.
248  * @cur_date    Date string of current restart message.
249  * @cur_time    Time string of current restart message.
250  * @utc         True if @cur_time is expressed in UTC.
251  * @comment     Comment to display.
252  * @file_hdr    System activity file standard header.
253  ***************************************************************************
254  */
255 __printf_funct_t print_db_comment(int *tab, int action, char *cur_date,
256                                   char *cur_time, int utc, char *comment,
257                                   struct file_header *file_hdr)
258 {
259         /* Actions F_BEGIN and F_END ignored */
260         if (action & F_MAIN) {
261                 print_dbppc_comment(cur_date, cur_time, utc, comment,
262                                     ';', file_hdr);
263         }
264 }
265
266 /*
267  ***************************************************************************
268  * Display comments (ppc format).
269  *
270  * IN:
271  * @tab         Number of tabulations (unused here).
272  * @action      Action expected from current function.
273  * @cur_date    Date string of current restart message.
274  * @cur_time    Time string of current restart message.
275  * @utc         True if @cur_time is expressed in UTC.
276  * @comment     Comment to display.
277  * @file_hdr    System activity file standard header.
278  ***************************************************************************
279  */
280 __printf_funct_t print_ppc_comment(int *tab, int action, char *cur_date,
281                                    char *cur_time, int utc, char *comment,
282                                    struct file_header *file_hdr)
283 {
284         /* Actions F_BEGIN and F_END ignored */
285         if (action & F_MAIN) {
286                 print_dbppc_comment(cur_date, cur_time, utc, comment,
287                                     '\t', file_hdr);
288         }
289 }
290
291 /*
292  ***************************************************************************
293  * Display comments (XML format).
294  *
295  * IN:
296  * @tab         Number of tabulations.
297  * @action      Action expected from current function.
298  * @cur_date    Date string of current comment.
299  * @cur_time    Time string of current comment.
300  * @utc         True if @cur_time is expressed in UTC.
301  * @comment     Comment to display.
302  * @file_hdr    System activity file standard header (unused here).
303  *
304  * OUT:
305  * @tab         Number of tabulations.
306  ***************************************************************************
307  */
308 __printf_funct_t print_xml_comment(int *tab, int action, char *cur_date,
309                                    char *cur_time, int utc, char *comment,
310                                    struct file_header *file_hdr)
311 {
312         if (action & F_BEGIN) {
313                 xprintf((*tab)++, "<comments>");
314         }
315         if (action & F_MAIN) {
316                 xprintf(*tab, "<comment date=\"%s\" time=\"%s\" utc=\"%d\" com=\"%s\"/>",
317                         cur_date, cur_time, utc ? 1 : 0, comment);
318         }
319         if (action & F_END) {
320                 xprintf(--(*tab), "</comments>");
321         }
322 }
323
324 /*
325  ***************************************************************************
326  * Display comments (JSON format).
327  *
328  * IN:
329  * @tab         Number of tabulations.
330  * @action      Action expected from current function.
331  * @cur_date    Date string of current comment.
332  * @cur_time    Time string of current comment.
333  * @utc         True if @cur_time is expressed in UTC.
334  * @comment     Comment to display.
335  * @file_hdr    System activity file standard header (unused here).
336  *
337  * OUT:
338  * @tab         Number of tabulations.
339  ***************************************************************************
340  */
341 __printf_funct_t print_json_comment(int *tab, int action, char *cur_date,
342                                     char *cur_time, int utc, char *comment,
343                                     struct file_header *file_hdr)
344 {
345         static int sep = FALSE;
346
347         if (action & F_BEGIN) {
348                 printf(",\n");
349                 xprintf((*tab)++, "\"comments\": [");
350         }
351         if (action & F_MAIN) {
352                 if (sep) {
353                         printf(",\n");
354                 }
355                 xprintf((*tab)++, "{");
356                 xprintf(*tab,
357                         "\"comment\": {\"date\": \"%s\", \"time\": \"%s\", "
358                         "\"utc\": %d, \"com\": \"%s\"}",
359                         cur_date, cur_time, utc ? 1 : 0, comment);
360                 xprintf0(--(*tab), "}");
361                 sep = TRUE;
362         }
363         if (action & F_END) {
364                 if (sep) {
365                         printf("\n");
366                         sep = FALSE;
367                 }
368                 xprintf0(--(*tab), "]");
369         }
370 }
371
372 /*
373  ***************************************************************************
374  * Display comments (raw format).
375  *
376  * IN:
377  * @tab         Number of tabulations (unused here).
378  * @action      Action expected from current function.
379  * @cur_date    Date string of current restart message.
380  * @cur_time    Time string of current restart message.
381  * @utc         True if @cur_time is expressed in UTC.
382  * @comment     Comment to display.
383  * @file_hdr    System activity file standard header (unused here).
384  ***************************************************************************
385  */
386 __printf_funct_t print_raw_comment(int *tab, int action, char *cur_date,
387                                    char *cur_time, int utc, char *comment,
388                                    struct file_header *file_hdr)
389 {
390         /* Actions F_BEGIN and F_END ignored */
391         if (action & F_MAIN) {
392                 printf("%s", cur_time);
393                 if (strlen(cur_date) && utc) {
394                         printf(" UTC");
395                 }
396                 printf("\tCOM %s\n", comment);
397         }
398 }
399
400 /*
401  ***************************************************************************
402  * Display the "statistics" part of the report (XML format).
403  *
404  * IN:
405  * @tab         Number of tabulations.
406  * @action      Action expected from current function.
407  *
408  * OUT:
409  * @tab         Number of tabulations.
410  ***************************************************************************
411  */
412 __printf_funct_t print_xml_statistics(int *tab, int action)
413 {
414         if (action & F_BEGIN) {
415                 xprintf((*tab)++, "<statistics>");
416         }
417         if (action & F_END) {
418                 xprintf(--(*tab), "</statistics>");
419         }
420 }
421
422 /*
423  ***************************************************************************
424  * Display the "statistics" part of the report (JSON format).
425  *
426  * IN:
427  * @tab         Number of tabulations.
428  * @action      Action expected from current function.
429  *
430  * OUT:
431  * @tab         Number of tabulations.
432  ***************************************************************************
433  */
434 __printf_funct_t print_json_statistics(int *tab, int action)
435 {
436         static int sep = FALSE;
437
438         if (action & F_BEGIN) {
439                 printf(",\n");
440                 xprintf((*tab)++, "\"statistics\": [");
441         }
442         if (action & F_MAIN) {
443                 if (sep) {
444                         xprintf(--(*tab), "},");
445                 }
446                 xprintf((*tab)++, "{");
447                 sep = TRUE;
448         }
449         if (action & F_END) {
450                 if (sep) {
451                         xprintf(--(*tab), "}");
452                         sep = FALSE;
453                 }
454                 xprintf0(--(*tab), "]");
455         }
456 }
457
458 /*
459  ***************************************************************************
460  * Display the "timestamp" part of the report (db and ppc format).
461  *
462  * IN:
463  * @fmt         Output format (F_DB_OUTPUT or F_PPC_OUTPUT).
464  * @file_hdr    System activity file standard header.
465  * @cur_date    Date string of current record.
466  * @cur_time    Time string of current record.
467  * @utc         True if @cur_time is expressed in UTC.
468  * @itv         Interval of time with preceding record.
469  *
470  * RETURNS:
471  * Pointer on the "timestamp" string.
472  ***************************************************************************
473  */
474 char *print_dbppc_timestamp(int fmt, struct file_header *file_hdr, char *cur_date,
475                             char *cur_time, int utc, unsigned long long itv)
476 {
477         int isdb = (fmt == F_DB_OUTPUT);
478         static char pre[80];
479         char temp[80];
480
481         /* This substring appears on every output line, preformat it here */
482         snprintf(pre, 80, "%s%s%lld%s",
483                  file_hdr->sa_nodename, seps[isdb], itv, seps[isdb]);
484         if (strlen(cur_date)) {
485                 snprintf(temp, 80, "%s%s ", pre, cur_date);
486         }
487         else {
488                 strcpy(temp, pre);
489         }
490         snprintf(pre, 80, "%s%s%s", temp, cur_time,
491                  strlen(cur_date) && utc ? " UTC" : "");
492         pre[79] = '\0';
493
494         if (DISPLAY_HORIZONTALLY(flags)) {
495                 printf("%s", pre);
496         }
497
498         return pre;
499 }
500
501 /*
502  ***************************************************************************
503  * Display the "timestamp" part of the report (ppc format).
504  *
505  * IN:
506  * @parm        Pointer on specific parameters (unused here).
507  * @action      Action expected from current function.
508  * @cur_date    Date string of current record.
509  * @cur_time    Time string of current record.
510  * @itv         Interval of time with preceding record.
511  * @file_hdr    System activity file standard header.
512  * @flags       Flags for common options.
513  *
514  * RETURNS:
515  * Pointer on the "timestamp" string.
516  ***************************************************************************
517  */
518 __tm_funct_t print_ppc_timestamp(void *parm, int action, char *cur_date,
519                                  char *cur_time, unsigned long long itv,
520                                  struct file_header *file_hdr, unsigned int flags)
521 {
522         int utc = !PRINT_LOCAL_TIME(flags) && !PRINT_TRUE_TIME(flags);
523
524         if (action & F_BEGIN) {
525                 return print_dbppc_timestamp(F_PPC_OUTPUT, file_hdr, cur_date, cur_time, utc, itv);
526         }
527         if (action & F_END) {
528                 if (DISPLAY_HORIZONTALLY(flags)) {
529                         printf("\n");
530                 }
531         }
532
533         return NULL;
534 }
535
536 /*
537  ***************************************************************************
538  * Display the "timestamp" part of the report (db format).
539  *
540  * IN:
541  * @parm        Pointer on specific parameters (unused here).
542  * @action      Action expected from current function.
543  * @cur_date    Date string of current record.
544  * @cur_time    Time string of current record.
545  * @itv         Interval of time with preceding record.
546  * @file_hdr    System activity file standard header.
547  * @flags       Flags for common options.
548  *
549  * RETURNS:
550  * Pointer on the "timestamp" string.
551  ***************************************************************************
552  */
553 __tm_funct_t print_db_timestamp(void *parm, int action, char *cur_date,
554                                 char *cur_time, unsigned long long itv,
555                                 struct file_header *file_hdr, unsigned int flags)
556 {
557         int utc = !PRINT_LOCAL_TIME(flags) && !PRINT_TRUE_TIME(flags);
558
559         if (action & F_BEGIN) {
560                 return print_dbppc_timestamp(F_DB_OUTPUT, file_hdr, cur_date, cur_time, utc, itv);
561         }
562         if (action & F_END) {
563                 if (DISPLAY_HORIZONTALLY(flags)) {
564                         printf("\n");
565                 }
566         }
567
568         return NULL;
569 }
570
571 /*
572  ***************************************************************************
573  * Display the "timestamp" part of the report (XML format).
574  *
575  * IN:
576  * @parm        Specific parameter. Here: number of tabulations.
577  * @action      Action expected from current function.
578  * @cur_date    Date string of current comment.
579  * @cur_time    Time string of current comment.
580  * @itv         Interval of time with preceding record.
581  * @file_hdr    System activity file standard header (unused here).
582  * @flags       Flags for common options.
583  ***************************************************************************
584  */
585 __tm_funct_t print_xml_timestamp(void *parm, int action, char *cur_date,
586                                  char *cur_time, unsigned long long itv,
587                                  struct file_header *file_hdr, unsigned int flags)
588 {
589         int utc = !PRINT_LOCAL_TIME(flags) && !PRINT_TRUE_TIME(flags);
590         int *tab = (int *) parm;
591
592         if (action & F_BEGIN) {
593                 xprintf((*tab)++, "<timestamp date=\"%s\" time=\"%s\" utc=\"%d\" interval=\"%llu\">",
594                         cur_date, cur_time, utc ? 1 : 0, itv);
595         }
596         if (action & F_END) {
597                 xprintf(--(*tab), "</timestamp>");
598         }
599
600         return NULL;
601 }
602
603 /*
604  ***************************************************************************
605  * Display the "timestamp" part of the report (JSON format).
606  *
607  * IN:
608  * @parm        Specific parameter. Here: number of tabulations.
609  * @action      Action expected from current function.
610  * @cur_date    Date string of current comment.
611  * @cur_time    Time string of current comment.
612  * @itv         Interval of time with preceding record.
613  * @file_hdr    System activity file standard header (unused here).
614  * @flags       Flags for common options.
615  ***************************************************************************
616  */
617 __tm_funct_t print_json_timestamp(void *parm, int action, char *cur_date,
618                                   char *cur_time, unsigned long long itv,
619                                   struct file_header *file_hdr, unsigned int flags)
620 {
621         int utc = !PRINT_LOCAL_TIME(flags) && !PRINT_TRUE_TIME(flags);
622         int *tab = (int *) parm;
623
624         if (action & F_BEGIN) {
625                 xprintf0(*tab,
626                          "\"timestamp\": {\"date\": \"%s\", \"time\": \"%s\", "
627                          "\"utc\": %d, \"interval\": %llu}",
628                          cur_date, cur_time, utc ? 1 : 0, itv);
629         }
630         if (action & F_MAIN) {
631                 printf(",\n");
632         }
633         if (action & F_END) {
634                 printf("\n");
635         }
636
637         return NULL;
638 }
639
640 /*
641  ***************************************************************************
642  * Display the "timestamp" part of the report (raw format).
643  *
644  * IN:
645  * @parm        Pointer on specific parameters (unused here).
646  * @action      Action expected from current function.
647  * @cur_date    Date string of current record.
648  * @cur_time    Time string of current record.
649  * @itv         Interval of time with preceding record (unused here).
650  * @file_hdr    System activity file standard header (unused here).
651  * @flags       Flags for common options.
652  *
653  * RETURNS:
654  * Pointer on the "timestamp" string.
655  ***************************************************************************
656  */
657 __tm_funct_t print_raw_timestamp(void *parm, int action, char *cur_date,
658                                 char *cur_time, unsigned long long itv,
659                                 struct file_header *file_hdr, unsigned int flags)
660 {
661         int utc = !PRINT_LOCAL_TIME(flags) && !PRINT_TRUE_TIME(flags);
662         static char pre[80];
663
664         if (action & F_BEGIN) {
665                 snprintf(pre, 80, "%s%s", cur_time, strlen(cur_date) && utc ? " UTC" : "");
666                 pre[79] = '\0';
667                 return pre;
668         }
669
670         return NULL;
671 }
672
673 /*
674  ***************************************************************************
675  * Display the header of the report (XML format).
676  *
677  * IN:
678  * @parm        Specific parameter. Here: number of tabulations.
679  * @action      Action expected from current function.
680  * @dfile       Name of system activity data file.
681  * @file_magic  System activity file magic header.
682  * @file_hdr    System activity file standard header.
683  * @act         Array of activities (unused here).
684  * @id_seq      Activity sequence (unused here).
685  *
686  * OUT:
687  * @parm        Number of tabulations.
688  ***************************************************************************
689  */
690 __printf_funct_t print_xml_header(void *parm, int action, char *dfile,
691                                   struct file_magic *file_magic,
692                                   struct file_header *file_hdr,
693                                   struct activity *act[], unsigned int id_seq[])
694 {
695         struct tm rectime, *loc_t;
696         char cur_time[TIMESTAMP_LEN];
697         int *tab = (int *) parm;
698
699         if (action & F_BEGIN) {
700                 printf("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
701                 printf("<!DOCTYPE sysstat PUBLIC \"DTD v%s sysstat //EN\"\n",
702                        XML_DTD_VERSION);
703                 printf("\"http://pagesperso-orange.fr/sebastien.godard/sysstat-%s.dtd\">\n",
704                        XML_DTD_VERSION);
705
706                 xprintf(*tab, "<sysstat\n"
707                               "xmlns=\"http://pagesperso-orange.fr/sebastien.godard/sysstat\"\n"
708                               "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n"
709                               "xsi:schemaLocation=\"http://pagesperso-orange.fr/sebastien.godard sysstat.xsd\">");
710
711                 xprintf(++(*tab), "<sysdata-version>%s</sysdata-version>",
712                         XML_DTD_VERSION);
713
714                 xprintf(*tab, "<host nodename=\"%s\">", file_hdr->sa_nodename);
715                 xprintf(++(*tab), "<sysname>%s</sysname>", file_hdr->sa_sysname);
716                 xprintf(*tab, "<release>%s</release>", file_hdr->sa_release);
717
718                 xprintf(*tab, "<machine>%s</machine>", file_hdr->sa_machine);
719                 xprintf(*tab, "<number-of-cpus>%d</number-of-cpus>",
720                         file_hdr->sa_cpu_nr > 1 ? file_hdr->sa_cpu_nr - 1 : 1);
721
722                 /* Fill file timestmap structure (rectime) */
723                 get_file_timestamp_struct(flags, &rectime, file_hdr);
724                 strftime(cur_time, sizeof(cur_time), "%Y-%m-%d", &rectime);
725                 xprintf(*tab, "<file-date>%s</file-date>", cur_time);
726
727                 if ((loc_t = gmtime((const time_t *) &file_hdr->sa_ust_time)) != NULL) {
728                         strftime(cur_time, sizeof(cur_time), "%T", loc_t);
729                         xprintf(*tab, "<file-utc-time>%s</file-utc-time>", cur_time);
730                 }
731
732         }
733         if (action & F_END) {
734                 xprintf(--(*tab), "</host>");
735                 xprintf(--(*tab), "</sysstat>");
736         }
737 }
738
739 /*
740  ***************************************************************************
741  * Display the header of the report (JSON format).
742  *
743  * IN:
744  * @parm        Specific parameter. Here: number of tabulations.
745  * @action      Action expected from current function.
746  * @dfile       Name of system activity data file.
747  * @file_magic  System activity file magic header.
748  * @file_hdr    System activity file standard header.
749  * @act         Array of activities (unused here).
750  * @id_seq      Activity sequence (unused here).
751  *
752  * OUT:
753  * @parm        Number of tabulations.
754  ***************************************************************************
755  */
756 __printf_funct_t print_json_header(void *parm, int action, char *dfile,
757                                    struct file_magic *file_magic,
758                                    struct file_header *file_hdr,
759                                    struct activity *act[], unsigned int id_seq[])
760 {
761         struct tm rectime, *loc_t;
762         char cur_time[TIMESTAMP_LEN];
763         int *tab = (int *) parm;
764
765         if (action & F_BEGIN) {
766                 xprintf(*tab, "{\"sysstat\": {");
767
768                 xprintf(++(*tab), "\"hosts\": [");
769                 xprintf(++(*tab), "{");
770                 xprintf(++(*tab), "\"nodename\": \"%s\",", file_hdr->sa_nodename);
771                 xprintf(*tab, "\"sysname\": \"%s\",", file_hdr->sa_sysname);
772                 xprintf(*tab, "\"release\": \"%s\",", file_hdr->sa_release);
773
774                 xprintf(*tab, "\"machine\": \"%s\",", file_hdr->sa_machine);
775                 xprintf(*tab, "\"number-of-cpus\": %d,",
776                         file_hdr->sa_cpu_nr > 1 ? file_hdr->sa_cpu_nr - 1 : 1);
777
778                 /* Fill file timestmap structure (rectime) */
779                 get_file_timestamp_struct(flags, &rectime, file_hdr);
780                 strftime(cur_time, sizeof(cur_time), "%Y-%m-%d", &rectime);
781                 xprintf0(*tab, "\"file-date\": \"%s\"", cur_time);
782
783                 if ((loc_t = gmtime((const time_t *) &file_hdr->sa_ust_time)) != NULL) {
784                         strftime(cur_time, sizeof(cur_time), "%T", loc_t);
785                         printf(",\n");
786                         xprintf0(*tab, "\"file-utc-time\": \"%s\"", cur_time);
787                 }
788
789         }
790         if (action & F_END) {
791                 printf("\n");
792                 xprintf(--(*tab), "}");
793                 xprintf(--(*tab), "]");
794                 xprintf(--(*tab), "}}");
795         }
796 }
797
798 /*
799  ***************************************************************************
800  * Display data file header.
801  *
802  * IN:
803  * @parm        Specific parameter (unused here).
804  * @action      Action expected from current function.
805  * @dfile       Name of system activity data file.
806  * @file_magic  System activity file magic header.
807  * @file_hdr    System activity file standard header.
808  * @act         Array of activities.
809  * @id_seq      Activity sequence.
810  ***************************************************************************
811  */
812 __printf_funct_t print_hdr_header(void *parm, int action, char *dfile,
813                                   struct file_magic *file_magic,
814                                   struct file_header *file_hdr,
815                                   struct activity *act[], unsigned int id_seq[])
816 {
817         int i, p;
818         struct tm rectime, *loc_t;
819         char cur_time[TIMESTAMP_LEN];
820
821         /* Actions F_MAIN and F_END ignored */
822         if (action & F_BEGIN) {
823                 printf(_("System activity data file: %s (%#x)\n"),
824                        dfile, file_magic->format_magic);
825
826                 display_sa_file_version(stdout, file_magic);
827
828                 if (file_magic->format_magic != FORMAT_MAGIC) {
829                         return;
830                 }
831
832                 printf(_("Genuine sa datafile: %s (%x)\n"),
833                        file_magic->upgraded ? _("no") : _("yes"),
834                        file_magic->upgraded);
835
836                 printf(_("Host: "));
837                 print_gal_header(localtime((const time_t *) &(file_hdr->sa_ust_time)),
838                                  file_hdr->sa_sysname, file_hdr->sa_release,
839                                  file_hdr->sa_nodename, file_hdr->sa_machine,
840                                  file_hdr->sa_cpu_nr > 1 ? file_hdr->sa_cpu_nr - 1 : 1,
841                                  PLAIN_OUTPUT);
842
843                 /* Fill file timestmap structure (rectime) */
844                 get_file_timestamp_struct(flags, &rectime, file_hdr);
845                 strftime(cur_time, sizeof(cur_time), "%Y-%m-%d", &rectime);
846                 printf(_("File date: %s\n"), cur_time);
847
848                 if ((loc_t = gmtime((const time_t *) &file_hdr->sa_ust_time)) != NULL) {
849                         printf(_("File time: "));
850                         strftime(cur_time, sizeof(cur_time), "%T", loc_t);
851                         printf("%s UTC\n", cur_time);
852                 }
853
854                 printf(_("Size of a long int: %d\n"), file_hdr->sa_sizeof_long);
855                 printf("HZ = %lu\n", file_hdr->sa_hz);
856
857                 /* Number of activities in file */
858                 printf("sa_act_nr: %u\n",
859                        file_hdr->sa_act_nr);
860
861                 printf(_("List of activities:\n"));
862
863                 for (i = 0; i < NR_ACT; i++) {
864                         if (!id_seq[i])
865                                 continue;
866
867                         p = get_activity_position(act, id_seq[i], EXIT_IF_NOT_FOUND);
868
869                         printf("%02d: %s\t(x%d)", act[p]->id, act[p]->name, act[p]->nr);
870                         if (IS_MATRIX(act[p]->options)) {
871                                 printf("\t(x%d)", act[p]->nr2);
872                         }
873                         if (act[p]->magic == ACTIVITY_MAGIC_UNKNOWN) {
874                                 printf(_("\t[Unknown activity format]"));
875                         }
876                         printf("\n");
877                 }
878         }
879 }
880
881 /*
882  ***************************************************************************
883  * Display the header of the report (SVG format).
884  *
885  * IN:
886  * @parm        Specific parameters. Here: number of rows of views to display
887  *              or canvas height entered on the command line (@graph_nr), and
888  *              max number of views on a single row (@views_per_row).
889  * @action      Action expected from current function.
890  * @dfile       Name of system activity data file (unused here).
891  * @file_magic  System activity file magic header (unused here).
892  * @file_hdr    System activity file standard header.
893  * @act         Array of activities (unused here).
894  * @id_seq      Activity sequence (unused here).
895  ***************************************************************************
896  */
897 __printf_funct_t print_svg_header(void *parm, int action, char *dfile,
898                                   struct file_magic *file_magic,
899                                   struct file_header *file_hdr,
900                                   struct activity *act[], unsigned int id_seq[])
901 {
902         struct svg_hdr_parm *hdr_parm = (struct svg_hdr_parm *) parm;
903
904         if (action & F_BEGIN) {
905                 printf("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
906                 printf("<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" ");
907                 printf("\"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n");
908                 printf("<svg xmlns=\"http://www.w3.org/2000/svg\"");
909                 if (action & F_END) {
910                         printf(">\n");
911                 }
912         }
913
914         if (action & F_MAIN) {
915                 printf(" width=\"%d\" height=\"%d\""
916                        " fill=\"black\" stroke=\"gray\" stroke-width=\"1\">\n",
917                        SVG_T_XSIZE * (hdr_parm->views_per_row),
918                        SET_CANVAS_HEIGHT(flags) ? hdr_parm->graph_nr
919                                                 : SVG_H_YSIZE + SVG_T_YSIZE * (hdr_parm->graph_nr));
920                 printf("<text x= \"0\" y=\"30\" text-anchor=\"start\" stroke=\"brown\">");
921                 print_gal_header(localtime((const time_t *) &(file_hdr->sa_ust_time)),
922                                  file_hdr->sa_sysname, file_hdr->sa_release,
923                                  file_hdr->sa_nodename, file_hdr->sa_machine,
924                                  file_hdr->sa_cpu_nr > 1 ? file_hdr->sa_cpu_nr - 1 : 1,
925                                  PLAIN_OUTPUT);
926                 printf("</text>\n");
927         }
928
929         if (action & F_END) {
930                 if (!(action & F_BEGIN)) {
931                         if (!hdr_parm->graph_nr) {
932                                 /* No views displayed */
933                                 printf("<text x= \"0\" y=\"60\" text-anchor=\"start\" stroke=\"red\">");
934                                 printf("No data!</text>\n");
935                         }
936                         /* Give actual SVG height */
937                         printf("<!-- Actual canvas height: %d -->\n",
938                                SVG_H_YSIZE + SVG_T_YSIZE * (hdr_parm->graph_nr));
939                 }
940                 printf("</svg>\n");
941         }
942 }