"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 }