/** * Used for mapping deleted files to new ones when things are changed. * @changed Updated to a more tidy mechanism by Ceres 14/3/96 * @changed Changed clean_up() to not save when there are no changes, * and fixed up some broken messages. * - Sandoz, Nov. 2002. */ #define SAVE_FILE "/save/cloner" /* How long a mapping lasts, currently 3 months */ #define LIFE_TIME 7257600 inherit OBJECT_OBJ; mapping changes; /** This method returns the list of currently moved objects. */ mapping query_changes() { return copy(changes); } /** Saves the current configuration. */ void save_file() { unguarded( (: save_object, SAVE_FILE :) ); } void setup() { changes = ([ ]); if( file_exists(SAVE_FILE+".o") ) unguarded( (: restore_object, SAVE_FILE :) ); } /* setup() */ /** * Try and clone the passed in object. If the name exists in the changes * array then the new file name is cloned instead of the old one. * @param word the name of the file to clone * @return the cloned object * @see other_file() * @see list_mappings() */ object clone( string word ) { string new_file; object thing; if( changes[ word ] && new_file = changes[ word ][ 0 ] ) word = new_file; catch( thing = clone_object( word ) ); return thing; } /* clone() */ /** * This method returns the mapped name of the object. If no mapping * exists the passed in value is returned directly. * @param word the object name to get a mapping for * @return the file to use * @see clone() * @see list_mappings() */ string other_file( string word ) { if( changes[ word ] ) return changes[ word ][ 0 ]; return word; } /* other_file() */ /** * Use this function to add a new mapping of one filename to another. * Means that if an obhject of type 'from' is attempted to be cloned * an object of type 'to' will be cloned instead. * @param from the old object name * @param to the new object name * @return 1 on success, 0 on failure * @see remove_mapping() * @see list_mappings() */ int add_mapping( string from, string to ) { if( to[0..2] == "/w/") { write("Mapping to creator directories not allowed.\n"); return 0; } if( !file_exists(to) && !file_exists(to+".c") ) { write("Destination file does not exist.\n"); return 0; } changes[from] = ({ to, time() }); save_file(); write("Mapping of "+from+" to "+to+" added.\n"); log_file("CLONER", "Mapping of %s to %s added by %s at %s.\n", from, to, TP->query_cap_name(), ctime(time()) ); remove_call_out("clean_up"); call_out("clean_up", 120 + random(500) ); return 1; } /* add_mapping() */ /** * Removes a mapping from the object. This looks to see if an mapping * exists for the object and removes it if it does. * @param from the object to remove the mapping from * @return 1 on success and 0 on failure * @see add_mapping() * @see list_mappings() */ int remove_mapping( string from ) { if( changes && changes[ from ] ) { map_delete( changes, from ); save_file(); write("Mapping of "+from+" removed.\n"); log_file("CLONER", "Mapping of %s removed by %s at %s.\n", from, TP->query_cap_name(), ctime(time()) ); return 1; } write("No mapping found for "+from+".\n"); return 0; } /* remove_mapping() */ /** * This method returns a list of all the current mappings. If a * pattern is given, then only files which contain that string will * be returned. * @param str the pattern to search for * @return the list of mappings * @see add_mapping() * @see remove_mapping() */ string list_mappings( string str ) { string from, retval; retval = ""; foreach( from in keys(changes) ) { if( !str || strsrch( from, str ) != -1 || strsrch( changes[from][0], str ) != -1 ) retval += from+" -> "+changes[from][0]+"\n"; } return retval; } /* list_mappings() */ /** @ignore yes */ void clean_up() { string from; mixed to; int flag; foreach( from, to in changes ) { if( ( to[1] < time() - LIFE_TIME ) || ( !file_exists(to[0]) && !file_exists(to[0]+".c") ) ) { map_delete( changes, from ); flag = 1; } } if( flag ) save_file(); } /* clean_up() */