/* Set the module search path after changing it */ static void setpath(struct pathhead *pathq) { char *newpath; if (miblen == 0) getmib(); if ((newpath = qstring(pathq)) == NULL) { errno = ENOMEM; err(1, "building path string"); } if (sysctl(mib, miblen, NULL, NULL, newpath, strlen(newpath)+1) == -1) err(1, "setting path: sysctl(%s)", pathctl); if (modpath != NULL) free(modpath); modpath = newpath; }
/* Get the current module search path */ static void getpath(void) { char *path; size_t sz; if (modpath != NULL) { free(modpath); modpath = NULL; } if (miblen == 0) getmib(); if (sysctl(mib, miblen, NULL, &sz, NULL, 0) == -1) err(1, "getting path: sysctl(%s) - size only", pathctl); if ((path = malloc(sz + 1)) == NULL) { errno = ENOMEM; err(1, "allocating %lu bytes for the path", (unsigned long)sz+1); } if (sysctl(mib, miblen, path, &sz, NULL, 0) == -1) err(1, "getting path: sysctl(%s)", pathctl); modpath = path; }
/* * get MIB-II statistics. It maintaines a simple cache which buffers the last * read block of MIB statistics (which may contain the whole table). It calls * *comp to compare every entry with an entry pointed by arg. *comp should * return 0 if comparison is successful. Req_type may be GET_FIRST, GET_EXACT, * GET_NEXT. If search is successful getMibstat returns 0, otherwise 1. */ int getMibstat(mibgroup_e grid, void *resp, size_t entrysize, req_e req_type, int (*comp) (void *, void *), void *arg) { int ret, rc = -1, mibgr, mibtb, cache_valid; size_t length; mibcache *cachep; found_e result = NOT_FOUND; void *ep; /* * We assume that Mibcache is initialized in mibgroup_e enum order so we * don't check the validity of index here. */ DEBUGMSGTL(("kernel_sunos5", "getMibstat (%d, *, %d, %d, *, *)\n", grid, entrysize, req_type)); cachep = &Mibcache[grid]; mibgr = Mibmap[grid].group; mibtb = Mibmap[grid].table; if (cachep->cache_addr == (void *) -1) /* Hasn't been initialized yet */ init_mibcache_element(cachep); if (cachep->cache_size == 0) { /* Memory allocation problems */ cachep->cache_addr = resp; /* So use caller supplied address instead of cache */ cachep->cache_size = entrysize; cachep->cache_last_found = 0; } if (req_type != GET_NEXT) cachep->cache_last_found = 0; cache_valid = (cachep->cache_time > 0); DEBUGMSGTL(("kernel_sunos5","... cache_valid %d time %ld ttl %d now %ld\n", cache_valid, cachep->cache_time, cachep->cache_ttl, time(NULL))); if (cache_valid) { /* * Is it really? */ if (cachep->cache_comp != (void *)comp || cachep->cache_arg != arg) { cache_valid = 0; /* Nope. */ } } if (cache_valid) { /* * Entry is valid, let's try to find a match */ if (req_type == GET_NEXT) { result = getentry(req_type, (void *)((char *)cachep->cache_addr + (cachep->cache_last_found * entrysize)), cachep->cache_length - (cachep->cache_last_found * entrysize), entrysize, &ep, comp, arg); } else { result = getentry(req_type, cachep->cache_addr, cachep->cache_length, entrysize, &ep, comp, arg); } } if ((cache_valid == 0) || (result == NOT_FOUND) || (result == NEED_NEXT && cachep->cache_flags & CACHE_MOREDATA)) { /* * Either the cache is old, or we haven't found anything, or need the * next item which hasn't been read yet. In any case, fill the cache * up and try to find our entry. */ if (grid == MIB_INTERFACES) { rc = getif((mib2_ifEntry_t *) cachep->cache_addr, cachep->cache_size, req_type, (mib2_ifEntry_t *) & ep, &length, comp, arg); } else { rc = getmib(mibgr, mibtb, cachep->cache_addr, cachep->cache_size, entrysize, req_type, &ep, &length, comp, arg); } if (rc >= 0) { /* Cache has been filled up */ cachep->cache_time = cachep->cache_ttl; cachep->cache_length = length; if (rc == 1) /* Found but there are more unread data */ cachep->cache_flags |= CACHE_MOREDATA; else cachep->cache_flags &= ~CACHE_MOREDATA; cachep->cache_comp = (void *) comp; cachep->cache_arg = arg; } else { cachep->cache_comp = NULL; cachep->cache_arg = NULL; } } DEBUGMSGTL(("kernel_sunos5", "... result %d rc %d\n", result, rc)); if (result == FOUND || rc == 0 || rc == 1) { /* * Entry has been found, deliver it */ if (resp != NULL) { memcpy(resp, ep, entrysize); } ret = 0; cachep->cache_last_found = ((char *)ep - (char *)cachep->cache_addr) / entrysize; } else { ret = 1; /* Not found */ } DEBUGMSGTL(("kernel_sunos5", "... getMibstat returns %d\n", ret)); return ret; }