/* Build/rebuild the quest enemy/object data cache. */ int quest_cache_maps(ship_t *s, quest_map_t *map, const char *dir) { quest_map_elem_t *i; size_t dlen = strlen(dir); char mdir[dlen + 20]; char *fn1, *fn2; int j, k; sylverant_quest_t *q; const static char exts[2][4] = { "dat", "qst" }; uint8_t *dat; uint32_t dat_sz, tmp; /* Make sure we have all the directories we'll need. */ sprintf(mdir, "%s/.mapcache", dir); if(mkdir(mdir, 0755) && errno != EEXIST) { debug(DBG_ERROR, "Error creating map cache directory: %s\n", strerror(errno)); return -1; } sprintf(mdir, "%s/.mapcache/v1", dir); if(mkdir(mdir, 0755) && errno != EEXIST) { debug(DBG_ERROR, "Error creating map cache directory: %s\n", strerror(errno)); return -1; } sprintf(mdir, "%s/.mapcache/v2", dir); if(mkdir(mdir, 0755) && errno != EEXIST) { debug(DBG_ERROR, "Error creating map cache directory: %s\n", strerror(errno)); return -1; } sprintf(mdir, "%s/.mapcache/gc", dir); if(mkdir(mdir, 0755) && errno != EEXIST) { debug(DBG_ERROR, "Error creating map cache directory: %s\n", strerror(errno)); return -1; } sprintf(mdir, "%s/.mapcache/bb", dir); if(mkdir(mdir, 0755) && errno != EEXIST) { debug(DBG_ERROR, "Error creating map cache directory: %s\n", strerror(errno)); return -1; } TAILQ_FOREACH(i, map, qentry) { /* Process it. */ for(j = 0; j < CLIENT_VERSION_COUNT; ++j) { /* Skip PC, it is the same as v2. */ if(j == CLIENT_VERSION_PC) continue; for(k = 0; k < CLIENT_LANG_COUNT; ++k) { if((q = i->qptr[j][k])) { /* Don't bother with battle or challenge quests. */ tmp = quest_cat_type(s, j, k, q); if(tmp & (SYLVERANT_QUEST_BATTLE | SYLVERANT_QUEST_CHALLENGE)) break; if(!(fn1 = (char *)malloc(dlen + 25 + strlen(q->prefix)))) { debug(DBG_ERROR, "Error allocating memory: %s\n", strerror(errno)); return -1; } if(!(fn2 = (char *)malloc(dlen + 35))) { debug(DBG_ERROR, "Error allocating memory: %s\n", strerror(errno)); free(fn1); return -1; } sprintf(fn1, "%s/%s-%s/%s.%s", dir, version_codes[j], language_codes[k], q->prefix, exts[q->format]); sprintf(fn2, "%s/.mapcache/%s/%08x", dir, version_codes[j], q->qid); if(check_cache_age(fn1, fn2)) { debug(DBG_LOG, "Cache for %s-%s %d needs updating!\n", version_codes[j], language_codes[k], q->qid); } if(q->format == SYLVERANT_QUEST_BINDAT) { if((dat = read_and_dec_dat(fn1, &dat_sz))) { cache_quest_enemies(fn2, dat, dat_sz, q->episode); free(dat); } } else { if((dat = read_and_dec_qst(fn1, &dat_sz, j))) { cache_quest_enemies(fn2, dat, dat_sz, q->episode); free(dat); } } free(fn2); free(fn1); break; } } } } return 0; }
int main(int argc, char *argv[]) { int retc = 0; int ret; char *hostfile = NULL; char *cachefile = NULL; char *xml = NULL; char *xmlfile = NULL; int cachefd = -1; char value[64]; char units[64]; int retry_count = 0, ret2; if (get_config(argc, argv) < 0) { retc = 2; goto cleanup; } if (config.heartbeat > 0) { debug("Checking heartbeat for %s with threshold %d\n", config.host, config.heartbeat); } else { debug("Checking %s for %s metric\n", config.host, config.metric); } hostfile = get_full_cache_path(config.cachepath, config.host); cachefile = get_full_cache_path(config.cachepath, config.cachename); retry: debug("Checking cache at %s\n", cachefile); ret = check_cache_age(cachefile); if (ret < 0) { printf("ERROR: Unable to check cache age.\n"); retc = 2; goto cleanup; } if (ret < config.max_age) { debug("Cache age is %d\n", ret); } else { debug("Cache age greater than configured max (%d >= %d)\n", ret, config.max_age); debug("Connecting to %s on port %d\n", config.gmetad_host, config.gmetad_port); ret = fetch_xml(config.gmetad_host, config.gmetad_port, &xml); if (ret < 0) { printf("ERROR: Unable to get XML data: %d.\n", ret); retc = 2; goto cleanup; } debug("Read %d bytes from %s\n", ret, config.gmetad_host); if (config.dump) { xmlfile = calloc((strlen(config.cachepath) + 9), sizeof(char)); sprintf(xmlfile, "%s/dump.xml", config.cachepath); debug("Dumping XML to %s\n", xmlfile); if (write_xml(xml, ret, xmlfile) < 0) { printf("ERROR: Unable to dump XML.\n"); retc = 2; goto cleanup; } } ret2 = get_cache_lock(cachefile, &cachefd); if (ret2 < 0) { if (retry_count == MAX_RETRY) { printf("ERROR: Unable to get cache lock after retrying %d times. Stale lock?", retry_count); retc = 2; goto cleanup; } else { backoff(retry_count / 2.0); } retry_count++; goto retry; } debug("Parsing XML into %s\n", config.cachepath); ret = parse_xml_to_cache(xml, ret, config.cachepath, cachefile); if (ret < 0) { printf("ERROR: Unable to parse XML.\n"); retc = 2; goto cleanup; } touch_cache_lock(cachefile); release_cache_lock(cachefile, &cachefd); } if (config.heartbeat > 0) { strcpy(config.metric, "#REPORTED"); } if (locate_hostfile(hostfile) < 0) { printf("CRITICAL - Unable to locate cache file for %s\n", config.host); retc = 2; goto cleanup; } debug("Fetching %s metric from cache at %s\n", config.metric, hostfile); ret = fetch_value_from_cache(hostfile, config.metric, value, units); if (ret < 0) { printf("CRITICAL - Unable to read cache at %s\n", hostfile); retc = 2; goto cleanup; } else if (ret == 0) { printf("CRITICAL - Metric %s not found\n", config.metric); retc = 2; goto cleanup; } debug("Checking...\n"); if (config.heartbeat > 0) { int diff = time(NULL) - strtol(value, NULL, 10); if (diff > config.heartbeat) { printf("CRITICAL - %d over threshold %d\n", diff, config.heartbeat); retc = 2; goto cleanup; } else { printf("OK - %d\n", diff); goto cleanup; } } if (threshold_check(config.critical, value)) { printf("CRITICAL - %s %s\n", value, units); retc = 2; } else { if (threshold_check(config.warning, value)) { printf("WARNING - %s %s\n", value, units); retc = 1; } else { printf("OK - %s %s\n", value, units); } } cleanup: if (cachefd >= 0) { release_cache_lock(cachefile, &cachefd); } if (xml != NULL) free(xml); if (xmlfile != NULL) free(xmlfile); if (hostfile != NULL) free(hostfile); if (cachefile != NULL) free(cachefile); exit(retc); }