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

loadhosts.c

/*----------------------------------------------------------------------------*/
/* Hobbit monitor library.                                                    */
/*                                                                            */
/* This is a library module for Hobbit, responsible for loading the bb-hosts  */
/* file and keeping track of what hosts are known, their aliases and planned  */
/* downtime settings etc.                                                     */
/*                                                                            */
/* Copyright (C) 2004-2006 Henrik Storner <henrik@hswn.dk>                    */
/*                                                                            */
/* This program is released under the GNU General Public License (GPL),       */
/* version 2. See the file "COPYING" for details.                             */
/*                                                                            */
/*----------------------------------------------------------------------------*/


static char rcsid[] = "$Id: loadhosts.c,v 1.66 2006/07/11 20:08:47 henrik Rel $";

#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
#include <time.h>

#include "libbbgen.h"

static pagelist_t *pghead = NULL;
static namelist_t *namehead = NULL;
static namelist_t *defaulthost = NULL;
static const char *bbh_item_key[BBH_LAST];
static const char *bbh_item_name[BBH_LAST];
static int configloaded = 0;
static RbtHandle rbhosts;
static RbtHandle rbclients;

static void bbh_item_list_setup(void)
{
      static int setupdone = 0;
      int i;

      if (setupdone) return;

      /* Doing it this way makes sure the index matches the value */
      setupdone = 1;
      memset(bbh_item_key, 0, sizeof(bbh_item_key));
      memset(bbh_item_name, 0, sizeof(bbh_item_key));
      bbh_item_key[BBH_NET]                  = "NET:";
      bbh_item_name[BBH_NET]                 = "BBH_NET";
      bbh_item_key[BBH_DISPLAYNAME]          = "NAME:";
      bbh_item_name[BBH_DISPLAYNAME]         = "BBH_DISPLAYNAME";
      bbh_item_key[BBH_CLIENTALIAS]          = "CLIENT:";
      bbh_item_name[BBH_CLIENTALIAS]         = "BBH_CLIENTALIAS";
      bbh_item_key[BBH_COMMENT]              = "COMMENT:";
      bbh_item_name[BBH_COMMENT]             = "BBH_COMMENT";
      bbh_item_key[BBH_DESCRIPTION]          = "DESCR:";
      bbh_item_name[BBH_DESCRIPTION]         = "BBH_DESCRIPTION";
      bbh_item_key[BBH_DOCURL]               = "DOC:";
      bbh_item_name[BBH_DOCURL]              = "BBH_DOCURL";
      bbh_item_key[BBH_NK]                   = "NK:";
      bbh_item_name[BBH_NK]                  = "BBH_NK";
      bbh_item_key[BBH_NKTIME]               = "NKTIME=";
      bbh_item_name[BBH_NKTIME]              = "BBH_NKTIME";
      bbh_item_key[BBH_TRENDS]               = "TRENDS:";
      bbh_item_name[BBH_TRENDS]              = "BBH_TRENDS";
      bbh_item_key[BBH_WML]                  = "WML:";
      bbh_item_name[BBH_WML]                 = "BBH_WML";
      bbh_item_key[BBH_NOPROP]               = "NOPROP:";
      bbh_item_name[BBH_NOPROP]              = "BBH_NOPROP";
      bbh_item_key[BBH_NOPROPRED]            = "NOPROPRED:";
      bbh_item_name[BBH_NOPROPRED]           = "BBH_NOPROPRED";
      bbh_item_key[BBH_NOPROPYELLOW]         = "NOPROPYELLOW:";
      bbh_item_name[BBH_NOPROPYELLOW]        = "BBH_NOPROPYELLOW";
      bbh_item_key[BBH_NOPROPPURPLE]         = "NOPROPPURPLE:";
      bbh_item_name[BBH_NOPROPPURPLE]        = "BBH_NOPROPPURPLE";
      bbh_item_key[BBH_NOPROPACK]            = "NOPROPACK:";
      bbh_item_name[BBH_NOPROPACK]           = "BBH_NOPROPACK";
      bbh_item_key[BBH_REPORTTIME]           = "REPORTTIME=";
      bbh_item_name[BBH_REPORTTIME]          = "BBH_REPORTTIME";
      bbh_item_key[BBH_WARNPCT]              = "WARNPCT:";
      bbh_item_name[BBH_WARNPCT]             = "BBH_WARNPCT";
      bbh_item_key[BBH_DOWNTIME]             = "DOWNTIME=";
      bbh_item_name[BBH_DOWNTIME]            = "BBH_DOWNTIME";
      bbh_item_key[BBH_SSLDAYS]              = "ssldays=";
      bbh_item_name[BBH_SSLDAYS]             = "BBH_SSLDAYS";
      bbh_item_key[BBH_DEPENDS]              = "depends=";
      bbh_item_name[BBH_DEPENDS]             = "BBH_DEPENDS";
      bbh_item_key[BBH_BROWSER]              = "browser=";
      bbh_item_name[BBH_BROWSER]             = "BBH_BROWSER";
      bbh_item_key[BBH_FLAG_NOINFO]          = "noinfo";
      bbh_item_name[BBH_FLAG_NOINFO]         = "BBH_FLAG_NOINFO";
      bbh_item_key[BBH_FLAG_NOTRENDS]        = "notrends";
      bbh_item_name[BBH_FLAG_NOTRENDS]       = "BBH_FLAG_NOTRENDS";
      bbh_item_key[BBH_FLAG_NODISP]          = "nodisp";
      bbh_item_name[BBH_FLAG_NODISP]         = "BBH_FLAG_NODISP";
      bbh_item_key[BBH_FLAG_NOBB2]           = "nobb2";
      bbh_item_name[BBH_FLAG_NOBB2]          = "BBH_FLAG_NOBB2";
      bbh_item_key[BBH_FLAG_PREFER]          = "prefer";
      bbh_item_name[BBH_FLAG_PREFER]         = "BBH_FLAG_PREFER";
      bbh_item_key[BBH_FLAG_NOSSLCERT]       = "nosslcert";
      bbh_item_name[BBH_FLAG_NOSSLCERT]      = "BBH_FLAG_NOSSLCERT";
      bbh_item_key[BBH_FLAG_TRACE]           = "trace";
      bbh_item_name[BBH_FLAG_TRACE]          = "BBH_FLAG_TRACE";
      bbh_item_key[BBH_FLAG_NOTRACE]         = "notrace";
      bbh_item_name[BBH_FLAG_NOTRACE]        = "BBH_FLAG_NOTRACE";
      bbh_item_key[BBH_FLAG_NOCONN]          = "noconn";
      bbh_item_name[BBH_FLAG_NOCONN]         = "BBH_FLAG_NOCONN";
      bbh_item_key[BBH_FLAG_NOPING]          = "noping";
      bbh_item_name[BBH_FLAG_NOPING]         = "BBH_FLAG_NOPING";
      bbh_item_key[BBH_FLAG_DIALUP]          = "dialup";
      bbh_item_name[BBH_FLAG_DIALUP]         = "BBH_FLAG_DIALUP";
      bbh_item_key[BBH_FLAG_TESTIP]          = "testip";
      bbh_item_name[BBH_FLAG_TESTIP]         = "BBH_FLAG_TESTIP";
      bbh_item_key[BBH_FLAG_BBDISPLAY]       = "BBDISPLAY";
      bbh_item_name[BBH_FLAG_BBDISPLAY]      = "BBH_FLAG_BBDISPLAY";
      bbh_item_key[BBH_FLAG_BBNET]           = "BBNET";
      bbh_item_name[BBH_FLAG_BBNET]          = "BBH_FLAG_BBNET";
      bbh_item_key[BBH_FLAG_BBPAGER]         = "BBPAGER";
      bbh_item_name[BBH_FLAG_BBPAGER]        = "BBH_FLAG_BBPAGER";
      bbh_item_key[BBH_FLAG_LDAPFAILYELLOW]  = "ldapyellowfail";
      bbh_item_name[BBH_FLAG_LDAPFAILYELLOW] = "BBH_FLAG_LDAPFAILYELLOW";
      bbh_item_key[BBH_FLAG_NOCLEAR]         = "NOCLEAR";
      bbh_item_name[BBH_FLAG_NOCLEAR]        = "BBH_FLAG_NOCLEAR";
      bbh_item_key[BBH_FLAG_HIDEHTTP]        = "HIDEHTTP";
      bbh_item_name[BBH_FLAG_HIDEHTTP]       = "BBH_FLAG_HIDEHTTP";
      bbh_item_key[BBH_FLAG_PULLDATA]        = "PULLDATA";
      bbh_item_name[BBH_FLAG_PULLDATA]       = "BBH_FLAG_PULLDATA";
      bbh_item_key[BBH_LDAPLOGIN]            = "ldaplogin=";
      bbh_item_name[BBH_LDAPLOGIN]           = "BBH_LDAPLOGIN";
      bbh_item_key[BBH_CLASS]                = "CLASS:";
      bbh_item_name[BBH_CLASS]               = "BBH_CLASS";
      bbh_item_key[BBH_OS]                   = "OS:";
      bbh_item_name[BBH_OS]                  = "BBH_OS";
      bbh_item_key[BBH_NOCOLUMNS]            = "NOCOLUMNS:";
      bbh_item_name[BBH_NOCOLUMNS]           = "BBH_NOCOLUMNS";

      bbh_item_name[BBH_IP]                  = "BBH_IP";
      bbh_item_name[BBH_CLIENTALIAS]         = "BBH_CLIENTALIAS";
      bbh_item_name[BBH_BANKSIZE]            = "BBH_BANKSIZE";
      bbh_item_name[BBH_HOSTNAME]            = "BBH_HOSTNAME";
      bbh_item_name[BBH_PAGENAME]            = "BBH_PAGENAME";
      bbh_item_name[BBH_PAGEPATH]            = "BBH_PAGEPATH";
      bbh_item_name[BBH_PAGETITLE]           = "BBH_PAGETITLE";
      bbh_item_name[BBH_PAGEPATHTITLE]       = "BBH_PAGEPATHTITLE";
      bbh_item_name[BBH_GROUPID]             = "BBH_GROUPID";
      bbh_item_name[BBH_PAGEINDEX]           = "BBH_PAGEINDEX";
      bbh_item_name[BBH_RAW]                 = "BBH_RAW";

      i = 0; while (bbh_item_key[i]) i++;
      if (i != BBH_IP) {
            errprintf("ERROR: Setup failure in bbh_item_key position %d\n", i);
      }
}


static char *bbh_find_item(namelist_t *host, enum bbh_item_t item)
{
      int i;
      char *result;

      bbh_item_list_setup();
      i = 0;
      while (host->elems[i] && strncasecmp(host->elems[i], bbh_item_key[item], strlen(bbh_item_key[item]))) i++;
      result = (host->elems[i] ? (host->elems[i] + strlen(bbh_item_key[item])) : NULL);

      /* Handle the LARRD: tag in Hobbit 4.0.4 and earlier */
      if (!result && (item == BBH_TRENDS)) {
            i = 0;
            while (host->elems[i] && strncasecmp(host->elems[i], "LARRD:", 6)) i++;
            result = (host->elems[i] ? (host->elems[i] + 6) : NULL);
      }

      if (result || !host->defaulthost || (strcasecmp(host->bbhostname, ".default.") == 0))
            return result;
      else
            return bbh_find_item(host->defaulthost, item);
}

static void initialize_hostlist(void)
{
      while (defaulthost) {
            namelist_t *walk = defaulthost;
            defaulthost = defaulthost->defaulthost;

            if (walk->bbhostname) xfree(walk->bbhostname);
            if (walk->groupid) xfree(walk->groupid);
            if (walk->classname) xfree(walk->classname);
            if (walk->osname) xfree(walk->osname);
            if (walk->logname) xfree(walk->logname);
            if (walk->allelems) xfree(walk->allelems);
            if (walk->elems) xfree(walk->elems);
            xfree(walk);
      }

      while (namehead) {
            namelist_t *walk = namehead;

            namehead = namehead->next;

            if (walk->bbhostname) xfree(walk->bbhostname);
            if (walk->groupid) xfree(walk->groupid);
            if (walk->classname) xfree(walk->classname);
            if (walk->osname) xfree(walk->osname);
            if (walk->logname) xfree(walk->logname);
            if (walk->allelems) xfree(walk->allelems);
            if (walk->elems) xfree(walk->elems);
            xfree(walk);
      }

      while (pghead) {
            pagelist_t *walk = pghead;

            pghead = pghead->next;
            if (walk->pagepath) xfree(walk->pagepath);
            if (walk->pagetitle) xfree(walk->pagetitle);
            xfree(walk);
      }

      /* Setup the top-level page */
      pghead = (pagelist_t *) malloc(sizeof(pagelist_t));
      pghead->pagepath = strdup("");
      pghead->pagetitle = strdup("");
      pghead->next = NULL;
}

static void build_hosttree(void)
{
      static int hosttree_exists = 0;
      namelist_t *walk;
      RbtStatus status;

      if (hosttree_exists) {
            rbtDelete(rbhosts);
            rbtDelete(rbclients);
      }
      rbhosts = rbtNew(name_compare);
      rbclients = rbtNew(name_compare);
      hosttree_exists = 1;

      for (walk = namehead; (walk); walk = walk->next) {
            status = rbtInsert(rbhosts, walk->bbhostname, walk);
            if (walk->clientname) rbtInsert(rbclients, walk->clientname, walk);

            switch (status) {
              case RBT_STATUS_OK:
              case RBT_STATUS_DUPLICATE_KEY:
                  break;
              case RBT_STATUS_MEM_EXHAUSTED:
                  errprintf("loadhosts:build_hosttree - insert into tree failed (out of memory)\n");
                  break;
              default:
                  errprintf("loadhosts:build_hosttree - insert into tree failed code %d\n", status);
                  break;
            }
      }
}

#include "loadhosts_file.c"

char *knownhost(char *hostname, char *hostip, int ghosthandling)
{
      /*
       * ghosthandling = 0 : Default BB method (case-sensitive, no logging, keep ghosts)
       * ghosthandling = 1 : Case-insensitive, no logging, drop ghosts
       * ghosthandling = 2 : Case-insensitive, log ghosts, drop ghosts
       */
      RbtIterator hosthandle;
      namelist_t *walk = NULL;
      static char *result = NULL;
      void *k1, *k2;

      if (result) xfree(result);
      result = NULL;

      /* Find the host in the normal hostname list */
      hosthandle = rbtFind(rbhosts, hostname);
      if (hosthandle != rbtEnd(rbhosts)) {
            rbtKeyValue(rbhosts, hosthandle, &k1, &k2);
            walk = (namelist_t *)k2;
      }
      else {
            /* Not found - lookup in the client alias list */
            hosthandle = rbtFind(rbclients, hostname);
            if (hosthandle != rbtEnd(rbclients)) {
                  rbtKeyValue(rbclients, hosthandle, &k1, &k2);
                  walk = (namelist_t *)k2;
            }
      }

      if (walk) {
            /*
             * Force our version of the hostname. Done here so CLIENT works always.
             */
            strcpy(hostip, walk->ip);
            result = strdup(walk->bbhostname);
      }
      else {
            *hostip = '\0';
            result = strdup(hostname);
      }

      /* If default method, just say yes */
      if (ghosthandling == 0) return result;

      /* Allow all summaries and modembanks */
      if (strcmp(hostname, "summary") == 0) return result;
      if (strcmp(hostname, "dialup") == 0) return result;

      return (walk ? result : NULL);
}

int knownloghost(char *logdir)
{
      namelist_t *walk = NULL;

      /* Find the host */
      /* Must do the linear string search, since the tree is indexed by the bbhostname, not logname */
      for (walk = namehead; (walk && (strcasecmp(walk->logname, logdir) != 0)); walk = walk->next);

      return (walk != NULL);
}

namelist_t *hostinfo(char *hostname)
{
      RbtIterator hosthandle;
      namelist_t *result = NULL;

      if (!configloaded) load_hostnames(xgetenv("BBHOSTS"), NULL, get_fqdn());

      hosthandle = rbtFind(rbhosts, hostname);
      if (hosthandle != rbtEnd(rbhosts)) {
            void *k1, *k2;

            rbtKeyValue(rbhosts, hosthandle, &k1, &k2);
            result = (namelist_t *)k2;
      }

      return result;
}

namelist_t *localhostinfo(char *hostname)
{
      /* Returns a static fake hostrecord */
      static namelist_t *result = NULL;

      if (!result) {
            initialize_hostlist();
            result = (namelist_t *)calloc(1, sizeof(namelist_t));
      }

      strcpy(result->ip, "127.0.0.1");

      if (result->bbhostname) xfree(result->bbhostname);
      result->bbhostname = strdup(hostname);

      if (result->logname) xfree(result->logname);

      result->logname = strdup(hostname);
      { char *p = result->logname; while ((p = strchr(p, '.')) != NULL) { *p = '_'; } }

      result->preference = 1;
      result->page = pghead;

      if (result->rawentry) xfree(result->rawentry);
      result->rawentry = (char *)malloc(strlen(hostname) + 100);
      sprintf(result->rawentry, "127.0.0.1 %s #", hostname);

      if (result->allelems) xfree(result->allelems);
      result->allelems = strdup("");

      if (result->elems) xfree(result->elems);
      result->elems = (char **)malloc(sizeof(char *));
      result->elems[0] = NULL;

      return result;
}

char *bbh_item(namelist_t *host, enum bbh_item_t item)
{
      static char *result;
      static char intbuf[10];
      static char *inttxt = NULL;
      static strbuffer_t *rawtxt = NULL;
      char *p;

      if (rawtxt == NULL) rawtxt = newstrbuffer(0);
      if (inttxt == NULL) inttxt = (char *)malloc(10);

      if (host == NULL) return NULL;

      switch (item) {
        case BBH_CLIENTALIAS: 
              return host->clientname;

        case BBH_IP:
              return host->ip;

        case BBH_CLASS:
              if (host->classname) return host->classname;
              else return bbh_find_item(host, item);
              break;

        case BBH_OS:
              if (host->osname) return host->osname;
              else return bbh_find_item(host, item);
              break;

        case BBH_BANKSIZE:
              if (host->banksize == 0) return NULL;
              sprintf(inttxt, "%d", host->banksize);
              return inttxt;

        case BBH_HOSTNAME: 
              return host->bbhostname;

        case BBH_PAGENAME:
              p = strrchr(host->page->pagepath, '/');
              if (p) return (p+1); else return host->page->pagepath;

        case BBH_PAGEPATH:
              return host->page->pagepath;

        case BBH_PAGETITLE:
              p = strrchr(host->page->pagetitle, '/');
              if (p) return (p+1);
              /* else: Fall through */

        case BBH_PAGEPATHTITLE:
              if (strlen(host->page->pagetitle)) return host->page->pagetitle;
              return "Top Page";

        case BBH_PAGEINDEX:
              sprintf(intbuf, "%d", host->pageindex);
              return intbuf;

        case BBH_GROUPID:
              return host->groupid;

        case BBH_DOCURL:
              p = bbh_find_item(host, item);
              if (p) {
                  if (result) xfree(result);
                  result = (char *)malloc(strlen(p) + strlen(host->bbhostname) + 1);
                  sprintf(result, p, host->bbhostname);
                  return result;
              }
              else
                  return NULL;

        case BBH_DOWNTIME:
              if (host->downtime)
                    return host->downtime;
              else if (host->defaulthost)
                    return host->defaulthost->downtime;
              else
                    return NULL;

        case BBH_RAW:
              if (rawtxt) clearstrbuffer(rawtxt);
              p = bbh_item_walk(host);
              while (p) {
                    addtobuffer(rawtxt, nlencode(p));
                    p = bbh_item_walk(NULL);
                    if (p) addtobuffer(rawtxt, "|");
              }
              return STRBUF(rawtxt);

        default:
              return bbh_find_item(host, item);
      }

      return NULL;
}

char *bbh_custom_item(namelist_t *host, char *key)
{
      int i;

      i = 0;
      while (host->elems[i] && strncmp(host->elems[i], key, strlen(key))) i++;

      return host->elems[i];
}

enum bbh_item_t bbh_key_idx(char *item)
{
      enum bbh_item_t i;

      bbh_item_list_setup();

      i = 0; while (bbh_item_name[i] && strcmp(bbh_item_name[i], item)) i++;
      return (bbh_item_name[i] ? i : BBH_LAST);
}

char *bbh_item_byname(namelist_t *host, char *item)
{
      enum bbh_item_t i;

      i = bbh_key_idx(item);
      return ((i == -1) ? NULL : bbh_item(host, i));
}

char *bbh_item_walk(namelist_t *host)
{
      static int idx = -1;
      static namelist_t *curhost = NULL;
      char *result;

      if ((host == NULL) && (idx == -1)) return NULL; /* Programmer failure */
      if (host != NULL) { idx = 0; curhost = host; }

      result = curhost->elems[idx];
      if (result) idx++; else idx = -1;

      return result;
}

int bbh_item_idx(char *value)
{
      int i;

      bbh_item_list_setup();
      i = 0;
      while (bbh_item_key[i] && strncmp(bbh_item_key[i], value, strlen(bbh_item_key[i]))) i++;
      return (bbh_item_key[i] ? i : -1);
}

char *bbh_item_id(enum bbh_item_t idx)
{
      if ((idx >= 0) && (idx < BBH_LAST)) return bbh_item_name[idx];
      return NULL;
}

namelist_t *first_host(void)
{
      return namehead;
}


void bbh_set_item(namelist_t *host, enum bbh_item_t item, char *value)
{
      switch (item) {
        case BBH_CLASS:
            if (host->classname) xfree(host->classname);
            host->classname = strdup(value);
            break;

        case BBH_OS:
            if (host->osname) xfree(host->osname);
            host->osname = strdup(value);
            break;

        default:
            break;
      }
}


#ifdef STANDALONE

int main(int argc, char *argv[])
{
      int argi;
      namelist_t *hosts, *h;
      char *val;

      hosts = load_hostnames(argv[1], NULL, get_fqdn());

      for (argi = 2; (argi < argc); argi++) {
            char s[1024];
            char *p;
            char *hname;
            char hostip[IP_ADDR_STRLEN];

handlehost:
            hname = knownhost(argv[argi], hostip, 1);
            if (hname == NULL) {
                  printf("Unknown host '%s'\n", argv[argi]);
                  continue;
            }
            if (strcmp(hname, argv[argi])) {
                  printf("Using canonical name '%s'\n", hname);
            }
            h = hostinfo(hname);

            if (h == NULL) { printf("Host %s not found\n", argv[argi]); continue; }

            val = bbh_item_walk(h);
            printf("Entry for host %s\n", h->bbhostname);
            while (val) {
                  printf("\t%s\n", val);
                  val = bbh_item_walk(NULL);
            }

            do {
                  printf("Pick item:"); fflush(stdout); fgets(s, sizeof(s), stdin);
                  p = strchr(s, '\n'); if (p) *p = '\0';
                  if (*s == '!') {
                        hosts = load_hostnames(argv[1], NULL, get_fqdn());
                        /* Must restart! The "h" handle is no longer valid. */
                        goto handlehost;
                  }
                  else if (*s) {
                        val = bbh_item_byname(h, s);
                        if (val) printf("\t%s value is: '%s'\n", s, val);
                        else printf("\t%s not found\n", s);
                  }
            } while (*s);
      }

      return 0;
}

#endif


Generated by  Doxygen 1.6.0   Back to index