//***************************************************************************** // // log.c // // A set of utilities for logging strings with specified keywords in them to // files. If you would like to log someone's output, you can use the format: // log [name] [keywords to log] // // e.g. log jim give, set, drop // // You can log everything by, instead of putting keywords, using "all" // You can turn off logging for a specific character by not supplying a // keyword list. // //***************************************************************************** #include "mud.h" #include "utils.h" #include "character.h" #include "storage.h" #include "log.h" #define LOG_LIST LOG_DIR"/logs" // a map from filenames to the keywords we try to log HASHTABLE *logkeys = NULL; // // Begin logging the appearance of specific keywords when they come up // on a certain character's output. Supplying no keywords turns off logging // usage: log [person] [keywords] // // examples: // log jim get, give, set every time the words "get", "give", or "set" // appear in Jim's output, log the lines that // those words appeared in // log jim all log all of jim's output // log jim turn off logging for jim, if he is logged // COMMAND(cmd_log) { char name[MAX_BUFFER]; char *keywords = NULL; if(!arg || !*arg) send_to_char(ch, "Log who?\r\n"); else if(!(keywords = one_arg(arg, name))) send_to_char(ch, "What keywords did you want to log on %s?\r\n", name); else { *name = toupper(*name); if(*keywords) send_to_char(ch, "You set %s's log keywords to '%s'\r\n", name, keywords); else send_to_char(ch, "You no longer log output to %s.\r\n", name); log_keywords(name, keywords); } } // // write the names of all the logfiles and their keywords to disk // void save_logkeys() { STORAGE_SET *set = new_storage_set(); STORAGE_SET_LIST *log_list = new_storage_list(); HASH_ITERATOR *hash_i = newHashIterator(logkeys); const char *log = NULL; const char *words = NULL; store_list(set, "logs", log_list); ITERATE_HASH(log, words, hash_i) { STORAGE_SET *one_log = new_storage_set(); store_string(one_log, "log", log); store_string(one_log, "keywords", words); storage_list_put(log_list, one_log); } deleteHashIterator(hash_i); // write the logs to disk storage_write(set, LOG_LIST); storage_close(set); } void init_logs() { logkeys = newHashtable(); STORAGE_SET *set = storage_read(LOG_LIST); if(set != NULL) { STORAGE_SET_LIST *list = read_list(set, "logs"); STORAGE_SET *one_log = NULL; while( (one_log = storage_list_next(list)) != NULL) hashPut(logkeys, strdup(read_string(one_log, "log")), strdup(read_string(one_log, "keywords"))); storage_close(set); } add_cmd("log", NULL, cmd_log, "admin", FALSE); } void log_keywords(const char *file, const char *keywords) { // remove the old keywords char *keys = hashRemove(logkeys, file); if(keys) free(keys); keys = strdupsafe(keywords); trim(keys); // put the new keywords in if(*keys) hashPut(logkeys, file, keys); // save the changes save_logkeys(); } void try_log(const char *file, const char *string) { char *keywords = hashGet(logkeys, file); // didn't find anything if(!keywords || !*keywords) return; else { bool found = FALSE; if(is_keyword(keywords, "all", FALSE)) found = TRUE; // for each key, see if it exists in the string else { LIST *keys = parse_keywords(keywords); LIST_ITERATOR *key_i = newListIterator(keys); char *key = NULL; ITERATE_LIST(key, key_i) { // found one if(strstr(string, key)) { found = TRUE; break; } } deleteListIterator(key_i); deleteListWith(keys, free); } if(found) { char fname[MAX_BUFFER]; FILE *fl = NULL; sprintf(fname, "%s/%s", LOG_DIR, file); // couldn't open the file for appending if((fl = fopen(fname, "a+")) == NULL) return; // write the string and close the file fprintf(fl, "%s: %s", get_time(), string); fclose(fl); } } }