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

environ.c

/*----------------------------------------------------------------------------*/
/* Hobbit monitor library.                                                    */
/*                                                                            */
/* This is a library module, part of libbbgen.                                */
/* It contains environment variable handling routines.                        */
/*                                                                            */
/* Copyright (C) 2002-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: environ.c,v 1.37 2006/05/28 20:50:22 henrik Rel $";

#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>

#include "libbbgen.h"

const static struct {
      char *name;
      char *val;
} hobbitenv[] = {
      { "HOBBITDREL", VERSION },
      { "BBSERVERROOT", BBTOPDIR },
      { "BBSERVERLOGS", BBLOGDIR },
      { "BBSERVERHOSTNAME", BBHOSTNAME },
      { "BBSERVERIP", BBHOSTIP },
      { "BBSERVEROS", BBHOSTOS },
      { "BBSERVERWWWNAME", BBHOSTNAME },
      { "BBSERVERWWWURL", "/hobbit" },
      { "BBSERVERCGIURL", "/hobbit-cgi" },
      { "BBSERVERSECCGIURL", "/hobbit-cgisecure" },
      { "BBLOCATION", "" },
      { "PATH", "/bin:/usr/bin:/sbin:/usr/sbin:/usr/local/bin:/usr/local/sbin:"BUILD_HOME"/bin" },
      { "BBPORT", "1984" },
      { "BBDISP", "$BBSERVERIP" },
      { "BBDISPLAYS", "" },
      { "BBPAGE", "$BBSERVERIP" },
      { "BBPAGERS", "" },
      { "FQDN", "TRUE" },
      { "USEHOBBITD", "TRUE" },
      { "BBGHOSTS", "1" },
      { "PAGELEVELS", "red yellow purple" },
      { "PURPLEDELAY", "30" },
      { "BBLOGSTATUS", "DYNAMIC" },
      { "PINGCOLUMN", "conn" },
      { "INFOCOLUMN", "info" },
      { "TRENDSCOLUMN", "trends" },
      { "DOCOMBO", "TRUE" },
      { "BBMAXMSGSPERCOMBO", "100" },
      { "BBSLEEPBETWEENMSGS", "0" },
      { "BBOSTYPE", "$BBSERVEROS" },
      { "MACHINEDOTS", "$BBSERVERHOSTNAME" },
      { "MACHINEADDR", "$BBSERVERIP" },
      { "BBWEBHOST", "http://$BBSERVERWWWNAME" },
      { "BBWEBHOSTURL", "$BBWEBHOST$BBSERVERWWWURL" },
      { "BBWEBHTMLLOGS", "$BBWEBHOSTURL/html"    },
      { "BBWEB", "$BBSERVERWWWURL" },
      { "BBSKIN", "$BBSERVERWWWURL/gifs" },
      { "BBHELPSKIN", "$BBSERVERWWWURL/help" },
      { "BBNOTESSKIN", "$BBSERVERWWWURL/notes" },
      { "BBMENUSKIN", "$BBSERVERWWWURL/menu" },
      { "BBREPURL", "$BBSERVERWWWURL/rep" },
      { "BBSNAPURL", "$BBSERVERWWWURL/snap" },
      { "BBWAP", "$BBSERVERWWWURL/wml" },
      { "CGIBINURL", "$BBSERVERCGIURL" },
      { "BBHOME", BUILD_HOME },
      { "BBTMP", "$BBHOME/tmp" },
      { "BBHOSTS", "$BBHOME/etc/bb-hosts" },
      { "BB", "$BBHOME/bin/bb" },
      { "BBGEN", "$BBHOME/bin/bbgen" },
      { "BBVAR", "$BBSERVERROOT/data" },
      { "BBACKS", "$BBVAR/acks" },
      { "BBDATA", "$BBVAR/data" },
      { "BBDISABLED", "$BBVAR/disabled" },
      { "BBHIST", "$BBVAR/hist" },
      { "BBHISTLOGS", "$BBVAR/histlogs" },
      { "BBLOGS", "$BBVAR/logs" },
      { "BBWWW", "$BBHOME/www" },
      { "BBHTML", "$BBWWW/html" },
      { "BBNOTES", "$BBWWW/notes" },
      { "BBREP", "$BBWWW/rep" },
      { "BBSNAP", "$BBWWW/snap" },
      { "BBALLHISTLOG", "TRUE" },
      { "BBHOSTHISTLOG", "TRUE" },
      { "SAVESTATUSLOG", "TRUE" },
      { "CLIENTLOGS", "$BBVAR/hostdata" },
      { "MAILC", "mail" },
      { "MAIL", "$MAILC -s" },
      { "SVCCODES", "disk:100,cpu:200,procs:300,svcs:350,msgs:400,conn:500,http:600,dns:800,smtp:725,telnet:723,ftp:721,pop:810,pop3:810,pop-3:810,ssh:722,imap:843,ssh1:722,ssh2:722,imap2:843,imap3:843,imap4:843,pop2:809,pop-2:809,nntp:819,test:901" },
      { "ALERTCOLORS", "red,yellow,purple" },
      { "OKCOLORS", "green,blue,clear" },
      { "ALERTREPEAT", "30" },
      { "CONNTEST", "TRUE" },
      { "IPTEST_2_CLEAR_ON_FAILED_CONN", "TRUE" },
      { "NONETPAGE", "" },
      { "FPING", "hobbitping" },
      { "NTPDATE", "ntpdate" },
      { "TRACEROUTE", "traceroute" },
      { "RPCINFO", "rpcinfo" },
      { "BBROUTERTEXT", "router" },
      { "NETFAILTEXT", "not OK" },
      { "BBRRDS", "$BBVAR/rrd" },
      { "TEST2RRD", "cpu=la,disk,memory,$PINGCOLUMN=tcp,http=tcp,dns=tcp,dig=tcp,time=ntpstat,vmstat,iostat,netstat,temperature,apache,bind,sendmail,nmailq,socks,bea,iishealth,citrix,bbgen,bbtest,bbproxy,hobbitd" },
      { "GRAPHS", "la,disk:disk_part:5,memory,users,vmstat,iostat,tcp.http,tcp,netstat,temperature,ntpstat,apache,bind,sendmail,nmailq,socks,bea,iishealth,citrix,bbgen,bbtest,bbproxy,hobbitd" },
      { "SUMMARY_SET_BKG", "FALSE" },
      { "BBMKBB2EXT", "eventlog.sh acklog.sh" },
      { "BBREL", "Hobbit" },
      { "BBRELDATE", "" },
      { "DOTHEIGHT", "16" },
      { "DOTWIDTH", "16" },
      { "RRDHEIGHT", "120" },
      { "RRDWIDTH", "576" },
      { "COLUMNDOCURL", "$CGIBINURL/hobbitcolumn.sh?%s" },
      { "HOBBITLOGO", "Hobbit" },
      { "MKBBLOCAL", "<B><I>Pages Hosted Locally</I></B>" },
      { "MKBBREMOTE", "<B><I>Remote Status Display</I></B>" },
      { "MKBBSUBLOCAL", "<B><I>Subpages Hosted Locally</I></B>" },
      { "MKBBACKFONT", "COLOR=\"#33ebf4\" SIZE=\"-1\"" },
      { "MKBBCOLFONT", "COLOR=\"#87a9e5\" SIZE=\"-1\"" },
      { "MKBBROWFONT", "SIZE=\"+1\" COLOR=\"#FFFFCC\" FACE=\"Tahoma, Arial, Helvetica\"" },
      { "MKBBTITLE", "COLOR=\"ivory\" SIZE=\"+1\"" },
      { "BBDATEFORMAT", "%a %b %d %H:%M:%S %Y" },
      { "BBRSSTITLE", "Hobbit Alerts" },
      { "ACKUNTILMSG", "Next update at: %H:%M %Y-%m-%d" },
      { "WMLMAXCHARS", "1500" },
      { "BBREPWARN", "97" },
      { "BBGENREPOPTS", "--recentgifs --subpagecolumns=2" },
      { "BBGENSNAPOPTS", "--recentgifs --subpagecolumns=2" },
      { "BBMKBBEXT", "" },
      { "BBHISTEXT", "" },
      { "BBSLEEP", "300" },
      { "MKBB2COLREPEAT", "0" },
      { "BBHTACCESS", "" },
      { "BBPAGEHTACCESS", "" },
      { "BBSUBPAGEHTACCESS", "" },
      { "BBNETSVCS", "smtp telnet ftp pop pop3 pop-3 ssh imap ssh1 ssh2 imap2 imap3 imap4 pop2 pop-2 nntp" },
      { "HTMLCONTENTTYPE", "text/html" },
      { NULL, NULL }
};

char *xgetenv(const char *name)
{
      char *result, *newstr;
      int i;

      result = getenv(name);
      if ((result == NULL) && (strcmp(name, "MACHINE") == 0) && xgetenv("MACHINEDOTS")) {
            /* If MACHINE is undefined, but MACHINEDOTS is there, create MACHINE  */
            char *oneenv, *p;
            
            oneenv = (char *)malloc(10 + strlen(xgetenv("MACHINEDOTS")));
            sprintf(oneenv, "%s=%s", name, xgetenv("MACHINEDOTS"));
            p = oneenv; while ((p = strchr(p, '.')) != NULL) *p = ',';
            putenv(oneenv);
            result = getenv(name);
      }

      if (result == NULL) {
            for (i=0; (hobbitenv[i].name && (strcmp(hobbitenv[i].name, name) != 0)); i++) ;
            if (hobbitenv[i].name) result = expand_env(hobbitenv[i].val);
            if (result == NULL) {
                  errprintf("xgetenv: Cannot find value for variable %s\n", name);
                  return NULL;
            }

            /* 
             * If we got a result, put it into the environment so it will stay there.
             * Allocate memory for this new environment string - this stays allocated.
             */
            newstr = malloc(strlen(name) + strlen(result) + 2);
            sprintf(newstr, "%s=%s", name, result);
            putenv(newstr);

            /*
             * Return pointer to the environment string.
             */
            result = getenv(name);
      }

      return result;
}

void envcheck(char *envvars[])
{
      int i;
      int ok = 1;

      for (i = 0; (envvars[i]); i++) {
            if (xgetenv(envvars[i]) == NULL) {
                  errprintf("Environment variable %s not defined\n", envvars[i]);
                  ok = 0;
            }
      }

      if (!ok) {
            errprintf("Aborting\n");
            exit (1);
      }
}

void loadenv(char *envfile, char *area)
{
      FILE *fd;
      strbuffer_t *inbuf;
      char *p, *oneenv;
      int n;

      MEMDEFINE(l);
      inbuf = newstrbuffer(0);

      fd = stackfopen(envfile, "r", NULL);
      if (fd) {
            while (stackfgets(inbuf, NULL)) {
                  sanitize_input(inbuf, 1, 1);

                  if (STRBUFLEN(inbuf) && strchr(STRBUF(inbuf), '=')) {
                        /*
                         * Do the environment "area" stuff: If the input
                         * is of the form AREA/NAME=VALUE, then setup the variable
                         * only if we're called with the correct AREA setting.
                         */
                        oneenv = NULL;

                        p = STRBUF(inbuf) + strcspn(STRBUF(inbuf), "=/");
                        if (*p == '/') {
                              if (area) {
                                    *p = '\0';
                                    if (strcasecmp(STRBUF(inbuf), area) == 0) oneenv = strdup(expand_env(p+1));
                              }
                        }
                        else oneenv = strdup(expand_env(STRBUF(inbuf)));

                        if (oneenv) {
                              p = strchr(oneenv, '=');
                              if (*(p+1) == '"') {
                                    /* Move string over the first '"' */
                                    memmove(p+1, p+2, strlen(p+2)+1);
                                    /* Kill a trailing '"' */
                                    if (*(oneenv + strlen(oneenv) - 1) == '"') *(oneenv + strlen(oneenv) - 1) = '\0';
                              }
                              n = putenv(oneenv);
                        }
                  }
            }
            stackfclose(fd);
      }
      else {
            errprintf("Cannot open env file %s - %s\n", envfile, strerror(errno));
      }

      freestrbuffer(inbuf);
      MEMUNDEFINE(l);
}

char *getenv_default(char *envname, char *envdefault, char **buf)
{
      static char *val;

      val = getenv(envname);  /* Dont use xgetenv() here! */
      if (!val) {
            val = (char *)malloc(strlen(envname) + strlen(envdefault) + 2);
            sprintf(val, "%s=%s", envname, envdefault);
            putenv(val);
            /* Dont free the string - it must be kept for the environment to work */
            val = xgetenv(envname); /* OK to use xgetenv here */
      }

      if (buf) *buf = val;
      return val;
}


typedef struct envxp_t {
      char *result;
      int resultlen;
      struct envxp_t *next;
} envxp_t;
static envxp_t *xps = NULL;

char *expand_env(char *s)
{
      static char *res = NULL;
      static int depth = 0;
      char *sCopy, *bot, *tstart, *tend, *envval;
      char savech;
      envxp_t *myxp;

      if ((depth == 0) && res) xfree(res);
      depth++;

      myxp = (envxp_t *)malloc(sizeof(envxp_t));
      myxp->next = xps;
      xps = myxp;

      myxp->resultlen = 4096;
      myxp->result = (char *)malloc(myxp->resultlen);
      *(myxp->result) = '\0';

      sCopy = strdup(s);
      bot = sCopy;
      do {
            tstart = strchr(bot, '$');
            if (tstart) *tstart = '\0'; 

            if ((strlen(myxp->result) + strlen(bot) + 1) > myxp->resultlen) {
                  myxp->resultlen += strlen(bot) + 4096;
                  myxp->result = (char *)realloc(myxp->result, myxp->resultlen);
            }
            strcat(myxp->result, bot);

            if (tstart) {
                  tstart++;
                  envval = NULL;

                  if (*tstart == '{') {
                        tstart++;
                        tend = strchr(tstart, '}');
                        if (tend) { 
                              *tend = '\0'; 
                              envval = xgetenv(tstart);
                              bot = tend+1;
                        } 
                        else {
                              envval = xgetenv(tstart);
                              bot = NULL;
                        }
                  }
                  else {
                        tend = tstart + strspn(tstart, "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_");
                        savech = *tend;
                        *tend = '\0';
                        envval = xgetenv(tstart);
                        *tend = savech;
                        bot = tend;
                  }

                  if (envval) {
                        if ((strlen(myxp->result) + strlen(envval) + 1) > myxp->resultlen) {
                              myxp->resultlen += strlen(envval) + 4096;
                              myxp->result = (char *)realloc(myxp->result, myxp->resultlen);
                        }
                        strcat(myxp->result, envval);
                  }
            }
            else {
                  bot = NULL;
            }
      } while (bot);
      xfree(sCopy);

      depth--;
      if (depth == 0) {
            envxp_t *tmp;
            
            /* Free all xps except the last one (which is myxp) */
            while (xps->next) { tmp = xps; xps = xps->next; xfree(tmp->result); xfree(tmp); }
            if (xps != myxp) {
                  errprintf("Assertion failed: xps != myxp\n");
                  abort();
            }

            /* We KNOW that xps == myxp */
            res = myxp->result;
            xfree(myxp); 
            xps = NULL;

            return res;
      }
      else return myxp->result;
}


Generated by  Doxygen 1.6.0   Back to index