我修改过的那两段程序如下:
……
case "size": // return size of file
……
case "nlst": // give name list of files in directory
CHECK_LOGIN();
/* Send name list */
if ((i = sizeof(command)) > 1 && command[1] == "-l") {
if (i == 2)
command[1] = ".";
else
command = ({ command[0] }) + command[2..s-1];
// and fall through to "list"
} else {
/* Used by commands like "dir", "mget", and "mput" */
if ( i > 1 )
tmp = get_path( fd, command[ 1 ] );
else
tmp = socket_info[ fd ][ CWD ];
if ( check_valid_read( tmp, fd ) ) {
tmp2 = ls( tmp, 1, fd );
if (tmp2 == "")
socket_write( fd, "550 No files found.\n" );
else
data_conn( fd, tmp2, "ls", STRING );
} else
PERMISSION_DENIED550(command[ 1 ]);
break;
}
case "list": // give list files in a directory
CHECK_LOGIN();
/* Send directory file list (like exec'ing "ls") */
if ((i = sizeof(command)) > 1 &&
(command[1] == "-L" || command[1] == "-a" &&
command[2] == "-L")) {
if (i == 2)
command[1] = ".";
else
command = ({ command[0] }) + command[2..s-1];
}
if ( sizeof( command ) > 1 )
tmp = get_path( fd, command[ 1 ] );
else
tmp = socket_info[ fd ][ CWD ];
if ( check_valid_read( tmp, fd ) ) {
tmp2 = ls( tmp, 0, fd );
if (tmp2 == "")
socket_write( fd, "550 No files found.\n");
else
data_conn( fd, tmp2, "ls", STRING );
} else
PERMISSION_DENIED550(command[ 1 ]);
break;
case "xpwd": // print the current working directory (deprecated)
……
修改后的 ls() 函数:
string ls( string path, int column, int fd ) {
string *files;
int i, j, s;
mixed *xfiles;
mixed *stats;
string tmp, tmp2, creator, domain;
/* if path is a directory get contents */
if ( directory_exists( path ) ) {
if ( path[ strlen( path ) - 1 ] == '/' )
path += "*";
else
path += "/*";
}
/* begin narrow columnar "nlst" */
if (column) {
files = get_dir( path );
/* can only happen if permissions are messed up at account level */
if (!files)
return "";
files -= ({ ".", ".." });
if (!(i = sizeof( files )))
return "";
/* no wild cards...must have been the exact pathname to a file */
if (strsrch(path, '*') == -1 && strsrch(path, '?') == -1) {
return files[0] + "\n";
}
/* remove globber at end of path, leave a trailing slash */
j = strsrch(path, '/', -1);
path = path[0..j];
while ( i-- ) {
/* scan next level down for files */
tmp = sprintf("%s%s/", path, files[i]);
if ( directory_exists( tmp ) ) {
files[i] += "/";
}
}
return implode( files, "\n" ) + "\n";
}
/* begin long "list" */
xfiles = get_dir( path, -1 );
if (!xfiles || !(s = sizeof( xfiles )))
return "";
files = allocate(s);
// the Unix-like file permissions are mainly for effect...hopefully it
// isn't too much, since anything more would likely be too cpu intensive
// and cause it to max eval...
creator = (string)MASTER_OB->creator_file(path);
if (!creator) creator = ROOT_UID;
domain = (string)MASTER_OB->domain_file(path);
if (!domain) domain = ROOT_UID;
i = strsrch(path, '/', -1);
if (i >= 0)
path = path[0..i];
for (i = 0; i < s; i++) {
/* process timestamp */
tmp2 = ctime((xfiles[i])[2]); /* get last modified timestamp */
if ((xfiles[i])[2] + SECS_IN_YEAR < time()) {
/* MMM DD YYYY */
tmp = sprintf("%s %s", tmp2[4..9], tmp2[20..23]);
} else {
/* MMM DD hh:mm */
tmp = tmp2[4..15];
}
j = (xfiles[i])[1]; /* get filesize */
if (j == -2) {
/* directory */
// files[i] = sprintf("drwxrwsr-x %12s %12s <DIR> %12s %s/",
files[i] = sprintf("drwxrwsr-x 1 %-8s %-8s 0 %12s %s",
creator, domain, tmp, (xfiles[i])[0]);
} else {
/* file */
stats = stat(path + (xfiles[i])[0]);
// files[i] = sprintf("-rw%crw-r-- %12s %12s %8d %12s %s",
files[i] = sprintf("-rw%crw-r-- 1 %-8s %-8s %12d %12s %s",
stats[2] ? 'x' : '-', /* 'x' if loaded, else ' ' */
creator, domain, j, tmp, (xfiles[i])[0]);
}
}
return sprintf( "%s\n", implode( files, "\n" ) );
}
Well, are you clear ?
后记:
在西游记2000版中,西游记巫师组对 FTP 服务器程序作了一些修缮,不过因为
没有去掉 "<DIR>" 这个不合标准的东东,CuteFTP 还是不能识别它传回的目录。
把 "<DIR>" 换成目录的字节 "0" 就行了,整个 ftpd.c 就改这一个地方就可以
适应 CuteFTP 了,弄一个试试吧!
(完)
尊重作者 转载请注明出处52mud.com