/* * log.c - logging routines */ /* * $Id: log.cpp,v 1.2 2000/04/29 08:05:38 sdennis Exp $ */ #include "copyright.h" #include "autoconf.h" #include "config.h" #include "externs.h" #include <sys/types.h> #include "db.h" #include "mudconf.h" #include "flags.h" #include "powers.h" #include "alloc.h" #include "htab.h" #include "ansi.h" #ifndef STANDALONE NAMETAB logdata_nametab[] = { {(char *)"flags", 1, 0, LOGOPT_FLAGS}, {(char *)"location", 1, 0, LOGOPT_LOC}, {(char *)"owner", 1, 0, LOGOPT_OWNER}, {(char *)"timestamp", 1, 0, LOGOPT_TIMESTAMP}, { NULL, 0, 0, 0} }; NAMETAB logoptions_nametab[] = { {(char *)"accounting", 2, 0, LOG_ACCOUNTING}, {(char *)"all_commands", 2, 0, LOG_ALLCOMMANDS}, {(char *)"bad_commands", 2, 0, LOG_BADCOMMANDS}, {(char *)"buffer_alloc", 3, 0, LOG_ALLOCATE}, {(char *)"bugs", 3, 0, LOG_BUGS}, {(char *)"checkpoints", 2, 0, LOG_DBSAVES}, {(char *)"config_changes", 2, 0, LOG_CONFIGMODS}, {(char *)"create", 2, 0, LOG_PCREATES}, {(char *)"killing", 1, 0, LOG_KILLS}, {(char *)"logins", 1, 0, LOG_LOGIN}, {(char *)"network", 1, 0, LOG_NET}, {(char *)"problems", 1, 0, LOG_PROBLEMS}, {(char *)"security", 2, 0, LOG_SECURITY}, {(char *)"shouts", 2, 0, LOG_SHOUTS}, {(char *)"startup", 2, 0, LOG_STARTUP}, {(char *)"time_usage", 1, 0, LOG_TIMEUSE}, {(char *)"wizard", 1, 0, LOG_WIZARD}, { NULL, 0, 0, 0} }; #endif /* * --------------------------------------------------------------------------- * * start_log: see if it is OK to log something, and if so, start writing the * * log entry. */ int start_log(const char *primary, const char *secondary) { /* * Format the timestamp */ char buffer[256]; buffer[0] = '\0'; if ((mudconf.log_info & LOGOPT_TIMESTAMP) != 0) { CLinearTimeAbsolute ltaNow; ltaNow.GetLocal(); FIELDEDTIME ft; ltaNow.ReturnFields(&ft); sprintf(buffer, "%d.%02d%02d:%02d%02d%02d ",ft.iYear, ft.iMonth, ft.iDayOfMonth, ft.iHour, ft.iMinute, ft.iSecond); } #ifndef STANDALONE /* * Write the header to the log */ if (secondary && *secondary) Log.printf("%s%s %3s/%-5s: ", buffer, mudconf.mud_name, primary, secondary); else Log.printf("%s%s %-9s: ", buffer, mudconf.mud_name, primary); #endif return 1; } /* * --------------------------------------------------------------------------- * * end_log: Finish up writing a log entry */ void NDECL(end_log) { Log.WriteString("\n"); Log.Flush(); } /* * --------------------------------------------------------------------------- * * log_perror: Write perror message to the log */ void log_perror(const char *primary, const char *secondary, const char *extra, const char *failing_object) { start_log(primary, secondary); if (extra && *extra) { log_text((char *)"("); log_text((char *)extra); log_text((char *)") "); } // <Failing_object text>: <strerror() text> // Log.WriteString(failing_object); Log.WriteString(": "); Log.WriteString(strerror(errno)); #ifndef WIN32 Log.WriteString("\n"); #endif Log.Flush(); } /* * --------------------------------------------------------------------------- * * log_text, log_number: Write text or number to the log file. */ void log_text(char *text) { Log.WriteString(strip_ansi(text)); } void log_number(int num) { Log.WriteInteger(num); } /* * --------------------------------------------------------------------------- * * log_name: write the name, db number, and flags of an object to the log. * * If the object does not own itself, append the name, db number, and flags * * of the owner. */ void log_name(dbref target) { #ifndef STANDALONE char *tp; if ((mudconf.log_info & LOGOPT_FLAGS) != 0) tp = unparse_object((dbref) GOD, target, 0); else tp = unparse_object_numonly(target); Log.WriteString(strip_ansi(tp)); free_lbuf(tp); if (((mudconf.log_info & LOGOPT_OWNER) != 0) && (target != Owner(target))) { if ((mudconf.log_info & LOGOPT_FLAGS) != 0) tp = unparse_object((dbref) GOD, Owner(target), 0); else tp = unparse_object_numonly(Owner(target)); Log.printf("[%s]", strip_ansi(tp)); free_lbuf(tp); } #else Log.printf("%s(#%d)", Name(target), target); #endif return; } /* * --------------------------------------------------------------------------- * * log_name_and_loc: Log both the name and location of an object */ void log_name_and_loc(dbref player) { log_name(player); if ((mudconf.log_info & LOGOPT_LOC) && Has_location(player)) { log_text((char *)" in "); log_name(Location(player)); } return; } char *OBJTYP(dbref thing) { if (!Good_obj(thing)) { return (char *)"??OUT-OF-RANGE??"; } switch (Typeof(thing)) { case TYPE_PLAYER: return (char *)"PLAYER"; case TYPE_THING: return (char *)"THING"; case TYPE_ROOM: return (char *)"ROOM"; case TYPE_EXIT: return (char *)"EXIT"; case TYPE_GARBAGE: return (char *)"GARBAGE"; default: return (char *)"??ILLEGAL??"; } } void log_type_and_name(dbref thing) { char nbuf[16]; log_text(OBJTYP(thing)); sprintf(nbuf, " #%d(", thing); log_text(nbuf); if (Good_obj(thing)) log_text(Name(thing)); log_text((char *)")"); return; } void log_type_and_num(dbref thing) { char nbuf[16]; log_text(OBJTYP(thing)); sprintf(nbuf, " #%d", thing); log_text(nbuf); return; } #ifndef STANDALONE void do_log(dbref player, dbref cause, int key, char *whichlog, char *logtext) { BOOL bValid = TRUE; // Strip the filename of all ANSI. // char *pFilename = strip_ansi(whichlog); // Restrict filename to a subdirectory to reduce the possibility // of a security hole. // char *temp_ptr = strrchr(pFilename, '/'); if (temp_ptr) { pFilename = ++temp_ptr; } temp_ptr = strrchr(pFilename, '\\'); if (temp_ptr) { pFilename = ++temp_ptr; } // Check for and disallow leading periods, empty strings // and filenames over 30 characters. // if ( pFilename[0] == '\0' || pFilename[0] == '.' || strlen(pFilename) > 30) { bValid = FALSE; } char *pFullName = 0; char *pMessage; if (bValid) { pFullName = alloc_lbuf("do_log_filename"); sprintf(pFullName, "logs/%s", pFilename); // Strip the message of all ANSI. // pMessage = strip_ansi(logtext); // Check for and disallow empty messages. // if (pMessage[0] == '\0') { bValid = FALSE; } } if (!bValid) { if (pFullName) free_lbuf(pFullName); notify(player, "Syntax: @log file=message"); return; } FILE *hFile = fopen(pFullName, "a"); if (hFile == NULL) { notify(player, "Not a valid log file."); if (pFullName) free_lbuf(pFullName); return; } // Okay, at this point, the file exists. // fprintf(hFile, "%s\n", pMessage); fclose(hFile); /* Send and close... */ free_lbuf(pFullName); } #endif