#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);
}