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

hobbit-nkedit.c

/*----------------------------------------------------------------------------*/
/* Hobbit CGI for administering the hobbit-nkview.cfg file                    */
/*                                                                            */
/* Copyright (C) 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-nkedit.c,v 1.13 2006/07/11 17:18:22 henrik Rel $";

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

#include "libbbgen.h"

static char *operator = NULL;

static enum { NKEDIT_FIND, NKEDIT_NEXT, NKEDIT_UPDATE, NKEDIT_DELETE, NKEDIT_ADDCLONE, NKEDIT_DROPCLONE } editaction = NKEDIT_FIND;
static char *rq_hostname = NULL;
static char *rq_service = NULL;
static int rq_priority = 0;
static char *rq_group = NULL;
static char *rq_extra = NULL;
static char *rq_nktime = NULL;
static time_t rq_start = 0;
static time_t rq_end = 0;
static char *rq_clonestoadd = NULL;
static char *rq_clonestodrop = NULL;
static int  rq_dropevenifcloned = 0;

static void parse_query(void)
{
      cgidata_t *cgidata = cgi_request();
      cgidata_t *cwalk;
      char *rq_nkwkdays = NULL;
      char *rq_nkslastart = NULL;
      char *rq_nkslaend = NULL;
      int  rq_startday = 0;
      int  rq_startmon = 0;
      int  rq_startyear = 0;
      int  rq_endday = 0;
      int  rq_endmon = 0;
      int  rq_endyear = 0;

      cwalk = cgidata;
      while (cwalk) {
            if (strcasecmp(cwalk->name, "Find") == 0) {
                  editaction = NKEDIT_FIND;
            }
            else if (strcasecmp(cwalk->name, "Next") == 0) {
                  editaction = NKEDIT_NEXT;
            }
            else if (strcasecmp(cwalk->name, "Update") == 0) {
                  editaction = NKEDIT_UPDATE;
            }
            else if (strcasecmp(cwalk->name, "Drop") == 0) {
                  editaction = NKEDIT_DELETE;
            }
            else if (strcasecmp(cwalk->name, "Clone") == 0) {
                  /* The "clone" button does both things */
                  editaction = NKEDIT_ADDCLONE;
            }
            else if (strcasecmp(cwalk->name, "HOSTNAME") == 0) {
                  if (*cwalk->value) rq_hostname = strdup(cwalk->value);
            }
            else if (strcasecmp(cwalk->name, "SERVICE") == 0) {
                  if (*cwalk->value) rq_service = strdup(cwalk->value);
            }
            else if (strcasecmp(cwalk->name, "PRIORITY") == 0) {
                  rq_priority = atoi(cwalk->value);
            }
            else if (strcasecmp(cwalk->name, "GROUP") == 0) {
                  if (*cwalk->value) rq_group = strdup(cwalk->value);
            }
            else if (strcasecmp(cwalk->name, "NKWKDAYS") == 0) {
                  if (*cwalk->value) {
                        if (!rq_nkwkdays) rq_nkwkdays = strdup(cwalk->value);
                        else {
                              rq_nkwkdays = (char *)realloc(rq_nkwkdays, strlen(rq_nkwkdays) + strlen(cwalk->value) + 1);
                              strcat(rq_nkwkdays, cwalk->value);
                        }
                  }
            }
            else if (strcasecmp(cwalk->name, "NKSTARTHOUR") == 0) {
                  if (*cwalk->value) rq_nkslastart = strdup(cwalk->value);
            }
            else if (strcasecmp(cwalk->name, "NKENDHOUR") == 0) {
                  if (*cwalk->value) rq_nkslaend = strdup(cwalk->value);
            }
            else if (strcasecmp(cwalk->name, "start-day") == 0) {
                  rq_startday = atoi(cwalk->value);
            }
            else if (strcasecmp(cwalk->name, "start-mon") == 0) {
                  rq_startmon = atoi(cwalk->value);
            }
            else if (strcasecmp(cwalk->name, "start-yr") == 0) {
                  rq_startyear = atoi(cwalk->value);
            }
            else if (strcasecmp(cwalk->name, "end-day") == 0) {
                  rq_endday = atoi(cwalk->value);
            }
            else if (strcasecmp(cwalk->name, "end-mon") == 0) {
                  rq_endmon = atoi(cwalk->value);
            }
            else if (strcasecmp(cwalk->name, "end-yr") == 0) {
                  rq_endyear = atoi(cwalk->value);
            }
            else if (strcasecmp(cwalk->name, "EXTRA") == 0) {
                  if (*cwalk->value) rq_extra = strdup(cwalk->value);
            }
            else if (strcasecmp(cwalk->name, "DROPEVENIFCLONED") == 0) {
                  rq_dropevenifcloned = 1;
            }
            else if (strcasecmp(cwalk->name, "NKEDITADDCLONES") == 0) {
                  if (*cwalk->value) rq_clonestoadd = strdup(cwalk->value);
            }
            else if (strcasecmp(cwalk->name, "NKEDITCLONELIST") == 0) {
                  if (rq_clonestodrop) {
                        rq_clonestodrop = (char *)realloc(rq_clonestodrop, strlen(rq_clonestodrop) + strlen(cwalk->value) + 2);
                        strcat(rq_clonestodrop, " ");
                        strcat(rq_clonestodrop, cwalk->value);
                  }
                  else {
                        if (*cwalk->value) rq_clonestodrop = strdup(cwalk->value);
                  }
            }

            cwalk = cwalk->next;
      }

      if (editaction == NKEDIT_UPDATE) {
            struct tm tm;

            if ((rq_startday == 0) || (rq_startmon == 0) || (rq_startyear == 0))
                  rq_start = -1;
            else {
                  memset(&tm, 0, sizeof(tm));
                  tm.tm_mday = rq_startday;
                  tm.tm_mon = rq_startmon - 1;
                  tm.tm_year = rq_startyear - 1900;
                  tm.tm_isdst = -1;
                  rq_start = mktime(&tm);
            }

            if ((rq_endday == 0) || (rq_endmon == 0) || (rq_endyear == 0))
                  rq_end = -1;
            else {
                  memset(&tm, 0, sizeof(tm));
                  tm.tm_mday = rq_endday;
                  tm.tm_mon = rq_endmon - 1;
                  tm.tm_year = rq_endyear - 1900;
                  tm.tm_isdst = -1;
                  rq_end = mktime(&tm);
            }

            rq_nktime = (char *)malloc(strlen(rq_nkwkdays) + strlen(rq_nkslastart) + strlen(rq_nkslaend) + 3);
            sprintf(rq_nktime, "%s:%s:%s", rq_nkwkdays, rq_nkslastart, rq_nkslaend);
      }
      else if (editaction == NKEDIT_ADDCLONE) {
            if (!rq_clonestoadd && rq_clonestodrop) editaction = NKEDIT_DROPCLONE;
      }
}

void findrecord(char *hostname, char *service, char *nodatawarning, char *isclonewarning, char *hascloneswarning)
{
      nkconf_t *rec = NULL;
      int isaclone = 0;
      int hasclones = 0;
      char warnmsg[4096];

      /* Setup the list of cloned records */
      sethostenv_nkclonelist_clear();

      if (hostname && *hostname) {
            char *key, *realkey, *clonekey;
            nkconf_t *clonerec;

            if (service && *service) {
                  /* First check if the host+service is really a clone of something else */
                  key = (char *)malloc(strlen(hostname) + strlen(service) + 2);
                  sprintf(key, "%s|%s", hostname, service);
                  rec = get_nkconfig(key, NKCONF_FIRSTMATCH, &realkey);
            }
            else {
                  key = strdup(hostname);
                  rec = get_nkconfig(key, NKCONF_FIRSTHOSTMATCH, &realkey);
            }

            if (rec && realkey && (strcmp(key, realkey) != 0)) {
                  char *p;

                  xfree(key);
                  key = strdup(realkey);
                  hostname = realkey;
                  p = strchr(realkey, '|');
                  if (p) {
                        *p = '\0';
                        service = p+1;
                  }

                  isaclone = 1;
            }
            xfree(key);

            /* Next, see what hosts are clones of this one */
            clonerec = get_nkconfig(NULL, NKCONF_RAW_FIRST, &clonekey);
            while (clonerec) {
                  if ((*(clonekey + strlen(clonekey) -1) == '=') && (strcmp(hostname, (char *)clonerec) == 0)) {
                        sethostenv_nkclonelist_add(clonekey);
                        hasclones = 1;
                  }
                  clonerec = get_nkconfig(NULL, NKCONF_RAW_NEXT, &clonekey);
            }
      }
      else {
            hostname = "";
      }

      if (!service || !(*service)) service="";

      if (rec) sethostenv_nkedit(rec->updinfo, rec->priority, rec->ttgroup, rec->starttime, rec->endtime, rec->nktime, rec->ttextra);
      else sethostenv_nkedit("", 0, NULL, 0, 0, NULL, NULL);

      sethostenv(hostname, "", service, colorname(COL_BLUE), NULL);

      *warnmsg = '\0';
      if (!rec && nodatawarning) sprintf(warnmsg, "<SCRIPT LANGUAGE=\"Javascript\" type=\"text/javascript\"> alert('%s'); </SCRIPT>\n", nodatawarning);
      if (isaclone && isclonewarning) sprintf(warnmsg, "<SCRIPT LANGUAGE=\"Javascript\" type=\"text/javascript\"> alert('%s'); </SCRIPT>\n", isclonewarning);
      if (hasclones && hascloneswarning) sprintf(warnmsg, "<SCRIPT LANGUAGE=\"Javascript\" type=\"text/javascript\"> alert('%s'); </SCRIPT>\n", hascloneswarning);

      showform(stdout, "nkedit", "nkedit_form", COL_BLUE, getcurrenttime(NULL), warnmsg, NULL);
}


void nextrecord(char *hostname, char *service, char *isclonewarning, char *hascloneswarning)
{
      nkconf_t *rec;
      char *nexthost, *nextservice;

      /* First check if the host+service is really a clone of something else */
      if (hostname && service) {
            char *key;

            key = (char *)malloc(strlen(hostname) + strlen(service) + 2);
            sprintf(key, "%s|%s", hostname, service);
            rec = get_nkconfig(key, NKCONF_FIRSTMATCH, NULL);
            if (rec) rec = get_nkconfig(NULL, NKCONF_NEXT, NULL);
            xfree(key);
      }
      else {
            rec = get_nkconfig(NULL, NKCONF_FIRST, NULL);
      }

      if (rec) {
            nexthost = strdup(rec->key);
            nextservice = strchr(nexthost, '|'); if (nextservice) { *nextservice = '\0'; nextservice++; }
      }
      else {
            nexthost = strdup("");
            nextservice = "";
      }

      findrecord(nexthost, nextservice, NULL, isclonewarning, hascloneswarning);
      xfree(nexthost);
}

void updaterecord(char *hostname, char *service)
{
      nkconf_t *rec = NULL;

      if (hostname && service) {
            char *key = (char *)malloc(strlen(hostname) + strlen(service) + 2);
            char *realkey;
            char datestr[20];
            time_t now = getcurrenttime(NULL);

            strftime(datestr, sizeof(datestr), "%Y-%m-%d %H:%M:%S", localtime(&now));
            sprintf(key, "%s|%s", hostname, service);
            rec = get_nkconfig(key, NKCONF_FIRSTMATCH, &realkey);
            if (rec == NULL) {
                  rec = (nkconf_t *)calloc(1, sizeof(nkconf_t));
                  rec->key = strdup(key);
            }
            rec->priority = rq_priority;
            rec->starttime = (rq_start > 0) ? rq_start : 0;
            rec->endtime = (rq_end > 0) ? rq_end : 0;

            if (rec->nktime) {
                  xfree(rec->nktime); rec->nktime = NULL;
            }

            if (rq_nktime) {
                  rec->nktime = (strcmp(rq_nktime, "*:0000:2400") == 0) ? NULL : strdup(rq_nktime);
            }

            if (rec->ttgroup) xfree(rec->ttgroup); 
            rec->ttgroup = (rq_group ? strdup(rq_group) : NULL);
            if (rec->ttextra) xfree(rec->ttextra); 
            rec->ttextra = (rq_extra ? strdup(rq_extra) : NULL);
            if (rec->updinfo) xfree(rec->updinfo);
            rec->updinfo = (char *)malloc(strlen(operator) + strlen(datestr) + 2);
            sprintf(rec->updinfo, "%s %s", operator, datestr);

            update_nkconfig(rec);
            xfree(key);
      }

      findrecord(hostname, service, NULL, NULL, NULL);
}

void addclone(char *origin, char *newhosts, char *service)
{
      char *newclone;

      newclone = strtok(newhosts, " ");
      while (newclone) {
            addclone_nkconfig(origin, newclone);
            newclone = strtok(NULL, " ");
      }

      update_nkconfig(NULL);
      findrecord(origin, service, NULL, NULL, NULL);
}

void dropclone(char *origin, char *drops, char *service)
{
      char *drop;

      drop = strtok(drops, " ");
      while (drop) {
            dropclone_nkconfig(drop);
            drop = strtok(NULL, " ");
      }

      update_nkconfig(NULL);
      findrecord(origin, service, NULL, NULL, NULL);
}

void deleterecord(char *hostname, char *service, int evenifcloned)
{
      char *key;

      key = (char *)malloc(strlen(hostname) + strlen(service) + 2);
      sprintf(key, "%s|%s", hostname, service);
      if (delete_nkconfig(key, evenifcloned) == 0) {
            update_nkconfig(NULL);
      }

      findrecord(hostname, service, NULL, NULL, 
               (evenifcloned ? "Warning: Orphans will be ignored" : "Will not delete record that is cloned"));
}

int main(int argc, char *argv[])
{
      int argi;
      char *envarea = NULL;
      char *configfn = NULL;

      operator = getenv("REMOTE_USER");
      if (!operator) operator = "Anonymous";

      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 (argnmatch(argv[argi], "--config=")) {
                  char *p = strchr(argv[argi], '=');
                  configfn = strdup(p+1);
            }
            else if (strcmp(argv[argi], "--debug") == 0) {
                  debug = 1;
            }
      }

      redirect_cgilog("hobbit-nkedit");
      parse_query();
      load_nkconfig(configfn);

      switch (editaction) {
        case NKEDIT_FIND:
            findrecord(rq_hostname, rq_service, 
                     ((rq_hostname && rq_service) ? "No record for this host/service" : NULL),
                     "Cloned - showing master record", NULL);
            break;

        case NKEDIT_NEXT:
            nextrecord(rq_hostname, rq_service, "Cloned - showing master record", NULL);
            break;

        case NKEDIT_UPDATE:
            updaterecord(rq_hostname, rq_service);
            break;

        case NKEDIT_DELETE:
            deleterecord(rq_hostname, rq_service, rq_dropevenifcloned);
            break;

        case NKEDIT_ADDCLONE:
            addclone(rq_hostname, rq_clonestoadd, rq_service);
            break;

        case NKEDIT_DROPCLONE:
            dropclone(rq_hostname, rq_clonestodrop, rq_service);
            break;
      }

      return 0;
}


Generated by  Doxygen 1.6.0   Back to index