/* File : _unlog.c // Creator : Grendel@tmi-2 // When : 93-08-11 // Admin command for removing entries in the various logs. */ #include <mudlib.h> #include <config.h> #include <flock.h> // I want to put this in a header file #ifndef DELIM #define DELIM "-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-" #endif inherit DAEMON; #define PROG_NAME "unlog" #define SYNTAX "Usage: "+PROG_NAME+" <logfile> <log_id>\n" #define TMP_FILE TMP_DIR + PROG_NAME + "_" + getoid(this_player()) // this controls where the old entries go. Don't define it if you don't // want them to be stored #define ATTIC_FILE(x) LOG_DIR + "attic/" + (x) /* replacement for old member_array() */ int search_almost_member(string s, string *items) { int i, l; string t; if (!(l = s ? strlen(s) : 0) || !(i = items ? sizeof(items) : 0)) return -1; l--; while (i--) if ((((t = items[i]) ? strlen(t) : 0) > l) && (s == t[0..l])) return i; return -1; } // the unlog command int cmd_unlog (string arg) { string log_id; string log_name, file_name, old_name; int index; string *entries; // general usage variables string str; notify_fail(SYNTAX); if(!arg || arg=="") return 0; // get the arguments if(sscanf(arg,"%s %s", log_name, log_id)!=2) return 0; // check the file exists file_name = LOG_DIR + log_name; switch(file_size(file_name)) { case -2: notify_fail(PROG_NAME+": "+file_name+" is a directory\n"); return 0; case -1: notify_fail(PROG_NAME+": " + file_name + " does not exist\n"); return 0; case 0: write(PROG_NAME+": " + file_name + " is empty\n"); return 1; } // set our euid seteuid(geteuid(previous_object())); // check for write access if(!master()->valid_write(file_name, geteuid(), "write_file")) { notify_fail(PROG_NAME+": "+file_name+": permission denied\n"); return 0; } // lock the logfile if(!file_lock(file_name, F_LOCK)) { notify_fail(PROG_NAME+": could not gain lock on file\n"); return 0; } // read the log str = read_file(file_name); if(!str) { file_lock(file_name, F_UNLOCK); notify_fail(PROG_NAME+": could not read " + file_name +"\n"); return 0; } // get the new entries entries = explode(str, DELIM); // find the timestamped entry index = search_almost_member(log_id+"\n", entries); if(index == -1) { // unlock file file_lock(file_name, F_UNLOCK); notify_fail(PROG_NAME+": no entry with that id\n"); return 0; } #ifdef ATTIC_FILE write_file(ATTIC_FILE(log_name), DELIM + entries[index]); #endif entries -= ({ entries[index] }); // rename the old log file, // write the new log file, // delete the old logfile, // and release the lock old_name=file_name+"." + PROG_NAME + "_old"; rename(file_name, old_name); if(!write_file(file_name, implode(entries,DELIM))) { notify_fail(PROG_NAME+ ": fatal error: could not write to "+file_name+"\n"); rename(old_name, file_name); file_lock(file_name, F_UNLOCK); return 0; } rm(old_name); write( "Ok. That entry has been removed from " + file_name + "\n" ); file_lock(file_name, F_UNLOCK); return 1; } string help() { return(SYNTAX + "\n\n" + #ifdef ATTIC_FILE "This admin command moves an entry from a log to an archive file.\n" #else "This admin command deletes an entry from a log.\n" #endif ); }