/* Do not remove the headers from this file! see /USAGE for more info. */ //:COMMAND //USAGE: findfile <target> // findfile -u // //Find any file containing the specified target within its name. // //The system relies on a database of filenames for speed. //To rebuild that database, use a -u flag. inherit CMD; #define ITERS_PER_CALL 2 #define DATA_FILE "/data/find.codes" #define TMP_DATA_FILE "/data/find.tmp" mixed array stack; string path; int building_database = 0; private void end_building() { cp(TMP_DATA_FILE,DATA_FILE); rm(TMP_DATA_FILE); printf("Locate DB build done.\n"); building_database = 0; } private void do_building() { int i = ITERS_PER_CALL; string array this_dir; while(i--) { string new_path; if(!sizeof(stack)) { end_building(); return; } if(intp(stack[0])) { /* hit the sentinel. pop up one directory level */ stack = stack[1..]; path = split_path(path)[0]; i++; continue; } new_path = path + stack[0]+"/"; stack = stack[1..]; this_dir = get_dir(new_path+"*",-1); if(arrayp(this_dir)) { int w; if( (w = member_array(".", get_dir(new_path+"*"))) != -1 ) this_dir = this_dir[0..(w-1)] + this_dir[(w+2)..]; } else continue; /* prepend the dir and write into the file */ map(this_dir,(:write_file(TMP_DATA_FILE, join_path($(new_path),$1[0])+"\n"):)); /* filter out just the dirs and extract the names */ this_dir = map(filter(this_dir, (:$1[1] == -2:)), (:$1[0]:)); /* push onto stack w/ a sentinel to go up the dir tree */ if(sizeof(this_dir)) { stack = this_dir + ({0}) + stack; path = new_path; } } call_out((:do_building:), 2); } private void begin_database_build() { stack = ({""}); path = ""; if(is_file(TMP_DATA_FILE) && !rm(TMP_DATA_FILE)) { out("You don't have permission to do that.\n"); return; } do_building(); building_database = 1; } private void main(mixed * arg, mapping flags) { string find; string outstr; if (!arg[0] && !flags["u"]) { out( "Syntax: findfile <string>\n"); return; } if(flags["u"]) { if(building_database) { out("Already building database.\n"); return; } out("Building database... This takes a while.\n"); begin_database_build(); return; } else { /* arg[0] is an array of strings. use just the first */ find = arg[0]; ed_start(DATA_FILE); outstr = ed_cmd(sprintf("1,$g#%s#p", find)); if( !sizeof(outstr)) out( "No matching files found.\n"); else out( outstr ); ed_cmd("q"); return; } }