/* -*- LPC -*- */ /* * $Id: finderror_helper.c,v 1.7 2003/03/25 20:02:45 taffyd Exp taffyd $ */ /** * This handler contains the methods to handle the creators list of * directories to control bugs in. */ #include <log.h> #include <config.h> #include <db.h> nosave inherit "/std/object"; private void recursive_add_directory( string word, string dir ); // Class used for caching error data. class error_data { string name; string *dirs; int no_calls; } // Exciting global. nosave mapping _error_cache; // These are intermediary variables that are set with data by // restore_object() and save_object() and then // stored in the _error_cache mapping after loading. string name, *dirs; void create() { ::create(); set_name( "finderror_helper" ); set_short( "finderror helper" ); _error_cache = ([ ]); } /* create() */ /** * Make sure the data in the directories is in the right format * We must strip off any trailing /'s that get in there * by mistake. * @param file the name of the file to trim * @return the trimed file name */ private string strip_extension( string file ) { if ( file[<1] == '/' ) { return file[0..<2]; } return file; } /* strip_extension() */ // Retrieve the finderrors data for the given player name. private class error_data get_data_file( string word ) { string file; if ( _error_cache[ word ] ) { return _error_cache[ word ]; } seteuid( word ); file = "/w/" + word + "/finderror.o"; if ( file_size( file ) > 0 ) { unguarded( (: restore_object, file :) ); _error_cache[ word ] = new( class error_data, name : name, dirs : map( dirs, (: strip_extension :) ), no_calls : 0 ); } else { _error_cache[ word ] = new( class error_data, name : word, dirs : ({ }), no_calls : 0 ); } return _error_cache[ word ]; } /* get_data_file() */ // Save to disk. private int save_data_file( string word ) { seteuid( word ); if ( _error_cache[ word ] ) { name = _error_cache[ word ]->name; dirs = _error_cache[ word ]->dirs; unguarded( (: save_object, "/w/" + word + "/finderror" :) ); return 1; } return 0; } /* save_data_file() */ string escape( string txt ) { return replace( txt, ({ "'", "\\'" }) ); } /* escape() */ private string assemble_dirs_sql( string *dirs ) { dirs = map( dirs, (: escape :) ); return "(" + implode( map( dirs, (: "Directory" + ( strsrch( $1, "%" ) > -1 ? " LIKE " : " = " ) + "'" + $1 + "'" :) ), " OR " ) + ")"; } /* assemble_dirs_sql() */ void finished_query( int status, mixed data, function func, object player ) { evaluate( func, player, status, data ); } /* finished_query() */ /** * This method returns the error counts for all the directories in the * list of directories to watch. * @param word the creator to get the dir count for */ public int query_dirs_count(mixed player, function finish_func ) { class error_data info; string query; string txt; string word; if ( objectp( player ) ) { word = player->query_name(); } else { word = player; player = this_object(); } info = get_data_file( word ); if ( sizeof( info->dirs ) ) { txt = assemble_dirs_sql( info->dirs ); query = "SELECT Directory, Type, COUNT(Id) FROM errors WHERE " + txt + " AND " "Status = 'OPEN' GROUP BY Directory, Type;"; DB_HANDLER->make_sql_request("errors", CONFIG_DB_ERRORS_USER, "", query, (: finished_query( $1, $2, $(finish_func), $(player) ) :) ); return 1; } return 0; } /* query_dirs_count() */ /** * This method returns the error counts for all the directories in the * list of directories to watch. * @param word the creator to get the dir count for */ public int query_errors_in_dirs(string *directories, function finish_func ) { string query; string txt; if ( directories ) { directories = map( directories , (: escape :) ); txt = "(" + implode( map( directories, (: "Directory" + ( strsrch( $1, "%" ) > -1 ? " LIKE " : " = " ) + "'" + $1 + "'" :) ), " OR " ) + ")"; query = "SELECT Directory, Type, COUNT(Id) AS C FROM errors WHERE " + txt + " AND " "Status = 'OPEN' GROUP BY Directory, Type"; DB_HANDLER->make_sql_request("errors", CONFIG_DB_ERRORS_USER, "", query, (: finished_query( $1, $2, $(finish_func), $(this_player()) ) :) ); return 1; } return 0; } /* query_dirs_count() */ public void query_next_dir( object player, function finish_func ) { string query; string txt; string word; class error_data info; word = player->query_name(); info = get_data_file( word ); if ( sizeof( info->dirs ) ) { txt = assemble_dirs_sql( info->dirs ); query = "SELECT Directory, COUNT(Id) AS C FROM errors WHERE " + txt + " AND Status = 'OPEN' GROUP BY Directory HAVING C > 0 LIMIT 1;"; DB_HANDLER->make_sql_request( "errors", CONFIG_DB_ERRORS_USER, "", query, (: finished_query( $1, $2, $(finish_func), $(player) ) :) ); } else { tell_object( player, "You have no finderrors directories defined. Add " "them with 'finderrors add'\n" ); } } /* query_next_dir() */ public string *query_directories( string player ) { class error_data data; data = get_data_file( player ); return copy( data->dirs ); } /* query_directories() */ /** * This method adds the directory to the creators directory list to check. * @param player the creator to add the directory to * @param dir the directory to add * @param recursive to add the directory recursively */ public int add_directory( object player, string dir, int recursive ) { int res; class error_data info; string word; word = player->query_name(); info = get_data_file( word ); res = member_array( dir, info->dirs ); if ( recursive ) { /* This means it will do a "like" test. */ dir += "%"; //info->no_calls++; //call_out( (: recursive_add_directory :), 1, player, dir ); } if ( res == -1 ) { if ( dir[ <1 ] == '/') { dir = dir[ 0 .. <2 ]; } info->dirs = ({ dir }) + info->dirs; tell_object( player, "Added " + dir + (recursive ? " (recursive)" : "") + "\n" ); save_data_file( word ); } return 1; } /* add_directory() */ /** * This method adds all the subdirectories of the specified dir into the * search list. * @param player the creator to add to the list of * @param dir the directory to recursively add to */ private void recursive_add_directory( object player, string dir ) { mixed *directories, *file; class error_data info; string word; word = player->query_name(); info = get_data_file( word ); info->no_calls--; directories = get_dir( dir, -1 ); if ( directories ) { foreach ( file in directories ) { if ( file[ 1 ] == -2 && file[ 0 ] != "Maps") { add_directory( player, dir + file[ 0 ] +"/", 1 ); } } } if ( info->no_calls == 0 ) { tell_object( player, "All subdirectories have been added to the list.\n" ); save_data_file( word ); } } /* recursive_add_dir() */ public int remove_directory( object player, string directory, int recursive ) { class error_data info; string word; int pos; word = player->query_name(); info = get_data_file( word ); if ( recursive ) { pos = sizeof( directory ) - 1; info->dirs = filter( info->dirs, (: $1[ 0..$(pos) ] != $(directory) :)); } else { pos = member_array( directory, info->dirs ); if ( pos == -1 ) { return 0; } info->dirs = info->dirs[ 0..pos - 1 ] + info->dirs[ pos+1.. ]; } save_data_file( word ); return 1; } /* remove_directory() */