"Fossies" - the Fresh Open Source Software Archive 
Member "atop-2.8.1/atopcat.c" (7 Jan 2023, 6702 Bytes) of package /linux/misc/atop-2.8.1.tar.gz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
For more information about "atopcat.c" see the
Fossies "Dox" file reference documentation and the last
Fossies "Diffs" side-by-side code changes report:
2.7.1_vs_2.8.0.
1 /*
2 ** ATOP - System & Process Monitor
3 **
4 ** The program 'atop' offers the possibility to view the activity of
5 ** the system on system-level as well as process-level.
6 **
7 ** This program concatenates several raw logfiles into one output stream,
8 ** to be stored as new file or to be passed via a pipe to atop/atopsar directly.
9 ** ==========================================================================
10 ** Author: Gerlof Langeveld
11 ** E-mail: gerlof.langeveld@atoptool.nl
12 ** Initial: March 2020
13 ** --------------------------------------------------------------------------
14 ** Copyright (C) 2020 Gerlof Langeveld
15 **
16 ** This program is free software; you can redistribute it and/or modify it
17 ** under the terms of the GNU General Public License as published by the
18 ** Free Software Foundation; either version 2, or (at your option) any
19 ** later version.
20 **
21 ** This program is distributed in the hope that it will be useful, but
22 ** WITHOUT ANY WARRANTY; without even the implied warranty of
23 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
24 ** See the GNU General Public License for more details.
25 **
26 ** You should have received a copy of the GNU General Public License
27 ** along with this program; if not, write to the Free Software
28 ** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
29 ** --------------------------------------------------------------------------
30 */
31 #include <sys/types.h>
32 #include <sys/param.h>
33 #include <sys/stat.h>
34 #include <fcntl.h>
35 #include <time.h>
36 #include <stdio.h>
37 #include <errno.h>
38 #include <stdlib.h>
39 #include <sys/utsname.h>
40 #include <unistd.h>
41
42 #include "atop.h"
43 #include "rawlog.h"
44
45 char *convepoch(time_t);
46 void prusage(char *);
47
48 int
49 main(int argc, char *argv[])
50 {
51 int i, fd, n, c;
52 int firstfile, beverbose=0, dryrun=0;
53 struct rawheader rh;
54 struct rawrecord rr;
55 char *infile, *sstat, *pstat;
56 unsigned short aversion;
57
58 // verify the command line arguments: input filename(s)
59 //
60 if (argc < 2)
61 prusage(argv[0]);
62
63 while ((c = getopt(argc, argv, "?hvd")) != EOF)
64 {
65 switch (c)
66 {
67 case '?': // usage wanted?
68 case 'h': // usage wanted?
69 prusage(argv[0]);
70 break;
71
72 case 'v': // verbosity wanted?
73 beverbose = 1;
74 break;
75
76 case 'd': // dry run wanted?
77 dryrun = 1;
78 break;
79
80 default:
81 prusage(argv[0]);
82 }
83 }
84
85 if ( isatty(fileno(stdout)) && !dryrun)
86 {
87 fprintf(stderr,
88 "this program produces binary output on stdout "
89 "that should be redirected\nto a file or pipe!\n");
90 exit(1);
91 }
92
93 // open all input files one-by-one
94 //
95 for (i=optind, firstfile=1; i < argc; i++, firstfile=0)
96 {
97 infile = argv[i];
98
99 // open raw file for reading
100 //
101 if ( (fd = open(infile, O_RDONLY)) == -1)
102 {
103 fprintf(stderr, "%s - ", infile);
104 perror("open for reading");
105 exit(2);
106 }
107
108 // read the raw header
109 //
110 if ( read(fd, &rh, sizeof rh) < sizeof rh)
111 {
112 fprintf(stderr, "%s: cannot read raw header\n", infile);
113 close(fd);
114 exit(3);
115 }
116
117 // verify if this is a correct rawlog file
118 //
119 if (rh.magic != MYMAGIC)
120 {
121 fprintf(stderr, "%s: not a valid rawlog file "
122 "(wrong magic number)\n", infile);
123 close(fd);
124 exit(4);
125 }
126
127 // only for the first file, store the version number and write
128 // the raw header for the entire stream
129 //
130 // for the next files, be sure that the version is the same
131 // as the first file
132 //
133 if (firstfile)
134 {
135 aversion = rh.aversion;
136
137 if (!dryrun)
138 {
139 if ( write(1, &rh, sizeof rh) < sizeof rh)
140 {
141 fprintf(stderr,
142 "can not write raw header\n");
143 exit(10);
144 }
145 }
146
147 if (beverbose)
148 {
149 fprintf(stderr,
150 "Logs created by atop version %d.%d\n\n",
151 (rh.aversion >> 8) & 0x7f,
152 rh.aversion & 0xff);
153
154 fprintf(stderr, "%-10s %-8s %12s %8s %9s\n",
155 "date", "time", "interval",
156 "comprsys", "comprproc");
157 }
158
159 }
160 else // subsequent file
161 {
162 if (aversion != rh.aversion)
163 {
164 fprintf(stderr,
165 "Version of file %s is unequal to "
166 "version of first file\n", infile);
167 close(fd);
168 exit(5);
169 }
170 }
171
172 // read every raw record followed by the compressed
173 // system-level and process-level stats
174 //
175 while ( read(fd, &rr, sizeof rr) == sizeof rr )
176 {
177 if (beverbose)
178 {
179 fprintf(stderr, "%19s %12u %8u %9u %s\n",
180 convepoch(rr.curtime),
181 rr.interval, rr.scomplen, rr.pcomplen,
182 rr.flags&RRBOOT ? "boot" : "");
183 }
184
185 // dynamically allocate space to read stats
186 //
187 if ( (sstat = malloc(rr.scomplen)) == NULL)
188 {
189 fprintf(stderr, "malloc failed for sstat\n");
190 exit(7);
191 }
192
193 if ( (pstat = malloc(rr.pcomplen)) == NULL)
194 {
195 fprintf(stderr, "malloc failed for pstat\n");
196 exit(7);
197 }
198
199 // read system-level and process-level stats
200 //
201 if ((n = read(fd, sstat, rr.scomplen)) != rr.scomplen)
202 {
203 if (n == -1)
204 {
205 fprintf(stderr, "read file %s", infile);
206 perror("");
207 exit(8);
208 }
209 else
210 {
211 fprintf(stderr,
212 "file %s incomplete!\n", infile);
213
214 free(sstat);
215 free(pstat);
216 break;
217 }
218 }
219
220 if ((n = read(fd, pstat, rr.pcomplen)) != rr.pcomplen)
221 {
222 if (n == -1)
223 {
224 fprintf(stderr, "read file %s", infile);
225 perror("");
226 exit(8);
227 }
228 else
229 {
230 fprintf(stderr,
231 "file %s incomplete!\n", infile);
232
233 free(sstat);
234 free(pstat);
235 break;
236 }
237 }
238
239 if (!dryrun)
240 {
241 // write raw record followed by the compressed
242 // system-level and process-level stats
243 //
244 if ( write(1, &rr, sizeof rr) < sizeof rr)
245 {
246 fprintf(stderr,
247 "can not write raw record\n");
248 exit(11);
249 }
250
251 if ( write(1, sstat, rr.scomplen) < rr.scomplen)
252 {
253 fprintf(stderr,
254 "can not write sstat\n");
255 exit(11);
256 }
257
258 if ( write(1, pstat, rr.pcomplen) < rr.pcomplen)
259 {
260 fprintf(stderr,
261 "can not write pstat\n");
262 exit(11);
263 }
264 }
265
266 // free dynamically allocated buffers
267 //
268 free(sstat);
269 free(pstat);
270 }
271
272 close(fd);
273 }
274
275 return 0;
276 }
277
278 // Function to convert an epoch time to date-time format
279 //
280 char *
281 convepoch(time_t utime)
282 {
283 struct tm *tt;
284 static char datetime[64];
285
286
287 tt = localtime(&utime);
288
289 sprintf(datetime, "%04d/%02d/%02d %02d:%02d:%02d",
290 tt->tm_year+1900, tt->tm_mon+1, tt->tm_mday,
291 tt->tm_hour, tt->tm_min, tt->tm_sec);
292
293 return datetime;
294 }
295
296 // Function that shows the usage message
297 //
298 void
299 prusage(char *name)
300 {
301 fprintf(stderr, "Usage: %s [-dv] rawfile [rawfile]...\n", name);
302 fprintf(stderr, "\t-d\tdry run (no raw output generated)\n");
303 fprintf(stderr, "\t-v\tbe verbose\n");
304 exit(1);
305 }