📄 warftpdlite.cpp
字号:
/* WAR FTP DAEMON LITE This is a sample-implementation of a FTP server, using the War FTP Dameon Engine C++ library.*/#include "stdafx.h"#if WAR_CRYPTO# include <openssl/err.h># include <openssl/ssl.h>#endif#define EXT#include "WarFtpdlite.h"#include "WarFtpdLiteWin32NtService.h"#include "WarFunctionProfiler.h"#include "WarIfRoot.h"#include "WarIfServer.h"#include "WarIfSite.h"#include "WarSvrProtocolFtpLite.h"#include "WarWin32ShutdownKey.h"#include "WarFileEngine.h"#include "WarFileDriverWin32.h"#include "WarPerfmonDef.h"#include "WarLibObjects.h"#include "WarSvrProtocolHttpLite.h"#include "WarIfMimeTypes.h"#include "WarFileDriverDynamic.h"#include "WarLngTextWebadm.h"using namespace std;#ifdef WIN32BOOL WINAPI win32_break(DWORD dwCtrlType){ WarLog sys_log(WARLOG_SYSTEM, "win32_break()"); sys_log << "**** Signalled ***** "; switch(dwCtrlType) { case CTRL_LOGOFF_EVENT: sys_log << "CTRL_LOGOFF_EVENT - ";daemon_override: if (1 > DaemonFlag) goto shutdown; sys_log << "Running in daemon mode. The event is ignored." << war_endl; break; case CTRL_CLOSE_EVENT: sys_log << "CTRL_CLOSE_EVENT - "; goto daemon_override; break; case CTRL_BREAK_EVENT: sys_log << "CTRL_BREAK_EVENT - ";shutdown: sys_log << "Shutting down." << war_endl; WarShutdownEngine::GetEngine().Shutdown(); break; case CTRL_C_EVENT: sys_log << "CTRL_C_EVENT - "; goto shutdown; break; case CTRL_SHUTDOWN_EVENT: sys_log << "CTRL_SHUTDOWN_EVENT - "; goto shutdown; break; } return true;}#endifint main(int argc, char* argv[]){ int rval = EXIT_SUCCESS; WarFunctionProfiler *profiler = NULL; if (((myname = strrchr(argv[0], '/')) == NULL) || !*++myname) myname = argv[0];#if WAR_CRYPTO SSL_load_error_strings(); OpenSSL_add_ssl_algorithms();#endif WarLibObjects my_global_objects; my_global_objects.Open(); // Initialize global variables Priority = WAR_THRD_PRI_INVALID; // Don't set the priority unless specified // Prepare the native file system try {#ifdef WIN32 // Install "file://" driver for Win32 WarFileEngine::GetEngine().AttachDriver( new WarFileDriverWin32); #else WarFileEngine::GetEngine().AttachDriver( new WarFileDriverGeneric); #endif } catch(WarException& e) { cerr << "Failed to initialize the \"file://\" driver." << e.Explain() << endl; return EXIT_FAILURE; }#ifdef WAR_USE_WEBADM try { WarLngTextEngine::GetEngine().AddLngHandler( war_lngtext_ptr_t(new WarLngTextWebadm)); WarFileEngine::GetEngine().AttachDriver( new WarFileDriverDynamic("wfde")); } catch(WarException& e) { cerr << "Failed to initialize the \"wfde://\" driver." << e.Explain() << endl; return EXIT_FAILURE; }#endif // WAR_USE_WEBADM // Set up a tmp. log-facility so that modules can // output errors and information during start-up. try { WarLogEngine::GetEngine().InstallHandler(new WarLogIoStreamHandler(cout, "cout")); WarLogEngine::GetEngine().SetRelaxMode("cout"); } catch(WarException& ex) { WAR_CERR << _T("Warning: Failed to initialize prelimilary logging to stdout.") << endl << WarCollector<TCHAR>(ex.Explain()).GetValue().c_str() << endl; } // Look at the command-line arguments ParseOptions(argc, argv);#ifdef WIN32 // Initialize the Windows spesific stuff try { // Set a pointer to the root-registry handle if (ServiceName.empty()) ServiceName = "WARSVR"; } catch(WarException& e) { cerr << "Failed to initialize the Win32 subsystem. " << e.Explain() << endl; return EXIT_FAILURE; }#endif // Get startup info war_if_server_ptr_t my_server; war_if_root_ptr_t my_root = new WarIfRoot; try { my_root->Open(WAR_VENDOR, NULL); my_server = my_root->GetServer( WarCollector<TCHAR>(ServiceName).GetValue().c_str());#ifdef WIN32 WarWin32Registry::mRootPath = my_server->GetRegKey().GetRef().GetPath();#endif my_server->CwdToServerDir(); my_server->LoadOptions(); my_server->CreateDirectories(); if (WAR_THRD_PRI_INVALID == Priority) Priority = my_server->GetPriority(); if (WAR_THRD_PRI_INVALID != Priority) { WarThread::SetDefaultPriority(Priority); WarThreadEngine::GetEngine().SetPriOnAllThreads(Priority); } } catch(WarException& ex) { WAR_CERR << _T("Error in configuration data. Failed to prepere the initial startup procedure.") << endl << WarCollector<TCHAR>(ex.Explain()).GetValue().c_str() << endl; return EXIT_FAILURE; } // Shut down the tmp logging facility try { WarLogEngine::GetEngine().RemoveHandler("cout"); } catch(WarException& ex) { WAR_CERR << _T("Warning: Failed to remove prelimilary logging to stdout.") << endl << WarCollector<TCHAR>(ex.Explain()).GetValue().c_str() << endl; } // Start the log-modules try { my_server->StartLogModules(); } catch(WarException& ex) { WAR_CERR << _T("Failed to initialize logging.") << endl << WarCollector<TCHAR>(ex.Explain()).GetValue().c_str() << endl; return EXIT_FAILURE; } // Say hello WarLog sys_log(WARLOG_SYSTEM, "main()"); WarLog info_log(WARLOG_INFO, "main()"); WarLog err_log(WARLOG_ERROR, "main()"); sys_log << PROGRAM << " " << VERSION << " starting up\n" << COPYRIGHT << "\n" << LICENSE << "\n" << WarOs::GetOs().GetOsName() << war_endl;#ifdef WAR_WINNT // Initialize Windows NT optimized features try { info_log << "Initializing NT optimized IO" << war_endl; WarSvrWin32NtEngine::GetEngine().Create(20); } catch(WarException& ex) { cerr << "Failed to initialize the Win32 NT subsystem. " << ex.Explain() << endl; return EXIT_FAILURE; } g_PrfData.Activate(); // Reset all the counters WAR_PERFMON_SET(WAR_PRFSVR_USERS_ONLINE, 0); WAR_PERFMON_SET(WAR_PRFSVR_TRANSFERS_NOW, 0); WAR_PERFMON_SET(WAR_PRFSVR_TRANSFERS_TOTAL, 0); WAR_PERFMON_SET(WAR_PRFSVR_TRANSFERS_FAILED, 0); WAR_PERFMON_SET(WAR_PRFSVR_KPS_OUT, 0); WAR_PERFMON_SET(WAR_PRFSVR_KPS_IN, 0); WAR_PERFMON_SET(WAR_PRFSVR_USERS_ONLINE, 0); WAR_PERFMON_SET(WAR_PRFSVR_USERS_ONLINE, 0);# ifdef _DEBUG WAR_DB_PERFMON_SET(WAR_PRFDEBUG_NUM_AUTOPTR ,0); WAR_DB_PERFMON_SET(WAR_PRFDEBUG_NUM_OPEN_SOCKETS ,0); WAR_DB_PERFMON_SET(WAR_PRFDEBUG_NUM_SOCKETS ,0); WAR_DB_PERFMON_SET(WAR_PRFDEBUG_NUM_SOCKET_IO ,0); WAR_DB_PERFMON_SET(WAR_PRFDEBUG_NUM_OPEN_FILES ,0); WAR_DB_PERFMON_SET(WAR_PRFDEBUG_NUM_FILES ,0); WAR_DB_PERFMON_SET(WAR_PRFDEBUG_NUM_FTPCTL ,0); WAR_DB_PERFMON_SET(WAR_PRFDEBUG_NUM_FTPDATA ,0); WAR_DB_PERFMON_SET(WAR_PRFDEBUG_NUM_SCKPENDINGIO ,0); WAR_DB_PERFMON_SET(WAR_PRFDEBUG_NUM_FILEPENDINGIO ,0); WAR_DB_PERFMON_SET(WAR_PRFDEBUG_NUM_SCKCONNPNDIO ,0);# endif#endif // WAR_WINNT // Create and initialize the services try { war_if_site_list_t my_sites; my_server->EnumSites(my_sites, true); int num_sites = 0; for(war_if_site_list_t::iterator P = my_sites.begin() ; P != my_sites.end() ; ++P) { war_if_site_ptr_t site_ptr = *P; for(int prot = 0; prot < WarIfSite::PROT_INVALID; prot++) { WarIfSite::ProtocolE protocol = (WarIfSite::ProtocolE) prot; if (site_ptr->IsProtocolEnabled(protocol)) { war_svrdef_ptr_t my_site; switch(protocol) { case WarIfSite::PROT_FTP: my_site = new WarSvrDefinitionFtpLite; break; case WarIfSite::PROT_HTTP: my_site = new WarSvrDefinitionHttpLite; break; default: assert(false); continue; } site_ptr->InitializeRealSite(my_site, protocol); info_log << "Starting virtual " << site_ptr->GetProtocolName(protocol) << " server \"" << site_ptr->GetName() << "\" at " << site_ptr->GetAddress(protocol) << war_endl; WarSvrEngine::GetEngine().AddServer(my_site); num_sites++; } } } if (0 == num_sites) { err_log << "No virtual sites was configured. Nothing to do. Exiting." << war_endl; return EXIT_FAILURE; } } catch(WarException& ex) { err_log << "Failed to initialize the sites. " << ex << war_endl; return EXIT_FAILURE; }#ifdef WIN32 // Install a shutdown-timer that looks in the registry int delay_ms = WarOptionList::GetGlobalOptions().GetIntOption("svr_REGSHTDWNTIMER"); if (delay_ms < 1000) delay_ms = 2500; WarTimer::GetTimer().AddEvent(war_timer_event_ptr_t(new WarWin32ShutdownKey(delay_ms))); // Install an event handler to receive shutdown conditions SetConsoleCtrlHandler(win32_break, true); if ((1 == DaemonFlag) && WarOs::GetOs().IsNt()) { // Try to start as NT service WarFtpdLiteWin32NtService *pservice = new WarFtpdLiteWin32NtService( WarCollector<TCHAR>(ServiceName).GetValue().c_str()); if (pservice->IsInstalled() && pservice->StartService()) goto done; }#endif // WIN32 if (ProfilerFlag) { profiler = new WarFunctionProfiler; if (!VerboseFlag) VerboseFlag = 1; } rval = StartServer();done:#ifdef WAR_WINNT g_PrfData.Deactivate();#endif sys_log << "**** SHUTDOWN COMPLETED ****" << war_endl; if (profiler) { cout << "Profiler:" << endl << profiler->Explain() << endl; delete profiler; profiler = NULL; } return rval;}int StartServer(){ WarLog sys_log(WARLOG_SYSTEM, "StartServer()"); WarLog db_log(WARLOG_DEBUG, "main()"); if (db_log) { db_log << "Starting delayed logging [trough a dedicated thread]" << war_endl; } WarLogEngine::GetEngine().StartDelayedLogging(); // Enter daemon mode if (!DebugFlag && !VerboseFlag) { sys_log << "Entering daemon mode" << war_endl; WarLogEngine::GetEngine().RemoveHandler("cout");#ifdef WIN32 ::FreeConsole();#endif } else { if (!DebugFlag) { WarLogEngine::GetEngine().SetRelaxMode("cout"); } else { WarLogEngine::GetEngine().EnableEvent("cout", "WARLOG_DEBUG"); WarLogEngine::GetEngine().EnableEvent("cout", DebugLogOptions.c_str()); db_log << WarLogEngine::GetEngine().Explain() << war_endl; } } try { // start the services WarSvrEngine::GetEngine().StartServer(); WarShutdownEngine::GetEngine().WaitForShutdown(); } catch(...) { return EXIT_FAILURE; } return EXIT_SUCCESS;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -