#include <stdio.h> #include <stdlib.h> /* #include <unistd.h> */ #include <sys/types.h> #include <stdarg.h> #include <time.h> #include <string.h> #include <sys/timeb.h> #include "global.h" #include "utils.h" #include "comm.h" #include "multiclass.h" #include "db.h" #ifdef USE_SQL #include "sql.h" #endif /* USE_SQL */ #define _BUG_C #include "bug.h" #ifdef USE_SQL EXEC SQL INCLUDE sqlca; #endif /* USE_SQL */ const char * LogNames[] = { "INFO", "ERROR", "FATAL", "BOOT", "AUTH", "KILL", "DEATH", "RESET", "IMC" }; /* Handy query for checking logs: * * select to_char(date_trunc('second', log_date), 'HH24:MI:SS'), log_types.name, log_entry * from logfile join log_types using (log_type_id) * where log_date > now() - interval '1 day' * order by log_date desc * limit 20; */ /* * Things we want to have when logging events..... * * BugFile is the filename you want to log to, NULL means stderr * * File, Func, Line can all be provided by the compiler as * __FILE__, __PRETTY_FUNCTION__, and __LINE__ * * Level is the minimum character level which will see the * bug if they're logged in. * * The AreaFile and AreaLine are the file and line number * we were reading while booting the world database. * * Type is the type of error, typically things like * LOG_INFO, LOG_ERROR, LOG_FATAL, LOG_BOOT, LOG_AUTH * * ch is the char_data pointer for the player/mob * obj is an obj_data pointer, if you have one * room is.... the room_data pointer. * * Str is, of course, the message, and it gets printed * using varargs, so you can have this be a printf type * set of macros. */ void bug_logger( unsigned int Type, const char *BugFile, const char *File, const char *Func, int Line, const char *AreaFile, int AreaLine, struct char_data *ch, struct char_data *victim, unsigned int Level, const char *Str, ... ) { va_list arg; char Result[MAX_STRING_LENGTH] = "\0\0\0"; char Temp[MAX_STRING_LENGTH] = "\0\0\0"; FILE *fp = NULL; struct timeb right_now; struct tm *now_part = NULL; bzero(Result, MAX_STRING_LENGTH); va_start(arg, Str); if (Str && *Str) { struct descriptor_data *i; sprintf(Result, "%s> ", LogNames[Type]); vsprintf(Temp, Str, arg); strcat(Result, Temp); for (i = descriptor_list; i; i = i->next) if ((!i->connected) && (GetMaxLevel(i->character) >= Level) && (IS_SET(i->character->specials.act, PLR_LOGS))) write_to_q(Result, &i->output, 1); bzero(Result, MAX_STRING_LENGTH); } else strcpy(Temp, "PING!"); va_end(arg); ftime(&right_now); now_part = localtime((const time_t *)&right_now); sprintf(Result, "<: %02d%02d%02d.%02d%02d%02d.%03d", now_part->tm_year, now_part->tm_mon + 1, now_part->tm_mday, now_part->tm_hour, now_part->tm_min, now_part->tm_sec, right_now.millitm); sprintf(Result + strlen(Result), " - %s -", LogNames[Type]); if (File || Func || Line) { strcat(Result, " ("); if (File && *File) { strcat(Result, File); } if (Func && *Func) sprintf(Result + strlen(Result), ";%s", Func); if (Line) sprintf(Result + strlen(Result), ",%d)", Line); else strcat(Result, ")"); } if (ch || victim) { if (ch) sprintf(Result + strlen(Result), " ch \"%s\" [#%d]", NAME(ch), ch->in_room); if (victim) sprintf(Result + strlen(Result), " victim \"%s\" [#%d]", NAME(victim), victim->in_room); /* if (obj) sprintf(Result + strlen(Result), " obj \"%s\" [#%d]", SAFE_ONAME(obj), obj->in_room); if (room) sprintf(Result + strlen(Result), " room \"%s\" [#%d]", room->name?room->name:"", room->number); */ strcat(Result, "\n"); } else if (File || Func || Line) strcat(Result, "\n"); strcat(Result, " : "); strcat(Result, Temp); if (BugFile && *BugFile) { if (!(fp = fopen(BugFile, "a"))) { perror(BugFile); if (ch) send_to_char("Could not open the file!\r\n", ch); } else { fprintf(fp, "%s\n", Result); FCLOSE(fp); } } if(stderr) { fprintf(stderr, "%s\n", Result); fflush(stderr); } #ifdef USE_SQL if (db_logging && db_connected) { if ( (db_log_info && Type == LOG_INFO) || (db_log_errors && (Type == LOG_ERROR || Type == LOG_FATAL) ) || (db_log_boot && Type == LOG_BOOT) || (db_log_auth && Type == LOG_AUTH) || (db_log_kills && (Type == LOG_KILL || Type == LOG_DEATH) ) || (db_log_resets && Type == LOG_RESET) || (db_log_imc && Type == LOG_IMC) ) { EXEC SQL BEGIN DECLARE SECTION; int log_type_id = LOG_INFO; char log_entry[MAX_STRING_LENGTH]; char log_file[80]; int log_file_ind = -1; char log_function[80]; int log_function_ind = -1; int log_line = 0; int log_line_ind = -1; char log_areafile[80]; int log_areafile_ind = -1; int log_arealine = 0; int log_arealine_ind = -1; char log_pc_actor[80]; int log_pc_actor_ind = -1; char log_pc_victim[80]; int log_pc_victim_ind = -1; int log_npc_actor = 0; int log_npc_actor_ind = -1; int log_npc_victim = 0; int log_npc_victim_ind = -1; int log_obj = 0; int log_obj_ind = -1; int log_area = 0; int log_area_ind = -1; int log_room = 0; int log_room_ind = -1; EXEC SQL END DECLARE SECTION; log_type_id = Type; strcpy(log_entry, Temp); if (File || Func) { if (File && *File) { strcpy(log_file, File); log_file_ind = 0; } if (Func && *Func) { strcpy(log_function, Func); log_function_ind = 0; } log_line = Line; log_line_ind = 0; } if (AreaFile) { if (AreaFile && *AreaFile) { strcpy(log_areafile, AreaFile); log_areafile_ind = 0; } log_arealine = AreaLine; log_arealine_ind = 0; } if (ch) { if (IS_MOB(ch)) { log_npc_actor = mob_index[(int)ch->nr].virtual; log_npc_actor_ind = 0; } else { strcpy(log_pc_actor, NAME(ch)); log_pc_actor_ind = 0; } if(ch->in_room > -1) { log_room = ch->in_room; log_room_ind = 0; log_area = GET_ZONE(ch->in_room); log_area_ind = 0; } } if (victim) { if (IS_MOB(victim)) { log_npc_victim = mob_index[(int)victim->nr].virtual; log_npc_victim_ind = 0; } else { strcpy(log_pc_victim, NAME(victim)); log_pc_victim_ind = 0; } if (!ch || ch->in_room < 0) { if(victim->in_room > -1) { log_room = victim->in_room; log_room_ind = 0; log_area = GET_ZONE(victim->in_room); log_area_ind = 0; } } } /* if (obj) { log_obj = obj_index[(int)obj->item_number].virtual); log_obj_ind = 0; if (!room) { log_room = obj->in_room; log_room_ind = 0; } } if (room) { log_room = room->number; log_room_ind = 0; log_area = room->zone; log_area_ind = 0; } */ EXEC SQL BEGIN WORK; EXEC SQL INSERT INTO logfile ( log_type_id, log_entry, log_file, log_function, log_line, log_areafile, log_arealine, log_pc_actor, log_pc_victim, log_npc_actor, log_npc_victim, log_obj, log_area, log_room ) VALUES ( :log_type_id, :log_entry, :log_file :log_file_ind, :log_function :log_function_ind, :log_line :log_line_ind, :log_areafile :log_areafile_ind, :log_arealine :log_arealine_ind, :log_pc_actor :log_pc_actor_ind, :log_pc_victim :log_pc_victim_ind, :log_npc_actor :log_npc_actor_ind, :log_npc_victim :log_npc_victim_ind, :log_obj :log_obj_ind, :log_area :log_area_ind, :log_room :log_room_ind ); if (sqlca.sqlcode < 0) { fprintf(stderr, "error code %ld, message %s, rows %ld, warning %c\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc, sqlca.sqlerrd[2], sqlca.sqlwarn[0]); EXEC SQL ROLLBACK WORK; } else { EXEC SQL COMMIT WORK; } } } #endif /* USE_SQL */ }