Logo Search packages:      
Sourcecode: hobbit version File versions  Download package

hobbit-confreport.c

/*----------------------------------------------------------------------------*/
/* Hobbit CGI tool to generate a report of the Hobbit configuration           */
/*                                                                            */
/* Copyright (C) 2003-2006 Henrik Storner <henrik@storner.dk>                 */
/*                                                                            */
/* This program is released under the GNU General Public License (GPL),       */
/* version 2. See the file "COPYING" for details.                             */
/*                                                                            */
/*----------------------------------------------------------------------------*/

static char rcsid[] = "$Id: hobbit-confreport.c,v 1.15 2006/05/31 16:12:38 henrik Rel $";

#include <sys/types.h>
#include <sys/stat.h>
#include <limits.h>
#include <stdio.h>
#include <fcntl.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <ctype.h>
#include <time.h>
#include <dirent.h>

#include "libbbgen.h"

typedef struct hostlist_t {
      char *hostname;
      int testcount;
      htnames_t *tests;
      htnames_t *disks, *svcs, *procs;
      struct hostlist_t *next;
} hostlist_t;

typedef struct coltext_t {
      char *colname;
      char *coldescr;
      int used;
      struct coltext_t *next;
} coltext_t;

hostlist_t *hosthead = NULL;
static char *pingcolumn = "conn";
static char *pingplus = "conn=";
static char *coldelim = ";";
static coltext_t *chead = NULL;
static int ccount = 0;

void errormsg(char *msg)
{
        printf("Content-type: %s\n\n", xgetenv("HTMLCONTENTTYPE"));
        printf("<html><head><title>Invalid request</title></head>\n");
        printf("<body>%s</body></html>\n", msg);
        exit(1);
}

static int host_compare(const void *v1, const void *v2)
{
      hostlist_t **h1 = (hostlist_t **)v1;
      hostlist_t **h2 = (hostlist_t **)v2;

      return strcmp((*h1)->hostname, (*h2)->hostname);
}

static int test_compare(const void *v1, const void *v2)
{
      htnames_t **t1 = (htnames_t **)v1;
      htnames_t **t2 = (htnames_t **)v2;

      return strcmp((*t1)->name, (*t2)->name);
}


static int is_net_test(char *tname)
{
      char *miscnet[] = { NULL,  "http", "dns", "dig", "rpc", "ntp", "ldap", "content", "sslcert", NULL };
      int i;

      miscnet[0] = pingcolumn; /* Cannot be computed in advance */
      if (find_tcp_service(tname)) return 1;
      for (i=0; (miscnet[i]); i++) if (strcmp(tname, miscnet[i]) == 0) return 1;

      return 0;
}


void use_columndoc(char *column)
{
      coltext_t *cwalk;

      for (cwalk = chead; (cwalk && strcasecmp(cwalk->colname, column)); cwalk = cwalk->next);
      if (cwalk) cwalk->used = 1;
}

typedef struct tag_t {
      char *columnname;
      char *visualdata; /* The URL or other end-user visible test spec. */
      char *expdata;
      int b1, b2, b3;         /* "badFOO" values, if any */
      struct tag_t *next;
} tag_t;

static void print_disklist(char *hostname)
{
      /*
       * We get the list of monitored disks/filesystems by looking at the
       * set of disk RRD files for this host. That way we do not have to
       * parse the disk status reports that come in many different flavours.
       */

      char dirname[PATH_MAX];
      char fn[PATH_MAX];
      DIR *d;
      struct dirent *de;
      char *p;

      sprintf(dirname, "%s/%s", xgetenv("BBRRDS"), hostname);
      d = opendir(dirname);
      if (!d) return;

      while ((de = readdir(d)) != NULL) {
            if (strncmp(de->d_name, "disk,", 5) == 0) {
                  strcpy(fn, de->d_name + 4);
                  p = strstr(fn, ".rrd"); if (!p) continue;
                  *p = '\0';
                  p = fn; while ((p = strchr(p, ',')) != NULL) *p = '/';
                  fprintf(stdout, "%s<br>\n", fn);
            }
      }

      closedir(d);
}

static void print_host(hostlist_t *host, htnames_t *testnames[], int testcount)
{
      int testi, rowcount, netcount;
      namelist_t *hinfo = hostinfo(host->hostname);
      char *dispname = NULL, *clientalias = NULL, *comment = NULL, *description = NULL, *pagepathtitle = NULL;
      char *net = NULL, *nkalerts = NULL;
      char *nktime = NULL, *downtime = NULL, *reporttime = NULL;
      char *itm;
      tag_t *taghead = NULL;
      int contidx = 0, haveping = 0;
      char contcol[1024];
      activealerts_t *alert;
      strbuffer_t *buf = newstrbuffer(0); 

      fprintf(stdout, "<p style=\"page-break-before: always\">\n"); 
      fprintf(stdout, "<table width=\"100%%\" border=1 summary=\"%s configuration\">\n", host->hostname);

      pagepathtitle = bbh_item(hinfo, BBH_PAGEPATHTITLE);
      if (!pagepathtitle || (strlen(pagepathtitle) == 0)) pagepathtitle = "Top page";
      dispname = bbh_item(hinfo, BBH_DISPLAYNAME); 
      if (dispname && (strcmp(dispname, host->hostname) == 0)) dispname = NULL;
      clientalias = bbh_item(hinfo, BBH_CLIENTALIAS); 
      if (clientalias && (strcmp(clientalias, host->hostname) == 0)) clientalias = NULL;
      comment = bbh_item(hinfo, BBH_COMMENT);
      description = bbh_item(hinfo, BBH_DESCRIPTION); 
      net = bbh_item(hinfo, BBH_NET);
      nktime = bbh_item(hinfo, BBH_NKTIME); if (!nktime) nktime = "24x7"; else nktime = strdup(timespec_text(nktime));
      downtime = bbh_item(hinfo, BBH_DOWNTIME); if (downtime) downtime = strdup(timespec_text(downtime));
      reporttime = bbh_item(hinfo, BBH_REPORTTIME); if (!reporttime) reporttime = "24x7"; else reporttime = strdup(timespec_text(reporttime));

      rowcount = 1;
      if (pagepathtitle) rowcount++;
      if (dispname || clientalias) rowcount++;
      if (comment) rowcount++;
      if (description) rowcount++;
      if (nktime) rowcount++;
      if (downtime) rowcount++;
      if (reporttime) rowcount++;

      fprintf(stdout, "<tr>\n");
      fprintf(stdout, "<th rowspan=%d align=left width=\"25%%\" valign=top>Basics</th>\n", rowcount);
      fprintf(stdout, "<th align=center>%s (%s)</th>\n", 
            (dispname ? dispname : host->hostname), bbh_item(hinfo, BBH_IP));
      fprintf(stdout, "</tr>\n");

      if (dispname || clientalias) {
            fprintf(stdout, "<tr><td>Aliases:");
            if (dispname) fprintf(stdout, " %s", dispname);
            if (clientalias) fprintf(stdout, " %s", clientalias);
            fprintf(stdout, "</td></tr>\n");
      }
      if (pagepathtitle) fprintf(stdout, "<tr><td>Monitoring location: %s</td></tr>\n", pagepathtitle);
      if (comment) fprintf(stdout, "<tr><td>Comment: %s</td></tr>\n", comment);
      if (description) fprintf(stdout, "<tr><td>Description: %s</td></tr>\n", description);
      if (nktime) fprintf(stdout, "<tr><td>NK monitoring period: %s</td></tr>\n", nktime);
      if (downtime) fprintf(stdout, "<tr><td>Planned downtime: %s</td></tr>\n", downtime);
      if (reporttime) fprintf(stdout, "<tr><td>SLA Reporting Period: %s</td></tr>\n", reporttime);


      nkalerts = bbh_item(hinfo, BBH_NK);

      /* Build a list of the network tests */
      itm = bbh_item_walk(hinfo);
      while (itm) {
            char *visdata = NULL, *colname = NULL, *expdata = NULL;
            bburl_t bu;
            int dialuptest = 0, reversetest = 0, alwaystruetest = 0, httpextra = 0;

            if (*itm == '?') { dialuptest=1;     itm++; }
            if (*itm == '!') { reversetest=1;    itm++; }
            if (*itm == '~') { alwaystruetest=1; itm++; }

            if ( argnmatch(itm, "http")         ||
                 argnmatch(itm, "content=http") ||
                 argnmatch(itm, "cont;http")    ||
                 argnmatch(itm, "cont=")        ||
                 argnmatch(itm, "nocont;http")  ||
                 argnmatch(itm, "nocont=")      ||
                 argnmatch(itm, "post;http")    ||
                 argnmatch(itm, "post=")        ||
                 argnmatch(itm, "nopost;http")  ||
                 argnmatch(itm, "nopost=")      ||
                 argnmatch(itm, "type;http")    ||
                 argnmatch(itm, "type=")        ) {
                  visdata = decode_url(itm, &bu);
                  colname = bu.columnname; 
                  if (!colname) {
                        if (bu.expdata) {
                              httpextra = 1;
                              if (contidx == 0) {
                                    colname = "content";
                                    contidx++;
                              }
                              else {
                                    sprintf(contcol, "content%d", contidx);
                                    colname = contcol;
                                    contidx++;
                              }
                        }
                        else {
                              colname = "http";
                        }
                  }
                  expdata = bu.expdata;
            }
            else if (strncmp(itm, "rpc=", 4) == 0) {
                  colname = "rpc";
                  visdata = strdup(itm+4);
            }
            else if (strncmp(itm, "dns=", 4) == 0) {
                  colname = "dns";
                  visdata = strdup(itm+4);
            }
            else if (strncmp(itm, "dig=", 4) == 0) {
                  colname = "dns";
                  visdata = strdup(itm+4);
            }
            else if (strncmp(itm, pingplus, strlen(pingplus)) == 0) {
                  haveping = 1;
                  colname = pingcolumn;
                  visdata = strdup(itm+strlen(pingplus));
            }
            else if (is_net_test(itm)) {
                  colname = strdup(itm);
            }


            if (colname) {
                  tag_t *newitem;

addtolist:
                  for (newitem = taghead; (newitem && strcmp(newitem->columnname, colname)); newitem = newitem->next);

                  if (!newitem) {
                        newitem = (tag_t *)calloc(1, sizeof(tag_t));
                        newitem->columnname = strdup(colname);
                        newitem->visualdata = (visdata ? strdup(visdata) : NULL);
                        newitem->expdata = (expdata ? strdup(expdata) : NULL);
                        newitem->next = taghead;
                        taghead = newitem;
                  }
                  else {
                        /* Multiple tags for one column - must be http */
                        newitem->visualdata = (char *)realloc(newitem->visualdata, strlen(newitem->visualdata) + strlen(visdata) + 5);
                        strcat(newitem->visualdata, "<br>");
                        strcat(newitem->visualdata, visdata);
                  }

                  if (httpextra) {
                        httpextra = 0;
                        colname = "http";
                        expdata = NULL;
                        goto addtolist;
                  }
            }

            itm = bbh_item_walk(NULL);
      }

      if (!haveping && !bbh_item(hinfo, BBH_FLAG_NOCONN)) {
            for (testi = 0; (testi < testcount); testi++) {
                  if (strcmp(testnames[testi]->name, pingcolumn) == 0) {
                        tag_t *newitem = (tag_t *)calloc(1, sizeof(tag_t));
                        newitem->columnname = strdup(pingcolumn);
                        newitem->next = taghead;
                        taghead = newitem;
                  }
            }
      }

      /* Add the "badFOO" settings */
      itm = bbh_item_walk(hinfo);
      while (itm) {
            if (strncmp(itm, "bad", 3) == 0) {
                  char *tname, *p;
                  int b1, b2, b3, n = -1;
                  tag_t *tag = NULL;

                  tname = itm+3; 
                  p = strchr(tname, ':'); 
                  if (p) {
                        *p = '\0';
                        n = sscanf(p+1, "%d:%d:%d", &b1, &b2, &b3);
                        for (tag = taghead; (tag && strcmp(tag->columnname, tname)); tag = tag->next);
                        *p = ':';
                  }

                  if (tag && (n == 3)) {
                        tag->b1 = b1; tag->b2 = b2; tag->b3 = b3;
                  }
            }

            itm = bbh_item_walk(NULL);
      }

      if (taghead) {
            fprintf(stdout, "<tr>\n");
            fprintf(stdout, "<th align=left valign=top>Network tests");
            if (net) fprintf(stdout, "<br>(from %s)", net);
            fprintf(stdout, "</th>\n");

            fprintf(stdout, "<td><table border=0 cellpadding=\"3\" cellspacing=\"5\" summary=\"%s network tests\">\n", host->hostname);
            fprintf(stdout, "<tr><th align=left valign=top>Service</th><th align=left valign=top>NK</th><th align=left valign=top>C/Y/R limits</th><th align=left valign=top>Specifics</th></tr>\n");
      }
      for (testi = 0, netcount = 0; (testi < testcount); testi++) {
            tag_t *twalk;

            for (twalk = taghead; (twalk && strcasecmp(twalk->columnname, testnames[testi]->name)); twalk = twalk->next);
            if (!twalk) continue;

            use_columndoc(testnames[testi]->name);
            fprintf(stdout, "<tr>");
            fprintf(stdout, "<td valign=top>%s</td>", testnames[testi]->name);
            fprintf(stdout, "<td valign=top>%s</td>", (checkalert(nkalerts, testnames[testi]->name) ? "Yes" : "No"));

            fprintf(stdout, "<td valign=top>");
            if (twalk->b1 || twalk->b2 || twalk->b3) {
                  fprintf(stdout, "%d/%d/%d", twalk->b1, twalk->b2, twalk->b3);
            }
            else {
                  fprintf(stdout, "-/-/-");
            }
            fprintf(stdout, "</td>");

            fprintf(stdout, "<td valign=top>");
            fprintf(stdout, "<i>%s</i>", (twalk->visualdata ? twalk->visualdata : "&nbsp;"));
            if (twalk->expdata) fprintf(stdout, " must return <i>'%s'</i>", twalk->expdata);
            fprintf(stdout, "</td>");

            fprintf(stdout, "</tr>");
            netcount++;
      }
      if (taghead) {
            fprintf(stdout, "</table></td>\n");
            fprintf(stdout, "</tr>\n");
      }


      if (netcount != testcount) {
            fprintf(stdout, "<tr>\n");
            fprintf(stdout, "<th align=left valign=top>Local tests</th>\n");
            fprintf(stdout, "<td><table border=0 cellpadding=\"3\" cellspacing=\"5\" summary=\"%s local tests\">\n", host->hostname);
            fprintf(stdout, "<tr><th align=left valign=top>Service</th><th align=left valign=top>NK</th><th align=left valign=top>C/Y/R limits</th><th align=left valign=top>Configuration <i>(NB: Thresholds on client may differ)</i></th></tr>\n");
      }
      for (testi = 0; (testi < testcount); testi++) {
            tag_t *twalk;

            for (twalk = taghead; (twalk && strcasecmp(twalk->columnname, testnames[testi]->name)); twalk = twalk->next);
            if (twalk) continue;

            use_columndoc(testnames[testi]->name);
            fprintf(stdout, "<tr>");
            fprintf(stdout, "<td valign=top>%s</td>", testnames[testi]->name);
            fprintf(stdout, "<td valign=top>%s</td>", (checkalert(nkalerts, testnames[testi]->name) ? "Yes" : "No"));
            fprintf(stdout, "<td valign=top>-/-/-</td>");

            /* Make up some default configuration data */
            fprintf(stdout, "<td valign=top>");
            if (strcmp(testnames[testi]->name, "cpu") == 0) {
                  fprintf(stdout, "UNIX - Yellow: Load average > 1.5, Red: Load average > 3.0<br>");
                  fprintf(stdout, "Windows - Yellow: CPU utilisation > 80%%, Red: CPU utilisation > 95%%");
            }
            else if (strcmp(testnames[testi]->name, "disk") == 0) {
                  fprintf(stdout, "Default limits: Yellow 90%% full, Red 95%% full<br>\n");
                  print_disklist(host->hostname);
            }
            else if (strcmp(testnames[testi]->name, "memory") == 0) {
                  fprintf(stdout, "Yellow: swap/pagefile use > 80%%, Red: swap/pagefile use > 90%%");
            }
            else if (strcmp(testnames[testi]->name, "procs") == 0) {
                  htnames_t *walk;

                  if (!host->procs) fprintf(stdout, "No processes monitored<br>\n");

                  for (walk = host->procs; (walk); walk = walk->next) {
                        fprintf(stdout, "%s<br>\n", walk->name);
                  }
            }
            else if (strcmp(testnames[testi]->name, "svcs") == 0) {
                  htnames_t *walk;

                  if (!host->svcs) fprintf(stdout, "No services monitored<br>\n");

                  for (walk = host->svcs; (walk); walk = walk->next) {
                        fprintf(stdout, "%s<br>\n", walk->name);
                  }
            }
            else {
                  fprintf(stdout, "&nbsp;");
            }
            fprintf(stdout, "</td>");

            fprintf(stdout, "</tr>");
      }
      if (netcount != testcount) {
            fprintf(stdout, "</table></td>\n");
            fprintf(stdout, "</tr>\n");
      }

      /* Do the alerts */
      alert = (activealerts_t *)calloc(1, sizeof(activealerts_t));
      alert->hostname = host->hostname;
      alert->location = hinfo->page->pagepath;
      strcpy(alert->ip, "127.0.0.1");
      alert->color = COL_RED;
      alert->pagemessage = "";
      alert->state = A_PAGING;
      alert->cookie = 12345;
      alert_printmode(2);
      for (testi = 0; (testi < testcount); testi++) {
            alert->testname = testnames[testi]->name;
            if (have_recipient(alert, NULL)) print_alert_recipients(alert, buf);
      }
      xfree(alert);

      if (STRBUFLEN(buf) > 0) {
            fprintf(stdout, "<tr>\n");
            fprintf(stdout, "<th align=left valign=top>Alerts</th>\n");
            fprintf(stdout, "<td><table border=0 cellpadding=\"3\" cellspacing=\"5\" summary=\"%s alerts\">\n", host->hostname);
            fprintf(stdout, "<tr><th>Service</th><th>Recipient</th><th>1st Delay</th><th>Stop after</th><th>Repeat</th><th>Time of Day</th><th>Colors</th></tr>\n");

            fprintf(stdout, "%s", STRBUF(buf));

            fprintf(stdout, "</table></td>\n");
            fprintf(stdout, "</tr>\n");
      }

      /* Finish off this host */
      fprintf(stdout, "</table>\n");

      freestrbuffer(buf);
}


static int coltext_compare(const void *v1, const void *v2)
{
      coltext_t **t1 = (coltext_t **)v1;
      coltext_t **t2 = (coltext_t **)v2;

      return strcmp((*t1)->colname, (*t2)->colname);
}

void load_columndocs(void)
{
      char fn[PATH_MAX];
      FILE *fd;
      strbuffer_t *inbuf;

      sprintf(fn, "%s/etc/columndoc.csv", xgetenv("BBHOME"));
      fd = fopen(fn, "r"); if (!fd) return;

      inbuf = newstrbuffer(0);
      initfgets(fd);

      /* Skip the header line */
      if (!unlimfgets(inbuf, fd)) { fclose(fd); freestrbuffer(inbuf); return; }

      while (unlimfgets(inbuf, fd)) {
            char *s1 = NULL, *s2 = NULL;

            s1 = strtok(STRBUF(inbuf), coldelim);
            if (s1) s2 = strtok(NULL, coldelim);

            if (s1 && s2) {
                  coltext_t *newitem = (coltext_t *)calloc(1, sizeof(coltext_t));
                  newitem->colname = strdup(s1);
                  newitem->coldescr = strdup(s2);
                  newitem->next = chead;
                  chead = newitem;
                  ccount++;
            }
      }
      fclose(fd);
      freestrbuffer(inbuf);
}


void print_columndocs(void)
{
      coltext_t **clist;
      coltext_t *cwalk;
      int i;

      clist = (coltext_t **)malloc(ccount * sizeof(coltext_t *));
      for (i=0, cwalk=chead; (cwalk); cwalk=cwalk->next,i++) clist[i] = cwalk;
      qsort(&clist[0], ccount, sizeof(coltext_t **), coltext_compare);

      fprintf(stdout, "<p style=\"page-break-before: always\">\n"); 
      fprintf(stdout, "<table width=\"100%%\" border=1 summary=\"Column descriptions\">\n");
      fprintf(stdout, "<tr><th colspan=2>Hobbit column descriptions</th></tr>\n");
      for (i=0; (i<ccount); i++) {
            if (clist[i]->used) {
                  fprintf(stdout, "<tr><td align=left valign=top>%s</td><td>%s</td></tr>\n",
                        clist[i]->colname, clist[i]->coldescr);
            }
      }

      fprintf(stdout, "</table>\n");
}

htnames_t *get_proclist(char *hostname, char *statusbuf)
{
      char *bol, *eol;
      char *marker;
      htnames_t *head = NULL, *tail = NULL;

      if (!statusbuf) return NULL;

      marker = (char *)malloc(strlen(hostname) + 3);
      sprintf(marker, "\n%s|", hostname);
      if (strncmp(statusbuf, marker+1, strlen(marker)-1) == 0) {
            /* Found at start of buffer */
            bol = statusbuf;
      }
      else {
            bol = strstr(statusbuf, marker);
            if (bol) bol++;
      }
      xfree(marker);

      if (!bol) return NULL;

      bol += strlen(hostname) + 1;  /* Skip hostname and delimiter */
      marker = bol;
      eol = strchr(bol, '\n'); if (eol) *eol = '\0';
      marker = strstr(marker, "\\n&");
      while (marker) {
            char *p;
            htnames_t *newitem;

            marker += strlen("\\n&");
            if      (strncmp(marker, "green", 5) == 0) marker += 5;
            else if (strncmp(marker, "yellow", 6) == 0) marker += 6;
            else if (strncmp(marker, "red", 3) == 0) marker += 3;
            else marker = NULL;

            if (marker) {
                  marker += strspn(marker, " \t");

                  p = strstr(marker, " - "); if (p) *p = '\0';
                  newitem = (htnames_t *)malloc(sizeof(htnames_t));
                  newitem->name = strdup(marker);
                  newitem->next = NULL;
                  if (!tail) {
                        head = tail = newitem;
                  }
                  else {
                        tail->next = newitem;
                        tail = newitem;
                  }

                  if (p) {
                        *p = ' ';
                        marker = p;
                  }

                  marker = strstr(marker, "\\n&");
            }
      }
      if (eol) *eol = '\n';

      return head;
}

int main(int argc, char *argv[])
{
      int argi, hosti, testi;
      char *pagepattern = NULL, *hostpattern = NULL;
      char *envarea = NULL, *cookie = NULL, *p, *nexthost;
      char hobbitcmd[1024], procscmd[1024], svcscmd[1024];
        int alertcolors, alertinterval;
      char configfn[PATH_MAX];
      char *respbuf = NULL, *procsbuf = NULL, *svcsbuf = NULL;
      hostlist_t *hwalk;
      htnames_t *twalk;
      hostlist_t **allhosts = NULL;
      htnames_t **alltests = NULL;
      int hostcount = 0, maxtests = 0;
      time_t now = time(NULL);

      for (argi=1; (argi < argc); argi++) {
            if (argnmatch(argv[argi], "--env=")) {
                  char *p = strchr(argv[argi], '=');
                  loadenv(p+1, envarea);
            }
            else if (argnmatch(argv[argi], "--area=")) {
                  char *p = strchr(argv[argi], '=');
                  envarea = strdup(p+1);
            }
            else if (strcmp(argv[argi], "--debug") == 0) {
                  debug = 1;
            }
            else if (argnmatch(argv[argi], "--delimiter=")) {
                  char *p = strchr(argv[argi], '=');
                  coldelim = strdup(p+1);
            }
      }

      redirect_cgilog("hobbit-confreport");

      /* Setup the filter we use for the report */
      cookie = getenv("HTTP_COOKIE");
      if (cookie && ((p = strstr(cookie, "pagepath=")) != NULL)) {
            p += strlen("pagepath=");
            pagepattern = strdup(p);
            p = strchr(pagepattern, ';'); if (p) *p = '\0';
            if (strlen(pagepattern) == 0) { xfree(pagepattern); pagepattern = NULL; }
      }

      if (cookie && (!pagepattern) && ((p = strstr(cookie, "host=")) != NULL)) {
            p += strlen("host=");
            hostpattern = strdup(p);
            p = strchr(hostpattern, ';'); if (p) *p = '\0';
            if (strlen(hostpattern) == 0) { xfree(hostpattern); hostpattern = NULL; }
      }

      /* Fetch the list of host+test statuses we currently know about */
      if (pagepattern) {
            sprintf(hobbitcmd, "hobbitdboard page=%s fields=hostname,testname", pagepattern);
            sprintf(procscmd,  "hobbitdboard page=%s test=procs fields=hostname,msg", pagepattern);
            sprintf(svcscmd,   "hobbitdboard page=%s test=svcs fields=hostname,msg", pagepattern);
      }
      else if (hostpattern) {
            sprintf(hobbitcmd, "hobbitdboard host=%s fields=hostname,testname", hostpattern);
            sprintf(procscmd,  "hobbitdboard host=%s test=procs fields=hostname,msg", hostpattern);
            sprintf(svcscmd,   "hobbitdboard host=%s test=svcs fields=hostname,msg", hostpattern);
      }
      else {
            sprintf(hobbitcmd, "hobbitdboard fields=hostname,testname");
            sprintf(procscmd,  "hobbitdboard test=procs fields=hostname,msg");
            sprintf(svcscmd,   "hobbitdboard test=svcs fields=hostname,msg");
      }

      if (sendmessage(hobbitcmd, NULL, NULL, &respbuf, 1, BBTALK_TIMEOUT) != BB_OK) {
            errormsg("Cannot contact the Hobbit server\n");
            return 1;
      }
      if (sendmessage(procscmd, NULL, NULL, &procsbuf, 1, BBTALK_TIMEOUT) != BB_OK) {
            errormsg("Cannot contact the Hobbit server\n");
            return 1;
      }
      if (sendmessage(svcscmd, NULL, NULL, &svcsbuf, 1, BBTALK_TIMEOUT) != BB_OK) {
            errormsg("Cannot contact the Hobbit server\n");
            return 1;
      }

      if (!respbuf) {
            errormsg("Unable to find host information\n");
            return 1;
      }

      /* Parse it into a usable list */
      nexthost = respbuf;
      do {
            char *hname, *tname, *eoln;

            eoln = strchr(nexthost, '\n'); if (eoln) *eoln = '\0';
            hname = nexthost;
            tname = strchr(nexthost, '|'); if (tname) { *tname = '\0'; tname++; }

            if (hname && tname && strcmp(hname, "summary") && strcmp(tname, xgetenv("INFOCOLUMN")) && strcmp(tname, xgetenv("TRENDSCOLUMN"))) {
                  htnames_t *newitem = (htnames_t *)malloc(sizeof(htnames_t));

                  for (hwalk = hosthead; (hwalk && strcmp(hwalk->hostname, hname)); hwalk = hwalk->next);
                  if (!hwalk) {
                        hwalk = (hostlist_t *)calloc(1, sizeof(hostlist_t));
                        hwalk->hostname = strdup(hname);
                        hwalk->procs = get_proclist(hname, procsbuf);
                        hwalk->svcs  = get_proclist(hname, svcsbuf);
                        hwalk->next = hosthead;
                        hosthead = hwalk;
                        hostcount++;
                  }

                  newitem->name = strdup(tname);
                  newitem->next = hwalk->tests;
                  hwalk->tests = newitem;
                  hwalk->testcount++;
            }

            if (eoln) {
                  nexthost = eoln+1;
                  if (*nexthost == '\0') nexthost = NULL;
            }
      } while (nexthost);

      allhosts = (hostlist_t **) malloc(hostcount * sizeof(hostlist_t *));
      for (hwalk = hosthead, hosti=0; (hwalk); hwalk = hwalk->next, hosti++) {
            allhosts[hosti] = hwalk;
            if (hwalk->testcount > maxtests) maxtests = hwalk->testcount;
      }
      alltests = (htnames_t **) malloc(maxtests * sizeof(htnames_t *));
      qsort(&allhosts[0], hostcount, sizeof(hostlist_t **), host_compare);

      /* Get the static info */
      load_hostnames(xgetenv("BBHOSTS"), NULL, get_fqdn());
      load_all_links();
      init_tcp_services();
      pingcolumn = xgetenv("PINGCOLUMN");
      pingplus = (char *)malloc(strlen(pingcolumn) + 2);
      sprintf(pingplus, "%s=", pingcolumn);

      /* Load alert config */
      alertcolors = colorset(xgetenv("ALERTCOLORS"), ((1 << COL_GREEN) | (1 << COL_BLUE)));
      alertinterval = 60*atoi(xgetenv("ALERTREPEAT"));
      sprintf(configfn, "%s/etc/hobbit-alerts.cfg", xgetenv("BBHOME"));
      load_alertconfig(configfn, alertcolors, alertinterval);
      load_columndocs();


      printf("Content-Type: %s\n\n", xgetenv("HTMLCONTENTTYPE"));
      sethostenv("", "", "", colorname(COL_BLUE), NULL);
      headfoot(stdout, "confreport", "", "header", COL_BLUE);

      fprintf(stdout, "<table width=\"100%%\" border=0>\n");
      fprintf(stdout, "<tr><th align=center colspan=2><font size=\"+2\">Hobbit configuration Report</font></th></tr>\n");
      fprintf(stdout, "<tr><th valign=top align=left>Date</th><td>%s</td></tr>\n", ctime(&now));
      fprintf(stdout, "<tr><th valign=top align=left>%d hosts included</th><td>\n", hostcount);
      for (hosti=0; (hosti < hostcount); hosti++) {
            fprintf(stdout, "%s ", allhosts[hosti]->hostname);
      }
      fprintf(stdout, "</td></tr>\n");
      fprintf(stdout, "</table>\n");

      headfoot(stdout, "confreport", "", "front", COL_BLUE);

      for (hosti=0; (hosti < hostcount); hosti++) {
            for (twalk = allhosts[hosti]->tests, testi = 0; (twalk); twalk = twalk->next, testi++) {
                  alltests[testi] = twalk;
            }
            qsort(&alltests[0], allhosts[hosti]->testcount, sizeof(htnames_t **), test_compare);

            print_host(allhosts[hosti], alltests, allhosts[hosti]->testcount);
      }

      headfoot(stdout, "confreport", "", "back", COL_BLUE);
      print_columndocs();

      headfoot(stdout, "confreport", "", "footer", COL_BLUE);

      return 0;
}


Generated by  Doxygen 1.6.0   Back to index