/* * Author and date unknown ?? * help() added 1/27/92 Brian@TMI * revised for greater speed by Buddha (8/23/92) */ #include <config.h> #include <mudlib.h> inherit DAEMON ; // process_choice() and file_completion() were lifted almost verbatim from // Watcher's shell code by Ed Murphy (Guardian@TMI-2) on 16 Sep 93 and // slapped into the _cd.c code, in response to a suggestion that it allow // wildcards. // // Maybe a user property should turn this file-completion attempt on/off, like // the shell originally had it. // The function does the directory searches in an attempt // to complete the requested command's file path. static mixed *process_choice(string str) { mixed *dir, *tmp, *hold; string file, where, patt, dump; int loop; // Obtain user's present active directory file = resolv_path("cwd", str); // Obtain the requested file's root path tmp = explode(file, "/"); where = "/" + implode(tmp[0..(sizeof(tmp)-2)], "/") + "/"; // Form file search pattern if(sscanf(tmp[sizeof(tmp)-1],"%s\\*",patt) == 1) patt += "%s"; // Get requested directory contents dir = get_dir(where); // Get all possible filenames that would match requested pattern for(hold = ({}),loop=0; loop<sizeof(dir); loop++) if(sscanf(dir[loop], patt, dump) == 1) hold += ({ (where + dir[loop]) }); return hold; } // This function allows file path completion of sorts. // If the last character in the file path is a *, then the // shell will try to complete the path as best it can. static int file_completion(string str) { mixed *tmp, *result; string command; // If last char isn't a *, then ignore if(str[strlen(str)-1] != '*') return 0; // Break command into its word subsets and process last word tmp = explode(str, " "); result = process_choice(tmp[sizeof(tmp)-1]); // Indicate ability to complete the file path if(!result || !sizeof(result)) write("Unable to complete designated filename [" + tmp[sizeof(tmp)-1] + "]\n"); else if(sizeof(result) > 1) write("Multiple possible filename completions [" + tmp[sizeof(tmp)-1] + "]\n"); // Otherwise complete and initiate the command else { tmp[sizeof(tmp)-1] = result[0]; command = implode(tmp, " "); this_player()->force_me(command); } return 1; } int cmd_cd(string str) { int size; string name, path, hdir; path = this_player()->query("cwd"); name = geteuid(this_player()); seteuid(getuid()); if(!str) { str = user_path(name); hdir = (string)this_player()->query("home_dir"); if(hdir) str = hdir; if(str[strlen(str)-1] == '/') str = str[0..strlen(str)-2]; if(!str || !directory_exists(str)) str = "/doc"; this_player()->set("cwd", str); printf("%s\n", str); return 1; } // Guardian's hack to access the wildcard code stolen from shsh.c if(file_completion(str)) return 1; str = resolv_path(path, str); replace_string("//", "/", str); if ((int)master()->valid_read(str, this_player()) == 0) { notify_fail(sprintf("%s: permission denied\n", str)); return 0; } size = file_size(str); if (size > -1) { notify_fail(sprintf("%s: not a directory\n", str)); return 0; } if (size == -1) { notify_fail(sprintf("%s: no such file or directory\n", str)); return 0; } this_player()->set("cwd", str); printf("%s\n", str); return 1; } string help() { return("Command: cd\nSyntax: cd <directory>\n"+ "This command changes your current directory to the\n"+ "one you specify. If directory begins with a / then\n"+ "the command will look from the root, otherwise it\n"+ "will look in the child directories of your current\n"+ "directory. .. will back up to the parent of your\n"+ "current directory. Thus cd ../obj will attempt to\n"+ "move to the directory obj which is a child of your\n"+ "current parent directory.\n"+ "cd with no arguments will move you to your home dir-\n"+ "ectory if you are a student, or the /doc directory if\n"+ "not.\n"); }