]> granicus.if.org Git - sysstat/blob - sa_conv.c
Check untrusted values before use
[sysstat] / sa_conv.c
1 /*
2  * sa_conv.c: Convert an old format sa file to the up-to-date format.
3  * (C) 1999-2020 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 #include <stdlib.h>
25 #include <unistd.h>
26 #include <errno.h>
27
28 #include "version.h"
29 #include "sadf.h"
30 #include "sa_conv.h"
31
32 #ifdef USE_NLS
33 # include <locale.h>
34 # include <libintl.h>
35 # define _(string) gettext(string)
36 #else
37 # define _(string) (string)
38 #endif
39
40 extern int endian_mismatch;
41 extern unsigned int user_hz;
42 extern unsigned int act_types_nr[];
43 extern unsigned int rec_types_nr[];
44 extern unsigned int hdr_types_nr[];
45
46 unsigned int oact_types_nr[] = {OLD_FILE_ACTIVITY_ULL_NR, OLD_FILE_ACTIVITY_UL_NR, OLD_FILE_ACTIVITY_U_NR};
47
48 /*
49  ***************************************************************************
50  * Read and upgrade file's magic data section.
51  *
52  * IN:
53  * @dfile       System activity data file name.
54  * @stdfd       File descriptor for STDOUT.
55  *
56  * OUT:
57  * @fd          File descriptor for sa datafile to convert.
58  * @file_magic  File's magic structure.
59  * @hdr_size    Size of header structure read from file.
60  * @previous_format
61  *              Format magic number of file to convert, converted to
62  *              current endianness.
63  * @endian_mismatch
64  *              TRUE if data read from file don't match current machine's
65  *              endianness.
66  *
67  * RETURNS:
68  * -1 on error, 0 otherwise.
69  ***************************************************************************
70  */
71 int upgrade_magic_section(char dfile[], int *fd, int stdfd, struct file_magic *file_magic,
72                           unsigned int *hdr_size, int *previous_format, int *endian_mismatch)
73 {
74         struct file_magic fm;
75         unsigned int fm_types_nr[] = {FILE_MAGIC_ULL_NR, FILE_MAGIC_UL_NR, FILE_MAGIC_U_NR};
76
77         /* Open and read sa magic structure */
78         sa_open_read_magic(fd, dfile, file_magic, TRUE, endian_mismatch, FALSE);
79
80         switch (file_magic->format_magic) {
81
82                 case FORMAT_MAGIC:
83                 case FORMAT_MAGIC_SWAPPED:
84                         *previous_format = FORMAT_MAGIC;
85                         return 0;
86                         break;
87
88                 case FORMAT_MAGIC_2171:
89                 case FORMAT_MAGIC_2171_SWAPPED:
90                         *previous_format = FORMAT_MAGIC_2171;
91                         break;
92
93                 case FORMAT_MAGIC_2173:
94                 case FORMAT_MAGIC_2173_SWAPPED:
95                         *previous_format = FORMAT_MAGIC_2173;
96                         break;
97
98                 default:
99                         fprintf(stderr, _("Cannot convert the format of this file\n"));
100                         return -1;
101                         break;
102         }
103
104         fprintf(stderr, "file_magic: ");
105         if (*previous_format == FORMAT_MAGIC_2171) {
106                 /*
107                  * We have read too many bytes: file_magic structure
108                  * was smaller with previous sysstat versions.
109                  * Go back 4 (unsigned int header_size) + 64 (char pad[64]) bytes.
110                  */
111                 if (lseek(*fd, -68, SEEK_CUR) < 0) {
112                         fprintf(stderr, "\nlseek: %s\n", strerror(errno));
113                         return -1;
114                 }
115         }
116
117         /* Set format magic number to that of current version */
118         file_magic->format_magic = (*endian_mismatch ? FORMAT_MAGIC_SWAPPED
119                                                      : FORMAT_MAGIC);
120
121         /* Save original header structure's size */
122         *hdr_size = file_magic->header_size;
123
124         /* Fill new structure members */
125         file_magic->header_size = FILE_HEADER_SIZE;
126         file_magic->hdr_types_nr[0] = FILE_HEADER_ULL_NR;
127         file_magic->hdr_types_nr[1] = FILE_HEADER_UL_NR;
128         file_magic->hdr_types_nr[2] = FILE_HEADER_U_NR;
129         memset(file_magic->pad, 0, sizeof(unsigned char) * FILE_MAGIC_PADDING);
130
131         /* Indicate that file has been upgraded */
132         enum_version_nr(&fm);
133         file_magic->upgraded = (fm.sysstat_patchlevel << 8) +
134                                fm.sysstat_sublevel + 1;
135
136         memcpy(&fm, file_magic, FILE_MAGIC_SIZE);
137         /* Restore endianness before writing */
138         if (*endian_mismatch) {
139                 /* Start swapping at field "header_size" position */
140                 swap_struct(fm_types_nr, &(fm.header_size), 0);
141         }
142
143         /* Write file's magic structure */
144         if (write_all(stdfd, &fm, FILE_MAGIC_SIZE) != FILE_MAGIC_SIZE) {
145                 fprintf(stderr, "\nwrite: %s\n", strerror(errno));
146                 return -1;
147         }
148         fprintf(stderr, "OK\n");
149
150         return 0;
151 }
152
153 /*
154  ***************************************************************************
155  * Upgrade file_header structure (from 0x2171 format to current format).
156  *
157  * IN:
158  * @buffer      File's header structure (as read from file).
159  * @previous_format
160  *              Format magic number of file to convert.
161  * @endian_mismatch
162  *              TRUE if data read from file don't match current
163  *              machine's endianness.
164  *
165  * OUT:
166  * @file_hdr    File's header structure (up-to-date format).
167  * @arch_64     TRUE if file's data come from a 64-bit machine.
168  * @vol_act_nr  Number of volatile activity structures following a restart
169  *              record for 0x2173 file format.
170  ***************************************************************************
171  */
172 void upgrade_file_header(void *buffer, struct file_header *file_hdr, int previous_format,
173                          int endian_mismatch, int *arch_64, unsigned int *vol_act_nr)
174 {
175         struct file_header_2171 *f_hdr_2171 = (struct file_header_2171 *) buffer;
176         struct file_header_2173 *f_hdr_2173 = (struct file_header_2173 *) buffer;
177         unsigned int hdr_2171_types_nr[] = {FILE_HEADER_2171_ULL_NR, FILE_HEADER_2171_UL_NR, FILE_HEADER_2171_U_NR};
178         unsigned int hdr_2173_types_nr[] = {FILE_HEADER_2173_ULL_NR, FILE_HEADER_2173_UL_NR, FILE_HEADER_2173_U_NR};
179         int i;
180
181         memset(file_hdr, 0, FILE_HEADER_SIZE);
182         file_hdr->sa_hz = HZ;
183
184         if (previous_format == FORMAT_MAGIC_2171) {
185                 *arch_64 = (f_hdr_2171->sa_sizeof_long == SIZEOF_LONG_64BIT);
186
187                 /* Normalize endianness for f_hdr_2171 structure */
188                 if (endian_mismatch) {
189                         swap_struct(hdr_2171_types_nr, f_hdr_2171, *arch_64);
190                 }
191
192                 file_hdr->sa_ust_time = (unsigned long long) f_hdr_2171->sa_ust_time;
193                 /* sa_cpu_nr field will be updated later */
194                 file_hdr->sa_act_nr = f_hdr_2171->sa_act_nr;
195                 file_hdr->sa_year = (int) f_hdr_2171->sa_year;
196                 file_hdr->sa_day = f_hdr_2171->sa_day;
197                 file_hdr->sa_month = f_hdr_2171->sa_month;
198                 file_hdr->sa_sizeof_long = f_hdr_2171->sa_sizeof_long;
199                 strncpy(file_hdr->sa_sysname, f_hdr_2171->sa_sysname, sizeof(file_hdr->sa_sysname));
200                 file_hdr->sa_sysname[sizeof(file_hdr->sa_sysname) - 1] = '\0';
201                 strncpy(file_hdr->sa_nodename, f_hdr_2171->sa_nodename, sizeof(file_hdr->sa_nodename));
202                 file_hdr->sa_nodename[sizeof(file_hdr->sa_nodename) - 1] = '\0';
203                 strncpy(file_hdr->sa_release, f_hdr_2171->sa_release, sizeof(file_hdr->sa_release));
204                 file_hdr->sa_release[sizeof(file_hdr->sa_release) - 1] = '\0';
205                 strncpy(file_hdr->sa_machine, f_hdr_2171->sa_machine, sizeof(file_hdr->sa_machine));
206                 file_hdr->sa_machine[sizeof(file_hdr->sa_machine) - 1] = '\0';
207         }
208
209         else if (previous_format == FORMAT_MAGIC_2173) {
210                 *arch_64 = (f_hdr_2173->sa_sizeof_long == SIZEOF_LONG_64BIT);
211
212                 /* Normalize endianness for f_hdr_2171 structure */
213                 if (endian_mismatch) {
214                         swap_struct(hdr_2173_types_nr, f_hdr_2173, *arch_64);
215                 }
216
217                 file_hdr->sa_ust_time = (unsigned long long) f_hdr_2173->sa_ust_time;
218                 /* sa_cpu_nr field will be updated later */
219                 file_hdr->sa_act_nr = f_hdr_2173->sa_act_nr;
220                 file_hdr->sa_year = (int) f_hdr_2173->sa_year;
221                 file_hdr->sa_day = f_hdr_2173->sa_day;
222                 file_hdr->sa_month = f_hdr_2173->sa_month;
223                 file_hdr->sa_sizeof_long = f_hdr_2173->sa_sizeof_long;
224                 strncpy(file_hdr->sa_sysname, f_hdr_2173->sa_sysname, UTSNAME_LEN);
225                 file_hdr->sa_sysname[UTSNAME_LEN - 1] = '\0';
226                 strncpy(file_hdr->sa_nodename, f_hdr_2173->sa_nodename, UTSNAME_LEN);
227                 file_hdr->sa_nodename[UTSNAME_LEN - 1] = '\0';
228                 strncpy(file_hdr->sa_release, f_hdr_2173->sa_release, UTSNAME_LEN);
229                 file_hdr->sa_release[UTSNAME_LEN - 1] = '\0';
230                 strncpy(file_hdr->sa_machine, f_hdr_2173->sa_machine, UTSNAME_LEN);
231                 file_hdr->sa_machine[UTSNAME_LEN - 1] = '\0';
232
233                 *vol_act_nr = f_hdr_2173->sa_vol_act_nr;
234         }
235
236         for (i = 0; i < 3; i++) {
237                 file_hdr->act_types_nr[i] = act_types_nr[i];
238                 file_hdr->rec_types_nr[i] = rec_types_nr[i];
239         }
240         file_hdr->act_size = FILE_ACTIVITY_SIZE;
241         file_hdr->rec_size = RECORD_HEADER_SIZE;
242
243         /*
244          * Note: @extra_next and @sa_tzname[] members are set to zero
245          * because file_hdr has been memset'd to zero.
246          */
247 }
248
249 /*
250  ***************************************************************************
251  * Read and upgrade file's header section.
252  *
253  * IN:
254  * @dfile       System activity data file name.
255  * @fd          File descriptor for sa datafile to convert.
256  * @stdfd       File descriptor for STDOUT.
257  * @act         Array of activities.
258  * @file_magic  File's magic structure.
259  * @hdr_size    Size of header structure read from file.
260  * @previous_format
261  *              Format magic number of file to convert.
262  * @endian_mismatch
263  *              TRUE if data read from file don't match current machine's
264  *              endianness.
265  *
266  * OUT:
267  * @file_hdr    File's header structure (up-to-date format).
268  * @arch_64     TRUE if file's data come from a 64-bit machine.
269  * @vol_act_nr  Number of volatile activity structures following a restart
270  *              record for 0x2173 file format.
271  * @ofile_actlst
272  *              Activity list in file.
273  *
274  * RETURNS:
275  * -1 on error, 0 otherwise.
276 ***************************************************************************
277  */
278 int upgrade_header_section(char dfile[], int fd, int stdfd, struct activity *act[],
279                            struct file_magic *file_magic, struct file_header *file_hdr,
280                            unsigned int hdr_size, int previous_format, int *arch_64,
281                            int endian_mismatch, unsigned int *vol_act_nr,
282                            struct old_file_activity **ofile_actlst)
283 {
284         struct old_file_activity *ofal;
285         struct file_header fh;
286         int i, n, p;
287         unsigned int a_cpu = FALSE;
288         void *buffer = NULL;
289
290         fprintf(stderr, "file_header: ");
291
292         /* Read file header structure */
293         n = (previous_format == FORMAT_MAGIC_2171 ? FILE_HEADER_SIZE_2171
294                                                   : hdr_size);
295         SREALLOC(buffer, char, n);
296         sa_fread(fd, buffer, (size_t) n, HARD_SIZE, UEOF_STOP);
297
298         /* Upgrade file_header structure */
299         upgrade_file_header(buffer, file_hdr, previous_format,
300                             endian_mismatch, arch_64, vol_act_nr);
301
302         free(buffer);
303
304         /* Sanity check */
305         if (file_hdr->sa_act_nr > MAX_NR_ACT)
306                 goto invalid_header;
307
308         /* Read file activity list */
309         SREALLOC(*ofile_actlst, struct old_file_activity, OLD_FILE_ACTIVITY_SIZE * file_hdr->sa_act_nr);
310         ofal = *ofile_actlst;
311
312         for (i = 0; i < file_hdr->sa_act_nr; i++, ofal++) {
313
314                 sa_fread(fd, ofal, OLD_FILE_ACTIVITY_SIZE, HARD_SIZE, UEOF_STOP);
315
316                 /* Normalize endianness for file_activity structures */
317                 if (endian_mismatch) {
318                         swap_struct(oact_types_nr, ofal, *arch_64);
319                 }
320
321                 if ((ofal->nr < 1) || (ofal->nr2 < 1))
322                         /*
323                          * Every activity, known or unknown,
324                          * should have at least one item and sub-item.
325                          */
326                         goto invalid_header;
327
328                 if ((p = get_activity_position(act, ofal->id, RESUME_IF_NOT_FOUND)) >= 0) {
329                         /* This is a known activity, maybe with an unknown format */
330
331                         if ((ofal->id == A_CPU) && !a_cpu) {
332                                 /*
333                                  * We have found the CPU activity: Set sa_cpu_nr field
334                                  * in file_header structure that should contains the
335                                  * number of CPU when the file was created.
336                                  */
337                                 file_hdr->sa_cpu_nr = ofal->nr;
338                                 a_cpu = TRUE;
339                         }
340
341                         /* Sanity checks */
342                         if (!ofal->size || (ofal->size > MAX_ITEM_STRUCT_SIZE))
343                                 goto invalid_header;
344
345                         /* Size of activity in file is larger than up-to-date activity size */
346                         if (ofal->size > act[p]->msize) {
347                                 act[p]->msize = ofal->size;
348                         }
349
350                         /*
351                          * When upgrading a file:
352                          * ofal->size   : Size of an item for current activity, as
353                          *                read from the file.
354                          * act[p]->msize: Size of the buffer in memory where an item
355                          *                for current activity, as read from the file,
356                          *                will be saved. We have:
357                          *                act[p]->msize >= {ofal->size ; act[p]->fsize}
358                          * act[p]->fsize: Size of an item for current activity with
359                          *                up-to-date format.
360                          */
361                         act[p]->nr_ini = ofal->nr;
362                         act[p]->nr2    = ofal->nr2;
363                         /*
364                          * Don't set act[p]->fsize! Should retain the size of an item
365                          * for up-to-date format!
366                          */
367                 }
368         }
369
370         if (!a_cpu) {
371                 /*
372                  * CPU activity should always be in file for versions older than 11.7.1
373                  * and have a known format (expected magical number).
374                  */
375                 fprintf(stderr, _("\nCPU activity not found in file. Aborting...\n"));
376                 return -1;
377         }
378
379         memcpy(&fh, file_hdr, FILE_HEADER_SIZE);
380         /* Restore endianness before writing */
381         if (endian_mismatch) {
382                 /* Start swapping at field "header_size" position */
383                 swap_struct(hdr_types_nr, &fh, *arch_64);
384         }
385
386         /* Write file_header structure */
387         if ((n = write_all(stdfd, &fh, FILE_HEADER_SIZE)) != FILE_HEADER_SIZE) {
388                 fprintf(stderr, "\nwrite: %s\n", strerror(errno));
389                 return -1;
390         }
391
392         fprintf(stderr, "OK\n");
393
394         return 0;
395
396 invalid_header:
397
398         fprintf(stderr, _("\nInvalid data found. Aborting...\n"));
399
400         return -1;
401
402 }
403
404 /*
405  ***************************************************************************
406  * Convert a long integer value to a long long integer value.
407  * The long integer value may be 32 or 64-bit wide and come from a 32 or
408  * 64-bit architecture.
409  *
410  * Note: Consider the value 0x01020304 read on a 32-bit machine.
411  * Big-endian, saved as:   01 02 03 04
412  * Lille-endian, saved as: 04 03 02 01
413  * The value should be saved as a 64-bit value and endianness should be
414  * preserved:
415  * Big-endian:    00 00 00 00 01 02 03 04
416  * Little-endian: 04 03 02 01 00 00 00 00
417  *
418  * IN:
419  * @buffer      Address of value to convert.
420  * @endian_mismatch
421  *              TRUE if data read from file don't match current machine's
422  *              endianness.
423  * @arch_64     TRUE if file's data come from a 64-bit machine.
424  ***************************************************************************
425  */
426 unsigned long long moveto_long_long(void *buffer, int endian_mismatch, int arch_64)
427 {
428         unsigned int *u_int;
429         unsigned long long *ull_int, ull_i;
430
431         if (arch_64) {
432                 ull_int = (unsigned long long *) buffer;
433                 return *ull_int;
434         }
435
436         u_int = (unsigned int *) buffer;
437         if (endian_mismatch) {
438                 ull_i = (unsigned long long) *u_int;
439                 return (ull_i >> 32) | (ull_i << 32);
440         }
441         else {
442                 return (unsigned long long) *u_int;
443         }
444 }
445
446 /*
447  ***************************************************************************
448  * Upgrade stats_cpu structure (from ACTIVITY_MAGIC_BASE format to
449  * ACTIVITY_MAGIC_BASE + 1 format).
450  *
451  * IN:
452  * @act         Array of activities.
453  * @p           Position of activity in array.
454  * @st_size     Size of the structure read from file.
455  ***************************************************************************
456  */
457 void upgrade_stats_cpu(struct activity *act[], int p, int st_size)
458 {
459         int i;
460         struct stats_cpu *scc;
461         struct stats_cpu_8a *scp;
462
463         for (i = 0; i < act[p]->nr_ini; i++) {
464                 /*
465                  * For previous structure's format: Use msize (which has possibly been set to
466                  * the size of the structure read from disk if it's greater than that of
467                  * current format: See upgrade_header_section()).
468                  * For current structure format: Use fsize. This is the normal size of
469                  * structure's up-to-date format that will be written to file.
470                  */
471                 scp = (struct stats_cpu_8a *) ((char *) act[p]->buf[0] + i * act[p]->msize);
472                 scc = (struct stats_cpu *)    ((char *) act[p]->buf[1] + i * act[p]->fsize);
473
474                 scc->cpu_user = scp->cpu_user;
475                 scc->cpu_nice = scp->cpu_nice;
476                 scc->cpu_sys = scp->cpu_sys;
477                 scc->cpu_idle = scp->cpu_idle;
478                 scc->cpu_iowait = scp->cpu_iowait;
479                 scc->cpu_steal = scp->cpu_steal;
480                 scc->cpu_hardirq = scp->cpu_hardirq;
481                 scc->cpu_softirq = scp->cpu_softirq;
482                 scc->cpu_guest = scp->cpu_guest;
483
484                 if (st_size >= STATS_CPU_8A_SIZE) {
485                         /* guest_nice field has been added without a structure format change */
486                         scc->cpu_guest_nice = scp->cpu_guest_nice;
487                 }
488         }
489 }
490
491 /*
492  ***************************************************************************
493  * Upgrade stats_pcsw structure (from ACTIVITY_MAGIC_BASE format to
494  * ACTIVITY_MAGIC_BASE + 1 format).
495  *
496  * IN:
497  * @act         Array of activities.
498  * @p           Position of activity in array.
499  ***************************************************************************
500  */
501 void upgrade_stats_pcsw(struct activity *act[], int p)
502 {
503         struct stats_pcsw *spc = (struct stats_pcsw *) act[p]->buf[1];
504         struct stats_pcsw_8a *spp = (struct stats_pcsw_8a *) act[p]->buf[0];
505
506         spc->context_switch = spp->context_switch;
507         /*
508          * Copy a long into a long. Take into account that file may have been
509          * created on a 64-bit machine and we may be converting on a 32-bit machine.
510          */
511         memcpy(&spc->processes, &spp->processes, 8);
512 }
513
514 /*
515  ***************************************************************************
516  * Upgrade stats_irq structure (from ACTIVITY_MAGIC_BASE format to
517  * ACTIVITY_MAGIC_BASE + 1 format).
518  *
519  * IN:
520  * @act         Array of activities.
521  * @p           Position of activity in array.
522  ***************************************************************************
523  */
524 void upgrade_stats_irq(struct activity *act[], int p)
525 {
526         int i;
527         struct stats_irq *sic;
528         struct stats_irq_8a *sip;
529
530         for (i = 0; i < act[p]->nr_ini; i++) {
531                 sip = (struct stats_irq_8a *) ((char *) act[p]->buf[0] + i * act[p]->msize);
532                 sic = (struct stats_irq *)    ((char *) act[p]->buf[1] + i * act[p]->fsize);
533
534                 sic->irq_nr = sip->irq_nr;
535         }
536 }
537
538 /*
539  ***************************************************************************
540  * Upgrade stats_io structure (from ACTIVITY_MAGIC_BASE format to
541  * ACTIVITY_MAGIC_BASE + 1 format).
542  *
543  * IN:
544  * @act         Array of activities.
545  * @p           Position of activity in array.
546  * @endian_mismatch
547  *              TRUE if data read from file don't match current machine's
548  *              endianness.
549  ***************************************************************************
550  */
551 void upgrade_stats_io(struct activity *act[], int p, int endian_mismatch)
552 {
553         struct stats_io *sic = (struct stats_io *) act[p]->buf[1];
554         struct stats_io_8a *sip = (struct stats_io_8a *) act[p]->buf[0];
555
556         sic->dk_drive = moveto_long_long(&sip->dk_drive, endian_mismatch, FALSE);
557         sic->dk_drive_rio = moveto_long_long(&sip->dk_drive_rio, endian_mismatch, FALSE);
558         sic->dk_drive_wio = moveto_long_long(&sip->dk_drive_wio, endian_mismatch, FALSE);
559         sic->dk_drive_rblk = moveto_long_long(&sip->dk_drive_rblk, endian_mismatch, FALSE);
560         sic->dk_drive_wblk = moveto_long_long(&sip->dk_drive_wblk, endian_mismatch, FALSE);
561 }
562
563 /*
564  ***************************************************************************
565  * Upgrade stats_memory structure (from ACTIVITY_MAGIC_BASE format to
566  * ACTIVITY_MAGIC_BASE + 1 format).
567  *
568  * IN:
569  * @act         Array of activities.
570  * @p           Position of activity in array.
571  * @st_size     Size of the structure read from file.
572  * @endian_mismatch
573  *              TRUE if data read from file don't match current machine's
574  *              endianness.
575  * @arch_64     TRUE if file's data come from a 64-bit machine.
576  ***************************************************************************
577  */
578 void upgrade_stats_memory(struct activity *act[], int p, int st_size,
579                           int endian_mismatch, int arch_64)
580 {
581         struct stats_memory *smc = (struct stats_memory *) act[p]->buf[1];
582         struct stats_memory_8a *smp = (struct stats_memory_8a *) act[p]->buf[0];
583
584         smc->frmkb = moveto_long_long(&smp->frmkb, endian_mismatch, arch_64);
585         smc->bufkb = moveto_long_long(&smp->bufkb, endian_mismatch, arch_64);
586         smc->camkb = moveto_long_long(&smp->camkb, endian_mismatch, arch_64);
587         smc->tlmkb = moveto_long_long(&smp->tlmkb, endian_mismatch, arch_64);
588         smc->frskb = moveto_long_long(&smp->frskb, endian_mismatch, arch_64);
589         smc->tlskb = moveto_long_long(&smp->tlskb, endian_mismatch, arch_64);
590         smc->caskb = moveto_long_long(&smp->caskb, endian_mismatch, arch_64);
591         smc->comkb = moveto_long_long(&smp->comkb, endian_mismatch, arch_64);
592         smc->activekb = moveto_long_long(&smp->activekb, endian_mismatch, arch_64);
593         smc->inactkb = moveto_long_long(&smp->inactkb, endian_mismatch, arch_64);
594
595         /* Some fields have been added without a structure format change */
596         if (st_size >= STATS_MEMORY_8A_1_SIZE) {
597                                 smc->dirtykb = moveto_long_long(&smp->dirtykb, endian_mismatch, arch_64);
598         }
599         if (st_size >= STATS_MEMORY_8A_2_SIZE) {
600                 smc->anonpgkb = moveto_long_long(&smp->anonpgkb, endian_mismatch, arch_64);
601                 smc->slabkb = moveto_long_long(&smp->slabkb, endian_mismatch, arch_64);
602                 smc->kstackkb = moveto_long_long(&smp->kstackkb, endian_mismatch, arch_64);
603                 smc->pgtblkb = moveto_long_long(&smp->pgtblkb, endian_mismatch, arch_64);
604                 smc->vmusedkb = moveto_long_long(&smp->vmusedkb, endian_mismatch, arch_64);
605         }
606         if (st_size >= STATS_MEMORY_8A_SIZE) {
607                 smc->availablekb = moveto_long_long(&(smp->availablekb), endian_mismatch, arch_64);;
608         }
609 }
610
611 /*
612  ***************************************************************************
613  * Upgrade stats_ktables structure (from ACTIVITY_MAGIC_BASE format to
614  * ACTIVITY_MAGIC_BASE + 1 format).
615  *
616  * IN:
617  * @act         Array of activities.
618  * @p           Position of activity in array.
619  * @endian_mismatch
620  *              TRUE if data read from file don't match current machine's
621  *              endianness.
622  ***************************************************************************
623  */
624 void upgrade_stats_ktables(struct activity *act[], int p, int endian_mismatch)
625 {
626         struct stats_ktables *skc = (struct stats_ktables *) act[p]->buf[1];
627         struct stats_ktables_8a *skp = (struct stats_ktables_8a *) act[p]->buf[0];
628
629         skc->file_used = moveto_long_long(&skp->file_used, endian_mismatch, FALSE);
630         skc->inode_used = moveto_long_long(&skp->inode_used, endian_mismatch, FALSE);
631         skc->dentry_stat = moveto_long_long(&skp->dentry_stat, endian_mismatch, FALSE);
632         skc->pty_nr = moveto_long_long(&skp->pty_nr, endian_mismatch, FALSE);
633 }
634
635 /*
636  ***************************************************************************
637  * Upgrade stats_queue structure (from ACTIVITY_MAGIC_BASE or
638  * ACTIVITY_MAGIC_BASE + 1 format to ACTIVITY_MAGIC_BASE + 2 format).
639  *
640  * IN:
641  * @act         Array of activities.
642  * @p           Position of activity in array.
643  * @magic       Structure format magic value.
644  * @endian_mismatch
645  *              TRUE if data read from file don't match current machine's
646  *              endianness.
647  * @arch_64     TRUE if file's data come from a 64-bit machine.
648  ***************************************************************************
649  */
650 void upgrade_stats_queue(struct activity *act[], int p, unsigned int magic,
651                          int endian_mismatch, int arch_64)
652 {
653         struct stats_queue *sqc = (struct stats_queue *) act[p]->buf[1];
654
655         if (magic == ACTIVITY_MAGIC_BASE) {
656                 struct stats_queue_8a *sqp = (struct stats_queue_8a *) act[p]->buf[0];
657
658                 sqc->nr_running = moveto_long_long(&sqp->nr_running, endian_mismatch, arch_64);
659                 sqc->procs_blocked = 0ULL;      /* New field */
660                 sqc->nr_threads = moveto_long_long(&sqp->nr_threads, endian_mismatch, FALSE);
661                 sqc->load_avg_1 = sqp->load_avg_1;
662                 sqc->load_avg_5 = sqp->load_avg_5;
663                 sqc->load_avg_15 = sqp->load_avg_15;
664         }
665         else {
666                 struct stats_queue_8b *sqp = (struct stats_queue_8b *) act[p]->buf[0];
667
668                 sqc->nr_running = moveto_long_long(&sqp->nr_running, endian_mismatch, arch_64);
669                 sqc->procs_blocked = moveto_long_long(&sqp->procs_blocked, endian_mismatch, arch_64);
670                 sqc->nr_threads = moveto_long_long(&sqp->nr_threads, endian_mismatch, FALSE);
671                 sqc->load_avg_1 = sqp->load_avg_1;
672                 sqc->load_avg_5 = sqp->load_avg_5;
673                 sqc->load_avg_15 = sqp->load_avg_15;
674         }
675 }
676
677 /*
678  ***************************************************************************
679  * Upgrade stats_serial structure (from ACTIVITY_MAGIC_BASE format to
680  * ACTIVITY_MAGIC_BASE + 1 format).
681  *
682  * IN:
683  * @act         Array of activities.
684  * @p           Position of activity in array.
685  * @st_size     Size of the structure read from file.
686  * @endian_mismatch
687  *              TRUE if data read from file don't match current machine's
688  *              endianness.
689  *
690  * RETURNS:
691  * Number of serial line structures that actually need to be written to
692  * disk.
693  ***************************************************************************
694  */
695 int upgrade_stats_serial(struct activity *act[], int p, size_t st_size, int endian_mismatch)
696 {
697         int i;
698         unsigned int line;
699         struct stats_serial *ssc;
700
701         /* Copy TTY stats to target structure */
702         memcpy(act[p]->buf[1], act[p]->buf[0], (size_t) act[p]->nr_ini * st_size);
703
704         for (i = 0; i < act[p]->nr_ini; i++) {
705                 ssc = (struct stats_serial *) ((char *) act[p]->buf[1] + i * act[p]->fsize);
706
707                 /* Line number now starts at 0 instead of 1 */
708                 line = (endian_mismatch ? __builtin_bswap32(ssc->line) : ssc->line);
709                 if (!line)
710                         break;
711                 line--;
712                 ssc->line = (endian_mismatch ? __builtin_bswap32(line) : line);
713         }
714
715         return i;
716 }
717
718 /*
719  ***************************************************************************
720  * Upgrade stats_disk structure (from ACTIVITY_MAGIC_BASE format to
721  * ACTIVITY_MAGIC_BASE + 1 format).
722  *
723  * IN:
724  * @act         Array of activities.
725  * @p           Position of activity in array.
726  * @magic       Structure format magic value.
727  * @endian_mismatch
728  *              TRUE if data read from file don't match current machine's
729  *              endianness.
730  * @arch_64     TRUE if file's data come from a 64-bit machine.
731  ***************************************************************************
732  */
733 void upgrade_stats_disk(struct activity *act[], int p, unsigned int magic,
734                         int endian_mismatch, int arch_64)
735 {
736         int i;
737         struct stats_disk *sdc;
738
739         if (magic == ACTIVITY_MAGIC_BASE) {
740                 struct stats_disk_8a *sdp;
741
742                 for (i = 0; i < act[p]->nr_ini; i++) {
743                         sdp = (struct stats_disk_8a *) ((char *) act[p]->buf[0] + i * act[p]->msize);
744                         sdc = (struct stats_disk *) ((char *) act[p]->buf[1] + i * act[p]->fsize);
745
746                         sdc->nr_ios = moveto_long_long(&sdp->nr_ios, endian_mismatch, arch_64);
747                         sdc->rd_sect = (unsigned long) sdp->rd_sect;
748                         sdc->wr_sect = (unsigned long) sdp->wr_sect;
749                         sdc->rd_ticks = (unsigned int) sdp->rd_ticks;
750                         sdc->wr_ticks = (unsigned int) sdp->wr_ticks;
751                         sdc->tot_ticks = (unsigned int) sdp->tot_ticks;
752                         sdc->rq_ticks = (unsigned int) sdp->rq_ticks;
753                         sdc->major = sdp->major;
754                         sdc->minor = sdp->minor;
755                 }
756         }
757         else {
758                 struct stats_disk_8b *sdp;
759
760                 for (i = 0; i < act[p]->nr_ini; i++) {
761                         sdp = (struct stats_disk_8b *) ((char *) act[p]->buf[0] + i * act[p]->msize);
762                         sdc = (struct stats_disk *) ((char *) act[p]->buf[1] + i * act[p]->fsize);
763
764                         sdc->nr_ios = sdp->nr_ios;
765                         memcpy(&sdc->rd_sect, &sdp->rd_sect, 8);
766                         memcpy(&sdc->wr_sect, &sdp->wr_sect, 8);
767                         sdc->rd_ticks = sdp->rd_ticks;
768                         sdc->wr_ticks = sdp->wr_ticks;
769                         sdc->tot_ticks = sdp->tot_ticks;
770                         sdc->rq_ticks = sdp->rq_ticks;
771                         sdc->major = sdp->major;
772                         sdc->minor = sdp->minor;
773                 }
774         }
775 }
776
777 /*
778  ***************************************************************************
779  * Upgrade stats_net_dev structure (from ACTIVITY_MAGIC_BASE or
780  * ACTIVITY_MAGIC_BASE + 1 format to ACTIVITY_MAGIC_BASE + 3 format).
781  *
782  * IN:
783  * @act         Array of activities.
784  * @p           Position of activity in array.
785  * @magic       Structure format magic value.
786  * @endian_mismatch
787  *              TRUE if data read from file don't match current machine's
788  *              endianness.
789  * @arch_64     TRUE if file's data come from a 64-bit machine.
790  ***************************************************************************
791  */
792 void upgrade_stats_net_dev(struct activity *act[], int p, unsigned int magic,
793                            int endian_mismatch, int arch_64)
794 {
795         int i;
796         struct stats_net_dev *sndc;
797
798         if (magic == ACTIVITY_MAGIC_BASE) {
799                 struct stats_net_dev_8a *sndp;
800
801                 for (i = 0; i < act[p]->nr_ini; i++) {
802                         sndp = (struct stats_net_dev_8a *) ((char *) act[p]->buf[0] + i * act[p]->msize);
803                         sndc = (struct stats_net_dev *) ((char *) act[p]->buf[1] + i * act[p]->fsize);
804
805                         sndc->rx_packets = moveto_long_long(&sndp->rx_packets, endian_mismatch, arch_64);
806                         sndc->tx_packets = moveto_long_long(&sndp->tx_packets, endian_mismatch, arch_64);
807                         sndc->rx_bytes = moveto_long_long(&sndp->rx_bytes, endian_mismatch, arch_64);
808                         sndc->tx_bytes = moveto_long_long(&sndp->tx_bytes, endian_mismatch, arch_64);
809                         sndc->rx_compressed = moveto_long_long(&sndp->rx_compressed, endian_mismatch, arch_64);
810                         sndc->tx_compressed = moveto_long_long(&sndp->tx_compressed, endian_mismatch, arch_64);
811                         sndc->multicast = moveto_long_long(&sndp->multicast, endian_mismatch, arch_64);
812                         sndc->speed = 0; /* New field */
813                         strncpy(sndc->interface, sndp->interface, sizeof(sndc->interface));
814                         sndc->interface[sizeof(sndc->interface) - 1] = '\0';
815                         sndc->duplex = '\0'; /* New field */
816                 }
817         }
818         else if (magic == ACTIVITY_MAGIC_BASE + 1) {
819                 struct stats_net_dev_8b *sndp;
820
821                 for (i = 0; i < act[p]->nr_ini; i++) {
822                         sndp = (struct stats_net_dev_8b *) ((char *) act[p]->buf[0] + i * act[p]->msize);
823                         sndc = (struct stats_net_dev *) ((char *) act[p]->buf[1] + i * act[p]->fsize);
824
825                         sndc->rx_packets = sndp->rx_packets;
826                         sndc->tx_packets = sndp->tx_packets;
827                         sndc->rx_bytes = sndp->rx_bytes;
828                         sndc->tx_bytes = sndp->tx_bytes;
829                         sndc->rx_compressed = sndp->rx_compressed;
830                         sndc->tx_compressed = sndp->tx_compressed;
831                         sndc->multicast = sndp->multicast;
832                         sndc->speed = 0; /* New field */
833                         strncpy(sndc->interface, sndp->interface, sizeof(sndc->interface));
834                         sndc->interface[sizeof(sndc->interface) - 1] = '\0';
835                         sndc->duplex = '\0'; /* New field */
836                 }
837         }
838         else {
839                 struct stats_net_dev_8c *sndp;
840
841                 for (i = 0; i < act[p]->nr_ini; i++) {
842                         sndp = (struct stats_net_dev_8c *) ((char *) act[p]->buf[0] + i * act[p]->msize);
843                         sndc = (struct stats_net_dev *) ((char *) act[p]->buf[1] + i * act[p]->fsize);
844
845                         sndc->rx_packets = sndp->rx_packets;
846                         sndc->tx_packets = sndp->tx_packets;
847                         sndc->rx_bytes = sndp->rx_bytes;
848                         sndc->tx_bytes = sndp->tx_bytes;
849                         sndc->rx_compressed = sndp->rx_compressed;
850                         sndc->tx_compressed = sndp->tx_compressed;
851                         sndc->multicast = sndp->multicast;
852                         sndc->speed = sndp->speed;
853                         strncpy(sndc->interface, sndp->interface, sizeof(sndc->interface));
854                         sndc->interface[sizeof(sndc->interface) - 1] = '\0';
855                         sndc->duplex = sndp->duplex;
856                 }
857         }
858 }
859
860 /*
861  ***************************************************************************
862  * Upgrade stats_net_edev structure (from ACTIVITY_MAGIC_BASE format to
863  * ACTIVITY_MAGIC_BASE + 1 format).
864  *
865  * IN:
866  * @act         Array of activities.
867  * @p           Position of activity in array.
868  * @magic       Structure format magic value.
869  * @endian_mismatch
870  *              TRUE if data read from file don't match current machine's
871  *              endianness.
872  * @arch_64     TRUE if file's data come from a 64-bit machine.
873  ***************************************************************************
874  */
875 void upgrade_stats_net_edev(struct activity *act[], int p, unsigned int magic,
876                             int endian_mismatch, int arch_64)
877 {
878         int i;
879         struct stats_net_edev *snedc;
880
881         if (magic == ACTIVITY_MAGIC_BASE) {
882                 struct stats_net_edev_8a *snedp;
883
884                 for (i = 0; i < act[p]->nr_ini; i++) {
885                         snedp = (struct stats_net_edev_8a *) ((char *) act[p]->buf[0] + i * act[p]->msize);
886                         snedc = (struct stats_net_edev *) ((char *) act[p]->buf[1] + i * act[p]->fsize);
887
888                         snedc->collisions = moveto_long_long(&snedp->collisions, endian_mismatch, arch_64);
889                         snedc->rx_errors = moveto_long_long(&snedp->rx_errors, endian_mismatch, arch_64);
890                         snedc->tx_errors = moveto_long_long(&snedp->tx_errors, endian_mismatch, arch_64);
891                         snedc->rx_dropped = moveto_long_long(&snedp->rx_dropped, endian_mismatch, arch_64);
892                         snedc->tx_dropped = moveto_long_long(&snedp->tx_dropped, endian_mismatch, arch_64);
893                         snedc->rx_fifo_errors = moveto_long_long(&snedp->rx_fifo_errors, endian_mismatch, arch_64);
894                         snedc->tx_fifo_errors = moveto_long_long(&snedp->tx_fifo_errors, endian_mismatch, arch_64);
895                         snedc->rx_frame_errors = moveto_long_long(&snedp->rx_frame_errors, endian_mismatch, arch_64);
896                         snedc->tx_carrier_errors = moveto_long_long(&snedp->tx_carrier_errors, endian_mismatch, arch_64);
897                         strncpy(snedc->interface, snedp->interface, sizeof(snedc->interface));
898                         snedc->interface[sizeof(snedc->interface) - 1] = '\0';
899                 }
900         }
901         else {
902                 struct stats_net_edev_8b *snedp;
903
904                 for (i = 0; i < act[p]->nr_ini; i++) {
905                         snedp = (struct stats_net_edev_8b *) ((char *) act[p]->buf[0] + i * act[p]->msize);
906                         snedc = (struct stats_net_edev *) ((char *) act[p]->buf[1] + i * act[p]->fsize);
907
908                         snedc->collisions = snedp->collisions;
909                         snedc->rx_errors = snedp->rx_errors;
910                         snedc->tx_errors = snedp->tx_errors;
911                         snedc->rx_dropped = snedp->rx_dropped;
912                         snedc->tx_dropped = snedp->tx_dropped;
913                         snedc->rx_fifo_errors = snedp->rx_fifo_errors;
914                         snedc->tx_fifo_errors = snedp->tx_fifo_errors;
915                         snedc->rx_frame_errors = snedp->rx_frame_errors;
916                         snedc->tx_carrier_errors = snedp->tx_carrier_errors;
917                         strncpy(snedc->interface, snedp->interface, sizeof(snedc->interface));
918                         snedc->interface[sizeof(snedc->interface) - 1] = '\0';
919                 }
920         }
921 }
922
923 /*
924  ***************************************************************************
925  * Upgrade stats_net_ip structure (from ACTIVITY_MAGIC_BASE format to
926  * ACTIVITY_MAGIC_BASE + 1 format).
927  *
928  * IN:
929  * @act         Array of activities.
930  * @p           Position of activity in array.
931  * @magic       Structure format magic value.
932  * @endian_mismatch
933  *              TRUE if data read from file don't match current machine's
934  *              endianness.
935  * @arch_64     TRUE if file's data come from a 64-bit machine.
936  ***************************************************************************
937  */
938 void upgrade_stats_net_ip(struct activity *act[], int p, unsigned int magic,
939                           int endian_mismatch, int arch_64)
940 {
941         struct stats_net_ip *snic = (struct stats_net_ip *) act[p]->buf[1];
942
943         if (magic == ACTIVITY_MAGIC_BASE) {
944                 struct stats_net_ip_8a *snip = (struct stats_net_ip_8a *) act[p]->buf[0];
945
946                 snic->InReceives = moveto_long_long(&snip->InReceives, endian_mismatch, arch_64);
947                 snic->ForwDatagrams = moveto_long_long(&snip->ForwDatagrams, endian_mismatch, arch_64);
948                 snic->InDelivers = moveto_long_long(&snip->InDelivers, endian_mismatch, arch_64);
949                 snic->OutRequests = moveto_long_long(&snip->OutRequests, endian_mismatch, arch_64);
950                 snic->ReasmReqds = moveto_long_long(&snip->ReasmReqds, endian_mismatch, arch_64);
951                 snic->ReasmOKs = moveto_long_long(&snip->ReasmOKs, endian_mismatch, arch_64);
952                 snic->FragOKs = moveto_long_long(&snip->FragOKs, endian_mismatch, arch_64);
953                 snic->FragCreates = moveto_long_long(&snip->FragCreates, endian_mismatch, arch_64);
954         }
955         else {
956                 struct stats_net_ip_8b *snip = (struct stats_net_ip_8b *) act[p]->buf[0];
957
958                 snic->InReceives = snip->InReceives;
959                 snic->ForwDatagrams = snip->ForwDatagrams;
960                 snic->InDelivers = snip->InDelivers;
961                 snic->OutRequests = snip->OutRequests;
962                 snic->ReasmReqds = snip->ReasmReqds;
963                 snic->ReasmOKs = snip->ReasmOKs;
964                 snic->FragOKs = snip->FragOKs;
965                 snic->FragCreates = snip->FragCreates;
966         }
967 }
968
969 /*
970  ***************************************************************************
971  * Upgrade stats_net_eip structure (from ACTIVITY_MAGIC_BASE format to
972  * ACTIVITY_MAGIC_BASE + 1 format).
973  *
974  * IN:
975  * @act         Array of activities.
976  * @p           Position of activity in array.
977  * @magic       Structure format magic value.
978  * @endian_mismatch
979  *              TRUE if data read from file don't match current machine's
980  *              endianness.
981  * @arch_64     TRUE if file's data come from a 64-bit machine.
982  ***************************************************************************
983  */
984 void upgrade_stats_net_eip(struct activity *act[], int p, unsigned int magic,
985                            int endian_mismatch, int arch_64)
986 {
987         struct stats_net_eip *sneic = (struct stats_net_eip *) act[p]->buf[1];
988
989         if (magic == ACTIVITY_MAGIC_BASE) {
990                 struct stats_net_eip_8a *sneip = (struct stats_net_eip_8a *) act[p]->buf[0];
991
992                 sneic->InHdrErrors = moveto_long_long(&sneip->InHdrErrors, endian_mismatch, arch_64);
993                 sneic->InAddrErrors = moveto_long_long(&sneip->InAddrErrors, endian_mismatch, arch_64);
994                 sneic->InUnknownProtos = moveto_long_long(&sneip->InUnknownProtos, endian_mismatch, arch_64);
995                 sneic->InDiscards = moveto_long_long(&sneip->InDiscards, endian_mismatch, arch_64);
996                 sneic->OutDiscards = moveto_long_long(&sneip->OutDiscards, endian_mismatch, arch_64);
997                 sneic->OutNoRoutes = moveto_long_long(&sneip->OutNoRoutes, endian_mismatch, arch_64);
998                 sneic->ReasmFails = moveto_long_long(&sneip->ReasmFails, endian_mismatch, arch_64);
999                 sneic->FragFails = moveto_long_long(&sneip->FragFails, endian_mismatch, arch_64);
1000         }
1001         else {
1002                 struct stats_net_eip_8b *sneip = (struct stats_net_eip_8b *) act[p]->buf[0];
1003
1004                 sneic->InHdrErrors = sneip->InHdrErrors;
1005                 sneic->InAddrErrors = sneip->InAddrErrors;
1006                 sneic->InUnknownProtos = sneip->InUnknownProtos;
1007                 sneic->InDiscards = sneip->InDiscards;
1008                 sneic->OutDiscards = sneip->OutDiscards;
1009                 sneic->OutNoRoutes = sneip->OutNoRoutes;
1010                 sneic->ReasmFails = sneip->ReasmFails;
1011                 sneic->FragFails = sneip->FragFails;
1012         }
1013 }
1014
1015 /*
1016  ***************************************************************************
1017  * Upgrade stats_net_ip6 structure (from ACTIVITY_MAGIC_BASE format to
1018  * ACTIVITY_MAGIC_BASE + 1 format).
1019  *
1020  * IN:
1021  * @act         Array of activities.
1022  * @p           Position of activity in array.
1023  * @magic       Structure format magic value.
1024  * @endian_mismatch
1025  *              TRUE if data read from file don't match current machine's
1026  *              endianness.
1027  * @arch_64     TRUE if file's data come from a 64-bit machine.
1028  ***************************************************************************
1029  */
1030 void upgrade_stats_net_ip6(struct activity *act[], int p, unsigned int magic,
1031                            int endian_mismatch, int arch_64)
1032 {
1033         struct stats_net_ip6 *snic6 = (struct stats_net_ip6 *) act[p]->buf[1];
1034
1035         if (magic == ACTIVITY_MAGIC_BASE) {
1036                 struct stats_net_ip6_8a *snip6 = (struct stats_net_ip6_8a *) act[p]->buf[0];
1037
1038                 snic6->InReceives6 = moveto_long_long(&snip6->InReceives6, endian_mismatch, arch_64);
1039                 snic6->OutForwDatagrams6 = moveto_long_long(&snip6->OutForwDatagrams6, endian_mismatch, arch_64);
1040                 snic6->InDelivers6 = moveto_long_long(&snip6->InDelivers6, endian_mismatch, arch_64);
1041                 snic6->OutRequests6 = moveto_long_long(&snip6->OutRequests6, endian_mismatch, arch_64);
1042                 snic6->ReasmReqds6 = moveto_long_long(&snip6->ReasmReqds6, endian_mismatch, arch_64);
1043                 snic6->ReasmOKs6 = moveto_long_long(&snip6->ReasmOKs6, endian_mismatch, arch_64);
1044                 snic6->InMcastPkts6 = moveto_long_long(&snip6->InMcastPkts6, endian_mismatch, arch_64);
1045                 snic6->OutMcastPkts6 = moveto_long_long(&snip6->OutMcastPkts6, endian_mismatch, arch_64);
1046                 snic6->FragOKs6 = moveto_long_long(&snip6->FragOKs6, endian_mismatch, arch_64);
1047                 snic6->FragCreates6 = moveto_long_long(&snip6->FragCreates6, endian_mismatch, arch_64);
1048         }
1049         else {
1050                 struct stats_net_ip6_8b *snip6 = (struct stats_net_ip6_8b *) act[p]->buf[0];
1051
1052                 snic6->InReceives6 = snip6->InReceives6;
1053                 snic6->OutForwDatagrams6 = snip6->OutForwDatagrams6;
1054                 snic6->InDelivers6 = snip6->InDelivers6;
1055                 snic6->OutRequests6 = snip6->OutRequests6;
1056                 snic6->ReasmReqds6 = snip6->ReasmReqds6;
1057                 snic6->ReasmOKs6 = snip6->ReasmOKs6;
1058                 snic6->InMcastPkts6 = snip6->InMcastPkts6;
1059                 snic6->OutMcastPkts6 = snip6->OutMcastPkts6;
1060                 snic6->FragOKs6 = snip6->FragOKs6;
1061                 snic6->FragCreates6 = snip6->FragCreates6;
1062         }
1063 }
1064
1065 /*
1066  ***************************************************************************
1067  * Upgrade stats_net_eip6 structure (from ACTIVITY_MAGIC_BASE format to
1068  * ACTIVITY_MAGIC_BASE + 1 format).
1069  *
1070  * IN:
1071  * @act         Array of activities.
1072  * @p           Position of activity in array.
1073  * @magic       Structure format magic value.
1074  * @endian_mismatch
1075  *              TRUE if data read from file don't match current machine's
1076  *              endianness.
1077  * @arch_64     TRUE if file's data come from a 64-bit machine.
1078  ***************************************************************************
1079  */
1080 void upgrade_stats_net_eip6(struct activity *act[], int p, unsigned int magic,
1081                             int endian_mismatch, int arch_64)
1082 {
1083         struct stats_net_eip6 *sneic6 = (struct stats_net_eip6 *) act[p]->buf[1];
1084
1085         if (magic == ACTIVITY_MAGIC_BASE) {
1086                 struct stats_net_eip6_8a *sneip6 = (struct stats_net_eip6_8a *) act[p]->buf[0];
1087
1088                 sneic6->InHdrErrors6 = moveto_long_long(&sneip6->InHdrErrors6, endian_mismatch, arch_64);
1089                 sneic6->InAddrErrors6 = moveto_long_long(&sneip6->InAddrErrors6, endian_mismatch, arch_64);
1090                 sneic6->InUnknownProtos6 = moveto_long_long(&sneip6->InUnknownProtos6, endian_mismatch, arch_64);
1091                 sneic6->InTooBigErrors6 = moveto_long_long(&sneip6->InTooBigErrors6, endian_mismatch, arch_64);
1092                 sneic6->InDiscards6 = moveto_long_long(&sneip6->InDiscards6, endian_mismatch, arch_64);
1093                 sneic6->OutDiscards6 = moveto_long_long(&sneip6->OutDiscards6, endian_mismatch, arch_64);
1094                 sneic6->InNoRoutes6 = moveto_long_long(&sneip6->InNoRoutes6, endian_mismatch, arch_64);
1095                 sneic6->OutNoRoutes6 = moveto_long_long(&sneip6->OutNoRoutes6, endian_mismatch, arch_64);
1096                 sneic6->ReasmFails6 = moveto_long_long(&sneip6->ReasmFails6, endian_mismatch, arch_64);
1097                 sneic6->FragFails6 = moveto_long_long(&sneip6->FragFails6, endian_mismatch, arch_64);
1098                 sneic6->InTruncatedPkts6 = moveto_long_long(&sneip6->InTruncatedPkts6, endian_mismatch, arch_64);
1099         }
1100         else {
1101                 struct stats_net_eip6_8b *sneip6 = (struct stats_net_eip6_8b *) act[p]->buf[0];
1102
1103                 sneic6->InHdrErrors6 = sneip6->InHdrErrors6;
1104                 sneic6->InAddrErrors6 = sneip6->InAddrErrors6;
1105                 sneic6->InUnknownProtos6 = sneip6->InUnknownProtos6;
1106                 sneic6->InTooBigErrors6 = sneip6->InTooBigErrors6;
1107                 sneic6->InDiscards6 = sneip6->InDiscards6;
1108                 sneic6->OutDiscards6 = sneip6->OutDiscards6;
1109                 sneic6->InNoRoutes6 = sneip6->InNoRoutes6;
1110                 sneic6->OutNoRoutes6 = sneip6->OutNoRoutes6;
1111                 sneic6->ReasmFails6 = sneip6->ReasmFails6;
1112                 sneic6->FragFails6 = sneip6->FragFails6;
1113                 sneic6->InTruncatedPkts6 = sneip6->InTruncatedPkts6;
1114         }
1115 }
1116
1117 /*
1118  ***************************************************************************
1119  * Upgrade stats_huge structure (from ACTIVITY_MAGIC_BASE format to
1120  * ACTIVITY_MAGIC_BASE + 1 format).
1121  *
1122  * IN:
1123  * @act         Array of activities.
1124  * @p           Position of activity in array.
1125  * @endian_mismatch
1126  *              TRUE if data read from file don't match current machine's
1127  *              endianness.
1128  * @arch_64     TRUE if file's data come from a 64-bit machine.
1129  ***************************************************************************
1130  */
1131 void upgrade_stats_huge(struct activity *act[], int p,
1132                         int endian_mismatch, int arch_64)
1133 {
1134         struct stats_huge *shc = (struct stats_huge *) act[p]->buf[1];
1135         struct stats_huge_8a *shp = (struct stats_huge_8a *) act[p]->buf[0];
1136
1137         shc->frhkb = moveto_long_long(&shp->frhkb, endian_mismatch, arch_64);
1138         shc->tlhkb = moveto_long_long(&shp->tlhkb, endian_mismatch, arch_64);
1139 }
1140
1141 /*
1142  ***************************************************************************
1143  * Upgrade stats_pwr_wghfreq structure (from ACTIVITY_MAGIC_BASE format to
1144  * ACTIVITY_MAGIC_BASE + 1 format).
1145  *
1146  * IN:
1147  * @act         Array of activities.
1148  * @p           Position of activity in array.
1149  ***************************************************************************
1150  */
1151 void upgrade_stats_pwr_wghfreq(struct activity *act[], int p)
1152 {
1153         int i, k;
1154
1155         struct stats_pwr_wghfreq *spc, *spc_k;
1156         struct stats_pwr_wghfreq_8a *spp, *spp_k;
1157
1158         for (i = 0; i < act[p]->nr_ini; i++) {
1159                 spp = (struct stats_pwr_wghfreq_8a *) ((char *) act[p]->buf[0] + i * act[p]->msize * act[p]->nr2);
1160                 spc = (struct stats_pwr_wghfreq *) ((char *) act[p]->buf[1] + i * act[p]->fsize * act[p]->nr2);
1161
1162                 for (k = 0; k < act[p]->nr2; k++) {
1163                         spp_k = (struct stats_pwr_wghfreq_8a *) ((char *) spp + k * act[p]->msize);
1164                         if (!spp_k->freq)
1165                                 break;
1166                         spc_k = (struct stats_pwr_wghfreq *) ((char *) spc + k * act[p]->fsize);
1167
1168                         spc_k->time_in_state = spp_k->time_in_state;
1169                         memcpy(&spc_k->freq, &spp_k->freq, 8);
1170                 }
1171         }
1172 }
1173
1174 /*
1175  ***************************************************************************
1176  * Upgrade stats_filesystem structure (from ACTIVITY_MAGIC_BASE format to
1177  * ACTIVITY_MAGIC_BASE + 1 format).
1178  *
1179  * IN:
1180  * @act         Array of activities.
1181  * @p           Position of activity in array.
1182  * @st_size     Size of the structure read from file.
1183  ***************************************************************************
1184  */
1185 void upgrade_stats_filesystem(struct activity *act[], int p, int st_size)
1186 {
1187         int i;
1188         struct stats_filesystem *sfc;
1189         struct stats_filesystem_8a *sfp;
1190
1191         for (i = 0; i < act[p]->nr_ini; i++) {
1192                 sfp = (struct stats_filesystem_8a *) ((char *) act[p]->buf[0] + i * act[p]->msize);
1193                 sfc = (struct stats_filesystem *)    ((char *) act[p]->buf[1] + i * act[p]->fsize);
1194
1195                 sfc->f_blocks = sfp->f_blocks;
1196                 sfc->f_bfree = sfp->f_bfree;
1197                 sfc->f_bavail = sfp->f_bavail;
1198                 sfc->f_files = sfp->f_files;
1199                 sfc->f_ffree = sfp->f_ffree;
1200                 strncpy(sfc->fs_name, sfp->fs_name, sizeof(sfc->fs_name));
1201                 sfc->fs_name[sizeof(sfc->fs_name) - 1] = '\0';
1202
1203                 if (st_size <= STATS_FILESYSTEM_8A_1_SIZE) {
1204                         /* mountp didn't exist with older versions */
1205                         sfc->mountp[0] = '\0';
1206                 }
1207                 else {
1208                         strncpy(sfc->mountp, sfp->mountp, sizeof(sfc->mountp));
1209                         sfc->mountp[sizeof(sfc->mountp) - 1] = '\0';
1210                 }
1211         }
1212 }
1213
1214 /*
1215  ***************************************************************************
1216  * Count number of stats_disk structures that need to be written.
1217  *
1218  * IN:
1219  * @act         Array of activities.
1220  * @p           Position of activity in array.
1221  ***************************************************************************
1222  */
1223 __nr_t count_stats_disk(struct activity *act[], int p)
1224 {
1225         int i;
1226         __nr_t nr_dsk = 0;
1227         struct stats_disk *sdc;
1228
1229         for (i = 0; i < act[p]->nr_ini; i++) {
1230                 sdc = (struct stats_disk *) ((char *) act[p]->buf[1] + i * act[p]->fsize);
1231                 if (!(sdc->major + sdc->minor))
1232                         break;
1233
1234                 nr_dsk++;
1235         }
1236
1237         return nr_dsk;
1238 }
1239
1240 /*
1241  ***************************************************************************
1242  * Count number of stats_net_dev structures that need to be written.
1243  *
1244  * IN:
1245  * @act         Array of activities.
1246  * @p           Position of activity in array.
1247  ***************************************************************************
1248  */
1249 __nr_t count_stats_net_dev(struct activity *act[], int p)
1250 {
1251         int i;
1252         __nr_t nr_dev = 0;
1253         struct stats_net_dev *sndc;
1254
1255         for (i = 0; i < act[p]->nr_ini; i++) {
1256                 sndc = (struct stats_net_dev *) ((char *) act[p]->buf[1] + i * act[p]->fsize);
1257                 if (!strcmp(sndc->interface, ""))
1258                         break;
1259
1260                 nr_dev++;
1261         }
1262
1263         return nr_dev;
1264 }
1265
1266 /*
1267  ***************************************************************************
1268  * Count number of stats_net_edev structures that need to be written.
1269  *
1270  * IN:
1271  * @act         Array of activities.
1272  * @p           Position of activity in array.
1273  ***************************************************************************
1274  */
1275 __nr_t count_stats_net_edev(struct activity *act[], int p)
1276 {
1277         int i;
1278         __nr_t nr_edev = 0;
1279         struct stats_net_edev *snedc;
1280
1281         for (i = 0; i < act[p]->nr_ini; i++) {
1282                 snedc = (struct stats_net_edev *) ((char *) act[p]->buf[1] + i * act[p]->fsize);
1283                 if (!strcmp(snedc->interface, ""))
1284                         break;
1285
1286                 nr_edev++;
1287         }
1288
1289         return nr_edev;
1290 }
1291
1292 /*
1293  ***************************************************************************
1294  * Count number of stats_pwr_usb structures that need to be written.
1295  *
1296  * IN:
1297  * @act         Array of activities.
1298  * @p           Position of activity in array.
1299  ***************************************************************************
1300  */
1301 __nr_t count_stats_pwr_usb(struct activity *act[], int p)
1302 {
1303         int i;
1304         __nr_t nr_usb = 0;
1305         struct stats_pwr_usb *suc;
1306
1307         for (i = 0; i < act[p]->nr_ini; i++) {
1308                 suc = (struct stats_pwr_usb *) ((char *) act[p]->buf[1] + i * act[p]->fsize);
1309                 if (!suc->bus_nr)
1310                         break;
1311
1312                 nr_usb++;
1313         }
1314
1315         return nr_usb;
1316 }
1317
1318 /*
1319  ***************************************************************************
1320  * Count number of stats_filesystem structures that need to be written.
1321  *
1322  * IN:
1323  * @act         Array of activities.
1324  * @p           Position of activity in array.
1325  ***************************************************************************
1326  */
1327 __nr_t count_stats_filesystem(struct activity *act[], int p)
1328 {
1329         int i;
1330         __nr_t nr_fs = 0;
1331         struct stats_filesystem *sfc;
1332
1333         for (i = 0; i < act[p]->nr_ini; i++) {
1334                 sfc = (struct stats_filesystem *) ((char *) act[p]->buf[1] + i * act[p]->fsize);
1335                 if (!sfc->f_blocks)
1336                         break;
1337
1338                 nr_fs++;
1339         }
1340
1341         return nr_fs;
1342 }
1343
1344 /*
1345  ***************************************************************************
1346  * Count number of stats_fchost structures that need to be written.
1347  *
1348  * IN:
1349  * @act         Array of activities.
1350  * @p           Position of activity in array.
1351  ***************************************************************************
1352  */
1353 __nr_t count_stats_fchost(struct activity *act[], int p)
1354 {
1355         int i;
1356         __nr_t nr_fc = 0;
1357         struct stats_fchost *sfcc;
1358
1359         for (i = 0; i < act[p]->nr_ini; i++) {
1360                 sfcc = (struct stats_fchost *) ((char *) act[p]->buf[1] + i * act[p]->fsize);
1361                 if (!sfcc->fchost_name[0])
1362                         break;
1363
1364                 nr_fc++;
1365         }
1366
1367         return nr_fc;
1368 }
1369
1370 /*
1371  ***************************************************************************
1372  * Upgrade file's activity list section.
1373  *
1374  * IN:
1375  * @stdfd               File descriptor for STDOUT.
1376  * @act                 Array of activities.
1377  * @file_hdr            Pointer on file_header structure.
1378  * @ofile_actlst        Activity list in file.
1379  * @endian_mismatch
1380  *              TRUE if data read from file don't match current machine's
1381  *              endianness.
1382  * @arch_64     TRUE if file's data come from a 64-bit machine.
1383  *
1384  * OUT:
1385  * @file_actlst         Activity list with up-to-date format.
1386  *
1387  * RETURNS:
1388  * -1 on error, 0 otherwise.
1389 ***************************************************************************
1390  */
1391 int upgrade_activity_section(int stdfd, struct activity *act[],
1392                              struct file_header *file_hdr,
1393                              struct old_file_activity *ofile_actlst,
1394                              struct file_activity **file_actlst,
1395                              int endian_mismatch, int arch_64)
1396 {
1397         int i, j, p;
1398         struct old_file_activity *ofal;
1399         struct file_activity *fal, fa;
1400
1401         fprintf(stderr, "file_activity: ");
1402
1403         SREALLOC(*file_actlst, struct file_activity, FILE_ACTIVITY_SIZE * file_hdr->sa_act_nr);
1404         fal = *file_actlst;
1405         ofal = ofile_actlst;
1406
1407         for (i = 0; i < file_hdr->sa_act_nr; i++, ofal++, fal++) {
1408
1409                 /* Every activity should be known at the moment (may change in the future) */
1410                 p = get_activity_position(act, ofal->id, EXIT_IF_NOT_FOUND);
1411                 fal->id = ofal->id;
1412                 fal->nr = ofal->nr;
1413                 fal->nr2 = ofal->nr2;
1414                 fal->magic = act[p]->magic;     /* Update activity magic number */
1415                 fal->has_nr = HAS_COUNT_FUNCTION(act[p]->options);
1416                 /* Also update its size, which may have changed with recent versions */
1417                 fal->size = act[p]->fsize;
1418                 for (j = 0; j < 3; j++) {
1419                         fal->types_nr[j] = act[p]->gtypes_nr[j];
1420                 }
1421
1422                 memcpy(&fa, fal, FILE_ACTIVITY_SIZE);
1423                 /* Restore endianness before writing */
1424                 if (endian_mismatch) {
1425                         /* Start swapping at field "header_size" position */
1426                         swap_struct(act_types_nr, &fa, arch_64);
1427                 }
1428
1429                 /*
1430                  * Even unknown activities must be written
1431                  * (they are counted in sa_act_nr).
1432                  */
1433                 if (write_all(stdfd, &fa, FILE_ACTIVITY_SIZE) != FILE_ACTIVITY_SIZE) {
1434                         fprintf(stderr, "\nwrite: %s\n", strerror(errno));
1435                         return -1;
1436                 }
1437                 fprintf(stderr, "%s ", act[p]->name);
1438         }
1439
1440         fprintf(stderr, "OK\n");
1441
1442         return 0;
1443 }
1444
1445 /*
1446  ***************************************************************************
1447  * Upgrade a record header.
1448  *
1449  * IN:
1450  * @fd          File descriptor for sa datafile to convert.
1451  * @stdfd       File descriptor for STDOUT.
1452  * @orec_hdr    Record's header structure to convert.
1453  * @endian_mismatch
1454  *              TRUE if data read from file don't match current machine's
1455  *              endianness.
1456  * @arch_64     TRUE if file's data come from a 64-bit machine.
1457  *
1458  * RETURNS:
1459  * -1 on error, 0 otherwise.
1460 ***************************************************************************
1461  */
1462 int upgrade_record_header(int fd, int stdfd, struct old_record_header *orec_hdr,
1463                           int endian_mismatch, int arch_64)
1464 {
1465         struct record_header rec_hdr;
1466
1467         memset(&rec_hdr, 0, sizeof(struct record_header));
1468
1469         /* Convert current record header */
1470         rec_hdr.uptime_cs = orec_hdr->uptime0 * 100 / HZ;       /* Uptime in cs, not jiffies */
1471         rec_hdr.ust_time = (unsigned long long) orec_hdr->ust_time;
1472         rec_hdr.record_type = orec_hdr->record_type;
1473         rec_hdr.hour = orec_hdr->hour;
1474         rec_hdr.minute = orec_hdr->minute;
1475         rec_hdr.second = orec_hdr->second;
1476
1477         /* Restore endianness before writing */
1478         if (endian_mismatch) {
1479                 swap_struct(rec_types_nr, &rec_hdr, arch_64);
1480         }
1481
1482         /* Write record header */
1483         if (write_all(stdfd, &rec_hdr, RECORD_HEADER_SIZE) != RECORD_HEADER_SIZE) {
1484                 fprintf(stderr, "\nwrite: %s\n", strerror(errno));
1485                 return -1;
1486         }
1487
1488         fprintf(stderr, "H");
1489
1490         return 0;
1491 }
1492
1493 /*
1494  ***************************************************************************
1495  * Upgrade a COMMENT record.
1496  *
1497  * IN:
1498  * @fd          File descriptor for sa datafile to convert.
1499  * @stdfd       File descriptor for STDOUT.
1500  *
1501  * RETURNS:
1502  * -1 on error, 0 otherwise.
1503 ***************************************************************************
1504  */
1505 int upgrade_comment_record(int fd, int stdfd)
1506 {
1507         char file_comment[MAX_COMMENT_LEN];
1508
1509         /* Read the COMMENT record */
1510         sa_fread(fd, file_comment, sizeof(file_comment), HARD_SIZE, UEOF_STOP);
1511         file_comment[sizeof(file_comment) - 1] = '\0';
1512
1513         /* Then write it. No changes at this time */
1514         if (write_all(stdfd, file_comment, sizeof(file_comment)) != sizeof(file_comment)) {
1515                 fprintf(stderr, "\nwrite: %s\n", strerror(errno));
1516                 return -1;
1517         }
1518
1519         fprintf(stderr, "C");
1520
1521         return 0;
1522 }
1523
1524 /*
1525  ***************************************************************************
1526  * Upgrade a RESTART record.
1527  *
1528  * IN:
1529  * @fd          File descriptor for sa datafile to convert.
1530  * @stdfd       File descriptor for STDOUT.
1531  * @act         Array of activities.
1532  * @file_hdr    Pointer on file_header structure.
1533  * @previous_format
1534  *              TRUE is sa datafile has an old format which is no longer
1535  *              compatible with current one.
1536  * @endian_mismatch
1537  *              TRUE if data read from file don't match current machine's
1538  *              endianness.
1539  * @arch_64     TRUE if file's data come from a 64-bit machine.
1540  * @vol_act_nr  Number of volatile activity structures.
1541  *
1542  * RETURNS:
1543  * -1 on error, 0 otherwise.
1544 ***************************************************************************
1545  */
1546 int upgrade_restart_record(int fd, int stdfd, struct activity *act[],
1547                            struct file_header *file_hdr, int previous_format,
1548                            int endian_mismatch, int arch_64, unsigned int vol_act_nr)
1549 {
1550
1551         int i, p;
1552         struct old_file_activity ofile_act;
1553         /* Number of cpu read in the activity list. See upgrade_header_section() */
1554         __nr_t cpu_nr = file_hdr->sa_cpu_nr;
1555
1556         if (previous_format == FORMAT_MAGIC_2173) {
1557                 /*
1558                  * For versions from 10.3.1 to 11.6.x,
1559                  * the restart record is followed by a list
1560                  * of volatile activity structures. Among them is A_CPU activity.
1561                  */
1562                 for (i = 0; i < vol_act_nr; i++) {
1563                         sa_fread(fd, &ofile_act, OLD_FILE_ACTIVITY_SIZE, HARD_SIZE, UEOF_STOP);
1564
1565                         /* Normalize endianness for file_activity structures */
1566                         if (endian_mismatch) {
1567                                 swap_struct(oact_types_nr, &ofile_act, arch_64);
1568                         }
1569
1570                         if (ofile_act.id && (ofile_act.nr > 0)) {
1571                                 p = get_activity_position(act, ofile_act.id, EXIT_IF_NOT_FOUND);
1572                                 act[p]->nr_ini = ofile_act.nr;
1573
1574                                 if (ofile_act.id == A_CPU) {
1575                                         cpu_nr = ofile_act.nr;
1576                                 }
1577                         }
1578                 }
1579                 /* Reallocate structures */
1580                 allocate_structures(act);
1581         }
1582
1583         /* Restore endianness before writing */
1584         if (endian_mismatch) {
1585                 cpu_nr = __builtin_bswap32(cpu_nr);
1586         }
1587
1588         /* Write new number of CPU following the restart record */
1589         if (write_all(stdfd, &cpu_nr, sizeof(__nr_t)) != sizeof(__nr_t)) {
1590                 fprintf(stderr, "\nwrite: %s\n", strerror(errno));
1591                 return -1;
1592         }
1593
1594         fprintf(stderr, "R");
1595
1596         return 0;
1597 }
1598
1599 /*
1600  ***************************************************************************
1601  * Upgrade a record which is not a COMMENT or a RESTART one.
1602  *
1603  * IN:
1604  * @fd          File descriptor for sa datafile to convert.
1605  * @stdfd       File descriptor for STDOUT.
1606  * @act         Array of activities.
1607  * @file_hdr    Pointer on file_header structure (up-to-date format).
1608  * @ofile_actlst
1609  *              Activity list in file.
1610  * @file_actlst Activity list in file (up-to-date format).
1611  * @endian_mismatch
1612  *              TRUE if data read from file don't match current machine's
1613  *              endianness.
1614  * @arch_64     TRUE if file's data come from a 64-bit machine.
1615  *
1616  * RETURNS:
1617  * -1 on error, 0 otherwise.
1618 ***************************************************************************
1619  */
1620 int upgrade_common_record(int fd, int stdfd, struct activity *act[], struct file_header *file_hdr,
1621                           struct old_file_activity *ofile_actlst, struct file_activity *file_actlst,
1622                           int endian_mismatch, int arch_64)
1623 {
1624         int i, j, k, p;
1625         __nr_t nr_struct, nr;
1626         struct old_file_activity *ofal = ofile_actlst;
1627         struct file_activity *fal = file_actlst;
1628         char cc;
1629
1630         /*
1631          * This is not a special record, so read the extra fields,
1632          * even if the format of the activity is unknown.
1633          */
1634         for (i = 0; i < file_hdr->sa_act_nr; i++, ofal++, fal++) {
1635
1636                 /* Every activity should be known at the moment (may change in the future) */
1637                 p = get_activity_position(act, fal->id, EXIT_IF_NOT_FOUND);
1638
1639                 /* Warning: Stats structures keep their original endianness here */
1640                 if ((act[p]->nr_ini > 0) &&
1641                     ((act[p]->nr_ini > 1) || (act[p]->nr2 > 1)) &&
1642                     (act[p]->msize > ofal->size)) {
1643                         for (j = 0; j < act[p]->nr_ini; j++) {
1644                                 for (k = 0; k < act[p]->nr2; k++) {
1645                                         sa_fread(fd,
1646                                                  (char *) act[p]->buf[0] + (j * act[p]->nr2 + k) * act[p]->msize,
1647                                                  (size_t) ofal->size, HARD_SIZE, UEOF_STOP);
1648                                 }
1649                         }
1650                 }
1651                 else if (act[p]->nr_ini > 0) {
1652                         sa_fread(fd, act[p]->buf[0],
1653                                  (size_t) ofal->size * (size_t) act[p]->nr_ini * (size_t) act[p]->nr2,
1654                                  HARD_SIZE, UEOF_STOP);
1655                 }
1656
1657                 nr_struct = act[p]->nr_ini;
1658                 /*
1659                  * NB: Cannot upgrade a stats structure with
1660                  * a magic number higher than currently known.
1661                  */
1662                 if (ofal->magic < act[p]->magic) {
1663                         cc = 'u';
1664
1665                         /* Known activity but old format */
1666                         switch (fal->id) {
1667
1668                                 case A_CPU:
1669                                         upgrade_stats_cpu(act, p, ofal->size);
1670                                         break;
1671
1672                                 case A_PCSW:
1673                                         upgrade_stats_pcsw(act, p);
1674                                         break;
1675
1676                                 case A_IRQ:
1677                                         upgrade_stats_irq(act, p);
1678                                         break;
1679
1680                                 case A_IO:
1681                                         upgrade_stats_io(act, p, endian_mismatch);
1682                                         break;
1683
1684                                 case A_QUEUE:
1685                                         upgrade_stats_queue(act, p, ofal->magic,
1686                                                             endian_mismatch, arch_64);
1687                                         break;
1688
1689                                 case A_MEMORY:
1690                                         upgrade_stats_memory(act, p, ofal->size,
1691                                                              endian_mismatch, arch_64);
1692                                         break;
1693
1694                                 case A_KTABLES:
1695                                         upgrade_stats_ktables(act, p, endian_mismatch);
1696                                         break;
1697
1698                                 case A_SERIAL:
1699                                         nr_struct = upgrade_stats_serial(act, p, ofal->size,
1700                                                                          endian_mismatch);
1701                                         break;
1702
1703                                 case A_DISK:
1704                                         upgrade_stats_disk(act, p, ofal->magic,
1705                                                            endian_mismatch, arch_64);
1706                                         break;
1707
1708                                 case A_NET_DEV:
1709                                         upgrade_stats_net_dev(act, p, ofal->magic,
1710                                                               endian_mismatch, arch_64);
1711                                         break;
1712
1713                                 case A_NET_EDEV:
1714                                         upgrade_stats_net_edev(act, p, ofal->magic,
1715                                                                endian_mismatch, arch_64);
1716                                         break;
1717
1718                                 case A_NET_IP:
1719                                         upgrade_stats_net_ip(act, p, ofal->magic,
1720                                                              endian_mismatch, arch_64);
1721                                         break;
1722
1723                                 case A_NET_EIP:
1724                                         upgrade_stats_net_eip(act, p, ofal->magic,
1725                                                               endian_mismatch, arch_64);
1726                                         break;
1727
1728                                 case A_NET_IP6:
1729                                         upgrade_stats_net_ip6(act, p, ofal->magic,
1730                                                               endian_mismatch, arch_64);
1731                                         break;
1732
1733                                 case A_NET_EIP6:
1734                                         upgrade_stats_net_eip6(act, p, ofal->magic,
1735                                                                endian_mismatch, arch_64);
1736                                         break;
1737
1738                                 case A_HUGE:
1739                                         upgrade_stats_huge(act, p, endian_mismatch, arch_64);
1740                                         break;
1741
1742                                 case A_PWR_FREQ:
1743                                         upgrade_stats_pwr_wghfreq(act, p);
1744                                         break;
1745
1746                                 case A_FS:
1747                                         upgrade_stats_filesystem(act, p, ofal->size);
1748                                         break;
1749                                 }
1750                 }
1751                 else {
1752                         cc = '.';
1753                         /* Known activity with current up-to-date format */
1754                         for (j = 0; j < act[p]->nr_ini; j++) {
1755                                 for (k = 0; k < act[p]->nr2; k++) {
1756                                         memcpy((char *) act[p]->buf[1] + (j * act[p]->nr2 + k) * act[p]->msize,
1757                                                (char *) act[p]->buf[0] + (j * act[p]->nr2 + k) * act[p]->msize,
1758                                                fal->size);
1759                                 }
1760                         }
1761                 }
1762
1763                 if (fal->has_nr) {
1764
1765                         switch (fal->id) {
1766
1767                                 case A_SERIAL:
1768                                         /* Nothing to do: Already done in upgrade_stats_serial() */
1769                                         break;
1770
1771                                 case A_DISK:
1772                                         nr_struct = count_stats_disk(act, p);
1773                                         break;
1774
1775                                 case A_NET_DEV:
1776                                         nr_struct = count_stats_net_dev(act, p);
1777                                         break;
1778
1779                                 case A_NET_EDEV:
1780                                         nr_struct = count_stats_net_edev(act, p);
1781                                         break;
1782
1783                                 case A_PWR_USB:
1784                                         nr_struct = count_stats_pwr_usb(act, p);
1785                                         break;
1786
1787                                 case A_FS:
1788                                         nr_struct = count_stats_filesystem(act, p);
1789                                         break;
1790
1791                                 case A_NET_FC:
1792                                         nr_struct = count_stats_fchost(act, p);
1793                                         break;
1794                         }
1795
1796                         /* Restore endianness before writing */
1797                         if (endian_mismatch) {
1798                                 nr = __builtin_bswap32(nr_struct);
1799                         }
1800                         else {
1801                                 nr = nr_struct;
1802                         }
1803
1804                         /* Write number of structures for current activity */
1805                         if (write_all(stdfd, &nr, sizeof(__nr_t)) != sizeof(__nr_t))
1806                                 goto write_error;
1807
1808                         fprintf(stderr, "n");
1809                 }
1810
1811                 for (j = 0; j < nr_struct; j++) {
1812                         for (k = 0; k < act[p]->nr2; k++) {
1813                                 if (write_all(stdfd,
1814                                               (char *) act[p]->buf[1] + (j * act[p]->nr2 + k) * act[p]->fsize,
1815                                                act[p]->fsize) != act[p]->fsize)
1816                                         goto write_error;
1817                         }
1818                 }
1819                 fprintf(stderr, "%c", cc);
1820         }
1821
1822         return 0;
1823
1824 write_error:
1825
1826         fprintf(stderr, "\nwrite: %s\n", strerror(errno));
1827
1828         return -1;
1829
1830 }
1831
1832 /*
1833  ***************************************************************************
1834  * Upgrade statistics records.
1835  *
1836  * IN:
1837  * @fd          File descriptor for sa datafile to convert.
1838  * @stdfd       File descriptor for STDOUT.
1839  * @act         Array of activities.
1840  * @file_hdr    Pointer on file_header structure.
1841  * @ofile_actlst
1842  *              Activity list in file.
1843  * @file_actlst Activity list with up-to-date format.
1844  * @previous_format
1845  *              TRUE is sa datafile has an old format which is no longer * @endian_mismatch
1846  *              TRUE if data read from file don't match current machine's
1847  *              endianness.
1848  * @arch_64     TRUE if file's data come from a 64-bit machine.
1849
1850  *              compatible with current one.
1851  * @endian_mismatch
1852  *              TRUE if data read from file don't match current machine's
1853  *              endianness.
1854  * @arch_64     TRUE if file's data come from a 64-bit machine.
1855  * @vol_act_nr  Number of volatile activity structures.
1856  *
1857  * RETURNS:
1858  * -1 on error, 0 otherwise.
1859 ***************************************************************************
1860  */
1861 int upgrade_stat_records(int fd, int stdfd, struct activity *act[], struct file_header *file_hdr,
1862                          struct old_file_activity *ofile_actlst, struct file_activity *file_actlst,
1863                          int previous_format, int endian_mismatch, int arch_64,
1864                          unsigned int vol_act_nr)
1865 {
1866         int rtype;
1867         int eosaf;
1868         struct old_record_header orec_hdr;
1869         unsigned int orec_types_nr[] = {OLD_RECORD_HEADER_ULL_NR, OLD_RECORD_HEADER_UL_NR, OLD_RECORD_HEADER_U_NR};
1870
1871         fprintf(stderr, _("Statistics:\n"));
1872
1873         do {
1874                 eosaf = sa_fread(fd, &orec_hdr, OLD_RECORD_HEADER_SIZE, SOFT_SIZE, UEOF_STOP);
1875
1876                 /* Normalize endianness */
1877                 if (endian_mismatch) {
1878                         swap_struct(orec_types_nr, &orec_hdr, arch_64);
1879                 }
1880                 rtype = orec_hdr.record_type;
1881
1882                 if (!eosaf) {
1883                         /* Upgrade current record header */
1884                         if (upgrade_record_header(fd, stdfd, &orec_hdr,
1885                                                   endian_mismatch, arch_64) < 0)
1886                                 return -1;
1887
1888                         if (rtype == R_COMMENT) {
1889                                 /* Upgrade the COMMENT record */
1890                                 if (upgrade_comment_record(fd, stdfd) < 0)
1891                                         return -1;
1892                         }
1893                         else if (rtype == R_RESTART) {
1894                                 /* Upgrade the RESTART record */
1895                                 if (upgrade_restart_record(fd, stdfd, act, file_hdr,
1896                                                            previous_format, endian_mismatch,
1897                                                            arch_64, vol_act_nr) < 0)
1898                                         return -1;
1899                         }
1900                         else {
1901                                 /* Upgrade current statistics record */
1902                                 if (upgrade_common_record(fd, stdfd, act, file_hdr, ofile_actlst,
1903                                                           file_actlst, endian_mismatch, arch_64) < 0)
1904                                         return -1;
1905                         }
1906                 }
1907         }
1908         while (!eosaf);
1909
1910         fprintf(stderr, "\n");
1911
1912         return 0;
1913 }
1914
1915 /*
1916  ***************************************************************************
1917  * Close file descriptors and exit.
1918  *
1919  * IN:
1920  * @fd          File descriptor for sa datafile to convert.
1921  * @stdfd       File descriptor for STDOUT.
1922  * @exit_code   Exit code.
1923  ***************************************************************************
1924  */
1925 void upgrade_exit(int fd, int stdfd, int exit_code)
1926 {
1927         if (fd) {
1928                 close(fd);
1929         }
1930         if (stdfd) {
1931                 close(stdfd);
1932         }
1933         if (exit_code) {
1934                 exit(exit_code);
1935         }
1936 }
1937
1938 /*
1939  ***************************************************************************
1940  * Convert a sysstat activity data file from a previous version to the
1941  * up-to-date format. Presently data files from sysstat version 9.1.6 and
1942  * later are converted to current sysstat version format.
1943  *
1944  * IN:
1945  * @dfile       System activity data file name.
1946  * @act         Array of activities.
1947  ***************************************************************************
1948  */
1949 void convert_file(char dfile[], struct activity *act[])
1950 {
1951         int fd = 0, stdfd = 0, previous_format = 0;
1952         int arch_64 = TRUE;
1953         unsigned int vol_act_nr = 0, hdr_size;
1954         struct file_magic file_magic;
1955         struct file_header file_hdr;
1956         struct file_activity *file_actlst = NULL;
1957         struct old_file_activity *ofile_actlst = NULL;
1958
1959         /* Open stdout */
1960         if ((stdfd = dup(STDOUT_FILENO)) < 0) {
1961                 perror("dup");
1962                 upgrade_exit(0, 0, 2);
1963         }
1964
1965         /* Upgrade file's magic section */
1966         if (upgrade_magic_section(dfile, &fd, stdfd, &file_magic, &hdr_size,
1967                                   &previous_format, &endian_mismatch) < 0) {
1968                 upgrade_exit(fd, stdfd, 2);
1969         }
1970         if (previous_format == FORMAT_MAGIC) {
1971                 /* Nothing to do at the present time */
1972                 fprintf(stderr, _("\nFile format already up-to-date\n"));
1973                 goto success;
1974         }
1975
1976         if (!user_hz) {
1977                 /* Get HZ */
1978                 get_HZ();
1979         }
1980         else {
1981                 /* HZ set on the command line with option -O */
1982                 hz = user_hz;
1983         }
1984         fprintf(stderr, _("HZ: Using current value: %lu\n"), HZ);
1985
1986         /* Upgrade file's header section */
1987         if (upgrade_header_section(dfile, fd, stdfd, act, &file_magic,
1988                                    &file_hdr, hdr_size, previous_format, &arch_64,
1989                                    endian_mismatch, &vol_act_nr, &ofile_actlst) < 0) {
1990                 upgrade_exit(fd, stdfd, 2);
1991         }
1992
1993         /* Upgrade file's activity list section */
1994         if (upgrade_activity_section(stdfd, act, &file_hdr,
1995                                      ofile_actlst, &file_actlst,
1996                                      endian_mismatch, arch_64) < 0) {
1997                 upgrade_exit(fd, stdfd, 2);
1998         }
1999
2000         /* Perform required allocations */
2001         allocate_structures(act);
2002
2003         /* Upgrade statistics records */
2004         if (upgrade_stat_records(fd, stdfd, act, &file_hdr, ofile_actlst, file_actlst,
2005                                  previous_format, endian_mismatch, arch_64,
2006                                  vol_act_nr) < 0) {
2007                 upgrade_exit(fd, stdfd, 2);
2008         }
2009
2010         free(file_actlst);
2011         free(ofile_actlst);
2012         free_structures(act);
2013
2014         fprintf(stderr,
2015                 _("File successfully converted to sysstat format version %s\n"),
2016                 VERSION);
2017
2018 success:
2019         upgrade_exit(fd, stdfd, 0);
2020 }