1
1
#include " ftp_session.h"
2
2
3
+ #include < asio.hpp>
4
+
3
5
#include < algorithm>
4
6
#include < cassert> // assert
5
7
#include < cctype> // std::iscntrl, toupper
6
- #include < chrono>
8
+ #include < chrono> // IWYU pragma: keep (it is used for special preprocessor defines)
7
9
#include < cstddef>
8
10
#include < cstdio>
9
11
#include < fstream>
28
30
#include < sys/stat.h>
29
31
30
32
#ifdef WIN32
33
+ #define WIN32_LEAN_AND_MEAN
34
+ #ifndef NOMINMAX
35
+ #define NOMINMAX
36
+ #endif
37
+ #include < windows.h>
31
38
#include " win_str_convert.h"
32
39
#else
33
40
#include < unistd.h>
37
44
namespace fineftp
38
45
{
39
46
40
- FtpSession::FtpSession (asio::io_service& io_service, const UserDatabase& user_database, const std::function<void (FtpSession*)>& completion_handler)
47
+ FtpSession::FtpSession (asio::io_service& io_service, const UserDatabase& user_database, const std::function<void (FtpSession*)>& completion_handler, std::ostream& output, std::ostream& error )
41
48
: completion_handler_ (completion_handler)
42
49
, user_database_ (user_database)
43
50
, io_service_ (io_service)
@@ -49,6 +56,8 @@ namespace fineftp
49
56
, data_acceptor_ (io_service)
50
57
, data_socket_strand_ (io_service)
51
58
, timer_ (io_service)
59
+ , output_(output)
60
+ , error_(error)
52
61
{
53
62
}
54
63
@@ -62,7 +71,7 @@ namespace fineftp
62
71
{
63
72
asio::error_code ec;
64
73
command_socket_.set_option (asio::ip::tcp::no_delay (true ), ec);
65
- if (ec) std::cerr << " Unable to set socket option tcp::no_delay: " << ec.message () << std::endl;
74
+ if (ec) error_ << " Unable to set socket option tcp::no_delay: " << ec.message () << std::endl;
66
75
67
76
command_strand_.post ([me = shared_from_this ()]() { me->readFtpCommand (); });
68
77
sendFtpMessage (FtpMessage (FtpReplyCode::SERVICE_READY_FOR_NEW_USER, " Welcome to fineFTP Server" ));
@@ -73,7 +82,7 @@ namespace fineftp
73
82
{
74
83
#ifndef NDEBUG
75
84
// TODO: Have a "is stopped" variable, so that this log message is not printed every time
76
- std::cout << " Ftp Session shutting down" << std::endl;
85
+ output_ << " Ftp Session shutting down" << std::endl;
77
86
#endif // !NDEBUG
78
87
79
88
// TODO: protect the two sockets with mutexes, as it is now possible to call stop() from another thread!!!
@@ -142,7 +151,7 @@ namespace fineftp
142
151
void FtpSession::startSendingMessages ()
143
152
{
144
153
#ifndef NDEBUG
145
- std::cout << " FTP >> " << command_output_queue_.front () << std::endl;
154
+ output_ << " FTP >> " << command_output_queue_.front () << std::endl;
146
155
#endif
147
156
148
157
asio::async_write (command_socket_
@@ -175,7 +184,7 @@ namespace fineftp
175
184
auto trimmed_message = me->command_output_queue_ .front ();
176
185
trimmed_message.erase (trimmed_message.find_last_not_of (" \r\n " ) + 1 );
177
186
178
- std::cerr << " Command write error for message " << trimmed_message << " : " << ec.message () << std::endl;
187
+ error_ << " Command write error for message " << trimmed_message << " : " << ec.message () << std::endl;
179
188
}
180
189
}
181
190
));
@@ -190,12 +199,12 @@ namespace fineftp
190
199
{
191
200
if (ec != asio::error::eof)
192
201
{
193
- std::cerr << " read_until error: " << ec.message () << std::endl;
202
+ me-> error_ << " read_until error: " << ec.message () << std::endl;
194
203
}
195
204
#ifndef NDEBUG
196
205
else
197
206
{
198
- std::cout << " Control connection closed by client." << std::endl;
207
+ me-> output_ << " Control connection closed by client." << std::endl;
199
208
}
200
209
#endif // !NDEBUG
201
210
// Close the data connection, if it is open
@@ -223,7 +232,7 @@ namespace fineftp
223
232
224
233
stream.ignore (2 ); // Remove the "\r\n"
225
234
#ifndef NDEBUG
226
- std::cout << " FTP << " << packet_string << std::endl;
235
+ me-> output_ << " FTP << " << packet_string << std::endl;
227
236
#endif
228
237
229
238
me->handleFtpCommand (packet_string);
@@ -437,7 +446,7 @@ namespace fineftp
437
446
data_acceptor_.close (ec);
438
447
if (ec)
439
448
{
440
- std::cerr << " Error closing data acceptor: " << ec.message () << std::endl;
449
+ error_ << " Error closing data acceptor: " << ec.message () << std::endl;
441
450
}
442
451
}
443
452
@@ -448,7 +457,7 @@ namespace fineftp
448
457
data_acceptor_.open (endpoint.protocol (), ec);
449
458
if (ec)
450
459
{
451
- std::cerr << " Error opening data acceptor: " << ec.message () << std::endl;
460
+ error_ << " Error opening data acceptor: " << ec.message () << std::endl;
452
461
sendFtpMessage (FtpReplyCode::SERVICE_NOT_AVAILABLE, " Failed to enter passive mode." );
453
462
return ;
454
463
}
@@ -458,7 +467,7 @@ namespace fineftp
458
467
data_acceptor_.bind (endpoint, ec);
459
468
if (ec)
460
469
{
461
- std::cerr << " Error binding data acceptor: " << ec.message () << std::endl;
470
+ error_ << " Error binding data acceptor: " << ec.message () << std::endl;
462
471
sendFtpMessage (FtpReplyCode::SERVICE_NOT_AVAILABLE, " Failed to enter passive mode." );
463
472
return ;
464
473
}
@@ -468,7 +477,7 @@ namespace fineftp
468
477
data_acceptor_.listen (asio::socket_base::max_connections, ec);
469
478
if (ec)
470
479
{
471
- std::cerr << " Error listening on data acceptor: " << ec.message () << std::endl;
480
+ error_ << " Error listening on data acceptor: " << ec.message () << std::endl;
472
481
sendFtpMessage (FtpReplyCode::SERVICE_NOT_AVAILABLE, " Failed to enter passive mode." );
473
482
return ;
474
483
}
@@ -1085,7 +1094,7 @@ namespace fineftp
1085
1094
if (dir_status.canOpenDir ())
1086
1095
{
1087
1096
sendFtpMessage (FtpReplyCode::FILE_STATUS_OK_OPENING_DATA_CONNECTION, " Sending directory listing" );
1088
- sendDirectoryListing (Filesystem::dirContent (local_path));
1097
+ sendDirectoryListing (Filesystem::dirContent (local_path, error_ ));
1089
1098
return ;
1090
1099
}
1091
1100
else
@@ -1133,7 +1142,7 @@ namespace fineftp
1133
1142
if (dir_status.canOpenDir ())
1134
1143
{
1135
1144
sendFtpMessage (FtpReplyCode::FILE_STATUS_OK_OPENING_DATA_CONNECTION, " Sending name list" );
1136
- sendNameList (Filesystem::dirContent (local_path));
1145
+ sendNameList (Filesystem::dirContent (local_path, error_ ));
1137
1146
return ;
1138
1147
}
1139
1148
else
@@ -1399,7 +1408,7 @@ namespace fineftp
1399
1408
1400
1409
if (ec)
1401
1410
{
1402
- std::cerr << " Data write error: " << ec.message () << std::endl;
1411
+ me-> error_ << " Data write error: " << ec.message () << std::endl;
1403
1412
return ;
1404
1413
}
1405
1414
@@ -1440,7 +1449,7 @@ namespace fineftp
1440
1449
{
1441
1450
if (ec)
1442
1451
{
1443
- std::cerr << " Data transfer aborted: " << ec.message () << std::endl;
1452
+ me-> error_ << " Data transfer aborted: " << ec.message () << std::endl;
1444
1453
me->sendFtpMessage (FtpReplyCode::TRANSFER_ABORTED, " Data transfer aborted" );
1445
1454
return ;
1446
1455
}
0 commit comments