#include <ls.h> #include <autodoc.h> inherit COMMAND_BASE; /* this does an ls, now that get_dir has been written * Modified by Turrican 13-7-95 with nicked code from TMI-2's ftpd. * - Added different options. * Modified by Turrican 3-12-97. * - Made ls -CF the default format. The old 1 column format is available * with the -1 flag. */ #define CREATOR (master()->author_file(sprintf("%s/%s", str, direc[i][0]))? \ master()->author_file(sprintf("%s/%s", str, direc[i][0])): \ "Root") #define DOMAIN (master()->domain_file(sprintf("%s/%s", str, direc[i][0]))? \ master()->domain_file(sprintf("%s/%s", str, direc[i][0])): \ "Root") #define CREATOR_D (master()->author_file(sprintf("%s/%s/.", str, direc[i][0]))? \ master()->author_file(sprintf("%s/%s/.", str, direc[i][0])): \ "Root") #define DOMAIN_D (master()->domain_file(sprintf("%s/%s/.", str, direc[i][0]))? \ master()->domain_file(sprintf("%s/%s/.", str, direc[i][0])): \ "Root") int ls(string str, int mask); int check_dots(mixed arg); int fsize_count, dir_count; int t_file_size(string file) { fsize_count++; return file_size(file); } mixed *t_get_dir2(string dir, int flag) { dir_count++; return get_dir(dir, flag); } mixed *t_get_dir(string dir) { dir_count++; return get_dir(dir); } mixed cmd(string str) { string *bits, path; int mask, i; fsize_count = 0; dir_count = 0; mask = (MASK_C|MASK_F); if (str) { bits = explode(str, " ") - ({"", 0}); while (sizeof(bits) && bits[0][0] == '-') { i = strlen(bits[0]); while (i--) { if (bits[0][i] == '-') continue; switch (bits[0][i]) { case 'l': mask |= MASK_L; break; case 'C': mask |= MASK_C; break; case 'a': mask |= MASK_A; break; case 'd': mask |= MASK_D; break; case 'o': mask |= MASK_O; break; case 'F': mask |= MASK_F; break; case '1': mask &= ~MASK_C; break; case 'v': write("ls version 2.6 (c) 1995-1998 Turrican@Discworld\n"); return 1; case 'h': printf("Usage: ls [OPTION]... [PATH]...\n\n" " -a do not hide entries \"..\" and \".\"\n" " -d list directory entries instead of contents\n" " -h display this help and exit\n" " -l use a long listing format\n" " -o colorize entries according to type\n" " -v print version information and exit\n" " -C list entries by columns\n" " -F append a character to entries according to type\n" " -1 list one file per line\n" ); return 1; default : printf("Unknown option -%c\nTry `ls -h' for more information.\n", bits[0][i]); return 1; } } bits = delete(bits, 0, 1); } str = implode(bits, " "); } if (!str) { path = this_player()->query_current_path(); } else { path = this_player()->get_path(str); } if (!path) { return notify_fail("No current directory.\n"); } if (master()->valid_read(path+"/", geteuid(this_player()), "t_get_dir")) { ls(path, mask); } else { return notify_fail("$I$0=ls: "+ str + ": Permission denied.\n"); } printf("FSIZE: %d, DIR: %d\n", fsize_count, dir_count); return 1; } /* cmd() */ string dir_entry(string path, string name, int mask) { int size; string *obs, tmp; size = t_file_size(this_player()->get_path(path+name)); if (size == -2) { tmp = this_player()->get_path(path + name); if (tmp == "/") { obs = t_get_dir(tmp); } else { obs = t_get_dir(tmp + "/"); } if (!obs) { size = -1; } else { size = sizeof(obs); } if (mask & MASK_F) { name += "/"; } } else { tmp = ""; if (find_object(path+name)) { if (mask & MASK_F) { tmp += "*"; } } /* Autodoc stuff, so it shows up as in or out of the doc system. */ if ((mask & MASK_F) && AUTODOC_HANDLER->is_autodoc_file(path + name)) { tmp += "@"; } /* Put the extension bits on... */ name += tmp; size = (size / 1024) + 1; } if (size < 1000) { return " "[0..3-strlen(size+"")]+size+" "+name; } return size+" "+name; } /* dir_entry() */ int ls(string str, int mask) { string *bit, *bing, bong, path; int i, j, k, size; mixed *direc; path = str; if (t_file_size(str) == -2 && str[strlen(str)-1] != '/' && !(mask & MASK_D)) { path += "/"; } if (mask & MASK_A) { path += "*"; } direc = t_get_dir(path); if (!(mask & MASK_A)) { direc = filter(direc, (: check_dots($1) :)); } if (!direc) { printf("No files.\n"); return 0; } if (!sizeof(direc)) { if (t_file_size(str) == -2) { printf("No files.\n"); } else { printf("ls: %s: No such file or directory.\n", str); } return 0; } if (t_file_size(path) == -2) { if (path[strlen(path)-1] != '/') { path += "/"; } } else { bit = explode(path, "/"); bit = bit[0..sizeof(bit)-2]; path = "/"+implode(bit,"/")+"/"; } if(path == "//") path = "/"; printf( "Dir of: "+ path +"\n" ); bing = allocate(sizeof(direc)); j = sizeof(direc); if (!(mask & MASK_C) && !(mask & MASK_L)) { if (!(mask & MASK_F) && !(mask & MASK_O)) { bong = sprintf("%-=*s\n", this_player()->query_cols(), implode(direc, "\n")); bing = explode(bong, "\n"); } else for (i=0; i < j; i++) { if (t_file_size(path+direc[i]) == -2 || direc[i] == "..") { if (mask & MASK_O) { bing[i] = sprintf("%s%-=*s", "%^GREEN%^", (int)this_player()->query_cols()+8, direc[i]+"%^RESET%^"+ (mask & MASK_F?"/":"")); } else { bing[i] = sprintf("%-=*s", this_player()->query_cols(), direc[i]+"/"); } } else if (find_object(path+direc[i])) { if (mask & MASK_O) { bing[i] = sprintf("%s%-=*s", "%^MAGENTA%^", (int)this_player()->query_cols()-1, direc[i]+"%^RESET%^"+ (mask & MASK_F?"*":"")+ ((mask & MASK_F) && AUTODOC_HANDLER->is_autodoc_file(path+direc[i]) ?"@":"")); } else { bing[i] = sprintf("%-=*s", this_player()->query_cols(), direc[i]+"*"+ ((mask & MASK_F) && AUTODOC_HANDLER->is_autodoc_file(path+direc[i]) ?"@":"")); } } else { bing[i] = sprintf("%-=*s", this_player()->query_cols(), direc[i]+ ((mask & MASK_F) && AUTODOC_HANDLER->is_autodoc_file(path+direc[i]) ?"@":"")); } } bong = implode(bing, "\n"); } else if (!(mask & MASK_L)) { j = sizeof(direc); for ( i = 0; i < j; i++ ) { if ( strlen( direc[ i ] ) > 35 ) { printf( dir_entry( path, direc[ i ], mask ) +"\n" ); bing = delete(bing, i, 1); direc = delete(direc, i--, 1); j--; continue; } else { bing[i] = dir_entry(path, direc[i], mask)+"\n"; } } bong = sprintf( "%#-*s\n", this_player()->query_cols(), implode(bing, "")); if (mask & MASK_O) { /* Boy, it's hard to work with colors and sprintf. *sigh* *especially* in column mode :-( */ i = j; while (i--) { if (t_file_size(path+direc[i]) == -2 || direc[i] == "..") { bong = replace_string(bong, " "+direc[i], sprintf(" %s%s%s", "%^GREEN%^", direc[i], "%^RESET%^")); } else if (find_object(path+direc[i])) { bong = replace_string(bong, " "+direc[i], sprintf(" %s%s%s", "%^MAGENTA%^", direc[i], "%^RESET%^")); } else { /* Believe me, it's needed. */ bong = replace_string(bong, " "+direc[i], sprintf(" %s%s", "%^RESET%^", direc[i])); } } } } else { string tmp, tmp2; mixed *stats; int *count, current_time; /* if path is a directory get contents */ if ( t_file_size( str ) == -2 && !(mask & MASK_D)) { if ( str[ strlen( str ) - 1 ] == '/' ) { str += "*"; } else { str += "/*"; } } /* begin long "list" */ direc = t_get_dir2( str, -1 ); if (!(mask & MASK_A)) { direc = filter_array(direc, (: check_dots($1[0]) :)); } if (!direc || !(size = sizeof(direc))) { return 0; } bit = allocate(size); count = allocate(size); i = strsrch(str, '/', -1); if (i >= 0) { str = str[0..i]; } current_time = time(); for (i = 0; i < size; i++) { reset_eval_cost(); /* process timestamp */ tmp2 = ctime((direc[i])[2]); /* get last modified timestamp */ if ((direc[i])[2] + (6 * 30 * 24 * 60 * 60) < current_time || (direc[i])[2] - ( 60 * 60) > current_time ) { /* MMM DD YYYY */ tmp = sprintf("%s %s", tmp2[4..9], tmp2[20..23]); } else { /* MMM DD hh:mm */ tmp = tmp2[4..15]; } j = (direc[i])[1]; /* get filesize */ if (j == -2) { count[i] = 1; /* directory */ bit[i] = sprintf("%-=*s", (this_player()->query_cols()+ (mask & MASK_O?17:0)), sprintf("drwxr%cx%c%c%c %3d %-11.11s %-11.11s 0 %12s %s%s%s%s", (master()->valid_write(sprintf("%s%s/fl.uff",str,direc[i][0]), DOMAIN_D, "t_get_dir")?'w':'-'), (master()->valid_read(sprintf("%s%s",str,direc[i][0]), "NOBODY", "t_get_dir")?'r':'-'), (master()->valid_write(sprintf("%s%s/fl.uff",str,direc[i][0]), "NOBODY", "t_get_dir")?'w':'-'), (master()->valid_read(sprintf("%s%s",str,direc[i][0]), "NOBODY", "t_get_dir")?'x':'-'), sizeof(filter_array(((bing = t_get_dir(this_player()->get_path( sprintf("%s%s/*", str, direc[i][0]))))?bing:({ })), "is_dir", this_object(), sprintf("%s%s", str, direc[i][0])))+(direc[i][0] == ".." && str == "/"?2:0), CREATOR_D, DOMAIN_D, tmp, (mask & MASK_O?"%^GREEN%^":""), (direc[i])[0], (mask & MASK_O?"%^RESET%^":""), (mask & MASK_F?"/":""))); } else { /* file */ count[i] = 0; stats = stat(str + (direc[i])[0]); bit[i] = sprintf("%-=*s", (this_player()->query_cols()+ ((mask & MASK_O) && (k = sizeof(stats)) > 1 && stats[2]?19:0)), sprintf("-rw%c%c%c-%c%c- 1 %-11.11s %-11.11s %6d %12s %s%s%s%s%s", k > 1 && stats[2] ? 'x' : '-', (master()->valid_read(sprintf("%s/%s",str,direc[i][0]), DOMAIN, "t_get_dir")?'r':'-'), (master()->valid_write(sprintf("%s/%s",str,direc[i][0]), DOMAIN, "t_get_dir")?'w':'-'), (master()->valid_read(sprintf("%s/%s",str,direc[i][0]), "NOBODY", "t_get_dir")?'r':'-'), (master()->valid_write(sprintf("%s/%s",str,direc[i][0]), "NOBODY", "t_get_dir")?'w':'-'), CREATOR, DOMAIN, j, tmp, ((mask & MASK_O) && k > 1 && stats[2]?"%^MAGENTA%^":""), (direc[i])[0], ((mask & MASK_O) && k > 1 && stats[2]?"%^RESET%^":""), (k > 1 && stats[2] && (mask & MASK_F)?"*":""), ((mask & MASK_F) && AUTODOC_HANDLER->is_autodoc_file(str + direc[i][0])?"@":""))); } bong = implode(bit, "\n"); } } this_player()->more_string( bong, str, 1 ); } /* ls() */ int check_dots(mixed arg) { return arg[0] != '.'; } int is_dir(mixed arg, string path) { return (t_file_size(this_player()->get_path(sprintf("%s/%s", path, arg))) == -2); }