Request for comment about a resolution for Monitoring ServiceNames with white spaces

Matthew.Roberts at nt.gov.au Matthew.Roberts at nt.gov.au
Mon May 12 03:30:44 CEST 2008


Hi Again,

I didn't get a response to a post made to this mailing list about monitoring
Services with names that were multiple words separated by a whitespace character
http://www.hobbitmon.com/hobbiton/2008/05/msg00001.htm so I did some searching
through the hobbit source code to find out where my problem lay and managed to
identify the problem and resolve it.

The problem seemed to be in the way that the data containing the list of
Services and their status is formatted by the BBWin client when sent to the
Hobbit Server. It uses whitespaces to format the Service information into
columns so that it can be viewed in a nice way rather then scattered all over
the screen. To handle these whitespaces and determine which columns actually
contain useful data, the nextcolumn function inside lib/misc.c is used to
determine the location of these whitespaces within the string so that the
getcolumn function can be used to retrieve the ServiceName, StartupType and
Status for each service. This works brilliantly for services that are one word
or use an underscore character to separate the words, however fails when the
ServiceName contains a whitespace. In case I didn't explain this very well, an
example of what was being returned is:

If the service name is Alerter

namestr = getcolumn(p, namecol) which returns Alerter
startupstr = getcolumn(p, startupcol) which returns Disabled
statestr = getcolum(p, statecol) which returns Stopped

If the service name is multi word such as "VMware NAS Service"

namestr = getcolumn(p, namecol) which returns VMware
startupstr = getcolumn(p, startupcol) which returns NAS
statestr = getcolum(p, statecol) which returns Service


I am not a C programmer and the first time I actually looked at source code
written in C was to diagnose this problem. However I have managed to resolve the
problem by writing my own function within the bbwin.c source which checks the
string returned by getcoumn(p, startupcol) and if it doesnt contain either
StartupType, automatic, manual or disabled, then to keep looping until one of
these strings are located. Due to the fact that I am not a C programmer, and
that we rely heavily on Hobbit for our system monitoring, I am posting this to
the mailing list so that I can get comment from Henrik or someone else who does
have knowledge in C programming on the changes I have made and tell me if they
can identify any flaws in it which may jeopardize the Hobbit application. I have
tested the changes in our test environment containing a couple of monitored
clients and it works great! However I am hesitant to patch our production
environment until I can get some reassurance that the Hobbit Monitoring wont
crash a week or two later because of my poor coding. For easier reading, I have
pasted a copy of the difference file between my modified version of the bbwin.c
and the bbwin.patch release version below.


         --- bbwin.c    2008-09-08 08:51:59.000000000 +0930
         +++ ./hobbitd/client/bbwin.c     2008-05-12 09:21:22.000000000 +0930
         @@ -283,6 +283,57 @@
                  freestrbuffer(whomsg);
          }

         +/* This function was added to handle spaces in Service Names
         +        it is called by a modified section further below */
         +
         +int handle_bbwin_services(char substring[80])
         +{
         + int i=0,j=0,k=0,count=0,l=0,k1=0;
         + char mainstring[80] = "StartupType,automatic,manual,disabled"; /*
         Main String to be searched */
         + int result=0;
         + l=strlen(substring);
         +
         + while (mainstring[i]!=EOF)
         + {
         +  if (mainstring[i]==substring[j])
         +  {
         +   i++;
         +   j++;
         +   k1=1;
         +   if (j==l)
         +   {
         +    j=0;
         +    k=1;
         +    count=count+1;
         +   }
         +  }
         +  else
         +  {
         +   if (k1==1)
         +   {
         +    j=0;
         +    k1=0;
         +   }
         +   else
         +    i++;
         +  }
         + }
         +
         +  if (k==1)
         +  {
         +  //Match found! Set result to value of 1
         +   result = 1;
         +  }
         +  else
         +  {
         +   if (k==0)
         +  //Match not found! Set result to value of 0
         +    result = 0;
         +  }
         +//Return result, result of 1 will break WHILE loop.
         +return result;
         +}
         +
          void bbwin_svcs_report(char *hostname, char *clientclass, enum
         ostype_t os,
                                 void *hinfo, char *fromline, char *timestr,
                                 int namecol, int startupcol, int statecol, char
         *svcstr, char *svcauto)
         @@ -310,6 +361,9 @@
                          int scount, scolor;
                          char *namestr, *startupstr, *statestr;

         +/* This section was modified to handle spaces in Service Names
         +  the function handle_bbwin_services is defined above */
         +
                          bol = svcstr;
                          while (bol) {
                                  char *p;
         @@ -317,10 +371,31 @@
                                  nl = strchr(bol, '\n'); if (nl) *nl = '\0';

                                  /* Data lines */
         +
         +                        p = strdup(bol);
         +              namestr = getcolumn(p, namecol);
         +                        strcpy(p, bol);
         +              startupstr = getcolumn(p, startupcol);
         +
         +              int newnamecol = namecol;
         +                        int newstartupcol= startupcol;
         +                        int newstatecol = statecol;
         +
         +              int breaktest = handle_bbwin_services(startupstr);
         +
         +              while(breaktest == 0){
         +                    newstartupcol += 1; newstatecol +=1; newnamecol
         +=1;
         +                    p = strdup(bol);
         +                    sprintf(namestr, "%s %s", namestr, getcolumn(p,
         newnamecol));
         +                    strcpy(p, bol);
         +                    startupstr = getcolumn(p, newstartupcol);
         +                    breaktest = handle_bbwin_services(startupstr);
         +              }
         +
         +                        strcpy(p, bol);
         +              statestr = getcolumn(p, newstatecol);

         -                        p = strdup(bol); namestr = getcolumn(p,
         namecol);
         -                        strcpy(p, bol); startupstr = getcolumn(p,
         startupcol);
         -                        strcpy(p, bol); statestr = getcolumn(p,
         statecol);
         +// End of modified Section

                                  add_svc_count(namestr, startupstr, statestr);

         @@ -382,7 +457,7 @@
                  }

                          /* And the full svc output for those who want it
         "commented out because I dont care about other services*/
         -                if (svclistinsvcs) addtostatus(svcstr);
         +                //if (svclistinsvcs) addtostatus(svcstr);

                          if (fromline) addtostatus(fromline);
                          finish_status();


Appologies for the length of the email, I didnt want to attach my modified
source as a patch file incase it was blocked by firewalls.

Regards,

Matthew Roberts
Senior Systems Administrator - Windows




More information about the Xymon mailing list