Add FTP protocol debugging facilities.
[dftpd.git] / Server.cpp
blob2dfbc5519b672dfed4ea0de153ec87a1014eb424
1 #include <iostream>
2 #include <sys/select.h>
3 #include <string.h>
4 #include <errno.h>
5 #include "Server.hpp"
6 #include "Auth.hpp"
7 #include "Log.hpp"
8 #include "Exceptions.hpp"
10 Server::Server( const AuthPtr& auth )
11 : m_listener( new Listener )
12 , m_sessionController( new SessionController )
13 , m_auth( auth )
15 g_log->Print( "Dumb FTP server" );
16 g_log->Print( std::string("IP: ") + m_listener->GetIPAddr() );
18 LoadWelcomeMessage();
20 m_listener->Listen();
23 Server::Server( const AuthPtr& auth, const std::string& ip )
24 : m_listener( new Listener( ip ) )
25 , m_sessionController( new SessionController )
26 , m_auth( auth )
28 g_log->Print( "Dumb FTP server" );
29 g_log->Print( std::string("IP: ") + m_listener->GetIPAddr() );
31 LoadWelcomeMessage();
33 m_listener->Listen();
36 Server::~Server()
38 g_log->Print( "[Server] Shutting down" );
41 ServerPtr Server::Create( const AuthPtr& auth )
43 ServerPtr ret( new Server( auth ) );
44 ret->m_this = ret;
46 ret->InitListener();
48 return ret;
51 ServerPtr Server::Create( const AuthPtr& auth, const std::string& ip )
53 ServerPtr ret( new Server( auth, ip ) );
54 ret->m_this = ret;
56 ret->InitListener();
58 return ret;
61 void Server::Tick()
63 fd_set read, write;
64 std::list<int> fds = m_sessionController->GetFds();
65 int maxfd = m_listener->GetSock();
67 FD_ZERO( &read );
68 FD_ZERO( &write );
70 FD_SET( maxfd, &read );
72 for( std::list<int>::const_iterator it = fds.begin(); it != fds.end(); ++it )
74 maxfd = std::max( maxfd, abs( *it ) );
76 if( *it < 0 )
78 // Hack
79 FD_SET( -(*it), &write );
81 else
83 FD_SET( *it, &read );
87 timeval tv;
88 tv.tv_sec = 0;
89 tv.tv_usec = 50000;
91 int ret = select( maxfd + 1, &read, &write, NULL, &tv );
93 if( ret == -1 )
95 g_log->Print( strerror( errno ) );
96 throw ServerCrashException;
98 else if( ret == 0 )
100 // Descriptors not ready
101 return;
104 std::list<int> activeFds;
105 for( std::list<int>::const_iterator it = fds.begin(); it != fds.end(); ++it )
107 if( ( *it > 0 && FD_ISSET( *it, &read ) ) ||
108 ( *it < 0 && FD_ISSET( -(*it), &write ) ) )
110 activeFds.push_back( abs( *it ) );
114 if( activeFds.size() != 0 )
116 m_sessionController->Tick( activeFds );
119 if( FD_ISSET( m_listener->GetSock(), &read ) )
121 m_listener->Tick();
125 void Server::IncomingConnection( int sock )
127 m_sessionController->Add( Session::Create( sock, m_sessionController, m_auth, m_listener->GetIPAddr(), m_this ) );
130 void Server::InitListener()
132 m_listener->SetServer( m_this );
135 void Server::LoadWelcomeMessage()
137 FILE *f = fopen( "welcome", "r" );
138 if( !f )
140 return;
143 char buf[256];
144 while( fgets( buf, 256, f ) )
146 if( buf[strlen( buf ) - 1] == '\n' )
148 buf[strlen( buf ) - 1] = 0;
151 m_welcome.push_back( buf );
154 fclose( f );