Esempio n. 1
0
/* 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);
}