00001
00002
00003
00004
00005 #include "copyright.h"
00006 #include "config.h"
00007
00008 #include <sys/types.h>
00009 #include <sys/time.h>
00010 #include <time.h>
00011
00012 #include "db.h"
00013 #include "mudconf.h"
00014 #include "externs.h"
00015 #include "flags.h"
00016 #include "powers.h"
00017 #include "alloc.h"
00018 #include "htab.h"
00019 #include "ansi.h"
00020 #ifdef ARBITRARY_LOGFILES
00021 #include "logcache.h"
00022 #endif
00023
00024 NAMETAB logdata_nametab[] = {
00025 {(char *) "flags", 1, 0, LOGOPT_FLAGS},
00026 {(char *) "location", 1, 0, LOGOPT_LOC},
00027 {(char *) "owner", 1, 0, LOGOPT_OWNER},
00028 {(char *) "timestamp", 1, 0, LOGOPT_TIMESTAMP},
00029 {NULL, 0, 0, 0}
00030 };
00031
00032 NAMETAB logoptions_nametab[] = {
00033 {(char *) "accounting", 2, 0, LOG_ACCOUNTING},
00034 {(char *) "all_commands", 2, 0, LOG_ALLCOMMANDS},
00035 {(char *) "suspect_commands", 2, 0, LOG_SUSPECTCMDS},
00036 {(char *) "bad_commands", 2, 0, LOG_BADCOMMANDS},
00037 {(char *) "buffer_alloc", 3, 0, LOG_ALLOCATE},
00038 {(char *) "bugs", 3, 0, LOG_BUGS},
00039 {(char *) "checkpoints", 2, 0, LOG_DBSAVES},
00040 {(char *) "config_changes", 2, 0, LOG_CONFIGMODS},
00041 {(char *) "create", 2, 0, LOG_PCREATES},
00042 {(char *) "killing", 1, 0, LOG_KILLS},
00043 {(char *) "logins", 1, 0, LOG_LOGIN},
00044 {(char *) "network", 1, 0, LOG_NET},
00045 {(char *) "problems", 1, 0, LOG_PROBLEMS},
00046 {(char *) "security", 2, 0, LOG_SECURITY},
00047 {(char *) "shouts", 2, 0, LOG_SHOUTS},
00048 {(char *) "startup", 2, 0, LOG_STARTUP},
00049 {(char *) "wizard", 1, 0, LOG_WIZARD},
00050 {NULL, 0, 0, 0}
00051 };
00052
00053 char *strip_ansi_r(char *dest, const char *raw, size_t n)
00054 {
00055 char *p = (char *) raw;
00056 char *q = dest;
00057
00058 while (p && *p && ((q - dest) < n)) {
00059 if(*p == ESC_CHAR) {
00060
00061
00062
00063 while (*p && !isalpha(*p))
00064 p++;
00065 if(*p)
00066 p++;
00067 } else
00068 *q++ = *p++;
00069 }
00070 *q = '\0';
00071 return dest;
00072 }
00073
00074 char *normal_to_white_r(char *dest, const char *raw, size_t n) {
00075 char *p = (char *) raw;
00076 char *q = dest;
00077
00078 while (p && *p && ((q - dest) < n)) {
00079 if(*p == ESC_CHAR) {
00080
00081
00082
00083 *q++ = *p++;
00084
00085
00086 *q++ = *p++;
00087
00088
00089 if(*p == '0') {
00090 if((q - dest + 7) < n) {
00091 memcpy(q, "0m\x1b[37m", 7);
00092 q += 7;
00093 }
00094 p += 2;
00095 }
00096 } else
00097 *q++ = *p++;
00098 }
00099 *q = '\0';
00100 return dest;
00101 }
00102
00107 int start_log(const char *primary, const char *secondary)
00108 {
00109 struct tm *tp;
00110 time_t now;
00111
00112 mudstate.logging++;
00113 switch (mudstate.logging) {
00114 case 1:
00115 case 2:
00116
00117
00118
00119
00120
00121 if((mudconf.log_info & LOGOPT_TIMESTAMP) != 0) {
00122 time((time_t *) (&now));
00123 tp = localtime((time_t *) (&now));
00124 sprintf(mudstate.buffer, "%d%02d%02d.%02d%02d%02d ",
00125 tp->tm_year + 1900, tp->tm_mon + 1, tp->tm_mday,
00126 tp->tm_hour, tp->tm_min, tp->tm_sec);
00127 } else {
00128 mudstate.buffer[0] = '\0';
00129 }
00130
00131
00132
00133
00134
00135 if(secondary && *secondary)
00136 fprintf(stderr, "%s%s %3s/%-5s: ", mudstate.buffer,
00137 mudconf.mud_name, primary, secondary);
00138 else
00139 fprintf(stderr, "%s%s %-9s: ", mudstate.buffer,
00140 mudconf.mud_name, primary);
00141
00142
00143
00144
00145 if(mudstate.logging == 1)
00146 return 1;
00147 fprintf(stderr, "Recursive logging request.\r\n");
00148 default:
00149 mudstate.logging--;
00150 }
00151 return 0;
00152 }
00153
00157 void end_log(void)
00158 {
00159 fprintf(stderr, "\n");
00160 fflush(stderr);
00161 mudstate.logging--;
00162 }
00163
00167 void log_perror(const char *primary, const char *secondary, const char *extra,
00168 const char *failing_object)
00169 {
00170 start_log(primary, secondary);
00171 if(extra && *extra) {
00172 log_text((char *) "(");
00173 log_text((char *) extra);
00174 log_text((char *) ") ");
00175 }
00176 perror((char *) failing_object);
00177 fflush(stderr);
00178 mudstate.logging--;
00179 }
00180
00184 void log_text(char *text)
00185 {
00186 char new[LBUF_SIZE];
00187 strncpy(new, text, LBUF_SIZE-1);
00188 fprintf(stderr, "%s", strip_ansi_r(new,text,strlen(text)));
00189 }
00190
00191 void log_error(int key, char *primary, char *secondary, char *format, ...)
00192 {
00193 char buffer[LBUF_SIZE];
00194 char stripped_buffer[LBUF_SIZE];
00195 va_list ap;
00196
00197 if(!(key & mudconf.log_options))
00198 return;
00199
00200 if(mudconf.log_info & LOGOPT_TIMESTAMP) {
00201 time_t now;
00202 struct tm tm;
00203 time(&now);
00204 localtime_r(&now, &tm);
00205 fprintf(stderr, "%d%02d%02d.%02d%02d%02d ",
00206 tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
00207 tm.tm_hour, tm.tm_min, tm.tm_sec);
00208 }
00209
00210 if(secondary && &secondary) {
00211 fprintf(stderr, "%s%s %3s/%-5s: ", mudstate.buffer,
00212 mudconf.mud_name, primary, secondary);
00213 } else {
00214 fprintf(stderr, "%s%s %-9s: ", mudstate.buffer,
00215 mudconf.mud_name, primary);
00216 }
00217
00218 va_start(ap, format);
00219 vsnprintf(buffer, LBUF_SIZE, format, ap);
00220 va_end(ap);
00221
00222 strip_ansi_r(stripped_buffer, buffer, LBUF_SIZE);
00223 fprintf(stderr, "%s\n", stripped_buffer);
00224 }
00225
00226 void log_printf(char *format, ...)
00227 {
00228 char buffer[LBUF_SIZE];
00229 char stripped_buffer[LBUF_SIZE];
00230 va_list ap;
00231
00232 va_start(ap, format);
00233 vsnprintf(buffer, LBUF_SIZE, format, ap);
00234 va_end(ap);
00235
00236 strip_ansi_r(stripped_buffer, buffer, LBUF_SIZE);
00237 fprintf(stderr, "%s\n", stripped_buffer);
00238 }
00239
00240
00241
00242
00243 void log_number(int num)
00244 {
00245 fprintf(stderr, "%d", num);
00246 }
00247
00253 void log_name(dbref target)
00254 {
00255 char *tp;
00256 char new[LBUF_SIZE];
00257
00258 if((mudconf.log_info & LOGOPT_FLAGS) != 0)
00259 tp = unparse_object((dbref) GOD, target, 0);
00260 else
00261 tp = unparse_object_numonly(target);
00262 strncpy(new, tp, LBUF_SIZE-1);
00263 fprintf(stderr, "%s", strip_ansi_r(new,tp,strlen(tp)));
00264 free_lbuf(tp);
00265 if(((mudconf.log_info & LOGOPT_OWNER) != 0) && (target != Owner(target))) {
00266 if((mudconf.log_info & LOGOPT_FLAGS) != 0)
00267 tp = unparse_object((dbref) GOD, Owner(target), 0);
00268 else
00269 tp = unparse_object_numonly(Owner(target));
00270 strncpy(new, tp, LBUF_SIZE-1);
00271 fprintf(stderr, "[%s]", strip_ansi_r(new,tp,strlen(tp)));
00272 free_lbuf(tp);
00273 }
00274 return;
00275 }
00276
00280 void log_name_and_loc(dbref player)
00281 {
00282 log_name(player);
00283 if((mudconf.log_info & LOGOPT_LOC) && Has_location(player)) {
00284 log_text((char *) " in ");
00285 log_name(Location(player));
00286 }
00287 return;
00288 }
00289
00290
00291
00292
00293 char *OBJTYP(dbref thing)
00294 {
00295 if(!Good_obj(thing)) {
00296 return (char *) "??OUT-OF-RANGE??";
00297 }
00298 switch (Typeof(thing)) {
00299 case TYPE_PLAYER:
00300 return (char *) "PLAYER";
00301 case TYPE_THING:
00302 return (char *) "THING";
00303 case TYPE_ROOM:
00304 return (char *) "ROOM";
00305 case TYPE_EXIT:
00306 return (char *) "EXIT";
00307 case TYPE_GARBAGE:
00308 return (char *) "GARBAGE";
00309 default:
00310 return (char *) "??ILLEGAL??";
00311 }
00312 }
00313
00314 void log_type_and_name(dbref thing)
00315 {
00316 char nbuf[16];
00317
00318 log_text(OBJTYP(thing));
00319 sprintf(nbuf, " #%d(", thing);
00320 log_text(nbuf);
00321 if(Good_obj(thing))
00322 log_text(Name(thing));
00323 log_text((char *) ")");
00324 return;
00325 }
00326
00327 void log_type_and_num(dbref thing)
00328 {
00329 char nbuf[16];
00330
00331 log_text(OBJTYP(thing));
00332 sprintf(nbuf, " #%d", thing);
00333 log_text(nbuf);
00334 return;
00335 }
00336
00337 #ifdef ARBITRARY_LOGFILES
00338 int log_to_file(dbref thing, const char *logfile, const char *message)
00339 {
00340 char pathname[210];
00341 char message_buffer[4096];
00342
00343 if(!message || !*message)
00344 return 1;
00345
00346 if(!logfile || !*logfile || strlen(logfile) > 200)
00347 return 0;
00348
00349 if(strstr(pathname, "..") != NULL)
00350 return 0;
00351 if(strstr(pathname, "/") != NULL)
00352 return 0;
00353 snprintf(pathname, 210, "logs/%s", logfile);
00354
00355
00356
00357 if(access(pathname, R_OK | W_OK) != 0)
00358 return 0;
00359
00360 snprintf(message_buffer, 4096, "%s\n", message);
00361
00362 if(!logcache_writelog(pathname, message_buffer)) {
00363 notify(thing, "Serious failure while trying to write to log.");
00364 return 0;
00365 }
00366 return 1;
00367 }
00368
00369 void do_log(dbref player, dbref cause, int key, char *logfile, char *message)
00370 {
00371 if(!message || !*message) {
00372 notify(player, "Nothing to log!");
00373 return;
00374 }
00375
00376 if(!logfile || !*logfile) {
00377 notify(player, "Invalid logfile.");
00378 return;
00379 }
00380
00381 if(!log_to_file(player, logfile, message)) {
00382 notify(player, "Request failed.");
00383 return;
00384 }
00385
00386 notify(player, "Message logged.");
00387 }
00388 #endif