int ofi_mr_insert(struct ofi_util_mr * in_mr_h, const struct fi_mr_attr *in_attr, uint64_t * out_key, void * in_prov_mr) { struct fi_mr_attr * item; if (!in_attr || in_attr->iov_count <= 0 || !in_prov_mr) { return -FI_EINVAL; } item = create_mr_attr_copy(in_attr, in_prov_mr); if (!item) return -FI_ENOMEM; /* Scalable MR handling: use requested key and offset */ if (in_mr_h->mr_type == FI_MR_SCALABLE) { item->offset = (uintptr_t) in_attr->mr_iov[0].iov_base + in_attr->offset; /* verify key doesn't already exist */ if (rbtFind(in_mr_h->map_handle, &item->requested_key)) { free((void *)item->mr_iov); free(item); return -FI_EINVAL; } } else { item->requested_key = get_mr_key(in_mr_h); item->offset = (uintptr_t) in_attr->mr_iov[0].iov_base; } rbtInsert(in_mr_h->map_handle, &item->requested_key, item); *out_key = item->requested_key; return 0; }
int ofi_mr_insert(struct ofi_mr_map *map, const struct fi_mr_attr *attr, uint64_t *key, void *context) { struct fi_mr_attr *item; item = dup_mr_attr(attr); if (!item) return -FI_ENOMEM; if (!(map->mode & FI_MR_VIRT_ADDR)) item->offset = (uintptr_t) attr->mr_iov[0].iov_base; if (!(map->mode & FI_MR_PROV_KEY)) { if (rbtFind(map->rbtree, &item->requested_key)) { free(item); return -FI_ENOKEY; } } else { item->requested_key = map->key++; } rbtInsert(map->rbtree, &item->requested_key, item); *key = item->requested_key; item->context = context; return 0; }
static void locator_updatecache(enum locator_servicetype_t svc, char *key, char *resp) { RbtIterator handle; cacheitm_t *newitm; if (!havecache[svc]) return; handle = rbtFind(locatorcache[svc], key); if (handle == rbtEnd(locatorcache[svc])) { newitm = (cacheitm_t *)calloc(1, sizeof(cacheitm_t)); newitm->key = strdup(key); newitm->resp = strdup(resp); if (rbtInsert(locatorcache[svc], newitm->key, newitm) != RBT_STATUS_OK) { xfree(newitm->key); xfree(newitm->resp); xfree(newitm); } } else { newitm = (cacheitm_t *)gettreeitem(locatorcache[svc], handle); if (newitm->resp) xfree(newitm->resp); newitm->resp = strdup(resp); newitm->tstamp = getcurrenttime(NULL); } }
static void load_links(char *directory, char *urlprefix) { DIR *linkdir; struct dirent *d; char fn[PATH_MAX]; dbgprintf("load_links(%s, %s)\n", textornull(directory), textornull(urlprefix)); linkdir = opendir(directory); if (!linkdir) { errprintf("Cannot read links in directory %s\n", directory); return; } MEMDEFINE(fn); while ((d = readdir(linkdir))) { link_t *newlink; if (*(d->d_name) == '.') continue; strcpy(fn, d->d_name); newlink = init_link(fn, urlprefix); rbtInsert(linkstree, newlink->key, newlink); } closedir(linkdir); MEMUNDEFINE(fn); }
void addnetpeer(char *peername) { xymon_peer_t *newpeer; struct in_addr addr; char *oneip; int peerport = 0; char *delim; dbgprintf("Adding network peer %s\n", peername); oneip = strdup(peername); delim = strchr(oneip, ':'); if (delim) { *delim = '\0'; peerport = atoi(delim+1); } if (inet_aton(oneip, &addr) == 0) { /* peer is not an IP - do DNS lookup */ struct hostent *hent; hent = gethostbyname(oneip); if (hent) { char *realip; memcpy(&addr, *(hent->h_addr_list), sizeof(struct in_addr)); realip = inet_ntoa(addr); if (inet_aton(realip, &addr) == 0) { errprintf("Invalid IP address for %s (%s)\n", oneip, realip); goto done; } } else { errprintf("Cannot determine IP address of peer %s\n", oneip); goto done; } } if (peerport == 0) peerport = atoi(xgetenv("XYMONDPORT")); newpeer = calloc(1, sizeof(xymon_peer_t)); newpeer->peername = strdup(peername); newpeer->peerstatus = P_DOWN; newpeer->peertype = P_NET; newpeer->peeraddr.sin_family = AF_INET; newpeer->peeraddr.sin_addr.s_addr = addr.s_addr; newpeer->peeraddr.sin_port = htons(peerport); rbtInsert(peers, newpeer->peername, newpeer); done: xfree(oneip); }
void addclone_nkconfig(char *origin, char *newclone) { char *newkey; RbtHandle handle; newkey = (char *)malloc(strlen(newclone) + 2); sprintf(newkey, "%s=", newclone); handle = rbtFind(rbconf, newkey); if (handle != rbtEnd(rbconf)) dropclone_nkconfig(newclone); rbtInsert(rbconf, newkey, strdup(origin)); }
static void build_hosttree(void) { static int hosttree_exists = 0; namelist_t *walk; RbtStatus status; char *tstr; 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; } tstr = bbh_item(walk, BBH_NOTBEFORE); walk->notbefore = (tstr ? timestr2timet(tstr) : 0); if (walk->notbefore == -1) walk->notbefore = 0; tstr = bbh_item(walk, BBH_NOTAFTER); walk->notafter = (tstr ? timestr2timet(tstr) : INT_MAX); if (walk->notafter == -1) walk->notafter = INT_MAX; } }
static int psmx_ns_map_add(int service, psm_epid_t name) { if (rbtFind(psmx_ns_map, (void *)(uintptr_t)service)) { FI_WARN(&psmx_prov, FI_LOG_CORE, "failed to add address: service %u already in use.\n", service); return -FI_EBUSY; } if (rbtInsert(psmx_ns_map, (void *)(uintptr_t)service, (void *)name)) { FI_WARN(&psmx_prov, FI_LOG_CORE, "failed to add address for service %u: out of memory.\n", service); return -FI_ENOMEM; } return 0; }
static int ofi_mr_rbt_storage_insert(struct ofi_mr_storage *storage, struct iovec *key, struct ofi_mr_entry *entry) { int ret = rbtInsert((RbtHandle)storage->storage, (void *)&entry->iov, (void *)entry); if (ret != RBT_STATUS_OK) { switch (ret) { case RBT_STATUS_MEM_EXHAUSTED: return -FI_ENOMEM; case RBT_STATUS_DUPLICATE_KEY: return -FI_EALREADY; default: return -FI_EAVAIL; } } return ret; }
void addlocalpeer(char *childcmd, char **childargs) { xymon_peer_t *newpeer; int i, count; dbgprintf("Adding local peer using command %s\n", childcmd); for (count=0; (childargs[count]); count++) ; newpeer = (xymon_peer_t *)calloc(1, sizeof(xymon_peer_t)); newpeer->peername = strdup(""); newpeer->peerstatus = P_DOWN; newpeer->peertype = P_LOCAL; newpeer->childcmd = strdup(childcmd); newpeer->childargs = (char **)calloc(count+1, sizeof(char *)); for (i=0; (i<count); i++) newpeer->childargs[i] = strdup(childargs[i]); rbtInsert(peers, newpeer->peername, newpeer); }
RbtHandle columnlist(RbtHandle statetree) { RbtHandle rbcolumns; RbtIterator hhandle; rbcolumns = rbtNew(name_compare); for (hhandle = rbtBegin(statetree); (hhandle != rbtEnd(statetree)); hhandle = rbtNext(statetree, hhandle)) { void *k1, *k2; hstatus_t *itm; RbtStatus status; rbtKeyValue(statetree, hhandle, &k1, &k2); itm = (hstatus_t *)k2; status = rbtInsert(rbcolumns, itm->testname, NULL); } return rbcolumns; }
static int util_ns_map_add(struct util_ns *ns, void *service_in, void *name_in) { void *name, *service; int ret; service = calloc(ns->service_len, 1); if (!service) { ret = -FI_ENOMEM; goto err1; } memcpy(service, service_in, ns->service_len); name = calloc(ns->name_len, 1); if (!name) { ret = -FI_ENOMEM; goto err2; } memcpy(name, name_in, ns->name_len); if (rbtFind(ns->ns_map, service)) { ret = -FI_EADDRINUSE; goto err3; } if (rbtInsert(ns->ns_map, service, name)) { ret = -FI_ENOMEM; goto err3; } return FI_SUCCESS; err3: free(name); err2: free(service); err1: return ret; }
static int psmx2_mr_reserve_key(struct psmx2_fid_domain *domain, uint64_t requested_key, uint64_t *assigned_key, void *mr) { uint64_t key; int i; int try_count; int err = -FI_ENOKEY; fastlock_acquire(&domain->mr_lock); if (domain->mr_mode == FI_MR_SCALABLE) { key = requested_key; try_count = 1; } else { key = domain->mr_reserved_key; try_count = 10000; /* large enough */ } for (i=0; i<try_count; i++, key++) { if (!rbtFind(domain->mr_map, (void *)key)) { if (!rbtInsert(domain->mr_map, (void *)key, mr)) { if (domain->mr_mode != FI_MR_SCALABLE) domain->mr_reserved_key = key + 1; *assigned_key = key; err = 0; } break; } } fastlock_release(&domain->mr_lock); return err; }
int tex_cache_getid(int imgid,int* cacheid) { KeyType key = imgid; RbtStatus status; NodeType *p; int ret = 0; if ((p = rbtFind(rb,key)) != NULL) { *cacheid = ((tex_node_p)(p->val.node))->texid; ret = 1; } else { ValType val; val.stuff = imgid; val.node = get_free_node(); key = imgid; status = rbtInsert(rb,key, val); if (status) { printf("fail: status = %d\n", status); } *cacheid = ((tex_node_p)(val.node))->texid; } return ret; }
static int sock_regattr(struct fid *fid, const struct fi_mr_attr *attr, uint64_t flags, struct fid_mr **mr) { struct fi_eq_entry eq_entry; struct sock_domain *dom; struct sock_mr *_mr; uint64_t key; struct fid_domain *domain; RbtStatus res; int ret = 0; if (fid->fclass != FI_CLASS_DOMAIN || !attr || attr->iov_count <= 0) { return -FI_EINVAL; } domain = container_of(fid, struct fid_domain, fid); dom = container_of(domain, struct sock_domain, dom_fid); _mr = calloc(1, sizeof(*_mr) + sizeof(_mr->mr_iov) * (attr->iov_count - 1)); if (!_mr) return -FI_ENOMEM; fastlock_acquire(&dom->lock); if (dom->attr.mr_mode == FI_MR_SCALABLE && sock_mr_get_entry(dom, attr->requested_key) != NULL) { ret = -FI_ENOKEY; goto err; } _mr->mr_fid.fid.fclass = FI_CLASS_MR; _mr->mr_fid.fid.context = attr->context; _mr->mr_fid.fid.ops = &sock_mr_fi_ops; _mr->domain = dom; _mr->access = attr->access; _mr->flags = flags; _mr->offset = (dom->attr.mr_mode == FI_MR_SCALABLE) ? (uintptr_t) attr->mr_iov[0].iov_base + attr->offset : (uintptr_t) attr->mr_iov[0].iov_base; key = (dom->attr.mr_mode == FI_MR_BASIC) ? sock_get_mr_key(dom) : attr->requested_key; _mr->key = key; res = rbtInsert(dom->mr_heap, &_mr->key, _mr); if (res != RBT_STATUS_OK) { ret = -FI_ENOMEM; goto err; } _mr->mr_fid.key = key; _mr->mr_fid.mem_desc = (void *) (uintptr_t) key; fastlock_release(&dom->lock); _mr->iov_count = attr->iov_count; memcpy(&_mr->mr_iov, attr->mr_iov, sizeof(_mr->mr_iov) * attr->iov_count); *mr = &_mr->mr_fid; atomic_inc(&dom->ref); if (dom->mr_eq) { eq_entry.fid = &domain->fid; eq_entry.context = attr->context; return sock_eq_report_event(dom->mr_eq, FI_MR_COMPLETE, &eq_entry, sizeof(eq_entry), 0); } return 0; err: fastlock_release(&dom->lock); free(_mr); return ret; }
int load_hostnames(char *bbhostsfn, char *extrainclude, int fqdn) { /* Return value: 0 for load OK, 1 for "No files changed since last load", -1 for error (file not found) */ static void *bbhfiles = NULL; FILE *bbhosts; int ip1, ip2, ip3, ip4, groupid, pageidx; char hostname[4096]; strbuffer_t *inbuf; pagelist_t *curtoppage, *curpage, *pgtail; namelist_t *nametail = NULL; RbtHandle htree; /* First check if there were no modifications at all */ if (bbhfiles) { if (!stackfmodified(bbhfiles)){ dbgprintf("No files modified, skipping reload of %s\n", bbhostsfn); return 1; } else { stackfclist(&bbhfiles); bbhfiles = NULL; } } MEMDEFINE(hostname); MEMDEFINE(l); configloaded = 1; initialize_hostlist(); curpage = curtoppage = pgtail = pghead; pageidx = groupid = 0; bbhosts = stackfopen(bbhostsfn, "r", &bbhfiles); if (bbhosts == NULL) return -1; inbuf = newstrbuffer(0); htree = rbtNew(name_compare); while (stackfgets(inbuf, extrainclude)) { sanitize_input(inbuf, 0, 0); if (strncmp(STRBUF(inbuf), "page", 4) == 0) { pagelist_t *newp; char *name, *title; pageidx = groupid = 0; if (get_page_name_title(STRBUF(inbuf), "page", &name, &title) == 0) { newp = (pagelist_t *)malloc(sizeof(pagelist_t)); newp->pagepath = strdup(name); newp->pagetitle = (title ? strdup(title) : NULL); newp->next = NULL; pgtail->next = newp; pgtail = newp; curpage = curtoppage = newp; } } else if (strncmp(STRBUF(inbuf), "subpage", 7) == 0) { pagelist_t *newp; char *name, *title; pageidx = groupid = 0; if (get_page_name_title(STRBUF(inbuf), "subpage", &name, &title) == 0) { newp = (pagelist_t *)malloc(sizeof(pagelist_t)); newp->pagepath = malloc(strlen(curtoppage->pagepath) + strlen(name) + 2); sprintf(newp->pagepath, "%s/%s", curtoppage->pagepath, name); newp->pagetitle = malloc(strlen(curtoppage->pagetitle) + strlen(title) + 2); sprintf(newp->pagetitle, "%s/%s", curtoppage->pagetitle, title); newp->next = NULL; pgtail->next = newp; pgtail = newp; curpage = newp; } } else if (strncmp(STRBUF(inbuf), "subparent", 9) == 0) { pagelist_t *newp, *parent; char *pname, *name, *title; pageidx = groupid = 0; parent = NULL; if (get_page_name_title(STRBUF(inbuf), "subparent", &pname, &title) == 0) { for (parent = pghead; (parent && !pagematch(parent, pname)); parent = parent->next); } if (parent && (get_page_name_title(title, "", &name, &title) == 0)) { newp = (pagelist_t *)malloc(sizeof(pagelist_t)); newp->pagepath = malloc(strlen(parent->pagepath) + strlen(name) + 2); sprintf(newp->pagepath, "%s/%s", parent->pagepath, name); newp->pagetitle = malloc(strlen(parent->pagetitle) + strlen(title) + 2); sprintf(newp->pagetitle, "%s/%s", parent->pagetitle, title); newp->next = NULL; pgtail->next = newp; pgtail = newp; curpage = newp; } } else if (strncmp(STRBUF(inbuf), "group", 5) == 0) { groupid++; } else if (sscanf(STRBUF(inbuf), "%d.%d.%d.%d %s", &ip1, &ip2, &ip3, &ip4, hostname) == 5) { char *startoftags, *tag, *delim; int elemidx, elemsize; char clientname[4096]; char downtime[4096]; char groupidstr[10]; RbtIterator handle; namelist_t *newitem = calloc(1, sizeof(namelist_t)); namelist_t *iwalk, *iprev; MEMDEFINE(clientname); MEMDEFINE(downtime); /* Hostname beginning with '@' are "no-display" hosts. But we still want them. */ if (*hostname == '@') memmove(hostname, hostname+1, strlen(hostname)); if (!fqdn) { /* Strip any domain from the hostname */ char *p = strchr(hostname, '.'); if (p) *p = '\0'; } sprintf(newitem->ip, "%d.%d.%d.%d", ip1, ip2, ip3, ip4); sprintf(groupidstr, "%d", groupid); newitem->groupid = strdup(groupidstr); newitem->pageindex = pageidx++; newitem->bbhostname = strdup(hostname); if (ip1 || ip2 || ip3 || ip4) newitem->preference = 1; else newitem->preference = 0; newitem->logname = strdup(newitem->bbhostname); { char *p = newitem->logname; while ((p = strchr(p, '.')) != NULL) { *p = '_'; } } newitem->page = curpage; newitem->defaulthost = defaulthost; clientname[0] = downtime[0] = '\0'; startoftags = strchr(STRBUF(inbuf), '#'); if (startoftags == NULL) startoftags = ""; else startoftags++; startoftags += strspn(startoftags, " \t\r\n"); newitem->allelems = strdup(startoftags); elemsize = 5; newitem->elems = (char **)malloc((elemsize+1)*sizeof(char *)); tag = newitem->allelems; elemidx = 0; while (tag && *tag) { if (elemidx == elemsize) { elemsize += 5; newitem->elems = (char **)realloc(newitem->elems, (elemsize+1)*sizeof(char *)); } newitem->elems[elemidx] = tag; /* Skip until we hit a whitespace or a quote */ tag += strcspn(tag, " \t\r\n\""); if (*tag == '"') { delim = tag; /* Hit a quote - skip until the next matching quote */ tag = strchr(tag+1, '"'); if (tag != NULL) { /* Found end-quote, NULL the item here and move on */ *tag = '\0'; tag++; } /* Now move quoted data one byte down (including the NUL) to kill quotechar */ memmove(delim, delim+1, strlen(delim)); } else if (*tag) { /* Normal end of item, NULL it and move on */ *tag = '\0'; tag++; } else { /* End of line - no more to do. */ tag = NULL; } /* * If we find a "noconn", drop preference value to 0. * If we find a "prefer", up reference value to 2. */ if ((newitem->preference == 1) && (strcmp(newitem->elems[elemidx], "noconn") == 0)) newitem->preference = 0; else if (strcmp(newitem->elems[elemidx], "prefer") == 0) newitem->preference = 2; /* Skip whitespace until start of next tag */ if (tag) tag += strspn(tag, " \t\r\n"); elemidx++; } newitem->elems[elemidx] = NULL; /* See if this host is defined before */ handle = rbtFind(htree, newitem->bbhostname); if (strcasecmp(newitem->bbhostname, ".default.") == 0) { /* The pseudo DEFAULT host */ newitem->next = NULL; defaulthost = newitem; } else if (handle == rbtEnd(htree)) { /* New item, so add to end of list */ newitem->next = NULL; if (namehead == NULL) namehead = nametail = newitem; else { nametail->next = newitem; nametail = newitem; } rbtInsert(htree, newitem->bbhostname, newitem); } else { /* Find the existing record - compare the record pointer instead of the name */ namelist_t *existingrec = (namelist_t *)gettreeitem(htree, handle); for (iwalk = namehead, iprev = NULL; ((iwalk != existingrec) && iwalk); iprev = iwalk, iwalk = iwalk->next) ; if (newitem->preference <= iwalk->preference) { /* Add after the existing (more preferred) entry */ newitem->next = iwalk->next; iwalk->next = newitem; } else { /* New item has higher preference, so add before the iwalk item (i.e. after iprev) */ if (iprev == NULL) { newitem->next = namehead; namehead = newitem; } else { newitem->next = iprev->next; iprev->next = newitem; } } } newitem->clientname = bbh_find_item(newitem, BBH_CLIENTALIAS); if (newitem->clientname == NULL) newitem->clientname = newitem->bbhostname; newitem->downtime = bbh_find_item(newitem, BBH_DOWNTIME); MEMUNDEFINE(clientname); MEMUNDEFINE(downtime); } } stackfclose(bbhosts); freestrbuffer(inbuf); rbtDelete(htree); MEMUNDEFINE(hostname); MEMUNDEFINE(l); build_hosttree(); return 0; }
int main(int argc, char *argv[]) { int argi; struct sigaction sa; namelist_t *hostwalk; time_t nexttimeout; for (argi=1; (argi < argc); argi++) { if (argnmatch(argv[argi], "--server=")) { char *p = strchr(argv[argi], '='); serverip = strdup(p+1); } else if (argnmatch(argv[argi], "--interval=")) { char *p = strchr(argv[argi], '='); pollinterval = atoi(p+1); } else if (argnmatch(argv[argi], "--log-interval=")) { char *p = strchr(argv[argi], '='); errorloginterval = atoi(p+1); } else if (argnmatch(argv[argi], "--id=")) { char *p = strchr(argv[argi], '='); serverid = atoi(p+1); } else if (strcmp(argv[argi], "--debug") == 0) { debug = 1; } } setup_signalhandler("hobbitfetch"); memset(&sa, 0, sizeof(sa)); sa.sa_handler = sigmisc_handler; sigaction(SIGHUP, &sa, NULL); sigaction(SIGTERM, &sa, NULL); sigaction(SIGUSR1, &sa, NULL); /* SIGUSR1 triggers logging of active requests */ clients = rbtNew(name_compare); nexttimeout = time(NULL) + 60; { /* Seed the random number generator */ struct timeval tv; struct timezone tz; gettimeofday(&tv, &tz); srandom(tv.tv_usec); } do { RbtIterator handle; conn_t *connwalk, *cprev; fd_set fdread, fdwrite; int n, maxfd; struct timeval tmo; time_t now; now = time(NULL); if (now > reloadtime) { /* Time to reload the bb-hosts file */ reloadtime = now + 600; load_hostnames(xgetenv("BBHOSTS"), NULL, get_fqdn()); for (hostwalk = first_host(); (hostwalk); hostwalk = hostwalk->next) { char *hname; clients_t *newclient; if (!bbh_item(hostwalk, BBH_FLAG_PULLDATA)) continue; hname = bbh_item(hostwalk, BBH_HOSTNAME); handle = rbtFind(clients, hname); if (handle == rbtEnd(clients)) { newclient = (clients_t *)calloc(1, sizeof(clients_t)); newclient->hostname = strdup(hname); rbtInsert(clients, newclient->hostname, newclient); whentoqueue = now; } } } now = time(NULL); if (now > nexttimeout) { /* Check for connections that have timed out */ nexttimeout = now + 60; for (connwalk = chead; (connwalk); connwalk = connwalk->next) { if ((connwalk->tstamp + 60) < now) { if (debug || (connwalk->client->nexterrortxt < now)) { errprintf("Timeout while talking to %s (req %lu): Aborting session\n", addrstring(&connwalk->caddr), connwalk->seq); connwalk->client->nexterrortxt = now + errorloginterval; } flag_cleanup(connwalk); } } } if (needcleanup) { /* Remove any finished requests */ needcleanup = 0; connwalk = chead; cprev = NULL; dbgprintf("Doing cleanup\n"); while (connwalk) { conn_t *zombie; if ((connwalk->action == C_READING) || (connwalk->action == C_WRITING)) { /* Active connection - skip to the next conn_t record */ cprev = connwalk; connwalk = connwalk->next; continue; } if (connwalk->action == C_CLEANUP) { if (connwalk->ctype == C_CLIENT) { /* * Finished getting data from a client, * flag idle and set next poll time. */ connwalk->client->busy = 0; set_polltime(connwalk->client); } else if (connwalk->ctype == C_SERVER) { /* Nothing needed for server cleanups */ } } /* Unlink the request from the list of active connections */ zombie = connwalk; if (cprev == NULL) { chead = zombie->next; connwalk = chead; cprev = NULL; } else { cprev->next = zombie->next; connwalk = zombie->next; } /* Purge the zombie */ dbgprintf("Request completed: req %lu, peer %s, action was %d, type was %d\n", zombie->seq, addrstring(&zombie->caddr), zombie->action, zombie->ctype); close(zombie->sockfd); freestrbuffer(zombie->msgbuf); xfree(zombie); } /* Set the tail pointer correctly */ ctail = chead; if (ctail) { while (ctail->next) ctail = ctail->next; } } if (dumpsessions) { /* Set by SIGUSR1 - dump the list of active requests */ dumpsessions = 0; for (connwalk = chead; (connwalk); connwalk = connwalk->next) { char *ctypestr, *actionstr; char timestr[30]; switch (connwalk->ctype) { case C_CLIENT: ctypestr = "client"; break; case C_SERVER: ctypestr = "server"; break; } switch (connwalk->action) { case C_READING: actionstr = "reading"; break; case C_WRITING: actionstr = "writing"; break; case C_CLEANUP: actionstr = "cleanup"; break; } strftime(timestr, sizeof(timestr), "%Y-%m-%d %H:%M:%S", localtime(&connwalk->tstamp)); errprintf("Request %lu: state %s/%s, peer %s, started %s (%lu secs ago)\n", connwalk->seq, ctypestr, actionstr, addrstring(&connwalk->caddr), timestr, (now - connwalk->tstamp)); } } now = time(NULL); if (now >= whentoqueue) { /* Scan host-tree for clients we need to contact */ for (handle = rbtBegin(clients); (handle != rbtEnd(clients)); handle = rbtNext(clients, handle)) { clients_t *clientwalk; char msgline[100]; strbuffer_t *request; char *pullstr, *ip; int port; clientwalk = (clients_t *)gettreeitem(clients, handle); if (clientwalk->busy) continue; if (clientwalk->nextpoll > now) continue; /* Deleted hosts stay in our tree - but should disappear from the known hosts */ hostwalk = hostinfo(clientwalk->hostname); if (!hostwalk) continue; pullstr = bbh_item(hostwalk, BBH_FLAG_PULLDATA); if (!pullstr) continue; ip = strchr(pullstr, '='); port = atoi(xgetenv("BBPORT")); if (!ip) { ip = strdup(bbh_item(hostwalk, BBH_IP)); } else { /* There is an explicit IP setting in the pulldata tag */ char *p; ip++; /* Skip the '=' */ ip = strdup(ip); p = strchr(ip, ':'); if (p) { *p = '\0'; port = atoi(p+1); } if (*ip == '\0') { /* No IP given, just a port number */ xfree(ip); ip = strdup(bbh_item(hostwalk, BBH_IP)); } } if (strcmp(ip, "0.0.0.0") == 0) { struct hostent *hent; xfree(ip); ip = NULL; hent = gethostbyname(clientwalk->hostname); if (hent) { struct in_addr addr; memcpy(&addr, *(hent->h_addr_list), sizeof(addr)); ip = strdup(inet_ntoa(addr)); } } if (!ip) continue; /* * Build the "pullclient" request, which includes the latest * clientdata config we got from the server. Keep the clientdata * here - we send "pullclient" requests more often that we actually * contact the server, but we should provide the config data always. */ request = newstrbuffer(0); sprintf(msgline, "pullclient %d\n", serverid); addtobuffer(request, msgline); if (clientwalk->clientdata) addtobuffer(request, clientwalk->clientdata); /* Put the request on the connection queue */ addrequest(C_CLIENT, ip, port, request, clientwalk); clientwalk->busy = 1; xfree(ip); } } /* Handle request queue */ FD_ZERO(&fdread); FD_ZERO(&fdwrite); maxfd = -1; for (connwalk = chead; (connwalk); connwalk = connwalk->next) { switch (connwalk->action) { case C_READING: FD_SET(connwalk->sockfd, &fdread); if (connwalk->sockfd > maxfd) maxfd = connwalk->sockfd; break; case C_WRITING: FD_SET(connwalk->sockfd, &fdwrite); if (connwalk->sockfd > maxfd) maxfd = connwalk->sockfd; break; case C_CLEANUP: break; } } /* Do select with a 1 second timeout */ tmo.tv_sec = 1; tmo.tv_usec = 0; n = select(maxfd+1, &fdread, &fdwrite, NULL, &tmo); if (n == -1) { if (errno == EINTR) continue; /* Interrupted, e.g. a SIGHUP */ /* This is a "cannot-happen" failure. Bail out */ errprintf("select failure: %s\n", strerror(errno)); return 0; } if (n == 0) continue; /* Timeout */ for (connwalk = chead; (connwalk); connwalk = connwalk->next) { switch (connwalk->action) { case C_READING: if (FD_ISSET(connwalk->sockfd, &fdread)) grabdata(connwalk); break; case C_WRITING: if (FD_ISSET(connwalk->sockfd, &fdwrite)) senddata(connwalk); break; case C_CLEANUP: break; } } } while (running); return 0; }
int update_nkconfig(nkconf_t *rec) { char *bakfn; FILE *bakfd; unsigned char buf[8192]; int n; struct stat st; struct utimbuf ut; RbtHandle handle; FILE *fd; int result = 0; /* First, copy the old file */ bakfn = (char *)malloc(strlen(configfn) + 5); sprintf(bakfn, "%s.bak", configfn); if (stat(configfn, &st) == 0) { ut.actime = st.st_atime; ut.modtime = st.st_mtime; } else ut.actime = ut.modtime = getcurrenttime(NULL); fd = fopen(configfn, "r"); if (fd) { bakfd = fopen(bakfn, "w"); if (bakfd) { while ((n = fread(buf, 1, sizeof(buf), fd)) > 0) fwrite(buf, 1, n, bakfd); fclose(bakfd); utime(bakfn, &ut); } fclose(fd); } xfree(bakfn); fd = fopen(configfn, "w"); if (fd == NULL) { errprintf("Cannot open output file %s\n", configfn); return 1; } if (rec) { handle = rbtFind(rbconf, rec->key); if (handle == rbtEnd(rbconf)) rbtInsert(rbconf, rec->key, rec); } handle = rbtBegin(rbconf); while (handle != rbtEnd(rbconf)) { void *k1, *k2; char *onekey; rbtKeyValue(rbconf, handle, &k1, &k2); onekey = (char *)k1; if (*(onekey + strlen(onekey) - 1) == '=') { char *pointsto = (char *)k2; char *hostname; hostname = strdup(onekey); *(hostname + strlen(hostname) - 1) = '\0'; fprintf(fd, "%s|=%s\n", hostname, pointsto); } else { nkconf_t *onerec = (nkconf_t *)k2; char startstr[20], endstr[20]; *startstr = *endstr = '\0'; if (onerec->starttime > 0) sprintf(startstr, "%d", (int)onerec->starttime); if (onerec->endtime > 0) sprintf(endstr, "%d", (int)onerec->endtime); fprintf(fd, "%s|%s|%s|%s|%d|%s|%s|%s\n", onekey, startstr, endstr, (onerec->nktime ? onerec->nktime : ""), onerec->priority, (onerec->ttgroup ? onerec->ttgroup : ""), (onerec->ttextra ? onerec->ttextra : ""), (onerec->updinfo ? onerec->updinfo : "")); } handle = rbtNext(rbconf, handle); } fclose(fd); return result; }
int loadstatus(int maxprio, time_t maxage, int mincolor, int wantacked) { int xymondresult; char *board = NULL; char *bol, *eol; time_t now; char msg[1024]; int i; sendreturn_t *sres; sprintf(msg, "xymondboard acklevel=%d fields=hostname,testname,color,lastchange,logtime,validtime,acklist color=%s", critacklevel,colorname(mincolor)); for (i=mincolor+1; (i < COL_COUNT); i++) sprintf(msg+strlen(msg), ",%s", colorname(i)); sres = newsendreturnbuf(1, NULL); xymondresult = sendmessage(msg, NULL, XYMON_TIMEOUT, sres); if (xymondresult != XYMONSEND_OK) { freesendreturnbuf(sres); errormsg("Unable to fetch current status\n"); return 1; } else { board = getsendreturnstr(sres, 1); freesendreturnbuf(sres); } now = getcurrenttime(NULL); rbstate = rbtNew(name_compare); bol = board; while (bol && (*bol)) { char *endkey; RbtStatus status; eol = strchr(bol, '\n'); if (eol) *eol = '\0'; /* Find the config entry */ endkey = strchr(bol, '|'); if (endkey) endkey = strchr(endkey+1, '|'); if (endkey) { critconf_t *cfg; char *ackstr, *ackrtimestr, *ackvtimestr, *acklevelstr, *ackbystr, *ackmsgstr; *endkey = '\0'; cfg = get_critconfig(bol, CRITCONF_TIMEFILTER, NULL); *endkey = '|'; if (cfg) { hstatus_t *newitem = (hstatus_t *)calloc(1, sizeof(hstatus_t)); newitem->config = cfg; newitem->hostname = gettok(bol, "|"); newitem->testname = gettok(NULL, "|"); newitem->color = parse_color(gettok(NULL, "|")); newitem->lastchange = atoi(gettok(NULL, "|")); newitem->logtime = atoi(gettok(NULL, "|")); newitem->validtime = atoi(gettok(NULL, "|")); ackstr = gettok(NULL, "|"); ackrtimestr = ackvtimestr = acklevelstr = ackbystr = ackmsgstr = NULL; if (ackstr) { nldecode(ackstr); ackrtimestr = strtok(ackstr, ":"); if (ackrtimestr) ackvtimestr = strtok(NULL, ":"); if (ackvtimestr) acklevelstr = strtok(NULL, ":"); if (acklevelstr) ackbystr = strtok(NULL, ":"); if (ackbystr) ackmsgstr = strtok(NULL, ":"); } if ( (hostinfo(newitem->hostname) == NULL) || (newitem->config->priority > maxprio) || ((now - newitem->lastchange) > maxage) || (newitem->color < mincolor) || (ackmsgstr && !wantacked) ) { xfree(newitem); } else { if (ackvtimestr && ackbystr && ackmsgstr) { newitem->acktime = atoi(ackvtimestr); newitem->ackedby = strdup(ackbystr); newitem->ackmsg = strdup(ackmsgstr); } newitem->key = (char *)malloc(strlen(newitem->hostname) + strlen(newitem->testname) + 2); sprintf(newitem->key, "%s|%s", newitem->hostname, newitem->testname); status = rbtInsert(rbstate, newitem->key, newitem); } } } bol = (eol ? (eol+1) : NULL); } return 0; }
int load_nkconfig(char *fn) { static void *configfiles = NULL; static int firsttime = 1; FILE *fd; strbuffer_t *inbuf; /* Setup the default configuration filename */ if (!fn) { if (!defaultfn) { char *bbhome = xgetenv("BBHOME"); defaultfn = (char *)malloc(strlen(bbhome) + strlen(DEFAULTCONFIG) + 2); sprintf(defaultfn, "%s/%s", bbhome, DEFAULTCONFIG); } fn = defaultfn; } if (configfn) xfree(configfn); configfn = strdup(fn); /* First check if there were no modifications at all */ if (configfiles) { if (!stackfmodified(configfiles)){ dbgprintf("No files modified, skipping reload of %s\n", fn); return 0; } else { stackfclist(&configfiles); configfiles = NULL; } } if (!firsttime) { /* Clean up existing datatree */ RbtHandle handle; void *k1, *k2; for (handle = rbtBegin(rbconf); (handle != rbtEnd(rbconf)); handle = rbtNext(rbconf, handle)) { rbtKeyValue(rbconf, handle, &k1, &k2); flushrec(k1, k2); } rbtDelete(rbconf); } firsttime = 0; rbconf = rbtNew(name_compare); fd = stackfopen(fn, "r", &configfiles); if (fd == NULL) return 1; inbuf = newstrbuffer(0); while (stackfgets(inbuf, NULL)) { /* Full record : Host service START END TIMESPEC TTPrio TTGroup TTExtra */ /* Clone record: Host =HOST */ char *ehost, *eservice, *estart, *eend, *etime, *ttgroup, *ttextra, *updinfo; int ttprio = 0; nkconf_t *newitem; RbtStatus status; int idx = 0; ehost = gettok(STRBUF(inbuf), "|\n"); if (!ehost) continue; eservice = gettok(NULL, "|\n"); if (!eservice) continue; if (*eservice == '=') { char *key = (char *)malloc(strlen(ehost) + 2); char *pointsto = strdup(eservice+1); sprintf(key, "%s=", ehost); status = rbtInsert(rbconf, key, pointsto); } else { estart = gettok(NULL, "|\n"); if (!estart) continue; eend = gettok(NULL, "|\n"); if (!eend) continue; etime = gettok(NULL, "|\n"); if (!etime) continue; ttprio = atoi(gettok(NULL, "|\n")); if (ttprio == 0) continue; ttgroup = gettok(NULL, "|\n"); ttextra = gettok(NULL, "|\n"); updinfo = gettok(NULL, "|\n"); newitem = (nkconf_t *)malloc(sizeof(nkconf_t)); newitem->key = (char *)malloc(strlen(ehost) + strlen(eservice) + 15); sprintf(newitem->key, "%s|%s", ehost, eservice); newitem->starttime= ((estart && *estart) ? atoi(estart) : 0); newitem->endtime = ((eend && *eend) ? atoi(eend) : 0); newitem->nktime = ((etime && *etime) ? strdup(etime) : NULL); newitem->priority = ttprio; newitem->ttgroup = strdup(ttgroup); newitem->ttextra = strdup(ttextra); newitem->updinfo = strdup(updinfo); status = rbtInsert(rbconf, newitem->key, newitem); while (status == RBT_STATUS_DUPLICATE_KEY) { idx++; sprintf(newitem->key, "%s|%s|%d", ehost, eservice, idx); status = rbtInsert(rbconf, newitem->key, newitem); } } } stackfclose(fd); freestrbuffer(inbuf); if (debug) { RbtHandle handle; handle = rbtBegin(rbconf); while (handle != rbtEnd(rbconf)) { void *k1, *k2; rbtKeyValue(rbconf, handle, &k1, &k2); printf("%s\n", (char *)k1); handle = rbtNext(rbconf, handle); } } return 0; }