50c4c4 | 2001-08-23 | Martin Nilsson | |
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | |
63d855 | 1997-06-10 | Henrik Grubbström (Grubba) | | *
|
d90ab7 | 2002-10-24 | Martin Nilsson | | * $Id: ftp.pike,v 2.83 2002/10/24 00:11:28 nilsson Exp $
|
63d855 | 1997-06-10 | Henrik Grubbström (Grubba) | | *
|
0eb9d7 | 2000-03-16 | Martin Nilsson | | * Henrik Grubbström <grubba@roxen.com>
|
63d855 | 1997-06-10 | Henrik Grubbström (Grubba) | | */
|
b1fca0 | 1996-11-12 | Per Hedbor | |
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | |
686675 | 1997-08-29 | Henrik Grubbström (Grubba) | | *
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | * How much is supposed to be logged?
|
686675 | 1997-08-29 | Henrik Grubbström (Grubba) | | */
|
c175b9 | 1998-03-21 | Henrik Grubbström (Grubba) | | |
215923 | 1998-03-23 | Henrik Grubbström (Grubba) | | * RFC 764 TELNET PROTOCOL SPECIFICATION
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | * RFC 765 FILE TRANSFER PROTOCOL
|
c175b9 | 1998-03-21 | Henrik Grubbström (Grubba) | | * RFC 959 FILE TRANSFER PROTOCOL (FTP)
* RFC 1123 Requirements for Internet Hosts -- Application and Support
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | * RFC 1579 Firewall-Friendly FTP
* RFC 1635 How to Use Anonymous FTP
|
c175b9 | 1998-03-21 | Henrik Grubbström (Grubba) | | *
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | * RFC's describing extra commands:
*
* RFC 683 FTPSRV - Tenex extension for paged files
* RFC 737 FTP Extension: XSEN
* RFC 743 FTP extension: XRSQ/XRCP
* RFC 775 DIRECTORY ORIENTED FTP COMMANDS
* RFC 949 FTP unique-named store command
* RFC 1639 FTP Operation Over Big Address Records (FOOBAR)
|
316375 | 2001-03-13 | Henrik Grubbström (Grubba) | | * RFC 2428 FTP Extensions for IPv6 and NATs
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | *
|
7a8c5b | 2001-03-03 | Henrik Grubbström (Grubba) | | * IETF draft 12 Extended Directory Listing, TVFS,
* and Restart Mechanism for FTP
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | *
* RFC's with recomendations and discussions:
|
c175b9 | 1998-03-21 | Henrik Grubbström (Grubba) | | *
* RFC 607 Comments on the File Transfer Protocol
* RFC 614 Response to RFC 607, "Comments on the File Transfer Protocol"
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | * RFC 624 Comments on the File Transfer Protocol
|
c175b9 | 1998-03-21 | Henrik Grubbström (Grubba) | | * RFC 640 Revised FTP Reply Codes
* RFC 691 One More Try on the FTP
* RFC 724 Proposed Official Standard for the
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | * Format of ARPA Network Messages
*
* RFC's describing gateways and proxies:
*
* RFC 1415 FTP-FTAM Gateway Specification
*
* More or less obsolete RFC's:
*
* RFC 412 User FTP documentation
* *RFC 438 FTP server-server interaction
* *RFC 448 Print files in FTP
* *RFC 458 Mail retrieval via FTP
* *RFC 463 FTP comments and response to RFC 430
* *RFC 468 FTP data compression
* *RFC 475 FTP and network mail system
* *RFC 478 FTP server-server interaction - II
* *RFC 479 Use of FTP by the NIC Journal
* *RFC 480 Host-dependent FTP parameters
* *RFC 505 Two solutions to a file transfer access problem
* *RFC 506 FTP command naming problem
* *RFC 520 Memo to FTP group: Proposal for File Access Protocol
* *RFC 532 UCSD-CC Server-FTP facility
* RFC 542 File Transfer Protocol for the ARPA Network
* RFC 561 Standardizing Network Mail Headers
* *RFC 571 Tenex FTP problem
* *RFC 630 FTP error code usage for more reliable mail service
* *RFC 686 Leaving well enough alone
* *RFC 697 CWD Command of FTP
|
c175b9 | 1998-03-21 | Henrik Grubbström (Grubba) | | * RFC 751 SURVEY OF FTP MAIL AND MLFL
* RFC 754 Out-of-Net Host Addresses for Mail
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | *
* (RFC's marked with * are not available from http://www.roxen.com/rfc/)
|
c175b9 | 1998-03-21 | Henrik Grubbström (Grubba) | | */
|
b1fca0 | 1996-11-12 | Per Hedbor | | #include <config.h>
#include <module.h>
#include <stat.h>
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | |
|
50c4c4 | 2001-08-23 | Martin Nilsson | | #define FTP2_XTRA_HELP ({ "Report any bugs at http://community.roxen.com/crunch/" })
|
3e61d1 | 1997-03-09 | Henrik Grubbström (Grubba) | |
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | #define FTP2_TIMEOUT (5*60)
|
3e61d1 | 1997-03-09 | Henrik Grubbström (Grubba) | |
|
b0132d | 1999-10-08 | Henrik Grubbström (Grubba) | |
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | |
#ifdef FTP2_DEBUG
|
17e2b2 | 2001-06-15 | Johan Sundström | | # define DWRITE(X ...) werror(X)
|
6a409d | 1999-12-27 | Martin Nilsson | | #else
|
17e2b2 | 2001-06-15 | Johan Sundström | | # define DWRITE(X ...)
|
6a409d | 1999-12-27 | Martin Nilsson | | #endif
|
b1fca0 | 1996-11-12 | Per Hedbor | |
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | #if constant(thread_create)
#define BACKEND_CLOSE(FD) do { DWRITE("close\n"); FD->set_blocking(); call_out(FD->close, 0); FD = 0; } while(0)
#else /* !constant(thread_create) */
#define BACKEND_CLOSE(FD) do { DWRITE("close\n"); FD->set_blocking(); FD->close(); FD = 0; } while(0)
#endif /* constant(thread_create) */
class RequestID2
|
b1fca0 | 1996-11-12 | Per Hedbor | | {
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | inherit RequestID;
|
b1fca0 | 1996-11-12 | Per Hedbor | |
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | mapping file;
|
3e61d1 | 1997-03-09 | Henrik Grubbström (Grubba) | |
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | #ifdef FTP2_DEBUG
static void trace_enter(mixed a, mixed b)
{
|
17e2b2 | 2001-06-15 | Johan Sundström | | write("FTP: TRACE_ENTER(%O, %O)\n", a, b);
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | }
static void trace_leave(mixed a)
{
|
17e2b2 | 2001-06-15 | Johan Sundström | | write("FTP: TRACE_LEAVE(%O)\n", a);
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | }
#endif /* FTP2_DEBUG */
void ready_to_receive()
{
}
|
84fb68 | 2000-02-03 | Per Hedbor | | Configuration configuration()
{
return conf;
}
Stdio.File connection( )
{
return my_fd;
}
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | void send_result(mapping|void result)
{
|
80d2e6 | 1999-05-06 | Henrik Grubbström (Grubba) | | if (mappingp(result) && my_fd && my_fd->done) {
my_fd->done(result);
return;
}
|
894286 | 1999-05-19 | Henrik Grubbström (Grubba) | | error("Async sending with send_result() not supported yet.\n");
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | }
object(RequestID2) clone_me()
{
object(RequestID2) o = this_object();
return(object_program(o)(o));
}
void end()
{
}
|
1fd317 | 2002-02-26 | Anders Johansson | | constant __num = ({ 0 });
int _num;
void destroy()
{
#ifdef FTP_REQUESTID_DEBUG
report_debug("REQUESTID: Destroy request id #%d.\n", _num);
#endif
}
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | void create(object|void m_rid)
{
|
1fd317 | 2002-02-26 | Anders Johansson | | #ifdef FTP_REQUESTID_DEBUG
_num = ++__num[0];
report_debug("REQUESTID: New request id #%d.\n", _num);
#else
|
6a409d | 1999-12-27 | Martin Nilsson | | DWRITE("REQUESTID: New request id.\n");
|
1fd317 | 2002-02-26 | Anders Johansson | | #endif
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | |
if (m_rid) {
object o = this_object();
foreach(indices(m_rid), string var) {
|
f72bc9 | 2000-02-04 | Per Hedbor | | if (!(< "create", "connection", "configuration",
"__INIT", "clone_me", "end", "ready_to_receive",
|
bfb606 | 2001-08-03 | Mattias Wingstedt | | "send", "scan_for_query", "send_result", "misc",
|
5ad1cd | 2002-02-04 | Jonas Wallden | | "url_base", "set_response_header",
|
d90ab7 | 2002-10-24 | Martin Nilsson | | "add_response_header", "set_output_charset",
"adjust_for_config_path",
|
1fd317 | 2002-02-26 | Anders Johansson | | "destroy", "_num", "__num">)[var]) {
|
e81b18 | 2000-03-20 | Henrik Grubbström (Grubba) | | #ifdef FTP2_DEBUG
if (catch {
#endif /* FTP2_DEBUG */
o[var] = m_rid[var];
#ifdef FTP2_DEBUG
}) {
|
17e2b2 | 2001-06-15 | Johan Sundström | | report_error("FTP2: "
"Failed to copy variable %s (value:%O)\n",
var, m_rid[var]);
|
e81b18 | 2000-03-20 | Henrik Grubbström (Grubba) | | }
#endif /* FTP2_DEBUG */
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | }
|
3e61d1 | 1997-03-09 | Henrik Grubbström (Grubba) | | }
|
7cd688 | 2001-03-05 | Stefan Wallström | | o["misc"] = m_rid["misc"] + ([ ]);
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | } else {
client = ({ "ftp" });
prot = "FTP";
clientprot = "FTP";
|
1cabe5 | 2001-02-05 | Martin Stjernholm | | real_variables = ([]);
|
b6802c | 2002-07-04 | Per Hedbor | | variables = FakedVariables( real_variables );
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | misc = ([]);
cookies = ([]);
|
a58dd1 | 2000-03-29 | Henrik Grubbström (Grubba) | | throttle = ([]);
|
db4ca9 | 2000-09-18 | Henrik Grubbström (Grubba) | | client_var = ([]);
|
a58dd1 | 2000-03-29 | Henrik Grubbström (Grubba) | | request_headers = ([]);
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | |
prestate = (<>);
config = (<>);
supports = (< "ftp", "images", "tables", >);
pragma = (<>);
rest_query = "";
extra_extension = "";
|
3e61d1 | 1997-03-09 | Henrik Grubbström (Grubba) | | }
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | time = predef::time(1);
#ifdef FTP2_DEBUG
misc->trace_enter = trace_enter;
misc->trace_leave = trace_leave;
#endif /* FTP2_DEBUG */
|
3e61d1 | 1997-03-09 | Henrik Grubbström (Grubba) | | }
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | };
|
3e61d1 | 1997-03-09 | Henrik Grubbström (Grubba) | |
|
e01e95 | 2001-09-22 | Henrik Grubbström (Grubba) | | class FileWrapper
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | {
static string convert(string s);
|
b1fca0 | 1996-11-12 | Per Hedbor | |
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | static private function read_cb;
static private function close_cb;
static private mixed id;
|
280ffa | 1999-10-29 | Henrik Grubbström (Grubba) | |
|
e01e95 | 2001-09-22 | Henrik Grubbström (Grubba) | | static private object f;
static private string data;
static private object ftpsession;
int is_file;
static void create(object f_, string data_, object ftpsession_)
{
f = f_;
data = data_;
ftpsession = ftpsession_;
is_file = f_->is_file;
}
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | static private void read_callback(mixed i, string s)
{
read_cb(id, convert(s));
ftpsession->touch_me();
}
static private void close_callback(mixed i)
{
close_cb(id);
if (f) {
BACKEND_CLOSE(f);
}
ftpsession->touch_me();
}
|
280ffa | 1999-10-29 | Henrik Grubbström (Grubba) | | static private void delayed_nonblocking(function w_cb)
{
string d = data;
data = 0;
f->set_nonblocking(read_callback, w_cb, close_callback);
if (d) {
read_callback(0, d);
}
}
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | void set_nonblocking(function r_cb, function w_cb, function c_cb)
{
read_cb = r_cb;
close_cb = c_cb;
|
bb70ce | 1999-10-29 | Henrik Grubbström (Grubba) | | remove_call_out(delayed_nonblocking);
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | if (r_cb) {
|
280ffa | 1999-10-29 | Henrik Grubbström (Grubba) | | if (data) {
call_out(delayed_nonblocking, 0, w_cb);
f->set_nonblocking(0, w_cb, 0);
} else {
f->set_nonblocking(read_callback, w_cb, close_callback);
}
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | } else {
f->set_nonblocking(0, w_cb, 0);
}
}
void set_blocking()
{
|
280ffa | 1999-10-29 | Henrik Grubbström (Grubba) | | if (data) {
|
bb70ce | 1999-10-29 | Henrik Grubbström (Grubba) | | remove_call_out(delayed_nonblocking);
|
280ffa | 1999-10-29 | Henrik Grubbström (Grubba) | | }
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | f->set_blocking();
}
void set_id(mixed i)
{
id = i;
f->set_id(i);
}
int query_fd()
{
return -1;
}
string read(int|void n)
{
ftpsession->touch_me();
|
280ffa | 1999-10-29 | Henrik Grubbström (Grubba) | | if (data) {
if (n) {
if (n < sizeof(data)) {
string d = data[..n-1];
data = data[n..];
return convert(d);
} else {
string d = data;
data = 0;
return convert(d + f->read(n - sizeof(d)));
}
} else {
string d = data;
data = 0;
return convert(d + f->read());
}
}
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | return(convert(f->read(n)));
}
void close()
{
ftpsession->touch_me();
if (f) {
f->set_blocking();
BACKEND_CLOSE(f);
}
}
|
b1fca0 | 1996-11-12 | Per Hedbor | | }
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | class ToAsciiWrapper
|
b1fca0 | 1996-11-12 | Per Hedbor | | {
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | inherit FileWrapper;
int converted;
static string convert(string s)
|
b1fca0 | 1996-11-12 | Per Hedbor | | {
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | converted += sizeof(s);
|
e27e51 | 1999-05-22 | Henrik Grubbström (Grubba) | | return(replace(s, ({ "\r\n", "\n", "\r" }), ({ "\r\n", "\r\n", "\r\n" })));
|
b1fca0 | 1996-11-12 | Per Hedbor | | }
}
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | class FromAsciiWrapper
{
inherit FileWrapper;
int converted;
|
b1fca0 | 1996-11-12 | Per Hedbor | |
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | static string convert(string s)
{
converted += sizeof(s);
#ifdef __NT__
|
e27e51 | 1999-05-22 | Henrik Grubbström (Grubba) | |
return(replace(s, ({ "\r\n", "\n", "\r" }), ({ "\r\n", "\r\n", "\r\n" })));
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | #else /* !__NT__ */
|
e27e51 | 1999-05-22 | Henrik Grubbström (Grubba) | | #ifdef __MACOS__
return(replace(s, ({ "\r\n", "\n", "\r" }), ({ "\r", "\r", "\r" })));
#else /* !__MACOS__ */
return(replace(s, ({ "\r\n", "\n", "\r" }), ({ "\n", "\n", "\n" })));
#endif /* __MACOS__ */
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | #endif /* __NT__ */
}
}
|
b1fca0 | 1996-11-12 | Per Hedbor | |
|
c3e98f | 1999-05-01 | Henrik Grubbström (Grubba) | |
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | class BinaryWrapper
|
b1fca0 | 1996-11-12 | Per Hedbor | | {
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | inherit FileWrapper;
static string convert(string s)
{
return(s);
}
|
b1fca0 | 1996-11-12 | Per Hedbor | | }
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | |
|
031f32 | 1997-08-31 | Henrik Grubbström (Grubba) | |
|
ca5638 | 1999-05-01 | Henrik Grubbström (Grubba) | | class ToEBCDICWrapper
{
inherit FileWrapper;
int converted;
static object converter = Locale.Charset.encoder("EBCDIC-US", "");
static string convert(string s)
{
converted += sizeof(s);
return(converter->feed(s)->drain());
}
}
class FromEBCDICWrapper
{
inherit FileWrapper;
int converted;
static object converter = Locale.Charset.decoder("EBCDIC-US");
static string convert(string s)
{
converted += sizeof(s);
return(converter->feed(s)->drain());
}
}
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | |
|
e01e95 | 2001-09-22 | Henrik Grubbström (Grubba) | | class PutFileWrapper
|
031f32 | 1997-08-31 | Henrik Grubbström (Grubba) | | {
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | static int response_code = 226;
static string response = "Stored.";
static string gotdata = "";
|
80d2e6 | 1999-05-06 | Henrik Grubbström (Grubba) | | static int closed, recvd;
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | static function other_read_callback;
|
e01e95 | 2001-09-22 | Henrik Grubbström (Grubba) | | static object from_fd;
static object session;
static object ftpsession;
int is_file;
static void create(object from_fd_, object session_, object ftpsession_)
{
from_fd = from_fd_;
session = session_;
ftpsession = ftpsession_;
is_file = from_fd->is_file;
}
|
80d2e6 | 1999-05-06 | Henrik Grubbström (Grubba) | | #include <variables.h>
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | int bytes_received()
{
return recvd;
|
031f32 | 1997-08-31 | Henrik Grubbström (Grubba) | | }
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | |
int close(string|void how)
{
DWRITE("FTP: PUT: close()\n");
ftpsession->touch_me();
|
80d2e6 | 1999-05-06 | Henrik Grubbström (Grubba) | | if(how != "w" && !closed) {
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | ftpsession->send(response_code, ({ response }));
|
80d2e6 | 1999-05-06 | Henrik Grubbström (Grubba) | | closed = 1;
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | session->conf->received += recvd;
session->file->len = recvd;
session->conf->log(session->file, session);
session->file = 0;
session->my_fd = from_fd;
}
if (how) {
return from_fd->close(how);
} else {
BACKEND_CLOSE(from_fd);
return 0;
|
031f32 | 1997-08-31 | Henrik Grubbström (Grubba) | | }
}
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | string read(mixed ... args)
{
DWRITE("FTP: PUT: read()\n");
ftpsession->touch_me();
string r = from_fd->read(@args);
if(stringp(r))
recvd += sizeof(r);
return r;
}
|
41ddda | 1997-04-05 | Marcus Comstedt | |
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | static mixed my_read_callback(mixed id, string data)
{
|
17e2b2 | 2001-06-15 | Johan Sundström | | DWRITE("FTP: PUT: my_read_callback(X, \"%s\")\n", data||"");
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | ftpsession->touch_me();
if(stringp(data))
recvd += sizeof(data);
return other_read_callback(id, data);
|
031f32 | 1997-08-31 | Henrik Grubbström (Grubba) | | }
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | |
void set_read_callback(function read_callback)
{
DWRITE("FTP: PUT: set_read_callback()\n");
ftpsession->touch_me();
if(read_callback) {
other_read_callback = read_callback;
from_fd->set_read_callback(my_read_callback);
} else
from_fd->set_read_callback(read_callback);
}
void set_nonblocking(function ... args)
{
DWRITE("FTP: PUT: set_nonblocking()\n");
if(sizeof(args) && args[0]) {
other_read_callback = args[0];
from_fd->set_nonblocking(my_read_callback, @args[1..]);
} else
from_fd->set_nonblocking(@args);
}
|
80d2e6 | 1999-05-06 | Henrik Grubbström (Grubba) | | void set_blocking()
{
from_fd->set_blocking();
}
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | void set_id(mixed id)
{
from_fd->set_id(id);
}
int write(string data)
{
|
17e2b2 | 2001-06-15 | Johan Sundström | | DWRITE("FTP: PUT: write(\"%s\")\n", data||"");
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | |
ftpsession->touch_me();
int n, code;
string msg;
gotdata += data;
while((n=search(gotdata, "\n"))>=0) {
if(3==sscanf(gotdata[..n], "HTTP/%*s %d %[^\r\n]", code, msg)
&& code>199) {
if(code < 300)
code = 226;
else
code = 550;
response_code = code;
response = msg;
}
gotdata = gotdata[n+1..];
|
031f32 | 1997-08-31 | Henrik Grubbström (Grubba) | | }
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | return strlen(data);
}
|
80d2e6 | 1999-05-06 | Henrik Grubbström (Grubba) | | void done(mapping result)
{
if (result->error < 300) {
response_code = 226;
} else {
response_code = 550;
}
response = ((result->rettext || errors[result->error])/" ")[1..] * " ";
gotdata = result->data || "";
close();
}
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | string query_address(int|void loc)
{
return from_fd->query_address(loc);
|
031f32 | 1997-08-31 | Henrik Grubbström (Grubba) | | }
}
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | |
#define LS_FLAG_A 0x00001
#define LS_FLAG_a 0x00002
#define LS_FLAG_b 0x00004
#define LS_FLAG_C 0x00008
#define LS_FLAG_d 0x00010
#define LS_FLAG_F 0x00020
#define LS_FLAG_f 0x00040
#define LS_FLAG_G 0x00080
#define LS_FLAG_h 0x00100
#define LS_FLAG_l 0x00200
#define LS_FLAG_m 0x00400
#define LS_FLAG_n 0x00800
#define LS_FLAG_r 0x01000
#define LS_FLAG_Q 0x02000
#define LS_FLAG_R 0x04000
#define LS_FLAG_S 0x08000
#define LS_FLAG_s 0x10000
#define LS_FLAG_t 0x20000
#define LS_FLAG_U 0x40000
#define LS_FLAG_v 0x80000
|
802535 | 2001-01-22 | Henrik Grubbström (Grubba) | | class LS_L(static RequestID master_session,
|
f35256 | 2000-09-24 | Henrik Grubbström (Grubba) | | static int|void flags)
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | {
static constant decode_mode = ({
({ S_IRUSR, S_IRUSR, 1, "r" }),
({ S_IWUSR, S_IWUSR, 2, "w" }),
({ S_IXUSR|S_ISUID, S_IXUSR, 3, "x" }),
({ S_IXUSR|S_ISUID, S_ISUID, 3, "S" }),
({ S_IXUSR|S_ISUID, S_IXUSR|S_ISUID, 3, "s" }),
({ S_IRGRP, S_IRGRP, 4, "r" }),
({ S_IWGRP, S_IWGRP, 5, "w" }),
({ S_IXGRP|S_ISGID, S_IXGRP, 6, "x" }),
({ S_IXGRP|S_ISGID, S_ISGID, 6, "S" }),
({ S_IXGRP|S_ISGID, S_IXGRP|S_ISGID, 6, "s" }),
({ S_IROTH, S_IROTH, 7, "r" }),
({ S_IWOTH, S_IWOTH, 8, "w" }),
({ S_IXOTH|S_ISVTX, S_IXOTH, 9, "x" }),
({ S_IXOTH|S_ISVTX, S_ISVTX, 9, "T" }),
({ S_IXOTH|S_ISVTX, S_IXOTH|S_ISVTX, 9, "t" })
});
static constant months = ({ "Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec" });
|
abdff2 | 1999-12-27 | Martin Nilsson | |
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | static string name_from_uid(int uid)
|
031f32 | 1997-08-31 | Henrik Grubbström (Grubba) | | {
|
8f8ac6 | 2001-08-05 | Henrik Grubbström (Grubba) | | User user;
foreach(master_session->conf->user_databases(), UserDB user_db) {
if (user = user_db->find_user_from_uid(uid)) {
return user->name();
|
031f32 | 1997-08-31 | Henrik Grubbström (Grubba) | | }
}
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | return (uid?((string)uid):"root");
|
031f32 | 1997-08-31 | Henrik Grubbström (Grubba) | | }
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | string ls_l(string file, array st)
|
b1fca0 | 1996-11-12 | Per Hedbor | | {
|
17e2b2 | 2001-06-15 | Johan Sundström | | DWRITE("ls_l(\"%s\")\n", file);
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | |
int mode = st[0] & 007777;
array(string) perm = "----------"/"";
|
abdff2 | 1999-12-27 | Martin Nilsson | |
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | if (st[1] < 0) {
perm[0] = "d";
|
031f32 | 1997-08-31 | Henrik Grubbström (Grubba) | | }
|
abdff2 | 1999-12-27 | Martin Nilsson | |
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | foreach(decode_mode, array(string|int) info) {
if ((mode & info[0]) == info[1]) {
perm[info[2]] = info[3];
|
031f32 | 1997-08-31 | Henrik Grubbström (Grubba) | | }
}
|
abdff2 | 1999-12-27 | Martin Nilsson | |
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | mapping lt = localtime(st[3]);
|
25f654 | 1999-05-19 | Henrik Grubbström (Grubba) | |
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | string user = (string)st[5];
string group = (string)st[6];
if (!(flags & LS_FLAG_n)) {
if (!stringp(st[5])) {
user = name_from_uid(st[5]);
}
}
string ts;
int now = time(1);
if ((st[3] <= now - 15778800) || (st[3] > now)) {
ts = sprintf("%s %02d %04d",
months[lt->mon], lt->mday, 1900+lt->year);
|
031f32 | 1997-08-31 | Henrik Grubbström (Grubba) | | } else {
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | |
ts = sprintf("%s %02d %02d:%02d",
months[lt->mon], lt->mday, lt->hour, lt->min);
}
if (flags & LS_FLAG_G) {
return sprintf("%s 1 %-10s %12d %s %s\n", perm*"",
user, (st[1]<0? 512:st[1]),
ts, file);
} else {
return sprintf("%s 1 %-10s %-6s %12d %s %s\n", perm*"",
user, group, (st[1]<0? 512:st[1]),
ts, file);
|
031f32 | 1997-08-31 | Henrik Grubbström (Grubba) | | }
}
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | }
class LSFile
{
static inherit LS_L;
static string cwd;
static array(string) argv;
static object ftpsession;
static array(string) output_queue = ({});
static int output_pos;
static string output_mode = "A";
|
97b910 | 2000-09-13 | Henrik Grubbström (Grubba) | | static mapping(string:array|object) stat_cache = ([]);
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | |
|
b1ca39 | 1999-10-29 | Henrik Grubbström (Grubba) | | static object conv;
|
802535 | 2001-01-22 | Henrik Grubbström (Grubba) | | static array|object stat_file(string long, RequestID|void session)
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | {
|
97b910 | 2000-09-13 | Henrik Grubbström (Grubba) | | array|object st = stat_cache[long];
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | if (zero_type(st)) {
if (!session) {
session = RequestID2(master_session);
session->method = "DIR";
}
|
c0f454 | 2001-02-19 | Jonas Wallden | | long = replace(long, "//", "/");
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | st = session->conf->stat_file(long, session);
stat_cache[long] = st;
}
return st;
}
static void output(string s)
{
if(stringp(s)) {
s = replace(s, "\n", "\r\n");
|
b1ca39 | 1999-10-29 | Henrik Grubbström (Grubba) | | if (conv) {
s = conv->feed(s)->drain();
}
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | }
output_queue += ({ s });
}
static string quote_non_print(string s)
{
return(replace(s, ({
"\000", "\001", "\002", "\003", "\004", "\005", "\006", "\007",
"\010", "\011", "\012", "\013", "\014", "\015", "\016", "\017",
"\200", "\201", "\202", "\203", "\204", "\205", "\206", "\207",
"\210", "\211", "\212", "\213", "\214", "\215", "\216", "\217",
"\177",
}), ({
"\\000", "\\001", "\\002", "\\003", "\\004", "\\005", "\\006", "\\007",
"\\010", "\\011", "\\012", "\\013", "\\014", "\\015", "\\016", "\\017",
"\\200", "\\201", "\\202", "\\203", "\\204", "\\205", "\\206", "\\207",
"\\210", "\\211", "\\212", "\\213", "\\214", "\\215", "\\216", "\\217",
"\\177",
})));
}
static string list_files(array(string) files, string|void dir)
{
dir = dir || cwd;
|
17e2b2 | 2001-06-15 | Johan Sundström | | DWRITE("FTP: LSFile->list_files(%O, \"%s\"\n", files, dir);
|
a47671 | 1997-10-20 | Henrik Grubbström (Grubba) | |
|
adc97b | 1997-10-09 | Henrik Grubbström (Grubba) | | if (!(flags & LS_FLAG_U)) {
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | if (flags & LS_FLAG_S) {
array(int) sizes = allocate(sizeof(files));
int i;
for (i=0; i < sizeof(files); i++) {
|
97b910 | 2000-09-13 | Henrik Grubbström (Grubba) | | array|object st = stat_file(combine_path(dir, files[i]));
|
340590 | 1997-10-04 | Henrik Grubbström (Grubba) | | if (st) {
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | sizes[i] = st[1];
|
340590 | 1997-10-04 | Henrik Grubbström (Grubba) | | } else {
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | |
files -= ({ files[i] });
|
340590 | 1997-10-04 | Henrik Grubbström (Grubba) | | }
}
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | sort(sizes, files);
} else if (flags & LS_FLAG_t) {
array(int) times = allocate(sizeof(files));
int i;
for (i=0; i < sizeof(files); i++) {
|
97b910 | 2000-09-13 | Henrik Grubbström (Grubba) | | array|object st = stat_file(combine_path(dir, files[i]));
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | if (st) {
times[i] = -st[-4];
} else {
files -= ({ files[i] });
}
|
340590 | 1997-10-04 | Henrik Grubbström (Grubba) | | }
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | sort(times, files);
|
340590 | 1997-10-04 | Henrik Grubbström (Grubba) | | } else {
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | sort(files);
}
if (flags & LS_FLAG_r) {
files = reverse(files);
|
031f32 | 1997-08-31 | Henrik Grubbström (Grubba) | | }
}
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | |
|
031f32 | 1997-08-31 | Henrik Grubbström (Grubba) | | string res = "";
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | int total;
foreach(files, string short) {
string long = combine_path(dir, short);
|
97b910 | 2000-09-13 | Henrik Grubbström (Grubba) | | array|object st = stat_file(long);
|
9ad0c6 | 1997-09-03 | Henrik Grubbström (Grubba) | | if (st) {
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | if (flags & LS_FLAG_Q) {
short = "\"" +
replace(short,
({ "\n", "\r", "\\", "\"", "\'", " " }),
({ "\\n", "\\r", "\\\\", "\\\"", "\\\'", "\\020" })) +
"\"";
}
|
9ad0c6 | 1997-09-03 | Henrik Grubbström (Grubba) | | if (flags & LS_FLAG_F) {
if (st[1] < 0) {
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | |
|
9ad0c6 | 1997-09-03 | Henrik Grubbström (Grubba) | | short += "/";
} else if (st[0] & 0111) {
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | |
|
9ad0c6 | 1997-09-03 | Henrik Grubbström (Grubba) | | short += "*";
}
}
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | int blocks = 1;
if (st[1] >= 0) {
blocks = (st[1] + 1023)/1024;
}
total += blocks;
if (flags & LS_FLAG_s) {
res += sprintf("%7d ", blocks);
|
84fb68 | 2000-02-03 | Per Hedbor | | }
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | if (flags & LS_FLAG_b) {
short = quote_non_print(short);
}
|
9ad0c6 | 1997-09-03 | Henrik Grubbström (Grubba) | | if (flags & LS_FLAG_l) {
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | res += ls_l(short, st);
|
9ad0c6 | 1997-09-03 | Henrik Grubbström (Grubba) | | } else {
res += short + "\n";
|
031f32 | 1997-08-31 | Henrik Grubbström (Grubba) | | }
}
}
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | switch (flags & (LS_FLAG_l|LS_FLAG_C|LS_FLAG_m)) {
case LS_FLAG_C:
res = sprintf("%#-79s\n", res);
break;
case LS_FLAG_m:
res = sprintf("%=-79s\n", (res/"\n")*", ");
break;
case LS_FLAG_l:
res = "total " + total + "\n" + res;
break;
default:
break;
|
031f32 | 1997-08-31 | Henrik Grubbström (Grubba) | | }
return(res);
}
|
c39ebd | 2000-12-28 | Martin Stjernholm | | #if constant (ADT.Stack)
static ADT.Stack dir_stack = ADT.Stack();
#else
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | static object(Stack.stack) dir_stack = Stack.stack();
|
c39ebd | 2000-12-28 | Martin Stjernholm | | #endif
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | static int name_directories;
|
031f32 | 1997-08-31 | Henrik Grubbström (Grubba) | |
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | static string fix_path(string s)
{
return(combine_path(cwd, s));
}
static void list_next_directory()
{
if (dir_stack->ptr) {
string short = dir_stack->pop();
string long = fix_path(short);
if ((!sizeof(long)) || (long[-1] != '/')) {
long += "/";
|
39c811 | 1997-11-06 | Henrik Grubbström (Grubba) | | }
|
802535 | 2001-01-22 | Henrik Grubbström (Grubba) | | RequestID session = RequestID2(master_session);
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | session->method = "DIR";
|
7af291 | 2000-02-02 | Henrik Grubbström (Grubba) | |
mixed err;
mapping(string:array) dir;
err = catch {
dir = session->conf->find_dir_stat(long, session);
};
if (err) {
|
17e2b2 | 2001-06-15 | Johan Sundström | | report_error("FTP: LSFile->list_next_directory(): "
"find_dir_stat(\"%s\") failed:\n"
"%s\n", long, describe_backtrace(err));
|
7af291 | 2000-02-02 | Henrik Grubbström (Grubba) | | }
|
031f32 | 1997-08-31 | Henrik Grubbström (Grubba) | |
|
17e2b2 | 2001-06-15 | Johan Sundström | | DWRITE("FTP: LSFile->list_next_directory(): "
"find_dir_stat(\"%s\") => %O\n", long, dir);
|
031f32 | 1997-08-31 | Henrik Grubbström (Grubba) | |
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | |
foreach(indices(dir||({})), string f) {
stat_cache[combine_path(long, f)] = dir[f];
}
if ((flags & LS_FLAG_a) &&
(long != "/")) {
if (dir) {
dir[".."] = stat_file(combine_path(long,"../"));
} else {
dir = ([ "..":stat_file(combine_path(long,"../")) ]);
|
031f32 | 1997-08-31 | Henrik Grubbström (Grubba) | | }
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | }
string listing = "";
if (dir && sizeof(dir)) {
if (!(flags & LS_FLAG_A)) {
foreach(indices(dir), string f) {
if (sizeof(f) && (f[0] == '.')) {
m_delete(dir, f);
|
a47671 | 1997-10-20 | Henrik Grubbström (Grubba) | | }
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | }
} else if (!(flags & LS_FLAG_a)) {
foreach(indices(dir), string f) {
if ((< ".", ".." >)[f]) {
m_delete(dir, f);
|
a47671 | 1997-10-20 | Henrik Grubbström (Grubba) | | }
|
c25057 | 1997-09-07 | Henrik Grubbström (Grubba) | | }
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | }
if (flags & LS_FLAG_R) {
foreach(indices(dir), string f) {
if (!((<".","..">)[f])) {
array(mixed) st = dir[f];
if (st && (st[1] < 0)) {
if (short[-1] == '/') {
dir_stack->push(short + f);
} else {
dir_stack->push(short + "/" + f);
|
031f32 | 1997-08-31 | Henrik Grubbström (Grubba) | | }
}
}
}
}
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | if (sizeof(dir)) {
listing = list_files(indices(dir), long);
} else if (flags & LS_FLAG_l) {
listing = "total 0\n";
|
031f32 | 1997-08-31 | Henrik Grubbström (Grubba) | | }
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | } else {
DWRITE("FTP: LSFile->list_next_directory(): NO FILES!\n");
if (flags & LS_FLAG_l) {
listing = "total 0\n";
|
35e1bf | 1997-10-25 | Henrik Grubbström (Grubba) | | }
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | }
if (name_directories) {
listing = "\n" + short + ":\n" + listing;
}
if (listing != "") {
output(listing);
}
session = RequestID2(master_session);
session->method = "LIST";
session->not_query = long;
session->conf->log(([ "error":200, "len":sizeof(listing) ]), session);
}
if (!dir_stack->ptr) {
output(0);
} else {
name_directories = 1;
}
}
void set_blocking()
{
}
int query_fd()
{
return -1;
}
static mixed id;
void set_id(mixed i)
{
id = i;
}
string read(int|void n, int|void not_all)
{
|
17e2b2 | 2001-06-15 | Johan Sundström | | DWRITE("FTP: LSFile->read(%d, %d)\n", n, not_all);
|
031f32 | 1997-08-31 | Henrik Grubbström (Grubba) | |
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | ftpsession->touch_me();
while(sizeof(output_queue) <= output_pos) {
output_queue = ({});
output_pos = 0;
list_next_directory();
}
string s = output_queue[output_pos];
if (s) {
if (n && (n < sizeof(s))) {
output_queue[output_pos] = s[n..];
s = s[..n-1];
|
c25057 | 1997-09-07 | Henrik Grubbström (Grubba) | | } else {
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | output_queue[output_pos++] = 0;
|
c25057 | 1997-09-07 | Henrik Grubbström (Grubba) | | }
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | return s;
} else {
master_session->file = 0;
return "";
|
031f32 | 1997-08-31 | Henrik Grubbström (Grubba) | | }
|
b1fca0 | 1996-11-12 | Per Hedbor | | }
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | void create(string cwd_, array(string) argv_, int flags_,
object session_, string output_mode_, object ftpsession_)
|
031f32 | 1997-08-31 | Henrik Grubbström (Grubba) | | {
|
17e2b2 | 2001-06-15 | Johan Sundström | | DWRITE("FTP: LSFile(\"%s\", %O, %08x, X, \"%s\")\n",
cwd_, argv_, flags_, output_mode_);
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | |
::create(session_, flags_);
cwd = cwd_;
argv = argv_;
output_mode = output_mode_;
ftpsession = ftpsession_;
|
b1ca39 | 1999-10-29 | Henrik Grubbström (Grubba) | |
if (output_mode == "E") {
conv = Locale.Charset.encoder("EBCDIC-US", "");
}
|
abdff2 | 1999-12-27 | Martin Nilsson | |
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | array(string) files = allocate(sizeof(argv));
int n_files;
foreach(argv, string short) {
|
802535 | 2001-01-22 | Henrik Grubbström (Grubba) | | RequestID session = RequestID2(master_session);
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | session->method = "LIST";
string long = fix_path(short);
|
97b910 | 2000-09-13 | Henrik Grubbström (Grubba) | | array|object st = stat_file(long, session);
|
e1da69 | 2000-01-05 | Martin Stjernholm | | if (st) {
|
abdff2 | 1999-12-27 | Martin Nilsson | | if ((< -2, -3 >)[st[1]] &&
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | (!(flags & LS_FLAG_d))) {
|
abdff2 | 1999-12-27 | Martin Nilsson | |
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | dir_stack->push(short);
} else {
files[n_files++] = short;
|
031f32 | 1997-08-31 | Henrik Grubbström (Grubba) | | }
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | } else {
output(short + ": not found\n");
session->conf->log(([ "error":404 ]), session);
|
031f32 | 1997-08-31 | Henrik Grubbström (Grubba) | | }
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | }
|
b1fca0 | 1996-11-12 | Per Hedbor | |
|
17e2b2 | 2001-06-15 | Johan Sundström | | DWRITE("FTP: LSFile: %d files, %d directories\n",
n_files, dir_stack->ptr);
|
4fc7fe | 1998-04-21 | Henrik Grubbström (Grubba) | |
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | if (n_files) {
if (n_files < sizeof(files)) {
files -= ({ 0 });
|
c25057 | 1997-09-07 | Henrik Grubbström (Grubba) | | }
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | string s = list_files(files, cwd);
output(s);
|
802535 | 2001-01-22 | Henrik Grubbström (Grubba) | | RequestID session = RequestID2(master_session);
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | session->not_query = Array.map(files, fix_path) * " ";
session->method = "LIST";
session->conf->log(([ "error":200, "len":sizeof(s) ]), session);
}
if (dir_stack->ptr) {
name_directories = dir_stack->ptr &&
((dir_stack->ptr > 1) || n_files);
list_next_directory();
} else {
output(0);
}
}
}
class TelnetSession {
static object fd;
static object conf;
static private mapping cb;
static private mixed id;
static private function(mixed|void:string) write_cb;
static private function(mixed, string:void) read_cb;
static private function(mixed|void:void) close_cb;
static private constant TelnetCodes = ([
236:"EOF",
237:"SUSP",
238:"ABORT",
239:"EOR",
240:"SE",
241:"NOP",
242:"DM",
243:"BRK",
244:"IP",
245:"AO",
246:"AYT",
247:"EC",
248:"EL",
249:"GA",
250:"SB",
251:"WILL",
252:"WON'T",
253:"DO",
254:"DON'T",
255:"IAC",
]);
static private void got_data(mixed ignored, string s);
static private void send_data();
static private void got_oob(mixed ignored, string s);
void set_write_callback(function(mixed|void:string) w_cb)
{
if (fd) {
write_cb = w_cb;
fd->set_nonblocking(got_data, w_cb && send_data, close_cb, got_oob);
}
}
static private string to_send = "";
static private void send(string s)
{
to_send += s;
}
static private void send_data()
{
if (!sizeof(to_send)) {
to_send = write_cb(id);
}
if (fd) {
if (!to_send) {
BACKEND_CLOSE(fd);
} else if (sizeof(to_send)) {
int n = fd->write(to_send);
if (n >= 0) {
conf->hsent += n;
|
84fb68 | 2000-02-03 | Per Hedbor | |
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | to_send = to_send[n..];
if (sizeof(to_send)) {
fd->set_write_callback(send_data);
}
} else {
|
17e2b2 | 2001-06-15 | Johan Sundström | | DWRITE("TELNET: write failed: errno:%d\n", fd->errno());
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | BACKEND_CLOSE(fd);
}
} else {
fd->set_write_callback(0);
|
41c7fe | 1998-04-13 | Henrik Grubbström (Grubba) | |
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | report_warning("FTP2: Write callback with nothing to send.\n");
|
c25057 | 1997-09-07 | Henrik Grubbström (Grubba) | | }
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | } else {
report_error("FTP2: Write callback with no fd.\n");
destruct();
}
}
static private mapping(string:function) default_cb = ([
"BRK":lambda() {
destruct();
throw(0);
},
"AYT":lambda() {
send("\377\361");
},
"WILL":lambda(int code) {
send(sprintf("\377\376%c", code));
},
"DO":lambda(int code) {
send(sprintf("\377\374%c", code));
},
]);
static private int sync = 0;
static private void got_oob(mixed ignored, string s)
{
|
17e2b2 | 2001-06-15 | Johan Sundström | | DWRITE("TELNET: got_oob(\"%s\")\n", s);
|
b1fca0 | 1996-11-12 | Per Hedbor | |
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | sync = sync || (s == "\377");
if (cb["URG"]) {
cb["URG"](id, s);
|
031f32 | 1997-08-31 | Henrik Grubbström (Grubba) | | }
}
|
b1fca0 | 1996-11-12 | Per Hedbor | |
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | static private string rest = "";
static private void got_data(mixed ignored, string s)
|
031f32 | 1997-08-31 | Henrik Grubbström (Grubba) | | {
|
17e2b2 | 2001-06-15 | Johan Sundström | | DWRITE("TELNET: got_data(\"%s\")\n", s);
|
b1fca0 | 1996-11-12 | Per Hedbor | |
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | if (sizeof(s) && (s[0] == 242)) {
DWRITE("TELNET: Data Mark\n");
s = s[1..];
sync = 0;
}
|
b1fca0 | 1996-11-12 | Per Hedbor | |
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | |
|
b1fca0 | 1996-11-12 | Per Hedbor | |
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | array lines = s/"\r\n";
|
031f32 | 1997-08-31 | Henrik Grubbström (Grubba) | |
|
338ab7 | 2001-09-11 | Henrik Grubbström (Grubba) | |
s = sprintf("string(%d bytes)", sizeof(s));
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | int lineno;
for(lineno = 0; lineno < sizeof(lines); lineno++) {
string line = lines[lineno];
|
98ac72 | 2002-10-02 | Martin Nilsson | | if (has_value(line, "\377")) {
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | array a = line / "\377";
|
031f32 | 1997-08-31 | Henrik Grubbström (Grubba) | |
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | string parsed_line = a[0];
|
031f32 | 1997-08-31 | Henrik Grubbström (Grubba) | | int i;
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | for (i=1; i < sizeof(a); i++) {
string part = a[i];
if (sizeof(part)) {
string name = TelnetCodes[part[0]];
|
17e2b2 | 2001-06-15 | Johan Sundström | | DWRITE("TELNET: Code %s\n", name || "Unknown");
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | |
int j;
function fun;
switch (name) {
case 0:
break;
default:
if (fun = (cb[name] || default_cb[name])) {
mixed err = catch {
fun();
};
if (err) {
throw(err);
} else if (!zero_type(err)) {
return;
|
031f32 | 1997-08-31 | Henrik Grubbström (Grubba) | | }
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | }
a[i] = a[i][1..];
break;
case "EC":
for (j=i; j--;) {
if (sizeof(a[j])) {
a[j] = a[j][..sizeof(a[j])-2];
break;
|
031f32 | 1997-08-31 | Henrik Grubbström (Grubba) | | }
}
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | a[i] = a[i][1..];
break;
case "EL":
for (j=0; j < i; j++) {
a[j] = "";
}
a[i] = a[i][1..];
break;
case "WILL":
case "WON'T":
case "DO":
case "DON'T":
if (fun = (cb[name] || default_cb[name])) {
fun(a[i][1]);
|
031f32 | 1997-08-31 | Henrik Grubbström (Grubba) | | }
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | a[i] = a[i][2..];
break;
case "DM":
if (sync) {
for (j=0; j < i; j++) {
a[j] = "";
}
}
a[i] = a[i][1..];
sync = 0;
break;
|
031f32 | 1997-08-31 | Henrik Grubbström (Grubba) | | }
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | } else {
a[i] = "\377";
i++;
|
031f32 | 1997-08-31 | Henrik Grubbström (Grubba) | | }
}
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | line = a * "";
|
031f32 | 1997-08-31 | Henrik Grubbström (Grubba) | | }
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | if (!lineno) {
line = rest + line;
}
if (lineno < (sizeof(lines)-1)) {
if ((!sync) && read_cb) {
|
17e2b2 | 2001-06-15 | Johan Sundström | | DWRITE("TELNET: Calling read_callback(X, \"%s\")\n", line);
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | read_cb(id, line);
}
} else {
|
17e2b2 | 2001-06-15 | Johan Sundström | | DWRITE("TELNET: Partial line is \"%s\"\n", line);
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | rest = line;
|
031f32 | 1997-08-31 | Henrik Grubbström (Grubba) | | }
|
5155b5 | 1997-09-03 | Henrik Grubbström (Grubba) | | }
|
7a87c7 | 1997-09-03 | Henrik Grubbström (Grubba) | | }
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | void create(object f,
function(mixed,string:void) r_cb,
function(mixed|void:string) w_cb,
function(mixed|void:void) c_cb,
mapping callbacks, mixed|void new_id)
|
031f32 | 1997-08-31 | Henrik Grubbström (Grubba) | | {
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | fd = f;
cb = callbacks;
|
031f32 | 1997-08-31 | Henrik Grubbström (Grubba) | |
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | read_cb = r_cb;
write_cb = w_cb;
close_cb = c_cb;
id = new_id;
|
031f32 | 1997-08-31 | Henrik Grubbström (Grubba) | |
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | fd->set_nonblocking(got_data, w_cb && send_data, close_cb, got_oob);
|
031f32 | 1997-08-31 | Henrik Grubbström (Grubba) | | }
};
|
b1fca0 | 1996-11-12 | Per Hedbor | |
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | class FTPSession
|
2d3ff5 | 1997-04-10 | Marcus Comstedt | | {
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | |
|
2d3ff5 | 1997-04-10 | Marcus Comstedt | |
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | inherit TelnetSession;
inherit "roxenlib";
static private constant cmd_help = ([
"CLNT":"<sp> <client-name> <sp> <client-version> "
"[<sp> <optional platform info>] (Set client name)",
"FEAT":"(Feature list)",
"MDTM":"<sp> path-name (Modification time)",
"SIZE":"<sp> path-name (Size)",
"MLST":"<sp> path-name (Machine Processing List File)",
"MLSD":"<sp> path-name (Machine Processing List Directory)",
"OPTS":"<sp> command <sp> options (Set Command-specific Options)",
|
316375 | 2001-03-13 | Henrik Grubbström (Grubba) | |
"EPRT":"<sp> <d>net-prt<d>net-addr<d>tcp-port<d> (Extended Address Port)",
"EPSV":"[<sp> net-prt|ALL] (Extended Address Passive Mode)",
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | |
|
316375 | 2001-03-13 | Henrik Grubbström (Grubba) | | "LPRT":"<sp> <long-host-port> (Long Port)",
"LPSV":"(Long Passive)",
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | |
"USER":"<sp> username (Change user)",
"PASS":"<sp> password (Change password)",
"ACCT":"<sp> <account-information> (Account)",
"CWD":"[ <sp> directory-name ] (Change working directory)",
"CDUP":"(Change to parent directory)",
"SMNT":"<sp> <pathname> (Structure mount)",
"REIN":"(Reinitialize)",
"QUIT":"(Terminate service)",
"PORT":"<sp> b0, b1, b2, b3, b4 (Set port IP and number)",
"PASV":"(Set server in passive mode)",
"TYPE":"<sp> [ A | E | I | L ] (Ascii, Ebcdic, Image, Local)",
"STRU":"<sp> <structure-code> (File structure)",
"MODE":"<sp> <mode-code> (Transfer mode)",
"ALLO":"<sp> <decimal-integer> [<sp> R <sp> <decimal-integer>]"
" (Allocate space for file)",
"REST":"<sp> marker (Set restart marker)",
"STOR":"<sp> file-name (Store file)",
"STOU":"(Store file with unique name)",
"RETR":"<sp> file-name (Retreive file)",
|
0900e2 | 2001-08-22 | Henrik Grubbström (Grubba) | | "LIST":"[ <sp> <pathname> ] (List directory)",
"NLST":"[ <sp> <pathname> ] (List directory)",
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | "APPE":"<sp> <pathname> (Append file)",
"RNFR":"<sp> <pathname> (Rename from)",
"RNTO":"<sp> <pathname> (Rename to)",
"DELE":"<sp> file-name (Delete file)",
"RMD":"<sp> <pathname> (Remove directory)",
"MKD":"<sp> <pathname> (Make directory)",
"PWD":"(Return current directory)",
"ABOR":"(Abort current transmission)",
"SYST":"(Get type of operating system)",
|
0900e2 | 2001-08-22 | Henrik Grubbström (Grubba) | | "STAT":"[ <sp> <pathname> ] (Status for server/file)",
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | "HELP":"[ <sp> <string> ] (Give help)",
"SITE":"<sp> <string> (Site parameters)",
"NOOP":"(No operation)",
|
abdff2 | 1999-12-27 | Martin Nilsson | |
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | |
"XMKD":"<sp> path-name (Make directory)",
"XRMD":"<sp> path-name (Remove directory)",
"XPWD":"(Return current directory)",
"XCWD":"[ <sp> directory-name ] (Change working directory)",
"XCUP":"(Change to parent directory)",
"MAIL":"[<sp> <recipient name>] (Mail to user)",
"MSND":"[<sp> <recipient name>] (Mail send to terminal)",
"MSOM":"[<sp> <recipient name>] (Mail send to terminal or mailbox)",
"MSAM":"[<sp> <recipient name>] (Mail send to terminal and mailbox)",
"MRSQ":"[<sp> <scheme>] (Mail recipient scheme question)",
"MRCP":"<sp> <recipient name> (Mail recipient)",
"XRSQ":"[<sp> <scheme>] (Scheme selection)",
"XRCP":"<sp> <recipient name> (Recipient specification)",
"XSEN":"[<sp> <recipient name>] (Send to terminal)",
"XSEM":"[<sp> <recipient name>] (Send, mail if can\'t)",
"XMAS":"[<sp> <recipient name>] (Mail and send)",
"BYE":"(Logout)",
"BYTE":"<sp> <bits> (Byte size)",
"SOCK":"<sp> host-socket (Data socket)",
"MLFL":"(Mail file)",
]);
static private constant site_help = ([
"CHMOD":"<sp> mode <sp> file",
"UMASK":"<sp> mode",
"PRESTATE":"<sp> prestate",
]);
|
abdff2 | 1999-12-27 | Martin Nilsson | |
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | static private constant modes = ([
"A":"ASCII",
"E":"EBCDIC",
"I":"BINARY",
"L":"LOCAL",
]);
|
2d3ff5 | 1997-04-10 | Marcus Comstedt | |
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | static private int time_touch = time();
|
b1fca0 | 1996-11-12 | Per Hedbor | |
|
8ca111 | 2000-05-29 | Henrik Grubbström (Grubba) | | static private object(ADT.Queue) to_send = ADT.Queue();
|
240816 | 1997-05-07 | Henrik Grubbström (Grubba) | |
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | static private int end_marker = 0;
|
b1fca0 | 1996-11-12 | Per Hedbor | |
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | void touch_me()
|
b1fca0 | 1996-11-12 | Per Hedbor | | {
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | time_touch = time();
|
b1fca0 | 1996-11-12 | Per Hedbor | | }
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | |
static private string write_cb()
|
53e868 | 1997-10-05 | Per Hedbor | | {
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | touch_me();
|
b1fca0 | 1996-11-12 | Per Hedbor | |
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | if (to_send->is_empty()) {
|
0a34b1 | 1997-03-13 | Henrik Grubbström (Grubba) | |
|
17e2b2 | 2001-06-15 | Johan Sundström | | DWRITE("FTP2: write_cb(): Empty send queue.\n");
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | |
::set_write_callback(0);
if (end_marker) {
|
17e2b2 | 2001-06-15 | Johan Sundström | | DWRITE("FTP2: write_cb(): Sending EOF.\n");
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | return(0);
}
|
17e2b2 | 2001-06-15 | Johan Sundström | | DWRITE("FTP2: write_cb(): Sending \"\"\n");
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | return("");
} else {
string s = to_send->get();
|
d16b3e | 1997-03-27 | Henrik Grubbström (Grubba) | |
|
17e2b2 | 2001-06-15 | Johan Sundström | | DWRITE("FTP2: write_cb(): Sending \"%s\"\n", s);
|
d16b3e | 1997-03-27 | Henrik Grubbström (Grubba) | |
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | if ((to_send->is_empty()) && (!end_marker)) {
::set_write_callback(0);
} else {
::set_write_callback(write_cb);
}
return(s);
}
}
|
a36f05 | 1997-11-27 | Henrik Grubbström (Grubba) | |
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | void send(int code, array(string) data, int|void enumerate_all)
|
d16b3e | 1997-03-27 | Henrik Grubbström (Grubba) | | {
|
17e2b2 | 2001-06-15 | Johan Sundström | | DWRITE("FTP2: send(%d, %O)\n", code, data);
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | |
if (!data || end_marker) {
end_marker = 1;
::set_write_callback(write_cb);
|
d16b3e | 1997-03-27 | Henrik Grubbström (Grubba) | | return;
}
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | |
string s;
int i;
if (sizeof(data) > 1) {
data[0] = sprintf("%03d-%s\r\n", code, data[i]);
for (i = sizeof(data)-1; --i; ) {
if (enumerate_all) {
data[i] = sprintf("%03d-%s\r\n", code, data[i]);
} else {
data[i] = " " + data[i] + "\r\n";
}
}
}
data[sizeof(data)-1] = sprintf("%03d %s\r\n", code, data[sizeof(data)-1]);
s = data * "";
if (sizeof(s)) {
if (to_send->is_empty()) {
to_send->put(s);
::set_write_callback(write_cb);
} else {
to_send->put(s);
}
} else {
|
17e2b2 | 2001-06-15 | Johan Sundström | | DWRITE("FTP2: send(): Nothing to send!\n");
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | }
|
d16b3e | 1997-03-27 | Henrik Grubbström (Grubba) | | }
|
802535 | 2001-01-22 | Henrik Grubbström (Grubba) | | static private RequestID master_session;
|
d16b3e | 1997-03-27 | Henrik Grubbström (Grubba) | |
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | static private string dataport_addr;
static private int dataport_port;
|
d16b3e | 1997-03-27 | Henrik Grubbström (Grubba) | |
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | static private string mode = "A";
|
ad72bd | 1997-04-09 | Marcus Comstedt | |
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | static private string cwd = "/";
|
ad72bd | 1997-04-09 | Marcus Comstedt | |
|
802535 | 2001-01-22 | Henrik Grubbström (Grubba) | | static private User auth_user;
|
d90ab7 | 2002-10-24 | Martin Nilsson | |
|
802535 | 2001-01-22 | Henrik Grubbström (Grubba) | |
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | static private string user;
static private string password;
static private int logged_in;
|
ad72bd | 1997-04-09 | Marcus Comstedt | |
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | static private object curr_pipe;
static private int restart_point;
|
ad72bd | 1997-04-09 | Marcus Comstedt | |
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | static private multiset|int allowed_shells = 0;
string local_addr;
int local_port;
|
b0132d | 1999-10-08 | Henrik Grubbström (Grubba) | |
|
6abda8 | 2000-08-04 | Martin Stjernholm | | roxen.Protocol port_obj;
|
b0132d | 1999-10-08 | Henrik Grubbström (Grubba) | |
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | |
static private int check_shell(string shell)
|
94d84c | 1997-08-29 | Marcus Comstedt | | {
|
b0132d | 1999-10-08 | Henrik Grubbström (Grubba) | |
if (port_obj->query_option("shells") != "") {
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | |
if (!allowed_shells) {
object(Stdio.File) file = Stdio.File();
|
b0132d | 1999-10-08 | Henrik Grubbström (Grubba) | | if (file->open(port_obj->query_option("shells"), "r")) {
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | allowed_shells =
aggregate_multiset(@(Array.map(file->read(0x7fffffff)/"\n",
lambda(string line) {
return(((((line/"#")[0])/"") -
({" ", "\t"}))*"");
} )-({""})));
|
17e2b2 | 2001-06-15 | Johan Sundström | | DWRITE("ftp.pike: allowed_shells: %O\n", allowed_shells);
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | } else {
|
17e2b2 | 2001-06-15 | Johan Sundström | | report_debug("ftp.pike: Failed to open shell database (%O)\n",
port_obj->query_option("shells"));
return 0;
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | }
}
return(allowed_shells[shell]);
}
return 1;
|
94d84c | 1997-08-29 | Marcus Comstedt | | }
|
ad72bd | 1997-04-09 | Marcus Comstedt | |
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | static private string fix_path(string s)
|
ad72bd | 1997-04-09 | Marcus Comstedt | | {
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | if (!sizeof(s)) {
if (cwd[-1] == '/') {
return(cwd);
} else {
return(cwd + "/");
}
} else if (s[0] == '~') {
return(combine_path("/", s));
} else if (s[0] == '/') {
return(simplify_path(s));
} else {
return(combine_path(cwd, s));
|
ad72bd | 1997-04-09 | Marcus Comstedt | | }
}
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | |
static private object pasv_port;
static private function(object, mixed:void) pasv_callback;
static private mixed pasv_args;
static private array(object) pasv_accepted = ({});
void pasv_accept_callback(mixed id)
|
94d84c | 1997-08-29 | Marcus Comstedt | | {
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | touch_me();
if(pasv_port) {
object fd = pasv_port->accept();
if(fd) {
array(string) remote = (fd->query_address()||"? ?")/" ";
#ifdef FD_DEBUG
mark_fd(fd->query_fd(),
"ftp communication: -> "+remote[0]+":"+remote[1]);
#endif
if(pasv_callback) {
|
280ffa | 1999-10-29 | Henrik Grubbström (Grubba) | | pasv_callback(fd, "", @pasv_args);
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | pasv_callback = 0;
} else {
pasv_accepted += ({ fd });
}
}
}
|
94d84c | 1997-08-29 | Marcus Comstedt | | }
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | static private void ftp_async_accept(function(object,mixed ...:void) fun,
mixed ... args)
|
94d84c | 1997-08-29 | Marcus Comstedt | | {
|
17e2b2 | 2001-06-15 | Johan Sundström | | DWRITE("FTP: async_accept(%O, %@O)...\n", fun, args);
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | touch_me();
|
94d84c | 1997-08-29 | Marcus Comstedt | |
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | if (sizeof(pasv_accepted)) {
|
280ffa | 1999-10-29 | Henrik Grubbström (Grubba) | | fun(pasv_accepted[0], "", @args);
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | pasv_accepted = pasv_accepted[1..];
} else {
pasv_callback = fun;
pasv_args = args;
}
|
94d84c | 1997-08-29 | Marcus Comstedt | | }
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | |
|
94d84c | 1997-08-29 | Marcus Comstedt | |
|
280ffa | 1999-10-29 | Henrik Grubbström (Grubba) | | static private void ftp_async_connect(function(object,string,mixed ...:void) fun,
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | mixed ... args)
|
ad72bd | 1997-04-09 | Marcus Comstedt | | {
|
17e2b2 | 2001-06-15 | Johan Sundström | | DWRITE("FTP: async_connect(%O, %@O)...\n", fun, args);
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | |
|
280ffa | 1999-10-29 | Henrik Grubbström (Grubba) | |
if (!dataport_addr) {
DWRITE("FTP: No dataport specified.\n");
|
7a8c5b | 2001-03-03 | Henrik Grubbström (Grubba) | | fun(0, "", @args);
|
280ffa | 1999-10-29 | Henrik Grubbström (Grubba) | | return;
}
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | object(Stdio.File) f = Stdio.File();
|
23f42f | 1999-10-28 | Henrik Grubbström (Grubba) | |
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | object privs;
|
6cacde | 2001-10-18 | Martin Stjernholm | | if(local_port-1 < 1024 && geteuid())
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | privs = Privs("FTP: Opening the data connection on " + local_addr +
":" + (local_port-1) + ".");
if(!f->open_socket(local_port-1, local_addr))
{
privs = 0;
|
17e2b2 | 2001-06-15 | Johan Sundström | | DWRITE("FTP: socket(%d, %O) failed. Trying with any port.\n",
local_port-1, local_addr);
|
abdff2 | 1999-12-27 | Martin Nilsson | |
|
cff0e1 | 1999-10-28 | Henrik Grubbström (Grubba) | | if(!f->open_socket(0, local_addr))
{
|
17e2b2 | 2001-06-15 | Johan Sundström | | DWRITE("FTP: socket(0, %O) failed. "
"Trying with any port, any ip.\n", local_addr);
|
cff0e1 | 1999-10-28 | Henrik Grubbström (Grubba) | | if (!f->open_socket()) {
DWRITE("FTP: socket() failed. Out of sockets?\n");
|
280ffa | 1999-10-29 | Henrik Grubbström (Grubba) | | fun(0, 0, @args);
|
cff0e1 | 1999-10-28 | Henrik Grubbström (Grubba) | | destruct(f);
return;
}
|
ad72bd | 1997-04-09 | Marcus Comstedt | | }
}
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | privs = 0;
|
280ffa | 1999-10-29 | Henrik Grubbström (Grubba) | | f->set_nonblocking(lambda(mixed ignored, string data) {
DWRITE("FTP: async_connect ok. Got data.\n");
f->set_nonblocking(0,0,0);
fun(f, data, @args);
},
lambda(mixed ignored) {
DWRITE("FTP: async_connect ok.\n");
f->set_nonblocking(0,0,0);
fun(f, "", @args);
},
lambda(mixed ignored) {
DWRITE("FTP: connect_and_send failed\n");
destruct(f);
fun(0, 0, @args);
});
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | |
#ifdef FD_DEBUG
|
280ffa | 1999-10-29 | Henrik Grubbström (Grubba) | | mark_fd(f->query_fd(), sprintf("ftp communication: %s:%d -> %s:%d",
local_addr, local_port - 1,
dataport_addr, dataport_port));
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | #endif
|
280ffa | 1999-10-29 | Henrik Grubbström (Grubba) | | if(catch(f->connect(dataport_addr, dataport_port))) {
DWRITE("FTP: Illegal internet address in connect in async comm.\n");
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | destruct(f);
|
280ffa | 1999-10-29 | Henrik Grubbström (Grubba) | | fun(0, 0, @args);
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | return;
}
|
ad72bd | 1997-04-09 | Marcus Comstedt | | }
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | |
|
b6802c | 2002-07-04 | Per Hedbor | | static private void send_done_callback( object fd, object session,
int amount )
|
ad72bd | 1997-04-09 | Marcus Comstedt | | {
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | DWRITE("FTP: send_done_callback()\n");
|
ad72bd | 1997-04-09 | Marcus Comstedt | |
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | if(fd)
{
if (fd->set_blocking) {
fd->set_blocking();
}
BACKEND_CLOSE(fd);
}
curr_pipe = 0;
|
ad72bd | 1997-04-09 | Marcus Comstedt | |
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | if (session && session->file) {
|
b6802c | 2002-07-04 | Per Hedbor | | session->file->len = amount;
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | session->conf->log(session->file, session);
session->file = 0;
}
send(226, ({ "Transfer complete." }));
|
ad72bd | 1997-04-09 | Marcus Comstedt | | }
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | |
|
97b910 | 2000-09-13 | Henrik Grubbström (Grubba) | | static private mapping|array|object stat_file(string fname,
object|void session)
|
ad72bd | 1997-04-09 | Marcus Comstedt | | {
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | mapping file;
if (!session) {
session = RequestID2(master_session);
session->method = "STAT";
}
|
ad72bd | 1997-04-09 | Marcus Comstedt | |
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | session->not_query = fname;
|
ad72bd | 1997-04-09 | Marcus Comstedt | |
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | foreach(conf->first_modules(), function funp) {
if ((file = funp(session))) {
|
ad72bd | 1997-04-09 | Marcus Comstedt | | break;
}
}
|
b1fca0 | 1996-11-12 | Per Hedbor | |
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | if (!file) {
|
c0f454 | 2001-02-19 | Jonas Wallden | | fname = replace(fname, "//", "/");
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | return(conf->stat_file(fname, session));
|
b134ed | 1997-06-12 | Marcus Comstedt | | }
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | return(file);
}
|
240816 | 1997-05-07 | Henrik Grubbström (Grubba) | |
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | static private int expect_argument(string cmd, string args)
|
b1fca0 | 1996-11-12 | Per Hedbor | | {
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | if ((< "", 0 >)[args]) {
send(504, ({ sprintf("Syntax: %s %s", cmd, cmd_help[cmd]) }));
return 0;
|
6ae0d9 | 1997-03-13 | Henrik Grubbström (Grubba) | | }
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | return 1;
|
b1fca0 | 1996-11-12 | Per Hedbor | | }
|
240816 | 1997-05-07 | Henrik Grubbström (Grubba) | |
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | static private void send_error(string cmd, string f, mapping file,
object session)
{
switch(file && file->error) {
case 301:
case 302:
if (file->extra_heads && file->extra_heads->Location) {
send(504, ({ sprintf("'%s': %s: Redirect to %O.",
cmd, f, file->extra_heads->Location) }));
} else {
send(504, ({ sprintf("'%s': %s: Redirect.", cmd, f) }));
}
break;
|
8b094e | 1997-05-26 | Henrik Grubbström (Grubba) | | case 401:
case 403:
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | send(530, ({ sprintf("'%s': %s: Access denied.",
cmd, f) }));
|
8b094e | 1997-05-26 | Henrik Grubbström (Grubba) | | break;
|
ad72bd | 1997-04-09 | Marcus Comstedt | | case 405:
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | send(530, ({ sprintf("'%s': %s: Method not allowed.",
cmd, f) }));
break;
case 500:
send(451, ({ sprintf("'%s': Requested action aborted: "
"local error in processing.", cmd) }));
|
ad72bd | 1997-04-09 | Marcus Comstedt | | break;
default:
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | if (!file) {
file = ([ "error":404 ]);
}
send(550, ({ sprintf("'%s': %s: No such file or directory.",
cmd, f) }));
|
8b094e | 1997-05-26 | Henrik Grubbström (Grubba) | | break;
|
ad72bd | 1997-04-09 | Marcus Comstedt | | }
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | session->conf->log(file, session);
|
3d7af3 | 1998-04-03 | Johan Schön | | }
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | static private int open_file(string fname, object session, string cmd)
{
|
97b910 | 2000-09-13 | Henrik Grubbström (Grubba) | | object|array|mapping file;
|
47352e | 1997-08-13 | Henrik Grubbström (Grubba) | |
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | file = stat_file(fname, session);
|
abdff2 | 1999-12-27 | Martin Nilsson | |
|
97b910 | 2000-09-13 | Henrik Grubbström (Grubba) | | if (objectp(file) || arrayp(file)) {
array|object st = file;
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | file = 0;
|
cf1f18 | 2001-09-11 | Henrik Grubbström (Grubba) | | if (st && (st[1] < 0) && !((<"RMD", "XRMD", "CHMOD">)[cmd])) {
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | send(550, ({ sprintf("%s: not a plain file.", fname) }));
return 0;
}
mixed err;
if ((err = catch(file = conf->get_file(session)))) {
|
ba093e | 1999-12-06 | Martin Stjernholm | | report_error("FTP: Error opening file \"%s\"\n"
"%s\n", fname, describe_backtrace(err));
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | send(550, ({ sprintf("%s: Error, can't open file.", fname) }));
return 0;
}
|
cf1f18 | 2001-09-11 | Henrik Grubbström (Grubba) | | } else if ((< "STOR", "APPE", "MKD", "XMKD", "MOVE" >)[cmd]) {
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | mixed err;
if ((err = catch(file = conf->get_file(session)))) {
|
ba093e | 1999-12-06 | Martin Stjernholm | | report_error("FTP: Error opening file \"%s\"\n"
"%s\n", fname, describe_backtrace(err));
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | send(550, ({ sprintf("%s: Error, can't open file.", fname) }));
return 0;
}
}
|
7a87c7 | 1997-09-03 | Henrik Grubbström (Grubba) | |
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | session->file = file;
|
a2a719 | 1997-10-03 | Henrik Grubbström (Grubba) | |
|
5608a4 | 1999-05-19 | Henrik Grubbström (Grubba) | | if (!file || (file->error && (file->error >= 300))) {
|
17e2b2 | 2001-06-15 | Johan Sundström | | DWRITE("FTP: open_file(\"%s\") failed: %O\n", fname, file);
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | send_error(cmd, fname, file, session);
return 0;
}
|
980b33 | 1998-03-23 | Henrik Grubbström (Grubba) | |
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | file->full_path = fname;
file->request_start = time(1);
|
c175b9 | 1998-03-21 | Henrik Grubbström (Grubba) | |
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | if (!file->len) {
if (file->data) {
file->len = sizeof(file->data);
}
if (objectp(file->file)) {
file->len += file->file->stat()[1];
|
215923 | 1998-03-23 | Henrik Grubbström (Grubba) | | }
}
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | return 1;
|
7c8fd5 | 1998-03-23 | Henrik Grubbström (Grubba) | | }
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | |
|
280ffa | 1999-10-29 | Henrik Grubbström (Grubba) | | static private void connected_to_send(object fd, string ignored,
mapping file, object session)
|
b1fca0 | 1996-11-12 | Per Hedbor | | {
|
17e2b2 | 2001-06-15 | Johan Sundström | | DWRITE("FTP: connected_to_send(X, %O, %O, X)\n", ignored, file);
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | |
touch_me();
if(!file->len)
file->len = file->data?(stringp(file->data)?strlen(file->data):0):0;
|
df6704 | 1998-02-15 | Mattias Wingstedt | |
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | if (!file->mode) {
file->mode = mode;
}
|
215923 | 1998-03-23 | Henrik Grubbström (Grubba) | |
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | if(fd)
{
if (file->len) {
send(150, ({ sprintf("Opening %s data connection for %s (%d bytes).",
modes[file->mode], file->full_path, file->len) }));
} else {
send(150, ({ sprintf("Opening %s mode data connection for %s",
modes[file->mode], file->full_path) }));
|
879c1a | 1998-05-08 | Henrik Grubbström (Grubba) | | }
}
|
b1fca0 | 1996-11-12 | Per Hedbor | | else
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | {
|
abdff2 | 1999-12-27 | Martin Nilsson | | send(425, ({ "Can't build data connect: Connection refused." }));
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | return;
|
74ee78 | 1997-08-12 | Henrik Grubbström (Grubba) | | }
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | switch(file->mode) {
case "A":
if (file->data) {
|
889ac4 | 1999-06-27 | Henrik Grubbström (Grubba) | | file->data = replace(file->data,
({ "\r\n", "\n", "\r" }),
({ "\r\n", "\r\n", "\r\n" }));
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | }
if(objectp(file->file) && file->file->set_nonblocking)
{
|
280ffa | 1999-10-29 | Henrik Grubbström (Grubba) | | file->file = ToAsciiWrapper(file->file, 0, this_object());
|
b1fca0 | 1996-11-12 | Per Hedbor | | }
break;
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | case "E":
|
ca5638 | 1999-05-01 | Henrik Grubbström (Grubba) | | if (file->data) {
object conv = Locale.Charset.encoder("EBCDIC-US", "");
file->data = conv->feed(file->data)->drain();
}
if(objectp(file->file) && file->file->set_nonblocking)
{
|
b1ca39 | 1999-10-29 | Henrik Grubbström (Grubba) | |
|
280ffa | 1999-10-29 | Henrik Grubbström (Grubba) | | file->file = ToEBCDICWrapper(file->file, 0, this_object());
|
ca5638 | 1999-05-01 | Henrik Grubbström (Grubba) | | }
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | break;
default:
if (objectp(file->file) && file->file->set_nonblocking) {
|
280ffa | 1999-10-29 | Henrik Grubbström (Grubba) | | file->file = BinaryWrapper(file->file, 0, this_object());
|
b1fca0 | 1996-11-12 | Per Hedbor | | }
break;
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | }
|
c3e98f | 1999-05-01 | Henrik Grubbström (Grubba) | |
|
b6802c | 2002-07-04 | Per Hedbor | | object throttler=session->throttler;
|
df4fbf | 1999-10-10 | Francesco Chemolli | | object pipe;
|
b6802c | 2002-07-04 | Per Hedbor | | pipe = roxen.get_shuffler( fd );
if( conf )
conf->connection_add( this_object(), pipe );
if( throttler || conf->throttler )
pipe->set_throttler( throttler || conf->throttler );
|
abdff2 | 1999-12-27 | Martin Nilsson | |
|
b6802c | 2002-07-04 | Per Hedbor | | pipe->set_done_callback(
lambda( Shuffler.Shuffle r, int reason ) {
send_done_callback( fd, session, r->sent_data() );
} );
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | master_session->file = session->file = file;
if(stringp(file->data)) {
|
b6802c | 2002-07-04 | Per Hedbor | | pipe->add_source(file->data,0,strlen(file->data));
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | }
if(file->file) {
|
b6802c | 2002-07-04 | Per Hedbor | | int off;
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | file->file->set_blocking();
|
b6802c | 2002-07-04 | Per Hedbor | | catch( off = file->tell() );
pipe->add_source( file->file, max(off,0), (file->len||-1) );
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | }
|
b6802c | 2002-07-04 | Per Hedbor | | pipe->start();
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | curr_pipe = pipe;
}
|
b1fca0 | 1996-11-12 | Per Hedbor | |
|
280ffa | 1999-10-29 | Henrik Grubbström (Grubba) | | static private void connected_to_receive(object fd, string data, string args)
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | {
|
17e2b2 | 2001-06-15 | Johan Sundström | | DWRITE("FTP: connected_to_receive(X, %O, %O)\n", data, args);
|
b1fca0 | 1996-11-12 | Per Hedbor | |
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | touch_me();
|
215923 | 1998-03-23 | Henrik Grubbström (Grubba) | |
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | if (fd) {
send(150, ({ sprintf("Opening %s mode data connection for %s.",
modes[mode], args) }));
} else {
send(425, ({ "Can't build data connect: Connection refused." }));
return;
}
|
f35256 | 2000-09-24 | Henrik Grubbström (Grubba) | | data = data && sizeof(data) && data;
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | switch(mode) {
case "A":
|
280ffa | 1999-10-29 | Henrik Grubbström (Grubba) | | fd = FromAsciiWrapper(fd, data, this_object());
|
74ee78 | 1997-08-12 | Henrik Grubbström (Grubba) | | break;
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | case "E":
|
280ffa | 1999-10-29 | Henrik Grubbström (Grubba) | | fd = FromEBCDICWrapper(fd, data, this_object());
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | return;
default:
|
280ffa | 1999-10-29 | Henrik Grubbström (Grubba) | | fd = BinaryWrapper(fd, data, this_object());
|
74ee78 | 1997-08-12 | Henrik Grubbström (Grubba) | | break;
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | }
|
5babd1 | 1997-04-29 | Henrik Grubbström (Grubba) | |
|
b6802c | 2002-07-04 | Per Hedbor | | object session = RequestID2(master_session);
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | session->method = "PUT";
session->my_fd = PutFileWrapper(fd, session, this_object());
session->misc->len = 0x7fffffff;
|
974ffc | 1997-03-11 | Henrik Grubbström (Grubba) | |
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | if (open_file(args, session, "STOR")) {
if (!(session->file->pipe)) {
if (fd) {
BACKEND_CLOSE(fd);
|
b1fca0 | 1996-11-12 | Per Hedbor | | }
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | switch(session->file->error) {
case 401:
send(530, ({ sprintf("%s: Need account for storing files.", args)}));
break;
case 413:
send(550, ({ sprintf("%s: Quota exceeded.", args) }));
break;
case 501:
send(502, ({ sprintf("%s: Command not implemented.", args) }));
break;
default:
send(550, ({ sprintf("%s: Error opening file.", args) }));
|
c175b9 | 1998-03-21 | Henrik Grubbström (Grubba) | | break;
}
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | session->conf->log(session->file, session);
return;
|
9c83eb | 1997-08-25 | Henrik Grubbström (Grubba) | | }
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | master_session->file = session->file;
} else {
if (fd) {
BACKEND_CLOSE(fd);
|
b1fca0 | 1996-11-12 | Per Hedbor | | }
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | }
}
|
b1fca0 | 1996-11-12 | Per Hedbor | |
|
7cd688 | 2001-03-05 | Stefan Wallström | | static private void discard_data_connection() {
if(pasv_port && sizeof(pasv_accepted))
pasv_accepted = pasv_accepted[1..];
}
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | static private void connect_and_send(mapping file, object session)
{
|
17e2b2 | 2001-06-15 | Johan Sundström | | DWRITE("FTP: connect_and_send(%O)\n", file);
|
b1fca0 | 1996-11-12 | Per Hedbor | |
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | if (pasv_port) {
ftp_async_accept(connected_to_send, file, session);
} else {
ftp_async_connect(connected_to_send, file, session);
}
}
|
b1fca0 | 1996-11-12 | Per Hedbor | |
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | static private void connect_and_receive(string arg)
{
|
17e2b2 | 2001-06-15 | Johan Sundström | | DWRITE("FTP: connect_and_receive(\"%s\")\n", arg);
|
3085aa | 1997-04-29 | Henrik Grubbström (Grubba) | |
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | if (pasv_port) {
ftp_async_accept(connected_to_receive, arg);
} else {
ftp_async_connect(connected_to_receive, arg);
}
}
|
3085aa | 1997-04-29 | Henrik Grubbström (Grubba) | |
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | |
|
6ae0d9 | 1997-03-13 | Henrik Grubbström (Grubba) | |
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | |
array(string) my_combine_path_array(array(string) base, string part)
{
if ((part == ".") || (part == "")) {
if ((part == "") && (!sizeof(base))) {
return(({""}));
|
6ae0d9 | 1997-03-13 | Henrik Grubbström (Grubba) | | } else {
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | return(base);
|
b1fca0 | 1996-11-12 | Per Hedbor | | }
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | } else if ((part == "..") && sizeof(base) &&
(base[-1] != "..") && (base[-1] != "")) {
base[-1] = part;
return(base);
} else {
return(base + ({ part }));
}
}
|
4e59e6 | 1998-03-20 | Thomas Weber | |
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | static private string my_combine_path(string base, string part)
{
if ((sizeof(part) && (part[0] == '/')) ||
(sizeof(base) && (base[0] == '/'))) {
return(combine_path(base, part));
}
int i;
array(string) arr = ((base/"/") + (part/"/")) - ({ ".", "" });
foreach(arr, string part) {
if ((part == "..") && i && (arr[i-1] != "..")) {
i--;
} else {
arr[i++] = part;
|
4e59e6 | 1998-03-20 | Thomas Weber | | }
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | }
if (i) {
return(arr[..i-1]*"/");
} else {
return("");
}
}
|
74ee78 | 1997-08-12 | Henrik Grubbström (Grubba) | |
|
c46786 | 1999-08-08 | Henrik Grubbström (Grubba) | | static private constant IFS = (<" ", "\t">);
static private constant Quote = (< "\'", "\"", "\`", "\\" >);
static private constant Specials = IFS|Quote;
static private array(string) split_command_line(string cmdline)
{
int need_quoting;
foreach(indices(Quote), string c) {
if (need_quoting = (search(cmdline, c) >= 0)) {
break;
}
}
if (!need_quoting) {
return ((replace(cmdline, "\t", " ")/" ") - ({ "" }));
}
array(string) res = ({});
string arg = 0;
int argstart = 0;
int i;
for(i=0; i < sizeof(cmdline); i++) {
string c;
if (Specials[c = cmdline[i..i]]) {
if (argstart < i) {
arg = (arg || "") + cmdline[argstart..i-1];
}
switch(c) {
case "\"":
case "\'":
case "\`":
int j = search(cmdline, c, i+1);
if (j == -1) {
j = sizeof(cmdline);
}
arg = (arg || "") + cmdline[i+1..j-1];
i = j;
break;
case "\\":
i++;
arg += cmdline[i..i];
break;
case " ":
case "\t":
if (arg) {
res += ({ arg });
arg = 0;
}
break;
}
argstart = i+1;
}
}
if (argstart < i) {
arg = (arg || "") + cmdline[argstart..];
}
if (arg) {
res += ({ arg });
}
return res;
}
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | static private array(string) glob_expand_command_line(string cmdline)
{
|
17e2b2 | 2001-06-15 | Johan Sundström | | DWRITE("glob_expand_command_line(\"%s\")\n", cmdline);
|
74ee78 | 1997-08-12 | Henrik Grubbström (Grubba) | |
|
c46786 | 1999-08-08 | Henrik Grubbström (Grubba) | | array(string|array(string)) args = split_command_line(cmdline);
|
5babd1 | 1997-04-29 | Henrik Grubbström (Grubba) | |
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | int index;
|
5babd1 | 1997-04-29 | Henrik Grubbström (Grubba) | |
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | for(index = 0; index < sizeof(args); index++) {
|
b1fca0 | 1996-11-12 | Per Hedbor | |
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | |
|
c175b9 | 1998-03-21 | Henrik Grubbström (Grubba) | |
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | array (int) st;
|
c46786 | 1999-08-08 | Henrik Grubbström (Grubba) | |
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | if (replace(args[index], ({"*", "?"}), ({ "", "" })) != args[index]) {
|
74ee78 | 1997-08-12 | Henrik Grubbström (Grubba) | |
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | |
array(string|array(string)) matches = ({ ({ }) });
multiset(string) paths;
int i;
foreach(my_combine_path("", args[index])/"/", string part) {
paths = (<>);
if (replace(part, ({"*", "?"}), ({ "", "" })) != part) {
array(array(string)) new_matches = ({});
foreach(matches, array(string) path) {
array(string) dir;
|
802535 | 2001-01-22 | Henrik Grubbström (Grubba) | | RequestID id = RequestID2(master_session);
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | id->method = "LIST";
dir = id->conf->find_dir(combine_path(cwd, path*"/")+"/", id);
if (dir && sizeof(dir)) {
dir = glob(part, dir);
if ((< '*', '?' >)[part[0]]) {
dir = Array.filter(dir, lambda(string f) {
return (sizeof(f) && (f[0] != '.'));
});
}
foreach(sort(dir), string f) {
array(string) arr = my_combine_path_array(path, f);
string p = arr*"/";
if (!paths[p]) {
paths[p] = 1;
new_matches += ({ arr });
}
}
}
}
matches = new_matches;
} else {
for(i=0; i<sizeof(matches); i++) {
matches[i] = my_combine_path_array(matches[i], part);
string path = matches[i]*"/";
if (paths[path]) {
matches[i] = 0;
} else {
paths[path] = 1;
}
}
matches -= ({ 0 });
}
if (!sizeof(matches)) {
break;
}
}
if (sizeof(matches)) {
for (i=0; i < sizeof(matches); i++) {
matches[i] *= "/";
}
matches = Array.filter(matches,
lambda(string short, string cwd,
object m_id) {
object id = RequestID2(m_id);
id->method = "LIST";
id->not_query = combine_path(cwd, short);
return(id->conf->stat_file(id->not_query,
id));
}, cwd, master_session);
if (sizeof(matches)) {
args[index] = matches;
}
}
}
if (stringp(args[index])) {
args[index] = ({ my_combine_path("", args[index]) });
|
b1fca0 | 1996-11-12 | Per Hedbor | | }
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | }
return(args * ({}));
}
|
5babd1 | 1997-04-29 | Henrik Grubbström (Grubba) | |
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | |
static private constant ls_options = ({
({ ({ "-A", "--almost-all" }), LS_FLAG_A,
"do not list implied . and .." }),
({ ({ "-a", "--all" }), LS_FLAG_a|LS_FLAG_A,
"do not hide entries starting with ." }),
({ ({ "-b", "--escape" }), LS_FLAG_b,
"print octal escapes for nongraphic characters" }),
({ ({ "-C" }), LS_FLAG_C,
"list entries by columns" }),
({ ({ "-d", "--directory" }), LS_FLAG_d,
"list directory entries instead of contents" }),
({ ({ "-F", "--classify" }), LS_FLAG_F,
"append a character for typing each entry"}),
({ ({ "-f" }), LS_FLAG_a|LS_FLAG_A|LS_FLAG_U,
"do not sort, enable -aU, disable -lst" }),
({ ({ "-G", "--no-group" }), LS_FLAG_G,
"inhibit display of group information" }),
({ ({ "-g" }), 0,
"(ignored)" }),
({ ({ "-h", "--help" }), LS_FLAG_h,
"display this help and exit" }),
({ ({ "-k", "--kilobytes" }), 0,
"use 1024 blocks (ignored, always done anyway)" }),
({ ({ "-L", "--dereference" }), 0,
"(ignored)" }),
({ ({ "-l" }), LS_FLAG_l,
"use a long listing format" }),
({ ({ "-m" }), LS_FLAG_m,
"fill width with a comma separated list of entries" }),
({ ({ "-n", "--numeric-uid-gid" }), LS_FLAG_n,
"list numeric UIDs and GIDs instead of names" }),
({ ({ "-o" }), LS_FLAG_l|LS_FLAG_G,
"use long listing format without group info" }),
({ ({ "-Q", "--quote-name" }), LS_FLAG_Q,
"enclose entry names in double quotes" }),
({ ({ "-R", "--recursive" }), LS_FLAG_R,
"list subdirectories recursively" }),
({ ({ "-r", "--reverse" }), LS_FLAG_r,
"reverse order while sorting" }),
({ ({ "-S" }), LS_FLAG_S,
"sort by file size" }),
({ ({ "-s", "--size" }), LS_FLAG_s,
"print block size of each file" }),
({ ({ "-t" }), LS_FLAG_t,
"sort by modification time; with -l: show mtime" }),
({ ({ "-U" }), LS_FLAG_U,
"do not sort; list entries in directory order" }),
({ ({ "-v", "--version" }), LS_FLAG_v,
"output version information and exit" }),
});
|
5babd1 | 1997-04-29 | Henrik Grubbström (Grubba) | |
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | static private array(array(string)|string|int)
ls_getopt_args = Array.map(ls_options,
lambda(array(array(string)|int|string) entry) {
return({ entry[1], Getopt.NO_ARG, entry[0] });
});
static private string ls_help(string ls)
{
|
17e2b2 | 2001-06-15 | Johan Sundström | | return sprintf("Usage: %s [OPTION]... [FILE]...\n"
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | "List information about the FILEs "
"(the current directory by default).\n"
"Sort entries alphabetically if none "
"of -cftuSUX nor --sort.\n"
"\n"
"%@s\n",
ls,
Array.map(ls_options,
lambda(array entry) {
if (sizeof(entry[0]) > 1) {
return(sprintf(" %s, %-22s %s\n",
@(entry[0]), entry[2]));
}
return(sprintf(" %s "
" %s\n",
entry[0][0], entry[2]));
|
17e2b2 | 2001-06-15 | Johan Sundström | | }));
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | }
void call_ls(array(string) argv)
{
array options;
mixed err;
if (err = catch {
options = Getopt.find_all_options(argv, ls_getopt_args, 1, 1);
}) {
send(550, (argv[0]+": "+err[0])/"\n");
|
7cd688 | 2001-03-05 | Stefan Wallström | | discard_data_connection();
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | return;
}
int flags;
foreach(options, array(int) option) {
flags |= option[0];
}
if (err = catch {
argv = Getopt.get_args(argv, 1, 1);
}) {
send(550, (argv[0] + ": " + err[0])/"\n");
|
7cd688 | 2001-03-05 | Stefan Wallström | | discard_data_connection();
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | return;
}
|
abdff2 | 1999-12-27 | Martin Nilsson | |
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | if (sizeof(argv) == 1) {
argv += ({ "./" });
}
|
b610c9 | 1997-08-29 | Henrik Grubbström (Grubba) | |
|
802535 | 2001-01-22 | Henrik Grubbström (Grubba) | | RequestID session = RequestID2(master_session);
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | session->method = "LIST";
session->not_query = Array.map(argv[1..], fix_path)*" ";
|
b610c9 | 1997-08-29 | Henrik Grubbström (Grubba) | |
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | mapping file = ([]);
|
b610c9 | 1997-08-29 | Henrik Grubbström (Grubba) | |
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | |
if (mode != "E") {
file->mode = "A";
} else {
file->mode = "E";
}
|
74ee78 | 1997-08-12 | Henrik Grubbström (Grubba) | |
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | if (flags & LS_FLAG_v) {
file->data = "ls - builtin_ls 1.1\n";
} else if (flags & LS_FLAG_h) {
file->data = ls_help(argv[0]);
} else {
if (flags & LS_FLAG_d) {
flags &= ~LS_FLAG_R;
|
b1fca0 | 1996-11-12 | Per Hedbor | | }
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | if (flags & (LS_FLAG_f|LS_FLAG_C|LS_FLAG_m)) {
flags &= ~LS_FLAG_l;
}
if (flags & LS_FLAG_C) {
flags &= ~LS_FLAG_m;
}
file->file = LSFile(cwd, argv[1..], flags, session,
file->mode, this_object());
}
|
5babd1 | 1997-04-29 | Henrik Grubbström (Grubba) | |
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | if (!file->full_path) {
file->full_path = argv[0];
}
session->file = file;
connect_and_send(file, session);
}
|
5babd1 | 1997-04-29 | Henrik Grubbström (Grubba) | |
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | |
|
74ee78 | 1997-08-12 | Henrik Grubbström (Grubba) | |
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | string make_MDTM(int t)
{
|
c2849d | 2002-02-13 | Henrik Grubbström (Grubba) | | mapping lt = gmtime(t);
|
17e2b2 | 2001-06-15 | Johan Sundström | | return sprintf("%04d%02d%02d%02d%02d%02d",
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | lt->year + 1900, lt->mon + 1, lt->mday,
|
17e2b2 | 2001-06-15 | Johan Sundström | | lt->hour, lt->min, lt->sec);
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | }
|
5babd1 | 1997-04-29 | Henrik Grubbström (Grubba) | |
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | string make_MLSD_fact(string f, mapping(string:array) dir, object session)
{
array st = dir[f];
|
5babd1 | 1997-04-29 | Henrik Grubbström (Grubba) | |
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | mapping(string:string) facts = ([]);
|
ad72bd | 1997-04-09 | Marcus Comstedt | |
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | |
|
74ee78 | 1997-08-12 | Henrik Grubbström (Grubba) | |
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | facts["UNIX.mode"] = st[0];
|
b134ed | 1997-06-12 | Marcus Comstedt | |
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | if (st[1] >= 0) {
facts->size = (string)st[1];
facts->type = "File";
facts["media-type"] = session->conf->type_from_filename(f) ||
"application/octet-stream";
} else {
facts->type = ([ "..":"pdir", ".":"cdir" ])[f] || "dir";
}
|
b134ed | 1997-06-12 | Marcus Comstedt | |
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | facts->modify = make_MDTM(st[3]);
|
b134ed | 1997-06-12 | Marcus Comstedt | |
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | facts->charset = "8bit";
|
b134ed | 1997-06-12 | Marcus Comstedt | |
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | |
|
c175b9 | 1998-03-21 | Henrik Grubbström (Grubba) | |
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | return(Array.map(indices(facts), lambda(string s, mapping f) {
return s + "=" + f[s];
}, facts) * ";" + " " + f);
}
|
2d3ff5 | 1997-04-10 | Marcus Comstedt | |
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | void send_MLSD_response(mapping(string:array) dir, object session)
{
dir = dir || ([]);
array f = indices(dir);
|
7cd688 | 2001-03-05 | Stefan Wallström | | session->file->data = sizeof(f) ?
(Array.map(f, make_MLSD_fact, dir, session) * "\r\n") + "\r\n" :
"" ;
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | |
session->file->mode = "I";
connect_and_send(session->file, session);
}
|
7a8c5b | 2001-03-03 | Henrik Grubbström (Grubba) | | void send_MLST_response(mapping(string:array) dir, object session)
{
dir = dir || ([]);
send(250,({ "OK" }) +
Array.map(indices(dir), make_MLSD_fact, dir, session) +
({ "OK" }) );
}
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | |
c8a3ca | 2000-09-18 | Henrik Grubbström (Grubba) | | * Session handling
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | */
|
c8a3ca | 2000-09-18 | Henrik Grubbström (Grubba) | | int login()
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | {
|
c8a3ca | 2000-09-18 | Henrik Grubbström (Grubba) | | int session_limit = port_obj->query_option("ftp_user_session_limit");
if (session_limit > 0) {
if (session_limit <= (port_obj->ftp_sessions[user])) {
return 0;
}
if (logged_in) {
report_error("Internal error in session-handler.");
return 1;
}
|
17e2b2 | 2001-06-15 | Johan Sundström | | DWRITE("FTP2: Increasing # of sessions for user %O\n", user);
|
c8a3ca | 2000-09-18 | Henrik Grubbström (Grubba) | | port_obj->ftp_sessions[user]++;
}
logged_in = (user != 0) || -1;
return 1;
}
void logout()
{
if (!logged_in) return;
int session_limit = port_obj->query_option("ftp_user_session_limit");
if (session_limit > 0) {
|
17e2b2 | 2001-06-15 | Johan Sundström | | DWRITE("FTP2: Decreasing # of sessions for user %O\n", user);
|
c8a3ca | 2000-09-18 | Henrik Grubbström (Grubba) | | if ((--port_obj->ftp_sessions[user]) < 0) {
port_obj->ftp_sessions[user] = 0;
}
}
logged_in = 0;
}
int check_login()
{
int session_limit = port_obj->query_option("ftp_user_session_limit");
if (session_limit <= 0) return 1;
if (session_limit <= (port_obj->ftp_sessions[user])) {
return 0;
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | }
|
c8a3ca | 2000-09-18 | Henrik Grubbström (Grubba) | | return 1;
}
|
316375 | 2001-03-13 | Henrik Grubbström (Grubba) | |
|
ac291c | 2001-03-13 | Henrik Grubbström (Grubba) | | int epsv_only;
|
316375 | 2001-03-13 | Henrik Grubbström (Grubba) | |
|
c8a3ca | 2000-09-18 | Henrik Grubbström (Grubba) | | void ftp_REIN(string|int args)
{
logout();
|
316375 | 2001-03-13 | Henrik Grubbström (Grubba) | |
|
41cfa3 | 2001-09-10 | Henrik Grubbström (Grubba) | |
m_delete(master_session->misc, "home");
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | dataport_addr = 0;
dataport_port = 0;
mode = "A";
cwd = "/";
|
802535 | 2001-01-22 | Henrik Grubbström (Grubba) | | auth_user = 0;
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | user = password = 0;
curr_pipe = 0;
restart_point = 0;
logged_in = 0;
if (pasv_port) {
destruct(pasv_port);
pasv_port = 0;
}
if (args != 1) {
send(220, ({ "Server ready for new user." }));
}
}
void ftp_USER(string args)
{
|
c8a3ca | 2000-09-18 | Henrik Grubbström (Grubba) | | logout();
|
802535 | 2001-01-22 | Henrik Grubbström (Grubba) | | auth_user = 0;
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | user = args;
password = 0;
logged_in = 0;
cwd = "/";
master_session->method = "LOGIN";
if ((< 0, "ftp", "anonymous" >)[user]) {
master_session->not_query = "Anonymous";
user = 0;
|
b0132d | 1999-10-08 | Henrik Grubbström (Grubba) | | if (port_obj->query_option("anonymous_ftp")) {
|
c8a3ca | 2000-09-18 | Henrik Grubbström (Grubba) | | if (check_login()) {
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | #if 0
|
c8a3ca | 2000-09-18 | Henrik Grubbström (Grubba) | | send(200, ({ "Anonymous ftp, at your service" }));
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | #else /* !0 */
|
c8a3ca | 2000-09-18 | Henrik Grubbström (Grubba) | |
send(331, ({ "Anonymous ftp accepted, send "
"your complete e-mail address as password." }));
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | #endif /* 0 */
|
c8a3ca | 2000-09-18 | Henrik Grubbström (Grubba) | | conf->log(([ "error":200 ]), master_session);
} else {
send(530, ({
sprintf("Too many anonymous users (%d).",
port_obj->query_option("ftp_user_session_limit"))
}));
conf->log(([ "error":403 ]), master_session);
}
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | } else {
send(530, ({ "Anonymous ftp disabled" }));
conf->log(([ "error":403 ]), master_session);
|
abfd7d | 1997-06-12 | Marcus Comstedt | | }
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | } else {
|
c8a3ca | 2000-09-18 | Henrik Grubbström (Grubba) | | if (check_login()) {
send(331, ({ sprintf("Password required for %s.", user) }));
master_session->not_query = user;
conf->log(([ "error":407 ]), master_session);
} else {
send(530, ({
sprintf("Concurrent session limit (%d) exceeded for user \"%s\".",
port_obj->query_option("ftp_user_session_limit"), user)
}));
conf->log(([ "error":403 ]), master_session);
user = 0;
return;
|
abfd7d | 1997-06-12 | Marcus Comstedt | | }
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | }
}
|
c175b9 | 1998-03-21 | Henrik Grubbström (Grubba) | |
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | void ftp_PASS(string args)
{
if (!user) {
|
b0132d | 1999-10-08 | Henrik Grubbström (Grubba) | | if (port_obj->query_option("anonymous_ftp")) {
|
c8a3ca | 2000-09-18 | Henrik Grubbström (Grubba) | | if (login()) {
send(230, ({ "Guest login ok, access restrictions apply." }));
master_session->method = "LOGIN";
master_session->not_query = "Anonymous User:"+args;
conf->log(([ "error":200 ]), master_session);
logged_in = -1;
} else {
send(530, ({
sprintf("Too many anonymous users (%d).",
port_obj->query_option("ftp_user_session_limit"))
}));
conf->log(([ "error":403 ]), master_session);
}
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | } else {
send(503, ({ "Login with USER first." }));
}
return;
}
|
3bcd3b | 1997-05-07 | Henrik Grubbström (Grubba) | |
|
c8a3ca | 2000-09-18 | Henrik Grubbström (Grubba) | | logout();
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | password = args||"";
args = "CENSORED_PASSWORD";
master_session->method = "LOGIN";
master_session->realauth = user + ":" + password;
master_session->not_query = user;
|
cf4a90 | 2001-01-19 | Per Hedbor | | master_session->misc->user = user;
master_session->misc->password = password;
|
cc8381 | 2001-09-10 | Henrik Grubbström (Grubba) | |
m_delete(master_session->misc, "home");
|
cf4a90 | 2001-01-19 | Per Hedbor | |
|
802535 | 2001-01-22 | Henrik Grubbström (Grubba) | | auth_user = master_session->conf->authenticate(master_session);
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | |
|
802535 | 2001-01-22 | Henrik Grubbström (Grubba) | | if (!auth_user) {
|
b0132d | 1999-10-08 | Henrik Grubbström (Grubba) | | if (!port_obj->query_option("guest_ftp")) {
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | send(530, ({ sprintf("User %s access denied.", user) }));
conf->log(([ "error":401 ]), master_session);
} else {
|
c8a3ca | 2000-09-18 | Henrik Grubbström (Grubba) | |
string u = user;
user = 0;
if (login()) {
send(230, ({ sprintf("Guest user %s logged in.", u) }));
logged_in = -1;
conf->log(([ "error":200 ]), master_session);
|
17e2b2 | 2001-06-15 | Johan Sundström | | DWRITE("FTP: Guest-user: %O\n", master_session->realauth);
|
c8a3ca | 2000-09-18 | Henrik Grubbström (Grubba) | | } else {
send(530, ({
sprintf("Too many anonymous/guest users (%d).",
port_obj->query_option("ftp_user_session_limit"))
}));
conf->log(([ "error":403 ]), master_session);
}
|
3bcd3b | 1997-05-07 | Henrik Grubbström (Grubba) | | }
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | return;
}
|
002628 | 1999-06-07 | Martin Stjernholm | |
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | |
|
b0132d | 1999-10-08 | Henrik Grubbström (Grubba) | | if (!port_obj->query_option("named_ftp") ||
|
cc8381 | 2001-09-10 | Henrik Grubbström (Grubba) | | !check_shell(auth_user->shell())) {
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | send(530, ({ "You are not allowed to use named-ftp.",
"Try using anonymous, or check /etc/shells" }));
conf->log(([ "error":402 ]), master_session);
|
802535 | 2001-01-22 | Henrik Grubbström (Grubba) | | auth_user = 0;
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | return;
}
|
c8a3ca | 2000-09-18 | Henrik Grubbström (Grubba) | | if (!login()) {
send(530, ({
sprintf("Too many concurrent sessions (limit is %d).",
port_obj->query_option("ftp_user_session_limit"))
}));
conf->log(([ "error":403 ]), master_session);
return;
}
|
cc8381 | 2001-09-10 | Henrik Grubbström (Grubba) | | if (stringp(auth_user->homedir())) {
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | |
|
cc8381 | 2001-09-10 | Henrik Grubbström (Grubba) | | string home = auth_user->homedir();
if ((home == "") || (home[-1] != '/')) {
home += "/";
|
240816 | 1997-05-07 | Henrik Grubbström (Grubba) | | }
|
cc8381 | 2001-09-10 | Henrik Grubbström (Grubba) | |
master_session->misc->home = home;
array(int)|object st = conf->stat_file(home, master_session);
|
abdff2 | 1999-12-27 | Martin Nilsson | |
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | if (st && (st[1] < 0)) {
|
cc8381 | 2001-09-10 | Henrik Grubbström (Grubba) | | cwd = home;
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | }
|
b1fca0 | 1996-11-12 | Per Hedbor | | }
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | logged_in = 1;
|
abdff2 | 1999-12-27 | Martin Nilsson | | send(230, ({ sprintf("User %s logged in.", user) }));
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | conf->log(([ "error":202 ]), master_session);
|
b1fca0 | 1996-11-12 | Per Hedbor | | }
|
980b33 | 1998-03-23 | Henrik Grubbström (Grubba) | |
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | void ftp_CWD(string args)
{
if (!expect_argument("CWD", args)) {
return;
}
|
980b33 | 1998-03-23 | Henrik Grubbström (Grubba) | |
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | string ncwd = fix_path(args);
|
a2a719 | 1997-10-03 | Henrik Grubbström (Grubba) | |
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | if ((ncwd == "") || (ncwd[-1] != '/')) {
ncwd += "/";
}
|
b1fca0 | 1996-11-12 | Per Hedbor | |
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | object session = RequestID2(master_session);
session->method = "CWD";
session->not_query = ncwd;
|
acd03a | 1997-08-28 | Henrik Grubbström (Grubba) | |
|
97b910 | 2000-09-13 | Henrik Grubbström (Grubba) | | array|object st = conf->stat_file(ncwd, session);
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | ncwd = session->not_query;
if (!st) {
send(550, ({ sprintf("%s: No such file or directory, or access denied.",
ncwd) }));
session->conf->log(session->file || ([ "error":404 ]), session);
return;
}
if (!(< -2, -3 >)[st[1]]) {
send(504, ({ sprintf("%s: Not a directory.", ncwd) }));
session->conf->log(([ "error":400 ]), session);
return;
}
cwd = ncwd;
array(string) reply = ({ sprintf("Current directory is now %s.", cwd) });
session->method = "GET";
array(string) files = conf->find_dir(cwd, session);
if (files) {
files = reverse(sort(Array.filter(files, lambda(string s) {
return(s[..5] == "README");
})));
foreach(files, string f) {
|
c0f454 | 2001-02-19 | Jonas Wallden | | array|object st = conf->stat_file(replace(cwd + f, "//", "/"),
session);
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | |
if (st && (st[1] >= 0)) {
reply = ({ sprintf("Please read the file %s.", f),
sprintf("It was last modified %s - %d days ago.",
ctime(st[3]) - "\n",
(time(1) - st[3])/86400),
"" }) + reply;
}
}
}
|
7cd688 | 2001-03-05 | Stefan Wallström | | string message;
catch {
message = conf->try_get_file(cwd + ".message", session);
};
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | if (message) {
reply = (message/"\n")+({ "" })+reply;
}
session->method = "CWD";
send(250, reply);
session->conf->log(([ "error":200, "len":sizeof(reply*"\n") ]), session);
}
void ftp_XCWD(string args)
{
ftp_CWD(args);
|
acd03a | 1997-08-28 | Henrik Grubbström (Grubba) | | }
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | |
void ftp_CDUP(string args)
{
ftp_CWD("../");
|
7a87c7 | 1997-09-03 | Henrik Grubbström (Grubba) | | }
|
acd03a | 1997-08-28 | Henrik Grubbström (Grubba) | |
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | void ftp_XCUP(string args)
|
14179b | 1997-01-29 | Per Hedbor | | {
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | ftp_CWD("../");
}
void ftp_QUIT(string args)
{
send(221, ({ "Bye! It was nice talking to you!" }));
send(0, 0);
master_session->method = "QUIT";
master_session->not_query = user || "Anonymous";
conf->log(([ "error":200 ]), master_session);
ftp_REIN(1);
}
void ftp_BYE(string args)
{
ftp_QUIT(args);
}
void ftp_PORT(string args)
{
|
316375 | 2001-03-13 | Henrik Grubbström (Grubba) | | if (epsv_only) {
send(530, ({ "'PORT': Method not allowed in EPSV ALL mode." }));
return;
}
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | int a, b, c, d, e, f;
|
abdff2 | 1999-12-27 | Martin Nilsson | | if (sscanf(args||"", "%d,%d,%d,%d,%d,%d", a, b, c, d, e, f)<6)
|
316375 | 2001-03-13 | Henrik Grubbström (Grubba) | | send(501, ({ "I don't understand your parameters." }));
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | else {
dataport_addr = sprintf("%d.%d.%d.%d", a, b, c, d);
dataport_port = e*256 + f;
if (pasv_port) {
destruct(pasv_port);
}
send(200, ({ "PORT command ok ("+dataport_addr+
" port "+dataport_port+")" }));
}
}
|
316375 | 2001-03-13 | Henrik Grubbström (Grubba) | | void ftp_EPRT(string args)
{
if (epsv_only) {
send(530, ({ "'EPRT': Method not allowed in EPSV ALL mode." }));
return;
}
if (sizeof(args) < 3) {
send(501, ({ "I don't understand your parameters." }));
return;
}
string delimiter = args[0..0];
|
b82005 | 2001-03-13 | Martin Stjernholm | | if ((delimiter[0] <= 32) || (delimiter[0] >= 127)) {
|
316375 | 2001-03-13 | Henrik Grubbström (Grubba) | | send(501, ({ "Invalid delimiter." }));
}
array(string) segments = args/delimiter;
if (sizeof(args) != 4) {
send(501, ({ "I don't understand your parameters." }));
return;
}
if (segments[1] != "1") {
|
ac291c | 2001-03-13 | Henrik Grubbström (Grubba) | |
|
316375 | 2001-03-13 | Henrik Grubbström (Grubba) | | send(522, ({ "Network protocol not supported, use (1)" }));
return;
}
if ((sizeof(segments[2]/".") != 4) ||
sizeof(replace(segments[2], ".0123456789"/"", allocate(11, "")))) {
send(501, ({ sprintf("Bad IPv4 address: '%s'", segments[2]) }));
return;
}
|
819183 | 2001-03-13 | Martin Stjernholm | | if (!((int)segments[3])) {
|
316375 | 2001-03-13 | Henrik Grubbström (Grubba) | | send(501, ({ sprintf("Bad port number: '%s'", segments[3]) }));
return;
}
|
819183 | 2001-03-13 | Martin Stjernholm | | dataport_addr = segments[2];
dataport_port = (int)segments[3];
|
316375 | 2001-03-13 | Henrik Grubbström (Grubba) | |
if (pasv_port) {
destruct(pasv_port);
}
send(200, ({ "EPRT command ok ("+dataport_addr+
" port "+dataport_port+")" }));
}
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | void ftp_PASV(string args)
{
|
65e6f3 | 2001-04-14 | Werner Koch | | int min;
int max;
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | |
|
316375 | 2001-03-13 | Henrik Grubbström (Grubba) | | if (epsv_only) {
send(530, ({ "'PASV': Method not allowed in EPSV ALL mode." }));
return;
}
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | if(pasv_port)
destruct(pasv_port);
|
65e6f3 | 2001-04-14 | Werner Koch | |
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | pasv_port = Stdio.Port(0, pasv_accept_callback, local_addr);
int port=(int)((pasv_port->query_address()/" ")[1]);
|
65e6f3 | 2001-04-14 | Werner Koch | |
min = port_obj->query_option("passive_port_min");
max = port_obj->query_option("passive_port_max");
if ((port < min) || (port > max)) {
if (max > 65535) max = 65535;
if (min < 0) min = 0;
for (port = min; port <= max; port++) {
if (pasv_port->bind(port, pasv_accept_callback, local_addr)) {
break;
}
}
if (port > max) {
destruct(pasv_port);
pasv_port = 0;
send(452, ({ "Requested action aborted: Out of ports." }));
return;
}
}
|
11d345 | 2002-02-12 | Henrik Grubbström (Grubba) | | send(227, ({ sprintf("Entering Passive Mode. (%s,%d,%d)",
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | replace(local_addr, ".", ","),
(port>>8), (port&0xff)) }));
}
|
316375 | 2001-03-13 | Henrik Grubbström (Grubba) | | void ftp_EPSV(string args)
{
|
00e0bd | 2001-04-24 | Henrik Grubbström (Grubba) | | int min;
int max;
|
316375 | 2001-03-13 | Henrik Grubbström (Grubba) | |
if (args && args != "1") {
if (lower_case(args) == "all") {
epsv_only = 1;
send(200, ({ "Entering EPSV ALL mode." }));
} else {
|
b0f1a9 | 2001-03-13 | Henrik Grubbström (Grubba) | |
|
316375 | 2001-03-13 | Henrik Grubbström (Grubba) | | send(522, ({ "Network protocol not supported, use (1)" }));
}
return;
}
if (pasv_port)
destruct(pasv_port);
pasv_port = Stdio.Port(0, pasv_accept_callback, local_addr);
int port=(int)((pasv_port->query_address()/" ")[1]);
|
65e6f3 | 2001-04-14 | Werner Koch | |
min = port_obj->query_option("passive_port_min");
max = port_obj->query_option("passive_port_max");
if ((port < min) || (port > max)) {
if (max > 65535) max = 65535;
if (min < 0) min = 0;
for (port = min; port <= max; port++) {
if (pasv_port->bind(port, pasv_accept_callback, local_addr)) {
break;
}
}
if (port > max) {
destruct(pasv_port);
pasv_port = 0;
send(452, ({ "Requested action aborted: Out of ports." }));
return;
}
}
|
6e2db7 | 2001-06-28 | Marcus Wellhardh | | send(229, ({ sprintf("Entering Extended Passive Mode (|||%d|)",
port) }));
|
316375 | 2001-03-13 | Henrik Grubbström (Grubba) | | }
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | void ftp_TYPE(string args)
{
if (!expect_argument("TYPE", args)) {
return;
}
args = upper_case(replace(args, ({ " ", "\t" }), ({ "", "" })));
switch(args) {
case "L8":
case "L":
case "I":
mode = "I";
break;
case "A":
mode = "A";
break;
case "E":
|
c9f6a3 | 1999-05-01 | Henrik Grubbström (Grubba) | | mode = "E";
break;
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | default:
send(504, ({ "'TYPE': Unknown type:"+args }));
return;
|
031f32 | 1997-08-31 | Henrik Grubbström (Grubba) | | }
|
0a34b1 | 1997-03-13 | Henrik Grubbström (Grubba) | |
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | send(200, ({ sprintf("Using %s mode for transferring files.",
modes[mode]) }));
}
void ftp_RETR(string args)
{
if (!expect_argument("RETR", args)) {
return;
}
|
0a34b1 | 1997-03-13 | Henrik Grubbström (Grubba) | |
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | args = fix_path(args);
|
f7e750 | 1997-04-08 | Marcus Comstedt | |
|
802535 | 2001-01-22 | Henrik Grubbström (Grubba) | | RequestID session = RequestID2(master_session);
|
f7e750 | 1997-04-08 | Marcus Comstedt | |
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | session->method = "GET";
session->not_query = args;
|
2d3ff5 | 1997-04-10 | Marcus Comstedt | |
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | if (open_file(args, session, "RETR")) {
if (restart_point) {
if (session->file->data) {
if (sizeof(session->file->data) >= restart_point) {
session->file->data = session->file->data[restart_point..];
restart_point = 0;
} else {
restart_point -= sizeof(session->file->data);
m_delete(session->file, "data");
}
}
if (restart_point) {
if (!(session->file->file && session->file->file->seek &&
(session->file->file->seek(restart_point) != -1))) {
restart_point = 0;
send(550, ({ "'RETR': Error restoring restart point." }));
|
7cd688 | 2001-03-05 | Stefan Wallström | | discard_data_connection();
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | return;
}
restart_point = 0;
}
}
connect_and_send(session->file, session);
}
|
7cd688 | 2001-03-05 | Stefan Wallström | | else
discard_data_connection();
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | }
void ftp_STOR(string args)
{
if (!expect_argument("STOR", args)) {
return;
}
args = fix_path(args);
connect_and_receive(args);
|
14179b | 1997-01-29 | Per Hedbor | | }
|
b1fca0 | 1996-11-12 | Per Hedbor | |
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | void ftp_REST(string args)
{
if (!expect_argument("REST", args)) {
return;
}
restart_point = (int)args;
send(350, ({ "'REST' ok" }));
}
|
abdff2 | 1999-12-27 | Martin Nilsson | |
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | void ftp_ABOR(string args)
{
if (curr_pipe) {
catch {
|
b6802c | 2002-07-04 | Per Hedbor | | curr_pipe->stop();
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | };
curr_pipe = 0;
send(426, ({ "Data transmission terminated." }));
}
send(226, ({ "'ABOR' Completed." }));
}
void ftp_PWD(string args)
{
send(257, ({ sprintf("\"%s\" is current directory.", cwd) }));
}
void ftp_XPWD(string args)
{
ftp_PWD(args);
}
|
abdff2 | 1999-12-27 | Martin Nilsson | |
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | static private string rename_from;
|
abdff2 | 1999-12-27 | Martin Nilsson | |
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | void ftp_RNFR(string args)
{
if (!expect_argument("RNFR", args)) {
return;
}
args = fix_path(args);
|
abdff2 | 1999-12-27 | Martin Nilsson | |
|
802535 | 2001-01-22 | Henrik Grubbström (Grubba) | | RequestID session = RequestID2(master_session);
|
abdff2 | 1999-12-27 | Martin Nilsson | |
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | session->method = "STAT";
if (stat_file(args, session)) {
send(350, ({ sprintf("%s ok, waiting for destination name.", args) }) );
rename_from = args;
} else {
send(550, ({ sprintf("%s: no such file or permission denied.",args) }) );
}
}
void ftp_RNTO(string args)
{
if(!rename_from) {
send(503, ({ "RNFR needed before RNTO." }));
return;
}
if (!expect_argument("RNTO", args)) {
return;
}
args = fix_path(args);
|
abdff2 | 1999-12-27 | Martin Nilsson | |
|
802535 | 2001-01-22 | Henrik Grubbström (Grubba) | | RequestID session = RequestID2(master_session);
|
abdff2 | 1999-12-27 | Martin Nilsson | |
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | session->method = "MV";
session->misc->move_from = rename_from;
session->not_query = args;
if (open_file(args, session, "MOVE")) {
send(250, ({ sprintf("%s moved to %s.", rename_from, args) }));
session->conf->log(([ "error":200 ]), session);
}
rename_from = 0;
}
|
abdff2 | 1999-12-27 | Martin Nilsson | |
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | void ftp_NLST(string args)
{
array(string) argv = glob_expand_command_line("/usr/bin/ls " + (args||""));
call_ls(argv);
}
void ftp_LIST(string args)
{
ftp_NLST("-l " + (args||""));
}
void ftp_MLST(string args)
{
args = fix_path(args || ".");
|
802535 | 2001-01-22 | Henrik Grubbström (Grubba) | | RequestID session = RequestID2(master_session);
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | |
session->method = "DIR";
|
97b910 | 2000-09-13 | Henrik Grubbström (Grubba) | | array|object st = stat_file(args, session);
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | |
if (st) {
session->file = ([]);
session->file->full_path = args;
|
7a8c5b | 2001-03-03 | Henrik Grubbström (Grubba) | | send_MLST_response(([ args:st ]), session);
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | } else {
send_error("MLST", args, session->file, session);
}
}
void ftp_MLSD(string args)
{
args = fix_path(args || ".");
|
abdff2 | 1999-12-27 | Martin Nilsson | |
|
802535 | 2001-01-22 | Henrik Grubbström (Grubba) | | RequestID session = RequestID2(master_session);
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | |
session->method = "DIR";
|
97b910 | 2000-09-13 | Henrik Grubbström (Grubba) | | array|object st = stat_file(args, session);
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | |
if (st && (st[1] < 0)) {
if (args[-1] != '/') {
args += "/";
}
session->file = ([]);
session->file->full_path = args;
send_MLSD_response(session->conf->find_dir_stat(args, session), session);
} else {
if (st) {
session->file->error = 405;
}
send_error("MLSD", args, session->file, session);
|
7cd688 | 2001-03-05 | Stefan Wallström | | discard_data_connection();
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | }
}
void ftp_DELE(string args)
{
if (!expect_argument("DELE", args)) {
return;
}
args = fix_path(args);
|
802535 | 2001-01-22 | Henrik Grubbström (Grubba) | | RequestID session = RequestID2(master_session);
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | |
session->data = 0;
session->misc->len = 0;
session->method = "DELETE";
if (open_file(args, session, "DELE")) {
send(250, ({ sprintf("%s deleted.", args) }));
session->conf->log(([ "error":200 ]), session);
return;
}
}
void ftp_RMD(string args)
{
if (!expect_argument("RMD", args)) {
return;
}
args = fix_path(args);
|
802535 | 2001-01-22 | Henrik Grubbström (Grubba) | | RequestID session = RequestID2(master_session);
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | |
session->data = 0;
session->misc->len = 0;
session->method = "DELETE";
|
97b910 | 2000-09-13 | Henrik Grubbström (Grubba) | | array|object st = stat_file(args, session);
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | |
if (!st) {
send_error("RMD", args, session->file, session);
return;
} else if (st[1] != -2) {
if (st[1] == -3) {
send(504, ({ sprintf("%s is a module mountpoint.", args) }));
session->conf->log(([ "error":405 ]), session);
} else {
send(504, ({ sprintf("%s is not a directory.", args) }));
session->conf->log(([ "error":405 ]), session);
}
return;
}
if (open_file(args, session, "RMD")) {
send(250, ({ sprintf("%s deleted.", args) }));
session->conf->log(([ "error":200 ]), session);
return;
}
}
void ftp_XRMD(string args)
{
ftp_RMD(args);
}
void ftp_MKD(string args)
{
if (!expect_argument("MKD", args)) {
return;
}
args = fix_path(args);
|
802535 | 2001-01-22 | Henrik Grubbström (Grubba) | | RequestID session = RequestID2(master_session);
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | |
session->method = "MKDIR";
session->data = 0;
session->misc->len = 0;
|
abdff2 | 1999-12-27 | Martin Nilsson | |
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | if (open_file(args, session, "MKD")) {
send(257, ({ sprintf("\"%s\" created.", args) }));
session->conf->log(([ "error":200 ]), session);
return;
}
}
void ftp_XMKD(string args)
{
ftp_MKD(args);
}
void ftp_SYST(string args)
{
|
e6a171 | 2000-02-02 | Per Hedbor | | send(215, ({ "UNIX Type: L8: Roxen Information Server"}));
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | }
void ftp_CLNT(string args)
{
if (!expect_argument("CLNT", args)) {
return;
}
send(200, ({ "Ok, gottcha!"}));
master_session->client = args/" " - ({ "" });
}
void ftp_FEAT(string args)
{
array a = sort(Array.filter(indices(cmd_help),
lambda(string s) {
return(this_object()["ftp_"+s]);
}));
a = Array.map(a,
lambda(string s) {
return(([ "REST":"REST STREAM",
"MLST":"MLST UNIX.mode;size;type;modify;charset;media-type",
"MLSD":"",
])[s] || s);
}) - ({ "" });
send(211, ({ "The following features are supported:" }) + a +
({ "END" }));
}
void ftp_MDTM(string args)
{
if (!expect_argument("MDTM", args)) {
return;
}
args = fix_path(args);
|
802535 | 2001-01-22 | Henrik Grubbström (Grubba) | | RequestID session = RequestID2(master_session);
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | session->method = "STAT";
|
97b910 | 2000-09-13 | Henrik Grubbström (Grubba) | | mapping|array|object st = stat_file(args, session);
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | |
|
97b910 | 2000-09-13 | Henrik Grubbström (Grubba) | | if (!arrayp(st) && !objectp(st)) {
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | send_error("MDTM", args, st, session);
return;
}
send(213, ({ make_MDTM(st[3]) }));
}
void ftp_SIZE(string args)
{
if (!expect_argument("SIZE", args)) {
return;
}
args = fix_path(args);
|
802535 | 2001-01-22 | Henrik Grubbström (Grubba) | | RequestID session = RequestID2(master_session);
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | session->method = "STAT";
|
97b910 | 2000-09-13 | Henrik Grubbström (Grubba) | | mapping|array|object st = stat_file(args, session);
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | |
|
97b910 | 2000-09-13 | Henrik Grubbström (Grubba) | | if (!arrayp(st) && !objectp(st)) {
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | send_error("SIZE", args, st, session);
return;
}
int size = st[1];
if (size < 0) {
|
6ef8a4 | 1999-06-08 | Henrik Grubbström (Grubba) | | send_error("SIZE", args, ([ "error":405, ]), session);
return;
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | }
send(213, ({ (string)size }));
}
void ftp_STAT(string args)
{
|
0900e2 | 2001-08-22 | Henrik Grubbström (Grubba) | |
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | |
|
0900e2 | 2001-08-22 | Henrik Grubbström (Grubba) | | if ((< "", 0 >)[args]) {
send(211,
sprintf("%s FTP server status:\n"
"Version %s\n"
"Listening on %s\n"
"Connected to %s\n"
"Logged in %s\n"
"TYPE: %s, FORM: %s; STRUcture: %s; transfer MODE: %s\n"
"End of status",
replace(fd->query_address(1), " ", ":"),
roxen.version(),
port_obj->sorted_urls * "\nListening on ",
replace(fd->query_address(), " ", ":"),
user?sprintf("as %s", user):"anonymously",
(["A":"ASCII", "E":"EBCDIC", "I":"IMAGE", "L":"LOCAL"])
[mode],
"Non-Print",
"File",
"Stream"
)/"\n");
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | return;
}
string long = fix_path(args);
|
802535 | 2001-01-22 | Henrik Grubbström (Grubba) | | RequestID session = RequestID2(master_session);
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | session->method = "STAT";
|
97b910 | 2000-09-13 | Henrik Grubbström (Grubba) | | mapping|array|object st = stat_file(long);
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | |
|
97b910 | 2000-09-13 | Henrik Grubbström (Grubba) | | if (!arrayp(st) && !objectp(st)) {
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | send_error("STAT", long, st, session);
return;
}
string s = LS_L(master_session)->ls_l(args, st);
send(213, sprintf("status of \"%s\":\n"
"%s"
"End of Status", args, s)/"\n");
}
void ftp_NOOP(string args)
{
send(200, ({ "Nothing done ok" }));
}
void ftp_HELP(string args)
{
if ((< "", 0 >)[args]) {
send(214, ({
"The following commands are recognized (* =>'s unimplemented):",
@(sprintf(" %#70s", sort(Array.map(indices(cmd_help),
lambda(string s) {
return(upper_case(s)+
(this_object()["ftp_"+s]?
" ":"* "));
}))*"\n")/"\n"),
@(FTP2_XTRA_HELP),
}));
} else if ((args/" ")[0] == "SITE") {
array(string) a = (upper_case(args)/" ")-({""});
if (sizeof(a) == 1) {
send(214, ({ "The following SITE commands are recognized:",
@(sprintf(" %#70s", sort(indices(site_help))*"\n")/"\n")
}));
} else if (site_help[a[1]]) {
send(214, ({ sprintf("Syntax: SITE %s %s", a[1], site_help[a[1]]) }));
} else {
send(504, ({ sprintf("Unknown SITE command %s.", a[1]) }));
}
} else {
args = upper_case(args);
if (cmd_help[args]) {
send(214, ({ sprintf("Syntax: %s %s%s", args,
cmd_help[args],
(this_object()["ftp_"+args]?
"":"; unimplemented")) }));
} else {
send(504, ({ sprintf("Unknown command %s.", args) }));
}
}
}
void ftp_SITE(string args)
{
if ((< 0, "" >)[args]) {
ftp_HELP("SITE");
return;
}
array a = (args/" ") - ({ "" });
if (!sizeof(a)) {
ftp_HELP("SITE");
return;
}
a[0] = upper_case(a[0]);
if (!site_help[a[0]]) {
send(502, ({ sprintf("Bad SITE command: '%s'", a[0]) }));
} else if (this_object()["ftp_SITE_"+a[0]]) {
this_object()["ftp_SITE_"+a[0]](a[1..]);
} else {
send(502, ({ sprintf("SITE command '%s' is not currently supported.",
a[0]) }));
}
}
void ftp_SITE_CHMOD(array(string) args)
{
if (sizeof(args) < 2) {
send(501, ({ sprintf("'SITE CHMOD %s': incorrect arguments",
args*" ") }));
return;
}
|
abdff2 | 1999-12-27 | Martin Nilsson | |
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | int mode;
foreach(args[0] / "", string m)
{
mode *= 010;
if(m[0] < '0' || m[0] > '7')
{
mode = -1;
break;
}
mode += (int)("0"+m);
}
if(mode == -1 || mode > 0777)
{
send(501, ({ "SITE CHMOD: mode should be between 0 and 0777" }));
return;
}
string fname = fix_path(args[1..]*" ");
|
802535 | 2001-01-22 | Henrik Grubbström (Grubba) | | RequestID session = RequestID2(master_session);
|
abdff2 | 1999-12-27 | Martin Nilsson | |
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | session->method = "CHMOD";
session->misc->mode = mode;
session->not_query = fname;
if (open_file(fname, session, "CHMOD")) {
send(250, ({ sprintf("Changed permissions of %s to 0%o.",
fname, mode) }));
session->conf->log(([ "error":200 ]), session);
}
}
|
abdff2 | 1999-12-27 | Martin Nilsson | |
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | void ftp_SITE_UMASK(array(string) args)
{
if (sizeof(args) < 1) {
send(501, ({ sprintf("'SITE UMASK %s': incorrect arguments",
args*" ") }));
return;
}
|
abdff2 | 1999-12-27 | Martin Nilsson | |
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | int mode;
foreach(args[0] / "", string m)
{
mode *= 010;
if(m[0] < '0' || m[0] > '7')
{
mode = -1;
break;
}
mode += (int)("0"+m);
}
if(mode == -1 || mode > 0777)
{
send(501, ({ "SITE UMASK: mode should be between 0 and 0777" }));
return;
}
master_session->misc->umask = mode;
send(250, ({ sprintf("Umask set to 0%o.", mode) }));
}
void ftp_SITE_PRESTATE(array(string) args)
{
if (!sizeof(args)) {
master_session->prestate = (<>);
send(200, ({ "Prestate cleared" }));
} else {
master_session->prestate = aggregate_multiset(@((args*" ")/","-({""})));
send(200, ({ "Prestate set" }));
}
}
static private void timeout()
{
if (fd) {
int t = (time() - time_touch);
if (t > FTP2_TIMEOUT) {
send(421, ({ "Connection timed out." }));
send(0,0);
if (master_session->file) {
if (objectp(master_session->file->file)) {
destruct(master_session->file->file);
}
if (objectp(master_session->file->pipe)) {
destruct(master_session->file->pipe);
}
}
if (objectp(pasv_port)) {
destruct(pasv_port);
}
master_session->method = "QUIT";
master_session->not_query = user || "Anonymous";
master_session->conf->log(([ "error":408 ]), master_session);
} else {
call_out(timeout, FTP2_TIMEOUT + 30 - t);
}
|
490270 | 2000-09-20 | Henrik Grubbström (Grubba) | | } else {
DWRITE("FTP2: Timeout on dead connection.\n");
destruct();
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | }
}
static private void got_command(mixed ignored, string line)
{
|
17e2b2 | 2001-06-15 | Johan Sundström | | DWRITE("FTP2: got_command(X, \"%s\")\n", line);
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | |
touch_me();
string cmd = line;
string args;
int i;
if (line == "") {
return;
}
if ((i = search(line, " ")) != -1) {
cmd = line[..i-1];
|
d81924 | 2000-07-23 | Henrik Grubbström (Grubba) | | args = line[i+1..] - "\0";
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | }
cmd = upper_case(cmd);
if ((< "PASS" >)[cmd]) {
line = cmd + " CENSORED_PASSWORD";
}
|
802535 | 2001-01-22 | Henrik Grubbström (Grubba) | | #if 0
if (!conf->extra_statistics) {
conf->extra_statistics = ([ "ftp": (["commands":([ cmd:1 ])])]);
} else if (!conf->extra_statistics->ftp) {
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | conf->extra_statistics->ftp = (["commands":([ cmd:1 ])]);
} else if (!conf->extra_statistics->ftp->commands) {
conf->extra_statistics->ftp->commands = ([ cmd:1 ]);
} else {
conf->extra_statistics->ftp->commands[cmd]++;
}
|
802535 | 2001-01-22 | Henrik Grubbström (Grubba) | | #endif /* 0 */
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | |
if (cmd_help[cmd]) {
if (!logged_in) {
if (!(< "REIN", "USER", "PASS", "SYST",
"ACCT", "QUIT", "ABOR", "HELP" >)[cmd]) {
send(530, ({ "You need to login first." }));
return;
}
}
if (this_object()["ftp_"+cmd]) {
conf->requests++;
|
16675a | 2002-04-11 | Anders Johansson | | #if 1
mixed err;
if (err = catch {
this_object()["ftp_"+cmd](args);
}) {
report_error("Internal server error in FTP2\n"
"Handling command %O\n%s\n",
line, describe_backtrace(err));
}
#else
|
72c2a1 | 2002-02-11 | Henrik Grubbström (Grubba) | | roxen->handle(lambda(function f, string args, string line) {
mixed err;
if (err = catch {
f(args);
}) {
report_error("Internal server error in FTP2\n"
"Handling command %O\n%s\n",
line, describe_backtrace(err));
}
|
5e3c10 | 2002-02-12 | Henrik Grubbström (Grubba) | | }, this_object()["ftp_"+cmd], args, line);
|
16675a | 2002-04-11 | Anders Johansson | | #endif
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | } else {
send(502, ({ sprintf("'%s' is not currently supported.", cmd) }));
}
} else {
send(502, ({ sprintf("Unknown command '%s'.", cmd) }));
}
touch_me();
}
void con_closed()
{
|
490270 | 2000-09-20 | Henrik Grubbström (Grubba) | | DWRITE("FTP2: con_closed()\n");
logout();
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | master_session->method = "QUIT";
master_session->not_query = user || "Anonymous";
conf->log(([ "error":204, "request_time":(time(1)-master_session->time) ]),
master_session);
|
490270 | 2000-09-20 | Henrik Grubbström (Grubba) | |
if (fd) {
fd->close();
}
|
0cc9c5 | 2001-08-05 | Henrik Grubbström (Grubba) | | if (pasv_port) {
destruct(pasv_port);
pasv_port = 0;
}
|
490270 | 2000-09-20 | Henrik Grubbström (Grubba) | |
destruct();
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | }
void destroy()
{
|
490270 | 2000-09-20 | Henrik Grubbström (Grubba) | | DWRITE("FTP2: destroy()\n");
|
c8a3ca | 2000-09-18 | Henrik Grubbström (Grubba) | | logout();
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | |
|
65f64f | 2000-12-05 | Henrik Grubbström (Grubba) | | port_obj->sessions--;
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | }
void create(object fd, object c)
{
|
b0132d | 1999-10-08 | Henrik Grubbström (Grubba) | | port_obj = c;
conf = port_obj->urls[port_obj->sorted_urls[0]]->conf;
|
8653f6 | 2000-03-10 | Henrik Grubbström (Grubba) | |
if (!conf->inited) {
conf->enable_all_modules();
}
|
c8a3ca | 2000-09-18 | Henrik Grubbström (Grubba) | |
|
7da2b0 | 1999-10-08 | Henrik Grubbström (Grubba) | | #if 0
|
b0132d | 1999-10-08 | Henrik Grubbström (Grubba) | | werror("FTP: conf:%O\n"
"FTP:urls:%O\n",
mkmapping(indices(conf), values(conf)), port_obj->urls);
|
7da2b0 | 1999-10-08 | Henrik Grubbström (Grubba) | | #endif /* 0 */
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | |
master_session = RequestID2();
master_session->remoteaddr = (fd->query_address()/" ")[0];
|
b0132d | 1999-10-08 | Henrik Grubbström (Grubba) | | master_session->conf = conf;
|
6abda8 | 2000-08-04 | Martin Stjernholm | | master_session->port_obj = c;
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | master_session->my_fd = fd;
|
66090c | 2000-03-10 | Henrik Grubbström (Grubba) | | master_session->misc->defaulted = 1;
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | ::create(fd, got_command, 0, con_closed, ([]));
array a = fd->query_address(1)/" ";
local_addr = a[0];
local_port = (int)a[1];
call_out(timeout, FTP2_TIMEOUT);
|
b0132d | 1999-10-08 | Henrik Grubbström (Grubba) | | string s = c->query_option("FTPWelcome");
s = replace(s,
({ "$roxen_version", "$roxen_build", "$full_version",
"$pike_version", "$ident", }),
({ roxen->__roxen_version__, roxen->__roxen_build__,
roxen->real_version, version(), roxen->version() }));
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | |
send(220, s/"\n", 1);
}
};
void create(object f, object c)
{
|
f72bc9 | 2000-02-04 | Per Hedbor | | if (f)
{
|
b0132d | 1999-10-08 | Henrik Grubbström (Grubba) | | c->sessions++;
c->ftp_users++;
|
ea50e6 | 1999-05-01 | Henrik Grubbström (Grubba) | | FTPSession(f, c);
}
}
|