"Fossies" - the Fresh Open Source Software Archive

Member "procmeter3-3.6+svn387/procmeter.c" (3 Jan 2012, 12570 Bytes) of package /linux/misc/procmeter3-3.6+svn387.tgz:


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 "procmeter.c" see the Fossies "Dox" file reference documentation.

    1 /***************************************
    2   ProcMeter - A system monitoring program for Linux - Version 3.6.
    3 
    4   Main program.
    5   ******************/ /******************
    6   Written by Andrew M. Bishop
    7 
    8   This file Copyright 1998-2012 Andrew M. Bishop
    9   It may be distributed under the GNU Public License, version 2, or
   10   any higher version.  See section COPYING of the GNU Public license
   11   for conditions under which this file may be redistributed.
   12   ***************************************/
   13 
   14 #include <stdlib.h>
   15 #include <stdio.h>
   16 #include <string.h>
   17 #include <ctype.h>
   18 
   19 #include <unistd.h>
   20 #include <time.h>
   21 #include <signal.h>
   22 #include <sys/wait.h>
   23 
   24 #include "procmeter.h"
   25 #include "procmeterp.h"
   26 
   27 
   28 static char *get_substring(char **start,int length);
   29 static void sigexit(int signum);
   30 static void sigchild(int signum);
   31 
   32 /*+ The signal to tell us to exit. +*/
   33 int quit=0;
   34 
   35 /*+ Indicates that help mode is wanted. +*/
   36 static int help=0;
   37 
   38 
   39 int main(int argc,char **argv)
   40 {
   41  time_t now,now2;
   42  struct sigaction action;
   43  int i;
   44 
   45  /* Handle signals */
   46 
   47  /* SIGINT, SIGQUIT, SIGTERM */
   48  action.sa_handler = sigexit;
   49  sigemptyset(&action.sa_mask);
   50  sigaddset(&action.sa_mask, SIGINT);           /* Block all of them */
   51  sigaddset(&action.sa_mask, SIGQUIT);
   52  sigaddset(&action.sa_mask, SIGTERM);
   53  sigaddset(&action.sa_mask, SIGCHLD);
   54  action.sa_flags = 0;
   55  if(sigaction(SIGINT, &action, NULL) != 0)
   56     fprintf(stderr,"ProcMeter: Cannot install SIGINT handler.\n");
   57  if(sigaction(SIGQUIT, &action, NULL) != 0)
   58     fprintf(stderr,"ProcMeter: Cannot install SIGQUIT handler.\n");
   59  if(sigaction(SIGTERM, &action, NULL) != 0)
   60     fprintf(stderr,"ProcMeter: Cannot install SIGTERM handler.\n");
   61 
   62  /* SIGCHILD */
   63  action.sa_handler = sigchild;
   64  sigemptyset(&action.sa_mask);
   65  sigaddset(&action.sa_mask, SIGINT);           /* Block all of them */
   66  sigaddset(&action.sa_mask, SIGQUIT);
   67  sigaddset(&action.sa_mask, SIGTERM);
   68  action.sa_flags = 0;
   69  if(sigaction(SIGCHLD, &action, NULL) != 0)
   70     fprintf(stderr,"ProcMeter: Cannot install SIGCHLD handler.\n");
   71 
   72  /* Parse the command line. */
   73 
   74  for(i=1;i<argc;i++)
   75     if(!strcmp(argv[i],"-h") || !strcmp(argv[i],"--help"))
   76       {
   77        for(argc--;i<argc;i++)
   78           argv[i]=argv[i+1];
   79        help=1;
   80       }
   81 
   82  /* Initialise things */
   83 
   84  LoadProcMeterRC(&argc,argv);
   85 
   86  if(!help)
   87     Start(&argc,argv);
   88 
   89  LoadAllModules();
   90 
   91  if(!help)
   92     AddDefaultOutputs(argc,argv);
   93 
   94  if(!help)
   95    {
   96     /* The main loop */
   97 
   98     now=time(NULL);
   99 
  100     do
  101       {
  102        /* handle time leaps (rdate, xntpd, or laptop sleep/hibernation) */
  103        /* We choose to be somewhat lenient and decide that one occured if the
  104           expected time is more than 5 seconds ahead or behind the current time. */
  105 
  106        now2=time(NULL);            /* Should be now+interval if there is no jump. */
  107 
  108        if(now2>(now+4) || now2<(now-4))
  109           now=now2+1;
  110        else
  111           now=now+1;
  112 
  113        /* Wait for a while */
  114 
  115        Sleep(now);
  116 
  117        /* Update the outputs */
  118 
  119        UpdateOutputs(now);
  120       }
  121     while(!quit);
  122    }
  123  else
  124    {
  125     static char double_underline[]="===============================";
  126     static char underline[]="-------------------------------";
  127     Module *modulep;
  128     Output *outputp;
  129 
  130     printf("\nProcMeter Version %s\n%s\n\n",PROCMETER_VERSION,&double_underline[sizeof(double_underline)-18-sizeof(PROCMETER_VERSION)]);
  131     printf("An efficient modular system monitoring program for Linux.\n");
  132     printf("(c) Andrew M. Bishop 1998-2012 [amb@gedanken.demon.co.uk]\n\n");
  133 
  134     printf("Usage: ProcMeter [-h] [--rc=<filename>] [--...] [...]\n\n");
  135 
  136     printf("To specify the displayed outputs use <module>.<output>[-g|-t|-b] where module\n"
  137            "and output come from the list below and '-g', '-t' and '-b' choose graph, text\n"
  138            "or bar format.   e.g. procmeter3 Statistics.CPU-g Processes.Load-t\n");
  139 
  140     for(modulep=Modules;*modulep;modulep++)
  141       {
  142        ProcMeterOutput *last=NULL;
  143        char *p=(*modulep)->module->description;
  144 
  145        printf("\n\n%s\n%s\n\n",(*modulep)->module->name,&underline[sizeof(underline)-1-strlen((*modulep)->module->name)]);
  146 
  147        while(p)
  148           printf("%s\n",get_substring(&p,80));
  149 
  150        if(*(*modulep)->outputs)
  151           printf("\n");
  152 
  153        for(outputp=(*modulep)->outputs;*outputp;outputp++)
  154          {
  155           if(last!=(*outputp)->output)
  156             {
  157              char *p=(*outputp)->output->description;
  158              int first=1;
  159 
  160              while(p)
  161                {
  162                 if(first)
  163                    printf("%-*s (%c%c%c) : ",PROCMETER_NAME_LEN,(*outputp)->output->name,
  164                           (*outputp)->output->type&PROCMETER_GRAPH?'G':' ',
  165                           (*outputp)->output->type&PROCMETER_TEXT?'T':' ',
  166                           (*outputp)->output->type&PROCMETER_BAR?'B':' ');
  167                 else
  168                    printf("%-*s         ",PROCMETER_NAME_LEN," ");
  169 
  170                 printf("%s\n",get_substring(&p,80-PROCMETER_NAME_LEN-9));
  171 
  172                 first=0;
  173                }
  174             }
  175           last=(*outputp)->output;
  176          }
  177       }
  178    }
  179 
  180  /* Tidy up and exit. */
  181 
  182  UnloadAllModules();
  183 
  184  FreeProcMeterRC();
  185 
  186  if(!help)
  187     Stop();
  188 
  189  return(0);
  190 }
  191 
  192 
  193 /*++++++++++++++++++++++++++++++++++++++
  194   Perform the updates.
  195 
  196   time_t now The current time.
  197   ++++++++++++++++++++++++++++++++++++++*/
  198 
  199 void UpdateOutputs(time_t now)
  200 {
  201  Module *module;
  202  Output *output;
  203  ProcMeterOutput *last=NULL;
  204 
  205  for(module=Modules;*module;module++)
  206     for(output=(*module)->outputs;*output;output++)
  207        if((*output)->output_widget &&
  208           (((*output)->output->interval && !(now%(*output)->output->interval)) ||
  209           (*output)->first))
  210          {
  211           if(last!=(*output)->output)
  212              if((*module)->Update(now,(*output)->output)==-1)
  213                 fprintf(stderr,"ProcMeter: Error updating %s.%s\n",(*module)->module->name,(*output)->output->name);
  214 
  215           if((*output)->first)
  216              (*output)->first--;
  217 
  218           if(!(*output)->first)
  219             {
  220              if((*output)->type==PROCMETER_GRAPH)
  221                {
  222                 long value=(*output)->output->graph_value;
  223                 if(value<0)
  224                    value=0;
  225                 if(value>65535)
  226                    value=65535;
  227                 UpdateGraph(*output,value);
  228                }
  229              else if((*output)->type==PROCMETER_TEXT)
  230                 UpdateText(*output,(*output)->output->text_value);
  231              else if((*output)->type==PROCMETER_BAR)
  232                {
  233                 long value=(*output)->output->graph_value;
  234                 if(value<0)
  235                    value=0;
  236                 if(value>65535)
  237                    value=65535;
  238                 UpdateBar(*output,value);
  239                }
  240             }
  241 
  242           last=(*output)->output;
  243          }
  244 }
  245 
  246 
  247 /*++++++++++++++++++++++++++++++++++++++
  248   Add the default outputs at startup.
  249 
  250   int argc The number of command line arguments.
  251 
  252   char **argv The command line arguments.
  253   ++++++++++++++++++++++++++++++++++++++*/
  254 
  255 void AddDefaultOutputs(int argc,char **argv)
  256 {
  257  Output *outputp=NULL;
  258  Module *modulep=NULL;
  259  char *string;
  260  int arg;
  261 
  262  if((string=GetProcMeterRC("startup","order")))
  263    {
  264     char *s=string;
  265 
  266     while(*s && *s==' ')
  267        s++;
  268 
  269     while(*s)
  270       {
  271        int found=0;
  272 
  273        for(modulep=Modules;*modulep;modulep++)
  274          {
  275           if(!strncmp((*modulep)->module->name,s,strlen((*modulep)->module->name)) &&
  276              s[strlen((*modulep)->module->name)]=='.')
  277             {
  278              for(outputp=(*modulep)->outputs;*outputp;outputp++)
  279                 if(!strncmp((*outputp)->output->name,&s[strlen((*modulep)->module->name)+1],strlen((*outputp)->output->name)) &&
  280                    (s[strlen((*modulep)->module->name)+strlen((*outputp)->output->name)+1]=='-' ||
  281                     s[strlen((*modulep)->module->name)+strlen((*outputp)->output->name)+1]==' ' ||
  282                     s[strlen((*modulep)->module->name)+strlen((*outputp)->output->name)+1]==0))
  283                   {
  284                    if((s[strlen((*modulep)->module->name)+strlen((*outputp)->output->name)+1]==' ' ||
  285                        s[strlen((*modulep)->module->name)+strlen((*outputp)->output->name)+1]==0) &&
  286                       !(*outputp)->output_widget)
  287                       AddRemoveOutput(*outputp);
  288                    else if(s[strlen((*modulep)->module->name)+strlen((*outputp)->output->name)+2]=='g' &&
  289                            (*outputp)->type==PROCMETER_GRAPH &&
  290                            !(*outputp)->output_widget)
  291                       AddRemoveOutput(*outputp);
  292                    else if(s[strlen((*modulep)->module->name)+strlen((*outputp)->output->name)+2]=='t' &&
  293                            (*outputp)->type==PROCMETER_TEXT &&
  294                            !(*outputp)->output_widget)
  295                       AddRemoveOutput(*outputp);
  296                    else if(s[strlen((*modulep)->module->name)+strlen((*outputp)->output->name)+2]=='b' &&
  297                            (*outputp)->type==PROCMETER_BAR &&
  298                            !(*outputp)->output_widget)
  299                       AddRemoveOutput(*outputp);
  300                    found=1;
  301                   }
  302 
  303              if(found)
  304                 break;
  305             }
  306          }
  307 
  308        while(*s && *s!=' ')
  309           s++;
  310        while(*s && *s==' ')
  311           s++;
  312       }
  313    }
  314 
  315  for(arg=1;arg<argc;arg++)
  316    {
  317     int found=0;
  318 
  319     for(modulep=Modules;*modulep;modulep++)
  320        if(!strncmp((*modulep)->module->name,argv[arg],strlen((*modulep)->module->name)) &&
  321           argv[arg][strlen((*modulep)->module->name)]=='.')
  322          {
  323           for(outputp=(*modulep)->outputs;*outputp;outputp++)
  324              if(!strncmp((*outputp)->output->name,&argv[arg][strlen((*modulep)->module->name)+1],strlen((*outputp)->output->name)) &&
  325                 (argv[arg][strlen((*modulep)->module->name)+strlen((*outputp)->output->name)+1]=='-' ||
  326                  argv[arg][strlen((*modulep)->module->name)+strlen((*outputp)->output->name)+1]==0))
  327                {
  328                 if(!argv[arg][strlen((*modulep)->module->name)+strlen((*outputp)->output->name)+1] &&
  329                    !(*outputp)->output_widget)
  330                    AddRemoveOutput(*outputp);
  331                 else if(argv[arg][strlen((*modulep)->module->name)+strlen((*outputp)->output->name)+2]=='g' &&
  332                         (*outputp)->type==PROCMETER_GRAPH &&
  333                         !(*outputp)->output_widget)
  334                    AddRemoveOutput(*outputp);
  335                 else if(argv[arg][strlen((*modulep)->module->name)+strlen((*outputp)->output->name)+2]=='t' &&
  336                         (*outputp)->type==PROCMETER_TEXT &&
  337                         !(*outputp)->output_widget)
  338                    AddRemoveOutput(*outputp);
  339                 else if(argv[arg][strlen((*modulep)->module->name)+strlen((*outputp)->output->name)+2]=='b' &&
  340                         (*outputp)->type==PROCMETER_BAR &&
  341                         !(*outputp)->output_widget)
  342                    AddRemoveOutput(*outputp);
  343                 found=1;
  344                }
  345 
  346           if(found)
  347              break;
  348          }
  349 
  350     if(!*modulep)
  351        fprintf(stderr,"ProcMeter: Unrecognised output '%s'\n",argv[arg]);
  352    }
  353 }
  354 
  355 
  356 /*++++++++++++++++++++++++++++++++++++++
  357   Make a substring copy of the specified string.
  358 
  359   char *get_substring Returns a copy.
  360 
  361   char **start The start position in the string.
  362 
  363   int length The length of string to return.
  364   ++++++++++++++++++++++++++++++++++++++*/
  365 
  366 static char *get_substring(char **start,int length)
  367 {
  368  static char string[81];
  369 
  370  if(strlen(*start)>length)
  371    {
  372     char *p=*start+length;
  373 
  374     if(!isspace(*p))
  375       {
  376        while(p>*start && !isspace(*p))
  377           p--;
  378        if(p==*start)
  379           p=*start+length;
  380        else
  381           p++;
  382       }
  383 
  384     strncpy(string,*start,(p-*start));
  385     string[p-*start]=0;
  386 
  387     while(*p==' ')
  388        p++;
  389     if(!*p)
  390        p=NULL;
  391 
  392     *start=p;
  393    }
  394  else
  395    {
  396     strcpy(string,*start);
  397     *start=NULL;
  398    }
  399 
  400  return(string);
  401 }
  402 
  403 
  404 /*++++++++++++++++++++++++++++++++++++++
  405   The signal handler for the signals to tell us to exit.
  406 
  407   int signum The signal number.
  408   ++++++++++++++++++++++++++++++++++++++*/
  409 
  410 static void sigexit(int signum)
  411 {
  412  quit=1;
  413 }
  414 
  415 
  416 /*++++++++++++++++++++++++++++++++++++++
  417   The signal handler for the child processes terminating.
  418 
  419   int signum The signal number.
  420   ++++++++++++++++++++++++++++++++++++++*/
  421 
  422 static void sigchild(int signum)
  423 {
  424  pid_t pid;
  425  int status;
  426 
  427  while((pid=waitpid(-1,&status,WNOHANG))>0)
  428     ;
  429 }