// File : /cmds/file/_rm.c // Creator : Watcher@TMI (02/20/93) // Improved: Watcher@TMI (03/28/93) Substituted get_dir() call // for the wildcard() call so that 'dot' files can be // processed as well. Thanks to Zak for the fix. // Watcher@TMI (04/11/93) Added multiple line rms. // (ie: rm a1 a2) // Robocoder@TMI (06/23/93) to use file lock daemon // 93-08-12 Artagel@tmi-2 Fixed bug re: deleting files in non-existant dirs. // // This is the wizard remove file command. It also responds to // wildcard inputs and recursive deletion flags. #include <config.h> #include <mudlib.h> #include <daemons.h> #include <flock.h> #include <uid.h> inherit DAEMON ; #define SYNTAX "Syntax: rm [-r] [file pattern] [..] [..]\n" static int remove_file(string file, int flag); int cmd_rm(string str) { mixed *files, *path, *multi; string dir; int flag, loop; notify_fail( SYNTAX ); if(!str || str == "") return 0; seteuid(getuid(this_object())); if(sscanf(str, "-r %s", str) == 1) flag = 1; // Check for multiple file deletion request multi = explode(str, " "); if(multi && sizeof(multi) > 1) { for(loop=0; loop<sizeof(multi); loop++) cmd_rm( multi[loop] ); return 1; } // Check to see if the request is bad ("..*") if(str == "..*") { write("Rm: Illegal file pattern.\n"); return 1; } str = resolv_path("cwd", str); // Check the caller's write permissions in target directory path = explode(str, "/"); dir = "/" + implode( path[0..sizeof(path)-2], "/" ) + "/"; if(dir == "//") dir = ""; if((int)master()->valid_write(dir, previous_object(), "rm") == 0) { write("Rm: Permission denied in " + (dir == "" ? "root directory" : dir) + ".\n"); return 1; } // Check for wildcards present in rm request files = get_dir(str); if(files) { files -= ({ "." }); files -= ({ ".." }); } if(!files || !sizeof(files)) { write("Rm: No such pattern : " + str + "\n"); return 1; } if(dir == "") dir = "/"; // If only one selection match ... if(sizeof(files) == 1) return remove_file(dir + files[0], flag); // Otherwise loop through all the wildcard selections for(loop=0; loop<sizeof(files); loop++) remove_file(dir + files[loop], flag); return 1; } // This function removes individual files, and directories if // the flag passed returns a true value. static int remove_file(string file, int flag) { int try; // Check callers permissions on specific file/dir removal if((int)master()->valid_write(file, previous_object(), "rm") == 0) { write("Rm: " + file + " : Permission denied.\n"); return 1; } if(directory_exists(file)) { // If no recursive directory deletion ... if(!flag) { write("Rm: " + file + " is a directory.\n"); return 1; } seteuid(ROOT_UID); // Quickly set us to root try = CLEAN_D->clean_dir(file, 1); seteuid(geteuid(previous_object())); // And set us back if(!try || !rmdir(file)) { write("Rm: " + file + "/ failed.\n"); return 1; } write("Rm: " + file + " recursively removed.\n"); return 1; } if (file_lock(file, F_LOCK)) { write(rm(file) ? "Rm: " + file + " removed.\n" : "Rm: " + file + " remove failed.\n"); file_lock(file, F_UNLOCK); } else write("Rm: File \"" + file + "\" busy; remove failed.\n"); return 1; } string help() { return( SYNTAX + "\n" + "This command will erase any files with the specified file pattern\n"+ "and the use of '*' as a wildcard is permitted. If the -r flag is\n" + "specified, then any subdirectories flagged will be recursively\n" + "deleted, otherwise subdirectories are ignored. This command will\n" + "fail if you do not have the proper permission privileges to remove\n"+ "the specified file pattern. Multiple file deletion is also possible\n"+ "by separating the requests with spaces (ie: rm a1 b1).\n"); }