diff --git a/Source/changelog.txt b/Bin/changelog.txt
similarity index 78%
rename from Source/changelog.txt
rename to Bin/changelog.txt
index d54ef2c..ab6d2a8 100644
--- a/Source/changelog.txt
+++ b/Bin/changelog.txt
@@ -2,6 +2,15 @@
- Removed
* Fixed/Changed
+Jan 7, 2022, v2.2
++ basic session statistics logged
++ TLS session resumption
+* zero-length files transfer error
++ chmod command implemented
++ goodbye message now configurable (#21)
++ readme and fftp example config updated
++ hardcode compiler in makefile changed (PR #20, #19)
+
May 17, 2020, v2.1
* bugfixes and refactoring
diff --git a/Source/fftp.conf b/Bin/fftp.conf
similarity index 100%
rename from Source/fftp.conf
rename to Bin/fftp.conf
diff --git a/LightFTP.sha256 b/LightFTP.sha256
new file mode 100644
index 0000000..192b9ff
--- /dev/null
+++ b/LightFTP.sha256
@@ -0,0 +1,22 @@
+0b1f5c358dc0e0de24f53c86e38ed9f7fefcfe92db1cda9ddca68074a79421aa *Bin\changelog.txt
+909dba11551d5a58bba80bde49b93f1f543f4518ea440e27735ec06f1025b26d *Bin\fftp.conf
+e9c9b9f194f49ae4f6ed47fc765846594acd03c483d971a2fab11a40e6ef0eb4 *Source\cfgparse.c
+f6b932c3079f04c72a80a5542cf1f462434b03ae4d00f58ef2ad0b2bf5bbe0e6 *Source\cfgparse.h
+e4b6abb42e338aeb71154f44021f07bdb40ccac45e76acfbd435e9a752494889 *Source\fspathtools.c
+2b6c36e811da4e7d56345deda1415471b3d8b015c169b547d92871ad9d26c549 *Source\fspathtools.h
+5d4e5250df93ceb0ee46534805c2f4242b231ee040260e3fe58564de842cae6c *Source\ftpconst.c
+245483c7daa3782c63897ea69c4a8689500f201ba18155bbec100321015c0918 *Source\ftpserv.c
+6f3a0dfe34e357a9e41d42b977422a92d1419d833c0f2d192531e7ecd17eb0c5 *Source\ftpserv.h
+6a82ed4fa5819d893b378e8dd7803938e1227bea521324901718376c29f1d86f *Source\main.c
+1e739c93f5bdb7145fe97e8e840a1b3c033e417d9ca60b177314ffab3f042f5f *Source\x_malloc.c
+ba96488cbfa44c33311712ed7c3c9c906d793b77ec6214e4709c769e83984d5f *Source\x_malloc.h
+0f2806d3c51d05d76f68cb5a4cecc0da43121de7bd435056a59d5330c226be11 *Source\Debug\makefile
+b7c990cea76eb22265fb0e2aa72664b8c04d6d010a688d572da95df8217553c1 *Source\Debug\objects.mk
+289d8d240d914e4c48b9e286c7f993d4bbc4771b17c593ef1b708e41bdbdff80 *Source\Debug\sources.mk
+b4438965ccb9bc5d466338724130c145cf7c2110c4a0a924bb5262a6b7b07268 *Source\Debug\subdir.mk
+0f2806d3c51d05d76f68cb5a4cecc0da43121de7bd435056a59d5330c226be11 *Source\Release\makefile
+b7c990cea76eb22265fb0e2aa72664b8c04d6d010a688d572da95df8217553c1 *Source\Release\objects.mk
+289d8d240d914e4c48b9e286c7f993d4bbc4771b17c593ef1b708e41bdbdff80 *Source\Release\sources.mk
+ebce4d776ddf3b4ec226609125cd2d647b5edc7303d2e9a7adc54235ae204e8a *Source\Release\subdir.mk
+067d29d8592aedb1003d05a3e4deaa8bac34f7658b6e33cb9750cd309342cffa *Source\TLS-cert\gencert.sh
+9f0b4aa13b2285c3b0807c66ae088cdc0a6bfeac54bef97b3c18fd89b5a8c048 *Source\TLS-cert\mycert-req.txt
diff --git a/README.md b/README.md
index 55f8c3f..a89d839 100644
--- a/README.md
+++ b/README.md
@@ -133,7 +133,15 @@ Next use the following:
cd lightftp/Source/Release
make
-Result binary is fftp. Next setup ftp config, example config file is Source/fftp.conf. Set port, accounts, path to log file (optionally if you need it), path to certificates if you want to use them, etc.
+Result binary is fftp. Next setup ftp config, example config file is Bin/fftp.conf. Set port, accounts, path to log file (optionally if you need it), path to certificates if you want to use them, etc.
+
+# Old Windows version
+
+Since 2.2 old Windows unmaintained version moved to the separate archive repository, https://github.com/hfiref0x/LightFTP_win.
+
+# Changelog
+
+Changelog available at Bin/changelog.txt
# Authors
diff --git a/Source.sha256 b/Source.sha256
deleted file mode 100644
index 27377ae..0000000
--- a/Source.sha256
+++ /dev/null
@@ -1,46 +0,0 @@
-18364d8691f4bb9ec5f684940e05ddd70de658446417c1f6071a21ad7f4b3717 *Source\cfgparse.c
-fb951da7cb5aa17b79cc455bbcb3d7a3ef09182db34298a921138bdd9950cd17 *Source\cfgparse.h
-e0013dc69f2e46b70c360611463886be20b382709ef7c3c954bd3ab8963370b3 *Source\changelog.txt
-89f8ce6af9377236e226c810e228947c27fc1b233b0f164104ad26bbfe8ecda6 *Source\fftp.conf
-c02df4fe98511859d400a4357c66720254f8b7053f8655f26e6842ba6022227a *Source\fspathtools.c
-6a6f5df59cb19f62a964312a5efc1d285eba1d1a97563e4214c5b41666baf0ee *Source\fspathtools.h
-552be952422a3e3959e4f130be0c7fdff6ab0ef124eb161df21b0a264b0b2a32 *Source\ftpconst.c
-a8f896fe8fc640aa71335d1a6269ff790d9b7a4ed6379eeed86d2deca7234c7c *Source\ftpserv.c
-111269c386d9c6a34ebc12b4d51785ade70cc606d67d5840ab4e8c65d279e837 *Source\ftpserv.h
-eaff0ee73df59a2c5b53d12d65a62bc74023296099b93869c2192f69c21b1a93 *Source\main.c
-106d68ea37dd580b94c15cf1ca800929ccf92168d5b4794ea884916c8cc440bf *Source\x_malloc.c
-79876657549a772e6e48fdacc83f18352ad9a23529cab840e169fdfe62d6a01e *Source\x_malloc.h
-2850a07ea90193cc0206674ad1b62a0df01b343c7b5e548f7ecaca616ffb3a07 *Source\Debug\makefile
-fa3d96ba5c45cb2b0004c8ea687045e16768ec90ec788f0958905083164e52f1 *Source\Debug\objects.mk
-45bf7584af2acb3c6c806bd48b0774c661e081efdaff00d735554cde1ed76fbb *Source\Debug\sources.mk
-7f0e62dea14799046248c445771acf51b0e1015cb8512449ddf8c681a01bfa5c *Source\Debug\subdir.mk
-71f29f165b2554ec548bc56a113f38c0c993c2b34265acfd6d4c64a05f3db1ef *Source\Deprecated\Windows\fftp.sln
-8708f082b6072e0ab2c55984c2bd252f80049f2d4dceabf6fd8cf4815331cf7f *Source\Deprecated\Windows\fftp\debug.conf
-6315323d32acdc93160ed785f82631e686645370ae62082199f5c8000fc98e08 *Source\Deprecated\Windows\fftp\fftp.vcxproj
-016e2f6abf2fa7ee4ca49c518c3169cec6ba2ee15178b631b1313e22bbfcf123 *Source\Deprecated\Windows\fftp\fftp.vcxproj.filters
-c62aab3e5ead5d888a83355bfc322c86f873476213d4cfc961537731687dd2b0 *Source\Deprecated\Windows\fftp\fftp.vcxproj.user
-6145d9d5e7aaa668ae010c05c09a92473918b54119dd55141be9b62333e23966 *Source\Deprecated\Windows\fftp\ftpserv.c
-b50cb4bd51f5713d5189fab776e0cf654074ceb05532a9436744aeaa8ddba905 *Source\Deprecated\Windows\fftp\ftpserv.h
-159f10f1dc5e4be259a37a625174d1e643ec70a9708197e8e20931ebcd61c3f9 *Source\Deprecated\Windows\fftp\main.c
-893b90b942372928009bad64f166c7018701497e4f7cd1753cdc44f76da06707 *Source\Deprecated\Windows\fftp\minirtl\cmdline.c
-bd6fe82852c4fcdfab559defa33ea394b752a4e4a5ac0653ae20c4a94b0175ed *Source\Deprecated\Windows\fftp\minirtl\cmdline.h
-107245437ed86b6f1e839b2d3d9bbadb3d9980046cb5c7001f985fed3627962f *Source\Deprecated\Windows\fftp\minirtl\minirtl.h
-b9de99d3447bb1a125cb92aa1b3f9b56a59522436f1a1a97f23aac9cee90341c *Source\Deprecated\Windows\fftp\minirtl\rtltypes.h
-0320808115d42f04f63a382e8f386aa9bc77ba879892f5ccc94c40378b5131c8 *Source\Deprecated\Windows\fftp\minirtl\strtou64.c
-c51beca480d6e6f88174698503c0856c56488a59101d259c068dccb0902b01ec *Source\Deprecated\Windows\fftp\minirtl\strtoul.c
-4d15af5a22467795c5367c3956746d01424795784f62ca3f30e4619c063338a5 *Source\Deprecated\Windows\fftp\minirtl\u64tostr.c
-9cbedf9b92abaef3ea28de28dd523ac44079592178ef727c7003c339a5a54712 *Source\Deprecated\Windows\fftp\minirtl\ultostr.c
-83772aa217508279294d91af5cfabec9b5e00b836a2e2f5fe37cf1ebc2905a52 *Source\Deprecated\Windows\fftp\minirtl\_strcat.c
-2a67c7690ec6df8e233207116b0e4fe76c02ae43595d9e606e123572b6ac88a1 *Source\Deprecated\Windows\fftp\minirtl\_strcmp.c
-ef1b18997ea473ac8d516ef60efc64b9175418b8f078e088d783fdaef2544969 *Source\Deprecated\Windows\fftp\minirtl\_strcmpi.c
-969b35213fa23ff50a169e5498a97f28bc6f5820b447b78ec9dc6910dd8cc3e8 *Source\Deprecated\Windows\fftp\minirtl\_strcpy.c
-27159b8ff67d3f8e6c7fdb4b57b9f57f899bdfedf92cf10276269245c6f4e066 *Source\Deprecated\Windows\fftp\minirtl\_strend.c
-60f19c6b805801e13824c4d9d44748da8245cd936971411d3d36b873121888eb *Source\Deprecated\Windows\fftp\minirtl\_strlen.c
-87cc72bb8e3f1534bee09ee278ecd928d975ebb94aeffc767b67249815a0bf3a *Source\Deprecated\Windows\fftp\minirtl\_strncmpi.c
-0434d69daa20fbf87d829ffc17e43dcc2db3386aff434af888011fdec2f645a4 *Source\Deprecated\Windows\fftp\minirtl\_strncpy.c
-2850a07ea90193cc0206674ad1b62a0df01b343c7b5e548f7ecaca616ffb3a07 *Source\Release\makefile
-fa3d96ba5c45cb2b0004c8ea687045e16768ec90ec788f0958905083164e52f1 *Source\Release\objects.mk
-45bf7584af2acb3c6c806bd48b0774c661e081efdaff00d735554cde1ed76fbb *Source\Release\sources.mk
-c8a7f73c7aa597f350c40cb64a7dd4b51ad68862f46cc7ee8d3d5a0ea77f7e47 *Source\Release\subdir.mk
-f7d0ab874ee47ea673ddcdd3dfd9662646f9c1a796b94f3e1b33e1321baf52c3 *Source\TLS-cert\gencert.sh
-f3c8e1fdc3b05facb5e87ef1fc11b5fc1ee4d1d4832578f4fc1c23ecd488bab4 *Source\TLS-cert\mycert-req.txt
diff --git a/Source/Deprecated/Windows/fftp.sln b/Source/Deprecated/Windows/fftp.sln
deleted file mode 100644
index a0fb950..0000000
--- a/Source/Deprecated/Windows/fftp.sln
+++ /dev/null
@@ -1,28 +0,0 @@
-
-Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio 14
-VisualStudioVersion = 14.0.23107.0
-MinimumVisualStudioVersion = 10.0.40219.1
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "fftp", "fftp\fftp.vcxproj", "{65ED3B21-ABBD-4030-9F93-163805E8B9FC}"
-EndProject
-Global
- GlobalSection(SolutionConfigurationPlatforms) = preSolution
- Debug|x64 = Debug|x64
- Debug|x86 = Debug|x86
- Release|x64 = Release|x64
- Release|x86 = Release|x86
- EndGlobalSection
- GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {65ED3B21-ABBD-4030-9F93-163805E8B9FC}.Debug|x64.ActiveCfg = Debug|x64
- {65ED3B21-ABBD-4030-9F93-163805E8B9FC}.Debug|x64.Build.0 = Debug|x64
- {65ED3B21-ABBD-4030-9F93-163805E8B9FC}.Debug|x86.ActiveCfg = Debug|x64
- {65ED3B21-ABBD-4030-9F93-163805E8B9FC}.Debug|x86.Build.0 = Debug|x64
- {65ED3B21-ABBD-4030-9F93-163805E8B9FC}.Release|x64.ActiveCfg = Release|x64
- {65ED3B21-ABBD-4030-9F93-163805E8B9FC}.Release|x64.Build.0 = Release|x64
- {65ED3B21-ABBD-4030-9F93-163805E8B9FC}.Release|x86.ActiveCfg = Release|Win32
- {65ED3B21-ABBD-4030-9F93-163805E8B9FC}.Release|x86.Build.0 = Release|Win32
- EndGlobalSection
- GlobalSection(SolutionProperties) = preSolution
- HideSolutionNode = FALSE
- EndGlobalSection
-EndGlobal
diff --git a/Source/Deprecated/Windows/fftp/debug.conf b/Source/Deprecated/Windows/fftp/debug.conf
deleted file mode 100644
index 835c0d0..0000000
--- a/Source/Deprecated/Windows/fftp/debug.conf
+++ /dev/null
@@ -1,24 +0,0 @@
-[ftpconfig]
-port=21
-maxusers=8
-interface=0.0.0.0
-external_ip=99.99.99.99
-local_mask=255.255.255.0
-minport=10000
-maxport=20000
-logfilepath=C:\LOGS
-
-[anonymous]
-pswd=*
-accs=readonly
-root=Z:\FTP
-
-[uploader]
-pswd=uploader-password
-accs=upload
-root=Z:\FTP
-
-[root]
-pswd=admin-password
-accs=admin
-root=Z:\FTP
\ No newline at end of file
diff --git a/Source/Deprecated/Windows/fftp/fftp.vcxproj b/Source/Deprecated/Windows/fftp/fftp.vcxproj
deleted file mode 100644
index a915a09..0000000
--- a/Source/Deprecated/Windows/fftp/fftp.vcxproj
+++ /dev/null
@@ -1,263 +0,0 @@
-
-
-
-
- Debug
- Win32
-
-
- Release
- Win32
-
-
- Debug
- x64
-
-
- Release
- x64
-
-
-
- {65ED3B21-ABBD-4030-9F93-163805E8B9FC}
- fftp
- 8.1
-
-
-
- Application
- true
- v140
- Unicode
-
-
- Application
- false
- v140
- true
- Unicode
-
-
- Application
- true
- v140
- Unicode
-
-
- Application
- false
- v140
- true
- Unicode
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- AllRules.ruleset
- true
- .\output\$(Platform)\$(Configuration)\
- .\output\$(Platform)\$(Configuration)\
-
-
- AllRules.ruleset
- true
- false
- .\output\$(Platform)\$(Configuration)\
- .\output\$(Platform)\$(Configuration)\
-
-
- AllRules.ruleset
- true
- .\output\$(Platform)\$(Configuration)\
- .\output\$(Platform)\$(Configuration)\
- false
-
-
- AllRules.ruleset
- true
- false
- .\output\$(Platform)\$(Configuration)\
- .\output\$(Platform)\$(Configuration)\
-
-
-
- Level4
- Disabled
- true
- true
- true
- true
- All
- true
- CompileAsC
- 6258
-
-
- true
-
-
- false
-
-
- false
-
-
-
-
- Level4
- Disabled
- true
- true
- true
- true
- All
- true
- CompileAsC
- 6258
-
-
- true
- 6.3
- true
- true
- Console
-
-
-
-
- false
-
-
- false
-
-
- false
-
-
-
-
- Level4
- Full
- true
- true
- true
- true
- true
- true
- All
- true
- CompileAsC
- Speed
- true
- Guard
- 6258
-
-
- false
- true
- true
- 6.3
- true
- true
- Console
- main
- true
-
-
- false
-
-
- false
-
-
- false
-
-
-
-
- Level4
- Full
- true
- true
- true
- true
- true
- true
- All
- true
- CompileAsC
- Speed
- true
- Guard
- false
- MultiThreaded
- 6258
-
-
- false
- true
- true
- 6.3
- true
- true
- Console
- true
- true
- main
- true
-
- false
-
-
- false
-
-
- false
-
-
- false
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/Source/Deprecated/Windows/fftp/fftp.vcxproj.filters b/Source/Deprecated/Windows/fftp/fftp.vcxproj.filters
deleted file mode 100644
index c7f1e5e..0000000
--- a/Source/Deprecated/Windows/fftp/fftp.vcxproj.filters
+++ /dev/null
@@ -1,84 +0,0 @@
-
-
-
-
- {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
- cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
-
-
- {93995380-89BD-4b04-88EB-625FBE52EBFB}
- h;hh;hpp;hxx;hm;inl;inc;xsd
-
-
- {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
- rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
-
-
- {81073c34-4db9-483c-a154-1e9e30a78992}
-
-
- {96e240ff-d46f-4802-bd54-6836c2bbf393}
-
-
-
-
- Source Files
-
-
- Source Files
-
-
- Source Files\rtl_c
-
-
- Source Files\rtl_c
-
-
- Source Files\rtl_c
-
-
- Source Files\rtl_c
-
-
- Source Files\rtl_c
-
-
- Source Files\rtl_c
-
-
- Source Files\rtl_c
-
-
- Source Files\rtl_c
-
-
- Source Files\rtl_c
-
-
- Source Files\rtl_c
-
-
- Source Files\rtl_c
-
-
- Source Files\rtl_c
-
-
- Source Files\rtl_c
-
-
-
-
- Header Files
-
-
- Header Files\rtl_h
-
-
- Header Files\rtl_h
-
-
- Header Files\rtl_h
-
-
-
\ No newline at end of file
diff --git a/Source/Deprecated/Windows/fftp/fftp.vcxproj.user b/Source/Deprecated/Windows/fftp/fftp.vcxproj.user
deleted file mode 100644
index 8f51c29..0000000
--- a/Source/Deprecated/Windows/fftp/fftp.vcxproj.user
+++ /dev/null
@@ -1,7 +0,0 @@
-
-
-
- .\debug.conf
- WindowsLocalDebugger
-
-
\ No newline at end of file
diff --git a/Source/Deprecated/Windows/fftp/ftpserv.c b/Source/Deprecated/Windows/fftp/ftpserv.c
deleted file mode 100644
index 8b23414..0000000
--- a/Source/Deprecated/Windows/fftp/ftpserv.c
+++ /dev/null
@@ -1,1646 +0,0 @@
-// ftpserv.c - simple ftp server
-#include
-#include "minirtl\minirtl.h"
-#include "minirtl\cmdline.h"
-#include "ftpserv.h"
-
-FTP_CONFIG g_cfg;
-HANDLE g_LogHandle;
-LONG g_NewID = 0;
-ULONG g_NextPort = 0;
-
-BOOL sendstring(SOCKET s, const char *Buffer)
-{
- return ( send(s, Buffer, (int)_strlen_a(Buffer), 0) >= 0 );
-}
-
-BOOL writeconsolestr(const char *Buffer)
-{
- DWORD bytesIO, l;
-
- l = (DWORD)_strlen_a(Buffer);
-
- if ( (g_LogHandle != NULL) && (g_LogHandle != INVALID_HANDLE_VALUE) )
- WriteFile(g_LogHandle, Buffer, l, &bytesIO, NULL);
-
- return WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), Buffer, l, &bytesIO, NULL);
-}
-
-BOOL writelogentry(PFTPCONTEXT context, char *logtext1, char *logtext2)
-{
- char cvbuf[32], textbuf[MAX_PATH*4];
- SYSTEMTIME tm;
-
- GetLocalTime(&tm);
-
- textbuf[0] = 0;
-
- if ( tm.wDay < 10 )
- _strcat_a(textbuf, "0");
- ultostr_a(tm.wDay, cvbuf);
- _strcat_a(textbuf, cvbuf);
- _strcat_a(textbuf, "-");
- if ( tm.wMonth < 10 )
- _strcat_a(textbuf, "0");
- ultostr_a(tm.wMonth, cvbuf);
- _strcat_a(textbuf, cvbuf);
- _strcat_a(textbuf, "-");
- ultostr_a(tm.wYear, cvbuf);
- _strcat_a(textbuf, cvbuf);
- _strcat_a(textbuf, " ");
-
- if ( tm.wHour < 10 )
- _strcat_a(textbuf, "0");
- ultostr_a(tm.wHour, cvbuf);
- _strcat_a(textbuf, cvbuf);
- _strcat_a(textbuf, ":");
- if ( tm.wMinute < 10 )
- _strcat_a(textbuf, "0");
- ultostr_a(tm.wMinute, cvbuf);
- _strcat_a(textbuf, cvbuf);
- _strcat_a(textbuf, ":");
- if ( tm.wSecond < 10 )
- _strcat_a(textbuf, "0");
- ultostr_a(tm.wSecond, cvbuf);
- _strcat_a(textbuf, cvbuf);
-
- _strcat_a(textbuf, " S-id=");
- ultostr_a(context->SessionID, _strend_a(textbuf));
- _strcat_a(textbuf, ": ");
- _strcat_a(textbuf, logtext1);
- _strcat_a(textbuf, logtext2);
- _strcat_a(textbuf, CRLF);
-
- return writeconsolestr(textbuf);
-}
-
-void unixpath(char *s)
-{
- while ( *s != 0 ) {
- if ( *s == '\\' )
- *s = '/';
- s++;
- }
-}
-
-void ntpath(char *s)
-{
- while ( *s != 0 ) {
- if ( *s == '/' )
- *s = '\\';
- s++;
- }
-}
-
-void nolastslash(char *s)
-{
- if ( s == NULL )
- return;
-
- if ( *s == 0 )
- return;
-
- if ( (*s == '\\') && (s[1] == 0) )
- return;
-
- while ( s[1] != 0 )
- s++;
-
- if ( *s == '\\' )
- *s = 0;
-}
-
-void addlastslash(char *s)
-{
- if ( s == NULL )
- return;
-
- if ( *s == 0 ) {
- *s = '\\';
- s[1] = 0;
- return;
- }
-
- while ( s[1] != 0 )
- s++;
-
- if ( *s == '\\' )
- return;
-
- s[1] = '\\';
- s[2] = 0;
-}
-
-void formatpath(char *s) // removes multiple slashes, dots
-{
- char *d = s, *p = s;
-
- while ( *p != 0 ) {
- if ( *p == '\\' )
- if ( p[1] == '.' ) {
- if ( p[2] == '.' )
- if ( p[3] == '\\' ) {
- while ( d < p+3 ) {
- *d = '\\';
- d++;
- }
- p = s;
- d = s;
- continue;
- }
- } else
- if ( p[1] != '\\' )
- d = p;
- p++;
- }
-
- d = s;
- p = s;
-
- while ( *p != 0 ) {
- if ( *p == '\\' ) {
- if ( p[1] == '\\' ) {
- p++;
- continue;
- }
-
- if ( p[1] == '.' ) {
- if ( p[2] == '\\' ) {
- p += 2;
- continue;
- }
- }
- }
-
- *d = *p;
- d++;
- p++;
- }
- *d = 0;
-}
-
-void filepath(char *s)
-{
- char *p = s;
-
- if ( (*s == '\\') && (s[1] == 0) )
- return;
-
- while ( *s != 0 ) {
- if ( *s == '\\' )
- p = s;
- s++;
- }
- *p = 0;
-}
-
-void finalpath(LPCSTR RootDir, LPCSTR CurrentDir, LPSTR Params, LPSTR Buffer)
-{
- char *root = Buffer;
-
- _strcpy_a(Buffer, RootDir);
- root = _strend_a(Buffer);
-
- if ( Params == NULL ) {
- addlastslash(root);
- _strcat_a(root, CurrentDir);
- addlastslash(root);
- formatpath(root);
- return;
- }
-
- ntpath(Params);
- if ( *Params != '\\' ) {
- addlastslash(root);
- _strcat_a(root, CurrentDir);
- }
-
- _strcat_a(root, Params);
- addlastslash(root);
- formatpath(root);
- formatpath(Buffer);
-}
-
-BOOL list_sub(SOCKET s, WIN32_FIND_DATA *fdata)
-{
- TCHAR textbuf[MAX_PATH];
- CHAR sendbuf[MAX_PATH];
- FILETIME ltm;
- ULARGE_INTEGER sz, deltatime;
- SYSTEMTIME tm;
-
- if ( _strcmp(fdata->cFileName, TEXT(".")) == 0 )
- return TRUE;
- if ( _strcmp(fdata->cFileName, TEXT("..")) == 0 )
- return TRUE;
-
- RtlSecureZeroMemory(<m, sizeof(ltm));
- RtlSecureZeroMemory(&tm, sizeof(tm));
-
- if ((fdata->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0)
- _strcpy(textbuf, TEXT("-rw-rw-rw- 1"));
- else
- _strcpy(textbuf, TEXT("drwxrwxrwx 2"));
-
- _strcat(textbuf, TEXT(" 9001 9001 "));
-
- sz.LowPart = fdata->nFileSizeLow;
- sz.HighPart = fdata->nFileSizeHigh;
- u64tostr(sz.QuadPart, _strend(textbuf));
- _strcat(textbuf, TEXT(" "));
-
- GetSystemTimeAsFileTime(<m);
- sz.HighPart = fdata->ftLastWriteTime.dwHighDateTime;
- sz.LowPart = fdata->ftLastWriteTime.dwLowDateTime;
- deltatime.HighPart = ltm.dwHighDateTime;
- deltatime.LowPart = ltm.dwLowDateTime;
- deltatime.QuadPart -= sz.QuadPart;
-
- FileTimeToLocalFileTime(&fdata->ftLastWriteTime, <m);
- FileTimeToSystemTime(<m, &tm);
-
- _strncpy(_strend(textbuf), 4, &shortmonths[(tm.wMonth-1) * 3], 4);
- _strcat(textbuf, TEXT(" "));
-
- if ( tm.wDay < 10 )
- _strcat(textbuf, TEXT("0"));
- ultostr(tm.wDay, _strend(textbuf));
- _strcat(textbuf, TEXT(" "));
-
- if (deltatime.QuadPart < (180*24*60*60*10000000ui64)) {
- if (tm.wHour < 10)
- _strcat(textbuf, TEXT("0"));
- ultostr(tm.wHour, _strend(textbuf));
- _strcat(textbuf, TEXT(":"));
-
- if (tm.wMinute < 10)
- _strcat(textbuf, TEXT("0"));
- ultostr(tm.wMinute, _strend(textbuf));
- } else {
- ultostr(tm.wYear, _strend(textbuf));
- }
- _strcat(textbuf, TEXT(" "));
-
- WideCharToMultiByte(CP_UTF8, 0, textbuf, MAX_PATH, sendbuf, MAX_PATH, NULL, NULL);
- if ( !sendstring(s, sendbuf) )
- return FALSE;
- WideCharToMultiByte(CP_UTF8, 0, fdata->cFileName, MAX_PATH, sendbuf, MAX_PATH, NULL, NULL);
- if ( !sendstring(s, sendbuf) )
- return FALSE;
-
- return sendstring(s, CRLF);
-}
-
-BOOL mlsd_sub(SOCKET s, WIN32_FIND_DATA *fdata)
-{
- TCHAR textbuf[MAX_PATH];
- CHAR sendbuf[MAX_PATH];
- ULARGE_INTEGER sz;
- SYSTEMTIME tm;
-
- if (_strcmp(fdata->cFileName, TEXT(".")) == 0)
- return TRUE;
- if (_strcmp(fdata->cFileName, TEXT("..")) == 0)
- return TRUE;
-
- _strcpy(textbuf, TEXT("type="));
- if ((fdata->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0)
- _strcat(textbuf, TEXT("file;size="));
- else
- _strcat(textbuf, TEXT("dir;sizd="));
-
- sz.LowPart = fdata->nFileSizeLow;
- sz.HighPart = fdata->nFileSizeHigh;
- u64tostr(sz.QuadPart, _strend(textbuf));
- _strcat(textbuf, TEXT(";modify="));
-
- RtlSecureZeroMemory(&tm, sizeof(tm));
- FileTimeToSystemTime(&fdata->ftLastWriteTime, &tm);
-
- ultostr(tm.wYear, _strend(textbuf));
- if (tm.wMonth < 10)
- _strcat(textbuf, TEXT("0"));
- ultostr(tm.wMonth, _strend(textbuf));
- if (tm.wDay < 10)
- _strcat(textbuf, TEXT("0"));
- ultostr(tm.wDay, _strend(textbuf));
- if (tm.wHour < 10)
- _strcat(textbuf, TEXT("0"));
- ultostr(tm.wHour, _strend(textbuf));
- if (tm.wMinute < 10)
- _strcat(textbuf, TEXT("0"));
- ultostr(tm.wMinute, _strend(textbuf));
- if (tm.wSecond < 10)
- _strcat(textbuf, TEXT("0"));
- ultostr(tm.wSecond, _strend(textbuf));
- _strcat(textbuf, TEXT("; "));
-
- WideCharToMultiByte(CP_UTF8, 0, textbuf, MAX_PATH, sendbuf, MAX_PATH, NULL, NULL);
- if (!sendstring(s, sendbuf))
- return FALSE;
- WideCharToMultiByte(CP_UTF8, 0, fdata->cFileName, MAX_PATH, sendbuf, MAX_PATH, NULL, NULL);
- if (!sendstring(s, sendbuf))
- return FALSE;
-
- return sendstring(s, CRLF);
-}
-
-SOCKET create_datasocket(IN PFTPCONTEXT context)
-{
- SOCKET clientsocket = INVALID_SOCKET;
- struct sockaddr_in laddr;
- int asz;
-
- RtlSecureZeroMemory(&laddr, sizeof(laddr));
-
- switch ( context->Mode ) {
- case MODE_NORMAL:
- clientsocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
- if ( clientsocket == INVALID_SOCKET )
- return INVALID_SOCKET;
-
- laddr.sin_family = AF_INET;
- laddr.sin_port = (u_short)context->DataPort;
- laddr.sin_addr.S_un.S_addr = context->DataIPv4;
- if ( connect(clientsocket, (const struct sockaddr *)&laddr, sizeof(laddr)) == SOCKET_ERROR ) {
- closesocket(clientsocket);
- return INVALID_SOCKET;
- }
- break;
-
- case MODE_PASSIVE:
- asz = sizeof(laddr);
- clientsocket = accept(context->DataSocket, (struct sockaddr *)&laddr, &asz);
- if ( clientsocket == INVALID_SOCKET )
- return INVALID_SOCKET;
- context->DataIPv4 = 0;
- context->DataPort = 0;
- context->Mode = MODE_NORMAL;
- closesocket(context->DataSocket);
- context->DataSocket = 0;
- break;
-
- default:
- return INVALID_SOCKET;
- }
- return clientsocket;
-}
-
-DWORD WINAPI list_thread(IN PFTPCONTEXT context)
-{
- SOCKET clientsocket, control;
- HANDLE File;
- BOOL sendok = FALSE;
- WIN32_FIND_DATA fdata;
-
- EnterCriticalSection(&context->MTLock);
- control = context->ControlSocket;
- clientsocket = create_datasocket(context);
- if ( clientsocket == INVALID_SOCKET )
- goto error_exit;
-
- RtlSecureZeroMemory(&fdata, sizeof(fdata));
- File = FindFirstFile(context->TextBuffer, &fdata);
- if ( File != INVALID_HANDLE_VALUE ) {
- sendok = list_sub(clientsocket, &fdata);
- while ( FindNextFile(File, &fdata) && (!context->Stop) && sendok )
- sendok = list_sub(clientsocket, &fdata);
- FindClose(File);
- }
- sendok = ( context->Stop == FALSE ) && ( sendok != FALSE );
-
-error_exit:
- if ( clientsocket != INVALID_SOCKET )
- closesocket(clientsocket);
-
- writelogentry(context, " LIST complete", NULL);
-
- CloseHandle(context->WorkerThread);
- context->WorkerThread = NULL;
- LeaveCriticalSection(&context->MTLock);
-
- if ( clientsocket == INVALID_SOCKET ) {
- sendstring(control, error451);
- } else {
- if ( sendok )
- sendstring(control, success226);
- else
- sendstring(control, error426);
- }
-
- return 0;
-}
-
-DWORD WINAPI mlsd_thread(IN PFTPCONTEXT context)
-{
- SOCKET clientsocket, control;
- HANDLE File;
- BOOL sendok = FALSE;
- WIN32_FIND_DATA fdata;
-
- EnterCriticalSection(&context->MTLock);
- control = context->ControlSocket;
- clientsocket = create_datasocket(context);
- if (clientsocket == INVALID_SOCKET)
- goto error_exit;
-
- RtlSecureZeroMemory(&fdata, sizeof(fdata));
- File = FindFirstFile(context->TextBuffer, &fdata);
- if (File != INVALID_HANDLE_VALUE) {
- sendok = mlsd_sub(clientsocket, &fdata);
- while (FindNextFile(File, &fdata) && (!context->Stop) && sendok)
- sendok = mlsd_sub(clientsocket, &fdata);
- FindClose(File);
- }
- sendok = (context->Stop == FALSE) && (sendok != FALSE);
-
-error_exit:
- if (clientsocket != INVALID_SOCKET)
- closesocket(clientsocket);
-
- writelogentry(context, " LIST complete", NULL);
-
- CloseHandle(context->WorkerThread);
- context->WorkerThread = NULL;
- LeaveCriticalSection(&context->MTLock);
-
- if (clientsocket == INVALID_SOCKET) {
- sendstring(control, error451);
- }
- else {
- if (sendok)
- sendstring(control, success226);
- else
- sendstring(control, error426);
- }
-
- return 0;
-}
-
-DWORD WINAPI retr_thread(IN PFTPCONTEXT context)
-{
- SOCKET clientsocket, control;
- LPSTR textbuf = NULL;
- BOOL sendok = FALSE;
- int asz;
- LARGE_INTEGER lsz, dt0, dt1;
- FILETIME txtime;
-
- EnterCriticalSection(&context->MTLock);
- control = context->ControlSocket;
-
- clientsocket = create_datasocket(context);
- if ( clientsocket == INVALID_SOCKET )
- goto error_exit;
-
- textbuf = (char *)VirtualAlloc(NULL, TRANSMIT_BUFFER_SIZE, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
- if ( textbuf == NULL )
- goto error_exit;
-
- lsz.QuadPart = 0;
- GetFileSizeEx(context->FileHandle, &lsz);
-
- if ( lsz.QuadPart == 0 ) {
- sendok = TRUE;
- goto error_exit;
- }
-
- GetSystemTimeAsFileTime(&txtime);
- dt0.HighPart = txtime.dwHighDateTime;
- dt0.LowPart = txtime.dwLowDateTime;
- lsz.QuadPart = 0;
-
- SetFilePointerEx(context->FileHandle, context->RestPoint, NULL, FILE_BEGIN);
- while ( !context->Stop ) {
- asz = 0;
- if ( !ReadFile(context->FileHandle, textbuf, TRANSMIT_BUFFER_SIZE, (LPDWORD)&asz, NULL) ) {
- sendok = FALSE;
- break;
- }
-
- if ( asz > 0 )
- sendok = (send(clientsocket, textbuf, asz, 0) == asz);
- else
- break;
-
- if ( !sendok )
- break;
-
- lsz.QuadPart += asz;
- GetSystemTimeAsFileTime(&txtime);
- dt1.HighPart = txtime.dwHighDateTime;
- dt1.LowPart = txtime.dwLowDateTime;
- dt1.QuadPart -= dt0.QuadPart;
- if (dt1.QuadPart > 100000000ui64) { // 10 seconds
- _strcpy_a(textbuf, " retr speed: ");
- u64tostr_a(((10000000ui64*lsz.QuadPart) / dt1.QuadPart) / 1024, _strend_a(textbuf));
- _strcat_a(textbuf, " kBytes/s");
- writelogentry(context, textbuf, NULL);
- lsz.QuadPart = 0;
- dt0.HighPart = txtime.dwHighDateTime;
- dt0.LowPart = txtime.dwLowDateTime;
- }
- }
- sendok = ( context->Stop == FALSE ) && ( sendok != FALSE );
-
-error_exit:
- CloseHandle(context->FileHandle);
- context->FileHandle = INVALID_HANDLE_VALUE;
-
- if ( textbuf != NULL )
- VirtualFree(textbuf, 0, MEM_RELEASE);
-
- if ( clientsocket != INVALID_SOCKET )
- closesocket(clientsocket);
-
- writelogentry(context, " RETR complete", NULL);
-
- CloseHandle(context->WorkerThread);
- context->WorkerThread = NULL;
- LeaveCriticalSection(&context->MTLock);
-
- if ( clientsocket == INVALID_SOCKET )
- sendstring(control, error451);
- else {
- if ( sendok )
- sendstring(control, success226);
- else
- sendstring(control, error426);
- }
-
- return 0;
-}
-
-DWORD WINAPI stor_thread(IN PFTPCONTEXT context)
-{
- SOCKET clientsocket, control;
- LPSTR textbuf = NULL;
- BOOL sendok = FALSE;
- int asz, iobytes;
-
- EnterCriticalSection(&context->MTLock);
- control = context->ControlSocket;
-
- clientsocket = create_datasocket(context);
- if ( clientsocket == INVALID_SOCKET )
- goto error_exit;
-
- textbuf = (char *)VirtualAlloc(NULL, TRANSMIT_BUFFER_SIZE, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
- if ( textbuf == NULL )
- goto error_exit;
-
- while ( !context->Stop )
- {
- asz = 0;
- iobytes = recv(clientsocket, textbuf, TRANSMIT_BUFFER_SIZE, 0);
- if ( (iobytes > 0) && (iobytes != SOCKET_ERROR) )
- WriteFile(context->FileHandle, textbuf, iobytes, (LPDWORD)&asz, NULL);
- else
- break;
-
- sendok = (iobytes == asz);
-
- if ( !sendok )
- break;
- }
- sendok = ( context->Stop == FALSE ) && ( sendok != FALSE );
-
-error_exit:
- CloseHandle(context->FileHandle);
- context->FileHandle = INVALID_HANDLE_VALUE;
-
- if ( textbuf != NULL )
- VirtualFree(textbuf, 0, MEM_RELEASE);
-
- if ( clientsocket != INVALID_SOCKET )
- closesocket(clientsocket);
-
- writelogentry(context, " STOR complete", NULL);
-
- CloseHandle(context->WorkerThread);
- context->WorkerThread = NULL;
- LeaveCriticalSection(&context->MTLock);
-
- if ( clientsocket == INVALID_SOCKET )
- sendstring(control, error451);
- else {
- if ( sendok )
- sendstring(control, success226);
- else
- sendstring(control, error426);
- }
-
- return 0;
-}
-
-void StopWorkerThread(IN PFTPCONTEXT context)
-{
- if ( context->WorkerThread != NULL ) {
- context->Stop = TRUE; // trying to stop gracefully
- if ( WaitForSingleObjectEx(context->WorkerThread, 4000, FALSE) == STATUS_TIMEOUT ) {
- // fail? ok, will do bad things
- TerminateThread(context->WorkerThread, 0);
- }
- CloseHandle(context->WorkerThread);
- }
-
- if ( context->FileHandle != INVALID_HANDLE_VALUE ) {
- CloseHandle(context->FileHandle);
- context->FileHandle = INVALID_HANDLE_VALUE;
- }
-
- context->DataIPv4 = 0;
- context->DataPort = 0;
-
- if ( context->DataSocket != 0 ) {
- closesocket(context->DataSocket);
- context->DataSocket = 0;
- }
- context->WorkerThread = NULL;
-}
-
-/* FTP COMMANDS BEGIN */
-
-BOOL ftpSTOR(IN PFTPCONTEXT context, IN const char *params)
-{
- HANDLE wth;
- DWORD fileaccess;
- CHAR textbuf[MAX_PATH*3];
- TCHAR filename[MAX_PATH];
-
- if ( context->Access == FTP_ACCESS_NOT_LOGGED_IN )
- return sendstring(context->ControlSocket, error530);
- if ( context->Access < FTP_ACCESS_CREATENEW )
- return sendstring(context->ControlSocket, error550_r);
- if ( params == NULL )
- return sendstring(context->ControlSocket, error501);
- if ( context->WorkerThread != NULL )
- return sendstring(context->ControlSocket, error550_t);
-
- RtlSecureZeroMemory(textbuf, sizeof(textbuf));
- finalpath(context->RootDir, context->CurrentDir, (char *)params, textbuf);
- nolastslash(textbuf);
-
- if (MultiByteToWideChar(CP_UTF8, 0, textbuf, MAX_PATH, filename, MAX_PATH) <= 0)
- filename[0] = 0;
-
- if ( context->Access > FTP_ACCESS_CREATENEW )
- fileaccess = CREATE_ALWAYS;
- else
- fileaccess = CREATE_NEW;
-
- context->FileHandle = CreateFile(filename, SYNCHRONIZE | GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, fileaccess, FILE_ATTRIBUTE_NORMAL, NULL);
- if ( context->FileHandle == INVALID_HANDLE_VALUE )
- return sendstring(context->ControlSocket, error550);
-
- sendstring(context->ControlSocket, interm150);
- writelogentry(context, " STOR: ", (char *)params);
- context->Stop = FALSE;
-
- wth = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)&stor_thread, (LPVOID)context, 0, NULL);
- if ( wth == NULL ) {
- CloseHandle(context->FileHandle);
- context->FileHandle = INVALID_HANDLE_VALUE;
- sendstring(context->ControlSocket, error451);
- }
- else
- context->WorkerThread = wth;
-
- return TRUE;
-}
-
-BOOL ftpAPPE(IN PFTPCONTEXT context, IN const char *params)
-{
- HANDLE wth;
- LARGE_INTEGER fptr;
- CHAR textbuf[MAX_PATH*3];
- TCHAR filename[MAX_PATH];
-
- if ( context->Access == FTP_ACCESS_NOT_LOGGED_IN )
- return sendstring(context->ControlSocket, error530);
- if ( context->Access < FTP_ACCESS_FULL )
- return sendstring(context->ControlSocket, error550_r);
- if ( params == NULL )
- return sendstring(context->ControlSocket, error501);
- if ( context->WorkerThread != NULL )
- return sendstring(context->ControlSocket, error550_t);
-
- RtlSecureZeroMemory(textbuf, sizeof(textbuf));
- finalpath(context->RootDir, context->CurrentDir, (char *)params, textbuf);
- nolastslash(textbuf);
-
- if (MultiByteToWideChar(CP_UTF8, 0, textbuf, MAX_PATH, filename, MAX_PATH) <= 0)
- filename[0] = 0;
-
- context->FileHandle = CreateFile(filename, SYNCHRONIZE | GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
- if ( context->FileHandle == INVALID_HANDLE_VALUE )
- return sendstring(context->ControlSocket, error550);
-
- fptr.QuadPart = 0;
- SetFilePointerEx(context->FileHandle, fptr, NULL, FILE_END);
- sendstring(context->ControlSocket, interm150);
- writelogentry(context, " APPE: ", (char *)params);
- context->Stop = FALSE;
-
- wth = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)&stor_thread, (LPVOID)context, 0, NULL);
- if ( wth == NULL ) {
- CloseHandle(context->FileHandle);
- context->FileHandle = INVALID_HANDLE_VALUE;
- sendstring(context->ControlSocket, error451);
- } else
- context->WorkerThread = wth;
-
- return TRUE;
-}
-
-BOOL ftpRETR(IN PFTPCONTEXT context, IN const char *params)
-{
- CHAR textbuf[MAX_PATH*3];
- TCHAR filename[MAX_PATH];
- HANDLE wth;
-
- if ( context->Access == FTP_ACCESS_NOT_LOGGED_IN )
- return sendstring(context->ControlSocket, error530);
- if ( params == NULL )
- return sendstring(context->ControlSocket, error501);
- if ( context->WorkerThread != NULL )
- return sendstring(context->ControlSocket, error550_t);
-
- RtlSecureZeroMemory(textbuf, sizeof(textbuf));
- finalpath(context->RootDir, context->CurrentDir, (char *)params, textbuf);
- nolastslash(textbuf);
-
- if (MultiByteToWideChar(CP_UTF8, 0, textbuf, MAX_PATH, filename, MAX_PATH) <= 0)
- filename[0] = 0;
-
- context->FileHandle = CreateFile(filename, SYNCHRONIZE | GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL);
- if ( context->FileHandle == INVALID_HANDLE_VALUE )
- return sendstring(context->ControlSocket, error550);
-
- sendstring(context->ControlSocket, interm150);
- writelogentry(context, " RETR: ", (char *)params);
- context->Stop = FALSE;
-
- wth = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)&retr_thread, (LPVOID)context, 0, NULL);
- if ( wth == NULL ) {
- CloseHandle(context->FileHandle);
- context->FileHandle = INVALID_HANDLE_VALUE;
- sendstring(context->ControlSocket, error451);
- } else
- context->WorkerThread = wth;
-
- return TRUE;
-}
-
-BOOL ftpLIST(IN PFTPCONTEXT context, IN const char *params)
-{
- WIN32_FILE_ATTRIBUTE_DATA adata;
- HANDLE wth;
- CHAR textbuf[MAX_PATH*3];
-
- if ( context->Access == FTP_ACCESS_NOT_LOGGED_IN )
- return sendstring(context->ControlSocket, error530);
- if (context->WorkerThread != NULL)
- return sendstring(context->ControlSocket, error550_t);
-
- context->FileHandle = INVALID_HANDLE_VALUE;
-
- RtlSecureZeroMemory(textbuf, sizeof(textbuf));
- RtlSecureZeroMemory(context->TextBuffer, sizeof(context->TextBuffer));
-
- if ( params != NULL )
- if ( (params[0] == '-') && (params[1] == 'l') && (params[2] == 0) )
- params = NULL;
-
- finalpath(context->RootDir, context->CurrentDir, (char *)params, textbuf);
-
- if (MultiByteToWideChar(CP_UTF8, 0, textbuf, MAX_PATH, context->TextBuffer, MAX_PATH) <= 0)
- context->TextBuffer[0] = 0;
-
- if ( !GetFileAttributesEx(context->TextBuffer, GetFileExInfoStandard, &adata) )
- return sendstring(context->ControlSocket, error550);
- if ( (adata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0 )
- return sendstring(context->ControlSocket, error550);
-
- _strcat(context->TextBuffer, TEXT("*"));
-
- sendstring(context->ControlSocket, interm150);
- writelogentry(context, " LIST: ", (char *)params);
- context->Stop = FALSE;
-
- wth = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)&list_thread, (LPVOID)context, 0, NULL);
- if ( wth == NULL )
- sendstring(context->ControlSocket, error451);
- else
- context->WorkerThread = wth;
-
- return TRUE;
-}
-
-BOOL ftpPASV(IN PFTPCONTEXT context, IN const char *params)
-{
- SOCKET datasocket;
- struct sockaddr_in laddr;
- int socketret = SOCKET_ERROR;
- CHAR textbuf[MAX_PATH];
- ULONG c;
-
- UNREFERENCED_PARAMETER(params);
-
- if ( context->Access == FTP_ACCESS_NOT_LOGGED_IN )
- return sendstring(context->ControlSocket, error530);
- if (context->WorkerThread != NULL)
- return sendstring(context->ControlSocket, error550_t);
- if ( context->DataSocket != 0 )
- closesocket(context->DataSocket);
-
- datasocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
- if (datasocket == INVALID_SOCKET)
- return sendstring(context->ControlSocket, error451);
-
- RtlSecureZeroMemory(&laddr, sizeof(laddr));
- for (c = g_cfg.PasvPortBase; c <= g_cfg.PasvPortMax; c++) {
- RtlSecureZeroMemory(&laddr, sizeof(laddr));
- laddr.sin_family = AF_INET;
-
- laddr.sin_port = htons((u_short)(g_cfg.PasvPortBase +
- (InterlockedIncrement(&g_NewID) % (g_cfg.PasvPortMax-g_cfg.PasvPortBase))));
-
- laddr.sin_addr.S_un.S_addr = context->ServerIPv4;
- socketret = bind(datasocket, (struct sockaddr *)&laddr, sizeof(laddr));
- if ( socketret == 0 )
- break;
- }
-
- if ( socketret != 0 ) {
- closesocket(datasocket);
- return sendstring(context->ControlSocket, error451);
- }
- socketret = listen(datasocket, SOMAXCONN);
- if (socketret != 0) {
- closesocket(datasocket);
- return sendstring(context->ControlSocket, error451);
- }
-
- if ((context->ClientIPv4 & g_cfg.LocalIPMask) == (context->ServerIPv4 & g_cfg.LocalIPMask))
- {
- context->DataIPv4 = context->ServerIPv4;
- writelogentry(context, " local client.", NULL);
- }
- else
- {
- context->DataIPv4 = g_cfg.ExternalInterface;
- writelogentry(context, " nonlocal client.", NULL);
- }
-
- context->DataPort = laddr.sin_port;
- context->DataSocket = datasocket;
- context->Mode = MODE_PASSIVE;
-
- sendstring(context->ControlSocket, success227);
- for (c = 0; c < 4; c++) {
- ultostr_a((context->DataIPv4 >> (c*8)) & 0xff, textbuf);
- _strcat_a(textbuf, ",");
- sendstring(context->ControlSocket, textbuf);
- }
-
- ultostr_a(context->DataPort & 0xff, textbuf);
- _strcat_a(textbuf, ",");
- sendstring(context->ControlSocket, textbuf);
- ultostr_a((context->DataPort >> 8) & 0xff, textbuf);
- _strcat_a(textbuf, ").");
- _strcat_a(textbuf, CRLF);
-
- writelogentry(context, " entering passive mode", NULL);
-
- return sendstring(context->ControlSocket, textbuf);
-}
-
-BOOL ftpPORT(IN PFTPCONTEXT context, IN const char *params)
-{
- int c;
- ULONG DataIP = 0, DataP = 0;
- char *p = (char *)params;
-
- if ( context->Access == FTP_ACCESS_NOT_LOGGED_IN )
- return sendstring(context->ControlSocket, error530);
-
- if ( params == NULL )
- return sendstring(context->ControlSocket, error501);
-
- for (c = 0; c < 4; c++) {
- ((BYTE *)&DataIP)[c] = (BYTE)strtoul_a(p);
- while ( (*p >= '0') && (*p <= '9') )
- p++;
- if ( *p == 0 )
- break;
- p++;
- }
-
- for (c = 0; c < 2; c++) {
- ((BYTE *)&DataP)[c] = (BYTE)strtoul_a(p);
- while ( (*p >= '0') && (*p <= '9') )
- p++;
- if ( *p == 0 )
- break;
- p++;
- }
-
- if ( DataIP != context->ClientIPv4 )
- return sendstring(context->ControlSocket, error501);
-
- context->DataIPv4 = DataIP;
- context->DataPort = DataP;
- context->Mode = MODE_NORMAL;
-
- return sendstring(context->ControlSocket, success200);
-}
-
-BOOL ftpREST(IN PFTPCONTEXT context, IN const char *params)
-{
- CHAR textbuf[MAX_PATH];
-
- if ( context->Access == FTP_ACCESS_NOT_LOGGED_IN )
- return sendstring(context->ControlSocket, error530);
-
- if ( params == NULL )
- return sendstring(context->ControlSocket, error501);
-
- context->RestPoint.QuadPart = strtou64_a((char *)params);
- sendstring(context->ControlSocket, interm350);
- u64tostr_a(context->RestPoint.QuadPart, textbuf);
- _strcat_a(textbuf, CRLF);
- return sendstring(context->ControlSocket, textbuf);
-}
-
-BOOL ftpCWD(IN PFTPCONTEXT context, IN const char *params)
-{
- WIN32_FILE_ATTRIBUTE_DATA adata;
- CHAR textbuf[MAX_PATH*3];
- TCHAR dirname[MAX_PATH];
-
- if ( context->Access == FTP_ACCESS_NOT_LOGGED_IN )
- return sendstring(context->ControlSocket, error530);
- if ( params == NULL )
- return sendstring(context->ControlSocket, error501);
-
- RtlSecureZeroMemory(textbuf, sizeof(textbuf));
- finalpath(context->RootDir, context->CurrentDir, (char *)params, textbuf);
-
- if (MultiByteToWideChar(CP_UTF8, 0, textbuf, MAX_PATH, dirname, MAX_PATH) <= 0)
- dirname[0] = 0;
-
- if ( !GetFileAttributesEx(dirname, GetFileExInfoStandard, &adata) )
- return sendstring(context->ControlSocket, error550);
- if ( (adata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0 )
- return sendstring(context->ControlSocket, error550);
-
- RtlSecureZeroMemory(textbuf, sizeof(textbuf));
- if ( *params != '\\' ) {
- _strcpy_a(textbuf, context->CurrentDir);
- addlastslash(textbuf);
- }
- _strcat_a(textbuf, params);
- addlastslash(textbuf);
- formatpath(textbuf);
- _strcpy_a(context->CurrentDir, textbuf);
-
- writelogentry(context, " CWD: ", (char *)params);
-
- return sendstring(context->ControlSocket, success250);
-}
-
-BOOL ftpDELE(IN PFTPCONTEXT context, IN const char *params)
-{
- CHAR textbuf[MAX_PATH*3];
- TCHAR filename[MAX_PATH];
-
- if ( context->Access == FTP_ACCESS_NOT_LOGGED_IN )
- return sendstring(context->ControlSocket, error530);
- if ( context->Access < FTP_ACCESS_FULL )
- return sendstring(context->ControlSocket, error550_r);
- if ( params == NULL )
- return sendstring(context->ControlSocket, error501);
-
- RtlSecureZeroMemory(textbuf, sizeof(textbuf));
- finalpath(context->RootDir, context->CurrentDir, (char *)params, textbuf);
- nolastslash(textbuf);
-
- if (MultiByteToWideChar(CP_UTF8, 0, textbuf, MAX_PATH, filename, MAX_PATH) <= 0)
- filename[0] = 0;
-
- if ( DeleteFile(filename) ) {
- sendstring(context->ControlSocket, success250);
- writelogentry(context, " DELE: ", (char *)params);
- }
- else
- sendstring(context->ControlSocket, error550_r);
-
- return TRUE;
-}
-
-BOOL ftpRMD(IN PFTPCONTEXT context, IN const char *params)
-{
- CHAR textbuf[MAX_PATH*3];
- TCHAR filename[MAX_PATH];
-
- if ( context->Access == FTP_ACCESS_NOT_LOGGED_IN )
- return sendstring(context->ControlSocket, error530);
- if ( context->Access < FTP_ACCESS_FULL )
- return sendstring(context->ControlSocket, error550_r);
- if ( params == NULL )
- return sendstring(context->ControlSocket, error501);
-
- RtlSecureZeroMemory(textbuf, sizeof(textbuf));
- finalpath(context->RootDir, context->CurrentDir, (char *)params, textbuf);
-
- if (MultiByteToWideChar(CP_UTF8, 0, textbuf, MAX_PATH, filename, MAX_PATH) <= 0)
- filename[0] = 0;
-
- if ( RemoveDirectory(filename) ) {
- sendstring(context->ControlSocket, success250);
- writelogentry(context, " RMD: ", (char *)params);
- }
- else
- sendstring(context->ControlSocket, error550_r);
-
- return TRUE;
-}
-
-BOOL ftpMKD(IN PFTPCONTEXT context, IN const char *params)
-{
- CHAR textbuf[MAX_PATH*3];
- TCHAR filename[MAX_PATH];
-
- if ( context->Access == FTP_ACCESS_NOT_LOGGED_IN )
- return sendstring(context->ControlSocket, error530);
- if ( context->Access < FTP_ACCESS_CREATENEW )
- return sendstring(context->ControlSocket, error550_r);
- if ( params == NULL )
- return sendstring(context->ControlSocket, error501);
-
- RtlSecureZeroMemory(textbuf, sizeof(textbuf));
- finalpath(context->RootDir, context->CurrentDir, (char *)params, textbuf);
-
- if (MultiByteToWideChar(CP_UTF8, 0, textbuf, MAX_PATH, filename, MAX_PATH) <= 0)
- filename[0] = 0;
-
- if ( CreateDirectory(filename, NULL) ) {
- sendstring(context->ControlSocket, success257);
- writelogentry(context, " MKD: ", (char *)params);
- }
- else
- sendstring(context->ControlSocket, error550);
-
- return TRUE;
-}
-
-BOOL ftpSIZE(IN PFTPCONTEXT context, IN const char *params)
-{
- WIN32_FILE_ATTRIBUTE_DATA adata;
- ULARGE_INTEGER sz;
- CHAR textbuf[MAX_PATH*3];
- TCHAR filename[MAX_PATH];
-
- if ( context->Access == FTP_ACCESS_NOT_LOGGED_IN )
- return sendstring(context->ControlSocket, error530);
- if ( params == NULL )
- return sendstring(context->ControlSocket, error501);
-
- RtlSecureZeroMemory(textbuf, sizeof(textbuf));
- finalpath(context->RootDir, context->CurrentDir, (char *)params, textbuf);
- nolastslash(textbuf);
-
- if (MultiByteToWideChar(CP_UTF8, 0, textbuf, MAX_PATH, filename, MAX_PATH) <= 0)
- filename[0] = 0;
-
- if ( !GetFileAttributesEx(filename, GetFileExInfoStandard, &adata) )
- return sendstring(context->ControlSocket, error550);
-
- sz.HighPart = adata.nFileSizeHigh;
- sz.LowPart = adata.nFileSizeLow;
-
- sendstring(context->ControlSocket, "213 ");
- u64tostr_a(sz.QuadPart, textbuf);
- _strcat_a(textbuf, CRLF);
-
- sendstring(context->ControlSocket, textbuf);
- return TRUE;
-}
-
-BOOL ftpUSER(IN PFTPCONTEXT context, IN const char *params)
-{
- CHAR textbuf[MAX_PATH*3];
-
- if ( params == NULL )
- return sendstring(context->ControlSocket, error501);
-
- context->Access = FTP_ACCESS_NOT_LOGGED_IN;
- _strncpy_a(context->UserName, 256, params, 256);
-
- writelogentry(context, " USER: ", (char *)params);
-
- _strcpy_a(textbuf, interm331);
- _strcat_a(textbuf, (char *)params);
- _strcat_a(textbuf, interm331_tail);
- return sendstring(context->ControlSocket, textbuf);
-}
-
-BOOL ftpQUIT(IN PFTPCONTEXT context, IN const char *params)
-{
- UNREFERENCED_PARAMETER(params);
-
- writelogentry(context, " QUIT", NULL);
- sendstring(context->ControlSocket, success221);
- return FALSE;
-}
-
-BOOL ftpNOOP(IN PFTPCONTEXT context, IN const char *params)
-{
- UNREFERENCED_PARAMETER(params);
-
- return sendstring(context->ControlSocket, success200);
-}
-
-BOOL ftpPASS(IN PFTPCONTEXT context, IN const char *params)
-{
- BOOL cond = FALSE, found = FALSE;
- CHAR temptext[256];
-
- if ( params == NULL )
- return sendstring(context->ControlSocket, error501);
-
- RtlSecureZeroMemory(temptext, sizeof(temptext));
- if (!ParseConfig(g_cfg.ConfigFile, context->UserName, "pswd", temptext, 256))
- return sendstring(context->ControlSocket, error530_r);
-
- if ( (_strcmp_a(temptext, params) != 0) && (temptext[0] != '*') )
- return sendstring(context->ControlSocket, error530_r);
-
- RtlSecureZeroMemory(context->RootDir, sizeof(context->RootDir));
- RtlSecureZeroMemory(temptext, sizeof(temptext));
-
- ParseConfig(g_cfg.ConfigFile, context->UserName, "root", context->RootDir, MAX_PATH);
- ParseConfig(g_cfg.ConfigFile, context->UserName, "accs", temptext, 256);
-
- context->Access = FTP_ACCESS_NOT_LOGGED_IN;
-
- do {
- if (_strcmpi_a(temptext, "admin") == 0) {
- context->Access = FTP_ACCESS_FULL;
- found = TRUE;
- break;
- }
-
- if (_strcmpi_a(temptext, "upload") == 0) {
- context->Access = FTP_ACCESS_CREATENEW;
- found = TRUE;
- break;
- }
-
- if (_strcmpi_a(temptext, "readonly") == 0) {
- context->Access = FTP_ACCESS_READONLY;
- found = TRUE;
- break;
- }
-
- } while (cond);
-
- if (found == FALSE)
- return sendstring(context->ControlSocket, error530_b);
-
- writelogentry(context, " PASS->logon successful", NULL);
- return sendstring(context->ControlSocket, success230);
-}
-
-BOOL ftpSYST(IN PFTPCONTEXT context, IN const char *params)
-{
- UNREFERENCED_PARAMETER(params);
-
- return sendstring(context->ControlSocket, success215);
-}
-
-BOOL ftpFEAT(IN PFTPCONTEXT context, IN const char *params)
-{
- UNREFERENCED_PARAMETER(params);
-
- sendstring(context->ControlSocket, success211);
- return sendstring(context->ControlSocket, success211_end);
-}
-
-BOOL ftpPWD(IN PFTPCONTEXT context, IN const char *params)
-{
- CHAR textbuf[MAX_PATH];
-
- UNREFERENCED_PARAMETER(params);
-
- if ( context->Access == FTP_ACCESS_NOT_LOGGED_IN )
- return sendstring(context->ControlSocket, error530);
-
- sendstring(context->ControlSocket, "257 \"");
- _strcpy_a(textbuf, context->CurrentDir);
- nolastslash(textbuf);
- unixpath(textbuf);
- sendstring(context->ControlSocket, textbuf);
- sendstring(context->ControlSocket, "\" is a current directory.\r\n");
-
- return TRUE;
-}
-
-BOOL ftpTYPE(IN PFTPCONTEXT context, IN const char *params)
-{
- if ( context->Access == FTP_ACCESS_NOT_LOGGED_IN )
- return sendstring(context->ControlSocket, error530);
-
- if (params == NULL)
- return sendstring(context->ControlSocket, error501);
-
- switch (*params)
- {
- case 'A':
- case 'a':
- return sendstring(context->ControlSocket, success200_1);
- case 'I':
- case 'i':
- return sendstring(context->ControlSocket, success200_2);
- }
-
- return sendstring(context->ControlSocket, error501);
-}
-
-BOOL ftpABOR(IN PFTPCONTEXT context, IN const char *params)
-{
- UNREFERENCED_PARAMETER(params);
-
- if ( context->Access == FTP_ACCESS_NOT_LOGGED_IN )
- return sendstring(context->ControlSocket, error530);
-
- StopWorkerThread(context);
- return sendstring(context->ControlSocket, success226);
-}
-
-BOOL ftpCDUP(IN PFTPCONTEXT context, IN const char *params)
-{
- CHAR textbuf[MAX_PATH];
-
- UNREFERENCED_PARAMETER(params);
-
- if ( context->Access == FTP_ACCESS_NOT_LOGGED_IN )
- return sendstring(context->ControlSocket, error530);
-
- RtlSecureZeroMemory(textbuf, sizeof(textbuf));
- _strcpy_a(textbuf, context->CurrentDir);
- nolastslash(textbuf);
- filepath(textbuf);
- addlastslash(textbuf);
- _strcpy_a(context->CurrentDir, textbuf);
-
- writelogentry(context, " CDUP", NULL);
- return sendstring(context->ControlSocket, success250);
-}
-
-BOOL ftpRNFR(IN PFTPCONTEXT context, IN const char *params)
-{
- WIN32_FILE_ATTRIBUTE_DATA adata;
- CHAR textbuf[MAX_PATH*3];
- TCHAR filename[MAX_PATH];
-
- if ( context->Access == FTP_ACCESS_NOT_LOGGED_IN )
- return sendstring(context->ControlSocket, error530);
- if ( context->Access < FTP_ACCESS_FULL )
- return sendstring(context->ControlSocket, error550_r);
- if ( params == NULL )
- return sendstring(context->ControlSocket, error501);
-
- RtlSecureZeroMemory(context->RenFrom, sizeof(context->RenFrom));
- finalpath(context->RootDir, context->CurrentDir, (char *)params, textbuf);
- nolastslash(textbuf);
-
- if (MultiByteToWideChar(CP_UTF8, 0, textbuf, MAX_PATH, filename, MAX_PATH) <= 0)
- filename[0] = 0;
-
- if ( GetFileAttributesEx(filename, GetFileExInfoStandard, &adata) == 0 )
- return sendstring(context->ControlSocket, error550);
-
- _strncpy(context->RenFrom, MAX_PATH, filename, MAX_PATH);
-
- writelogentry(context, " RNFR: ", (char *)params);
- return sendstring(context->ControlSocket, interm350_ren);
-}
-
-BOOL ftpRNTO(IN PFTPCONTEXT context, IN const char *params)
-{
- WIN32_FILE_ATTRIBUTE_DATA adata;
- CHAR textbuf[MAX_PATH*3];
- TCHAR filename[MAX_PATH];
-
- if ( context->Access == FTP_ACCESS_NOT_LOGGED_IN )
- return sendstring(context->ControlSocket, error530);
- if ( context->Access < FTP_ACCESS_FULL )
- return sendstring(context->ControlSocket, error550_r);
- if ( params == NULL )
- return sendstring(context->ControlSocket, error501);
-
- finalpath(context->RootDir, context->CurrentDir, (char *)params, textbuf);
- nolastslash(textbuf);
-
- if (MultiByteToWideChar(CP_UTF8, 0, textbuf, MAX_PATH, filename, MAX_PATH) <= 0)
- filename[0] = 0;
-
- if ( GetFileAttributesEx(filename, GetFileExInfoStandard, &adata) != 0 )
- return sendstring(context->ControlSocket, error550);
- if ( !MoveFileEx(context->RenFrom, filename, MOVEFILE_COPY_ALLOWED) )
- return sendstring(context->ControlSocket, error550);
-
- RtlSecureZeroMemory(context->RenFrom, sizeof(context->RenFrom));
-
- writelogentry(context, " RNTO: ", (char *)params);
- return sendstring(context->ControlSocket, success250);
-}
-
-BOOL ftpOPTS(IN PFTPCONTEXT context, IN const char *params)
-{
- UNREFERENCED_PARAMETER(params);
- UNREFERENCED_PARAMETER(context);
-
- return sendstring(context->ControlSocket, success200);
-}
-
-BOOL ftpMLSD(IN PFTPCONTEXT context, IN const char *params)
-{
- WIN32_FILE_ATTRIBUTE_DATA adata;
- HANDLE wth;
- CHAR textbuf[MAX_PATH * 3];
-
- UNREFERENCED_PARAMETER(params);
-
- if (context->Access == FTP_ACCESS_NOT_LOGGED_IN)
- return sendstring(context->ControlSocket, error530);
- if (context->WorkerThread != NULL)
- return sendstring(context->ControlSocket, error550_t);
-
- context->FileHandle = INVALID_HANDLE_VALUE;
-
- RtlSecureZeroMemory(textbuf, sizeof(textbuf));
- RtlSecureZeroMemory(context->TextBuffer, sizeof(context->TextBuffer));
-
- finalpath(context->RootDir, context->CurrentDir, NULL, textbuf);
- if (MultiByteToWideChar(CP_UTF8, 0, textbuf, MAX_PATH, context->TextBuffer, MAX_PATH) <= 0)
- context->TextBuffer[0] = 0;
-
- if (!GetFileAttributesEx(context->TextBuffer, GetFileExInfoStandard, &adata))
- return sendstring(context->ControlSocket, error550);
- if ((adata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0)
- return sendstring(context->ControlSocket, error550);
-
- _strcat(context->TextBuffer, TEXT("*"));
-
- sendstring(context->ControlSocket, interm150);
- writelogentry(context, " MLSD-LIST", (char *)params);
- context->Stop = FALSE;
-
- wth = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)&mlsd_thread, (LPVOID)context, 0, NULL);
- if (wth == NULL)
- sendstring(context->ControlSocket, error451);
- else
- context->WorkerThread = wth;
-
- return TRUE;
-}
-
-/* FTP COMMANDS END */
-
-char recvchar(SOCKET s)
-{
- char c = 0;
-
- if ( recv(s, &c, 1, 0) != 1 )
- return 0;
-
- return c;
-}
-
-int recvcmd(SOCKET s, char *buffer, ULONG maxlen)
-{
- char r;
- ULONG c;
-
- // skip first spaces or nonliteral characters, that is possible
- do {
- r = recvchar(s);
- if ( r == 0 )
- return FALSE;
- } while ( !( ((r>='a') && (r<='z')) || ((r>='A') && (r<='Z')) ) );
-
- for (c=0; c> (c*8)) & 0xff, _strend_a(params));
-
- if (c < 3)
- _strcat_a(params, ".");
- else
- _strcat_a(params, ":");
- }
- ultostr_a(((laddr.sin_port >> 8) & 0xff) + ((laddr.sin_port << 8) & 0xff00), _strend_a(params));
-
- writelogentry(&ctx, "<- New user IP=", params);
-
- while ( ctx.ControlSocket != INVALID_SOCKET ) {
- RtlSecureZeroMemory(cmd, sizeof(cmd));
- c = recvcmd(ctx.ControlSocket, cmd, 7);
- if ( c == 0 )
- break;
-
- if ( c == 1 )
- p = NULL;
- else {
- p = params;
- RtlSecureZeroMemory(params, sizeof(params));
- if ( !recvparams(ctx.ControlSocket, params, MAX_PATH*2) )
- break;
- }
-
- cmdindex = -1;
- for (i=0; i
-#include
-#include "minirtl\minirtl.h"
-#include "minirtl\cmdline.h"
-#include "ftpserv.h"
-
-#if !defined UNICODE
-#error only UNICODE build is supported
-#endif
-
-DWORD dwMainThreadId = 0;
-HANDLE g_Thread = NULL;
-
-BOOL WINAPI ConHandler(
- _In_ DWORD dwCtrlType
- )
-{
- switch (dwCtrlType) {
- case CTRL_C_EVENT:
- case CTRL_BREAK_EVENT:
- case CTRL_CLOSE_EVENT:
- case CTRL_LOGOFF_EVENT:
- case CTRL_SHUTDOWN_EVENT:
-
- closesocket(g_cfg.ListeningSocket);
- g_cfg.ListeningSocket = INVALID_SOCKET;
- if (WaitForSingleObjectEx(g_Thread, 4000, FALSE) == STATUS_TIMEOUT)
- TerminateThread(g_Thread, 0);
-
- PostThreadMessage(dwMainThreadId, WM_QUIT, 0, 0);
- return TRUE;
- }
-
- return FALSE;
-}
-
-int ParseConfig(const char *pcfg, const char *section_name, const char *key_name, char *value, unsigned long value_size_max)
-{
- unsigned long p = 0, sp;
- char vname[256];
-
- if (value_size_max == 0)
- return 0;
- --value_size_max;
-
- while (pcfg[p] != 0)
- {
- while ((pcfg[p] != '[') && (pcfg[p] != 0)) // skip all characters before first '['
- ++p;
-
- if (pcfg[p] == 0) // we got eof so quit
- break;
-
- if ((pcfg[p] == '\r') || (pcfg[p] == '\n')) // newline - start over again
- continue;
-
- ++p; // skip '[' that we found
-
- sp = 0;
- while ((pcfg[p] != ']') && (pcfg[p] != 0) && (pcfg[p] != '\r') && (pcfg[p] != '\n') && (sp < 255))
- {
- vname[sp] = pcfg[p];
- ++sp;
- ++p;
- }
- vname[sp] = 0;
-
- if (pcfg[p] == 0)
- break;
-
- if ((pcfg[p] == '\r') || (pcfg[p] == '\n')) // newline - start over again
- continue;
-
- ++p; // skip ']' that we found
-
- if (strcmp(vname, section_name) == 0)
- {
- do {
- while ((pcfg[p] == ' ') || (pcfg[p] == '\r') || (pcfg[p] == '\n'))
- ++p;
-
- if ((pcfg[p] == 0) || (pcfg[p] == '['))
- break;
-
- sp = 0;
- while ((pcfg[p] != '=') && (pcfg[p] != 0) && (pcfg[p] != '\r') && (pcfg[p] != '\n') && (sp < 255))
- {
- vname[sp] = pcfg[p];
- ++sp;
- ++p;
- }
- vname[sp] = 0;
-
- if (pcfg[p] == 0)
- break;
- ++p;
-
- if (strcmp(vname, key_name) == 0)
- {
- sp = 0;
- while ((pcfg[p] != '\r') && (pcfg[p] != '\n') && (pcfg[p] != 0))
- {
- if (sp < value_size_max)
- value[sp] = pcfg[p];
- else
- return 0;
- ++sp;
- ++p;
- }
- value[sp] = 0;
- return 1;
- }
- else
- {
- while ((pcfg[p] != '\r') && (pcfg[p] != '\n') && (pcfg[p] != 0))
- ++p;
- }
-
- } while (pcfg[p] != 0);
- }
- else
- {
- // parse and skip all
- do {
- while ((pcfg[p] == ' ') || (pcfg[p] == '\r') || (pcfg[p] == '\n'))
- ++p;
-
- if ((pcfg[p] == 0) || (pcfg[p] == '['))
- break;
-
- while ((pcfg[p] != '=') && (pcfg[p] != 0) && (pcfg[p] != '\r') && (pcfg[p] != '\n'))
- ++p;
-
- if (pcfg[p] == 0)
- break;
- ++p;
-
- while ((pcfg[p] != '\r') && (pcfg[p] != '\n') && (pcfg[p] != 0))
- ++p;
-
- } while (pcfg[p] != 0);
- }
- }
-
- return 0;
-}
-
-char *InitConfig(LPTSTR cfg_filename)
-{
- BOOL cond = FALSE;
- ULONG iobytes;
- HANDLE f = INVALID_HANDLE_VALUE;
- char *buffer = NULL;
- LARGE_INTEGER fsz;
-
- f = CreateFile(cfg_filename, GENERIC_READ | SYNCHRONIZE,
- FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
-
- do {
-
- if (f == INVALID_HANDLE_VALUE)
- break;
-
- fsz.QuadPart = 0;
- if (!GetFileSizeEx(f, &fsz))
- break;
-
- fsz.LowPart += 1;
- buffer = (char *)VirtualAlloc(NULL, fsz.LowPart, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
- if (buffer == NULL)
- break;
-
- if (!ReadFile(f, buffer, fsz.LowPart - 1, &iobytes, NULL))
- break;
-
- buffer[fsz.LowPart - 1] = 0;
-
- } while (cond);
-
- if (f != INVALID_HANDLE_VALUE )
- CloseHandle(f);
-
- return buffer;
-}
-
-void main()
-{
- WSADATA wsdat1;
- int wsaerr;
- MSG msg1;
- BOOL rv;
- ULARGE_INTEGER UT;
- FILETIME t;
- char *cfg = NULL, textbuf[MAX_PATH];
- TCHAR ConfigFilePath[MAX_PATH];
-
- __security_init_cookie();
-
- dwMainThreadId = GetCurrentThreadId();
- SetConsoleCtrlHandler(&ConHandler, TRUE);
-
- RtlSecureZeroMemory(&wsdat1, sizeof(wsdat1));
- wsaerr = WSAStartup(0x0001, &wsdat1);
-
- while (wsaerr == 0)
- {
- RtlSecureZeroMemory(ConfigFilePath, sizeof(ConfigFilePath));
- GetCommandLineParam(GetCommandLine(), 1, ConfigFilePath, MAX_PATH, NULL);
- if (ConfigFilePath[0] == 0) {
- GetModuleFileName(NULL, ConfigFilePath, MAX_PATH);
- ExtractFilePath(ConfigFilePath, ConfigFilePath);
- _strcat(ConfigFilePath, CONFIG_FILE_NAME);
- }
-
- cfg = InitConfig(ConfigFilePath);
- if (cfg == NULL)
- {
- writeconsolestr("Could not find configuration file\r\n\r\n Usage: fftp [CONFIGFILE]\r\n\r\n");
- break;
- }
-
- g_cfg.ConfigFile = cfg;
-
- g_cfg.BindToInterface = inet_addr("127.0.0.1");
- if (ParseConfig(cfg, CONFIG_SECTION_NAME, "interface", textbuf, MAX_PATH))
- g_cfg.BindToInterface = inet_addr(textbuf);
-
- g_cfg.ExternalInterface = inet_addr("0.0.0.0");
- if (ParseConfig(cfg, CONFIG_SECTION_NAME, "external_ip", textbuf, MAX_PATH))
- g_cfg.ExternalInterface = inet_addr(textbuf);
-
- g_cfg.LocalIPMask = inet_addr("255.255.255.0");
- if (ParseConfig(cfg, CONFIG_SECTION_NAME, "local_mask", textbuf, MAX_PATH))
- g_cfg.LocalIPMask = inet_addr(textbuf);
-
- g_cfg.Port = DEFAULT_FTP_PORT;
- if (ParseConfig(cfg, CONFIG_SECTION_NAME, "port", textbuf, MAX_PATH))
- g_cfg.Port = strtoul_a(textbuf);
-
- g_cfg.MaxUsers = 1;
- if (ParseConfig(cfg, CONFIG_SECTION_NAME, "maxusers", textbuf, MAX_PATH))
- g_cfg.MaxUsers = strtoul_a(textbuf);
-
- g_cfg.PasvPortBase = 100;
- if (ParseConfig(cfg, CONFIG_SECTION_NAME, "minport", textbuf, MAX_PATH))
- g_cfg.PasvPortBase = strtoul_a(textbuf);
-
- g_cfg.PasvPortMax = 65535;
- if (ParseConfig(cfg, CONFIG_SECTION_NAME, "maxport", textbuf, MAX_PATH))
- g_cfg.PasvPortMax = strtoul_a(textbuf);
-
- g_LogHandle = INVALID_HANDLE_VALUE;
- RtlSecureZeroMemory(&textbuf, sizeof(textbuf));
- if (ParseConfig(cfg, CONFIG_SECTION_NAME, "logfilepath", textbuf, MAX_PATH))
- {
- GetSystemTimeAsFileTime(&t);
- UT.LowPart = t.dwLowDateTime;
- UT.HighPart = t.dwHighDateTime;
- _strcat_a(textbuf, "\\ftplog-");
- u64tostr_a(UT.QuadPart, _strend_a(textbuf));
- _strcat_a(textbuf, ".txt");
- g_LogHandle = CreateFileA(textbuf, GENERIC_WRITE | SYNCHRONIZE,
- FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
- }
- else
- {
- writeconsolestr("Error: logfilepath section is not found in configuration\r\n");
- break;
- }
-
- if (g_LogHandle == INVALID_HANDLE_VALUE)
- {
- writeconsolestr("Error: Failed to open / create log file. Please check logfilepath\r\n");
- break;
- }
-
- writeconsolestr("Log file : ");
- writeconsolestr(textbuf);
- writeconsolestr(CRLF);
-
- writeconsolestr("Config file : ");
- WideCharToMultiByte(CP_UTF8, 0, ConfigFilePath, MAX_PATH, textbuf, MAX_PATH, NULL, NULL);
- writeconsolestr(textbuf);
- writeconsolestr(CRLF);
-
- writeconsolestr("Interface : ");
- ultostr_a(g_cfg.BindToInterface & 0xff, textbuf);
- _strcat_a(textbuf, ".");
- ultostr_a((g_cfg.BindToInterface >> 8) & 0xff, _strend_a(textbuf));
- _strcat_a(textbuf, ".");
- ultostr_a((g_cfg.BindToInterface >> 16) & 0xff, _strend_a(textbuf));
- _strcat_a(textbuf, ".");
- ultostr_a((g_cfg.BindToInterface >> 24) & 0xff, _strend_a(textbuf));
- _strcat_a(textbuf, CRLF);
- writeconsolestr(textbuf);
-
- writeconsolestr("Port : ");
- ultostr_a(g_cfg.Port, textbuf);
- _strcat_a(textbuf, CRLF);
- writeconsolestr(textbuf);
-
- g_Thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)&ftpmain, NULL, 0, NULL);
- if (g_Thread == NULL)
- {
- writeconsolestr("Error: Failed to create main server thread\r\n");
- break;
- }
-
- /* common message loop for Windows application */
- do {
- rv = GetMessage(&msg1, NULL, 0, 0);
-
- if (rv == -1)
- break;
-
- TranslateMessage(&msg1);
- DispatchMessage(&msg1);
- } while (rv != 0);
-
- CloseHandle(g_Thread);
-
- if ((g_LogHandle != NULL) && (g_LogHandle != INVALID_HANDLE_VALUE))
- CloseHandle(g_LogHandle);
-
- OutputDebugString(TEXT("\r\nNormal exit\r\n"));
- break;
- }
-
- WSACleanup();
- ExitProcess(1);
-}
diff --git a/Source/Deprecated/Windows/fftp/minirtl/_strcat.c b/Source/Deprecated/Windows/fftp/minirtl/_strcat.c
deleted file mode 100644
index eb3c136..0000000
--- a/Source/Deprecated/Windows/fftp/minirtl/_strcat.c
+++ /dev/null
@@ -1,37 +0,0 @@
-#include "rtltypes.h"
-
-char *_strcat_a(char *dest, const char *src)
-{
- if ( (dest==0) || (src==0) )
- return dest;
-
- while ( *dest!=0 )
- dest++;
-
- while ( *src!=0 ) {
- *dest = *src;
- dest++;
- src++;
- }
-
- *dest = 0;
- return dest;
-}
-
-wchar_t *_strcat_w(wchar_t *dest, const wchar_t *src)
-{
- if ( (dest==0) || (src==0) )
- return dest;
-
- while ( *dest!=0 )
- dest++;
-
- while ( *src!=0 ) {
- *dest = *src;
- dest++;
- src++;
- }
-
- *dest = 0;
- return dest;
-}
diff --git a/Source/Deprecated/Windows/fftp/minirtl/_strcmp.c b/Source/Deprecated/Windows/fftp/minirtl/_strcmp.c
deleted file mode 100644
index fc35624..0000000
--- a/Source/Deprecated/Windows/fftp/minirtl/_strcmp.c
+++ /dev/null
@@ -1,47 +0,0 @@
-#include "rtltypes.h"
-
-int _strcmp_a(const char *s1, const char *s2)
-{
- char c1, c2;
-
- if ( s1==s2 )
- return 0;
-
- if ( s1==0 )
- return -1;
-
- if ( s2==0 )
- return 1;
-
- do {
- c1 = *s1;
- c2 = *s2;
- s1++;
- s2++;
- } while ( (c1 != 0) && (c1 == c2) );
-
- return (int)(c1 - c2);
-}
-
-int _strcmp_w(const wchar_t *s1, const wchar_t *s2)
-{
- wchar_t c1, c2;
-
- if ( s1==s2 )
- return 0;
-
- if ( s1==0 )
- return -1;
-
- if ( s2==0 )
- return 1;
-
- do {
- c1 = *s1;
- c2 = *s2;
- s1++;
- s2++;
- } while ( (c1 != 0) && (c1 == c2) );
-
- return (int)(c1 - c2);
-}
diff --git a/Source/Deprecated/Windows/fftp/minirtl/_strcmpi.c b/Source/Deprecated/Windows/fftp/minirtl/_strcmpi.c
deleted file mode 100644
index 5f6656b..0000000
--- a/Source/Deprecated/Windows/fftp/minirtl/_strcmpi.c
+++ /dev/null
@@ -1,47 +0,0 @@
-#include "rtltypes.h"
-
-int _strcmpi_a(const char *s1, const char *s2)
-{
- char c1, c2;
-
- if ( s1==s2 )
- return 0;
-
- if ( s1==0 )
- return -1;
-
- if ( s2==0 )
- return 1;
-
- do {
- c1 = locase_a(*s1);
- c2 = locase_a(*s2);
- s1++;
- s2++;
- } while ( (c1 != 0) && (c1 == c2) );
-
- return (int)(c1 - c2);
-}
-
-int _strcmpi_w(const wchar_t *s1, const wchar_t *s2)
-{
- wchar_t c1, c2;
-
- if ( s1==s2 )
- return 0;
-
- if ( s1==0 )
- return -1;
-
- if ( s2==0 )
- return 1;
-
- do {
- c1 = locase_w(*s1);
- c2 = locase_w(*s2);
- s1++;
- s2++;
- } while ( (c1 != 0) && (c1 == c2) );
-
- return (int)(c1 - c2);
-}
diff --git a/Source/Deprecated/Windows/fftp/minirtl/_strcpy.c b/Source/Deprecated/Windows/fftp/minirtl/_strcpy.c
deleted file mode 100644
index bad5c90..0000000
--- a/Source/Deprecated/Windows/fftp/minirtl/_strcpy.c
+++ /dev/null
@@ -1,43 +0,0 @@
-#include "rtltypes.h"
-
-char *_strcpy_a(char *dest, const char *src)
-{
- char *p;
-
- if ( (dest==0) || (src==0) )
- return dest;
-
- if (dest == src)
- return dest;
-
- p = dest;
- while ( *src!=0 ) {
- *p = *src;
- p++;
- src++;
- }
-
- *p = 0;
- return dest;
-}
-
-wchar_t *_strcpy_w(wchar_t *dest, const wchar_t *src)
-{
- wchar_t *p;
-
- if ((dest == 0) || (src == 0))
- return dest;
-
- if (dest == src)
- return dest;
-
- p = dest;
- while ( *src!=0 ) {
- *p = *src;
- p++;
- src++;
- }
-
- *p = 0;
- return dest;
-}
diff --git a/Source/Deprecated/Windows/fftp/minirtl/_strend.c b/Source/Deprecated/Windows/fftp/minirtl/_strend.c
deleted file mode 100644
index a4d4b6a..0000000
--- a/Source/Deprecated/Windows/fftp/minirtl/_strend.c
+++ /dev/null
@@ -1,23 +0,0 @@
-#include "rtltypes.h"
-
-char *_strend_a(const char *s)
-{
- if ( s==0 )
- return 0;
-
- while ( *s!=0 )
- s++;
-
- return (char *)s;
-}
-
-wchar_t *_strend_w(const wchar_t *s)
-{
- if ( s==0 )
- return 0;
-
- while ( *s!=0 )
- s++;
-
- return (wchar_t *)s;
-}
diff --git a/Source/Deprecated/Windows/fftp/minirtl/_strlen.c b/Source/Deprecated/Windows/fftp/minirtl/_strlen.c
deleted file mode 100644
index 1feda9e..0000000
--- a/Source/Deprecated/Windows/fftp/minirtl/_strlen.c
+++ /dev/null
@@ -1,27 +0,0 @@
-#include "rtltypes.h"
-
-size_t _strlen_a(const char *s)
-{
- char *s0 = (char *)s;
-
- if ( s==0 )
- return 0;
-
- while ( *s!=0 )
- s++;
-
- return (s-s0);
-}
-
-size_t _strlen_w(const wchar_t *s)
-{
- wchar_t *s0 = (wchar_t *)s;
-
- if ( s==0 )
- return 0;
-
- while ( *s!=0 )
- s++;
-
- return (s-s0);
-}
diff --git a/Source/Deprecated/Windows/fftp/minirtl/_strncmpi.c b/Source/Deprecated/Windows/fftp/minirtl/_strncmpi.c
deleted file mode 100644
index ddbe8b8..0000000
--- a/Source/Deprecated/Windows/fftp/minirtl/_strncmpi.c
+++ /dev/null
@@ -1,55 +0,0 @@
-#include "rtltypes.h"
-
-int _strncmpi_a(const char *s1, const char *s2, size_t cchars)
-{
- char c1, c2;
-
- if ( s1==s2 )
- return 0;
-
- if ( s1==0 )
- return -1;
-
- if ( s2==0 )
- return 1;
-
- if ( cchars==0 )
- return 0;
-
- do {
- c1 = locase_a(*s1);
- c2 = locase_a(*s2);
- s1++;
- s2++;
- cchars--;
- } while ( (c1 != 0) && (c1 == c2) && (cchars>0) );
-
- return (int)(c1 - c2);
-}
-
-int _strncmpi_w(const wchar_t *s1, const wchar_t *s2, size_t cchars)
-{
- wchar_t c1, c2;
-
- if ( s1==s2 )
- return 0;
-
- if ( s1==0 )
- return -1;
-
- if ( s2==0 )
- return 1;
-
- if ( cchars==0 )
- return 0;
-
- do {
- c1 = locase_w(*s1);
- c2 = locase_w(*s2);
- s1++;
- s2++;
- cchars--;
- } while ( (c1 != 0) && (c1 == c2) && (cchars>0) );
-
- return (int)(c1 - c2);
-}
diff --git a/Source/Deprecated/Windows/fftp/minirtl/_strncpy.c b/Source/Deprecated/Windows/fftp/minirtl/_strncpy.c
deleted file mode 100644
index f3a519b..0000000
--- a/Source/Deprecated/Windows/fftp/minirtl/_strncpy.c
+++ /dev/null
@@ -1,45 +0,0 @@
-#include "rtltypes.h"
-
-char *_strncpy_a(char *dest, size_t ccdest, const char *src, size_t ccsrc)
-{
- char *p;
-
- if ( (dest==0) || (src==0) || (ccdest==0) )
- return dest;
-
- ccdest--;
- p = dest;
-
- while ( (*src!=0) && (ccdest>0) && (ccsrc>0) ) {
- *p = *src;
- p++;
- src++;
- ccdest--;
- ccsrc--;
- }
-
- *p = 0;
- return dest;
-}
-
-wchar_t *_strncpy_w(wchar_t *dest, size_t ccdest, const wchar_t *src, size_t ccsrc)
-{
- wchar_t *p;
-
- if ( (dest==0) || (src==0) || (ccdest==0) )
- return dest;
-
- ccdest--;
- p = dest;
-
- while ( (*src!=0) && (ccdest>0) && (ccsrc>0) ) {
- *p = *src;
- p++;
- src++;
- ccdest--;
- ccsrc--;
- }
-
- *p = 0;
- return dest;
-}
diff --git a/Source/Deprecated/Windows/fftp/minirtl/cmdline.c b/Source/Deprecated/Windows/fftp/minirtl/cmdline.c
deleted file mode 100644
index 1a3aecb..0000000
--- a/Source/Deprecated/Windows/fftp/minirtl/cmdline.c
+++ /dev/null
@@ -1,180 +0,0 @@
-#include
-
-BOOL GetCommandLineParamW(
- IN LPCWSTR CmdLine,
- IN ULONG ParamIndex,
- OUT LPWSTR Buffer,
- IN ULONG BufferSize,
- OUT PULONG ParamLen
- )
-{
- ULONG c, plen = 0;
- TCHAR divider;
-
- if (ParamLen != NULL)
- *ParamLen = 0;
-
- if (CmdLine == NULL) {
- if ((Buffer != NULL) && (BufferSize > 0))
- *Buffer = 0;
- return FALSE;
- }
-
- for (c = 0; c <= ParamIndex; c++) {
- plen = 0;
-
- while (*CmdLine == ' ')
- CmdLine++;
-
- switch (*CmdLine) {
- case 0:
- goto zero_term_exit;
-
- case '"':
- CmdLine++;
- divider = '"';
- break;
-
- default:
- divider = ' ';
- }
-
- while ((*CmdLine != '"') && (*CmdLine != divider) && (*CmdLine != 0)) {
- plen++;
- if (c == ParamIndex)
- if ((plen < BufferSize) && (Buffer != NULL)) {
- *Buffer = *CmdLine;
- Buffer++;
- }
- CmdLine++;
- }
-
- if (*CmdLine != 0)
- CmdLine++;
- }
-
-zero_term_exit:
-
- if ((Buffer != NULL) && (BufferSize > 0))
- *Buffer = 0;
-
- if (ParamLen != NULL)
- *ParamLen = plen;
-
- if (plen < BufferSize)
- return TRUE;
- else
- return FALSE;
-}
-
-BOOL GetCommandLineParamA(
- IN LPCSTR CmdLine,
- IN ULONG ParamIndex,
- OUT LPSTR Buffer,
- IN ULONG BufferSize,
- OUT PULONG ParamLen
- )
-{
- ULONG c, plen = 0;
- TCHAR divider;
-
- if (CmdLine == NULL)
- return FALSE;
-
- if (ParamLen != NULL)
- *ParamLen = 0;
-
- for (c = 0; c <= ParamIndex; c++) {
- plen = 0;
-
- while (*CmdLine == ' ')
- CmdLine++;
-
- switch (*CmdLine) {
- case 0:
- goto zero_term_exit;
-
- case '"':
- CmdLine++;
- divider = '"';
- break;
-
- default:
- divider = ' ';
- }
-
- while ((*CmdLine != '"') && (*CmdLine != divider) && (*CmdLine != 0)) {
- plen++;
- if (c == ParamIndex)
- if ((plen < BufferSize) && (Buffer != NULL)) {
- *Buffer = *CmdLine;
- Buffer++;
- }
- CmdLine++;
- }
-
- if (*CmdLine != 0)
- CmdLine++;
- }
-
-zero_term_exit:
-
- if ((Buffer != NULL) && (BufferSize > 0))
- *Buffer = 0;
-
- if (ParamLen != NULL)
- *ParamLen = plen;
-
- if (plen < BufferSize)
- return TRUE;
- else
- return FALSE;
-}
-
-char *ExtractFilePathA(const char *FileName, char *FilePath)
-{
- char *p = (char *)FileName, *p0 = (char *)FileName;
-
- if ((FileName == 0) || (FilePath == 0))
- return 0;
-
- while (*FileName != 0) {
- if (*FileName == '\\')
- p = (char *)FileName + 1;
- FileName++;
- }
-
- while (p0 < p) {
- *FilePath = *p0;
- FilePath++;
- p0++;
- }
-
- *FilePath = 0;
-
- return FilePath;
-}
-
-wchar_t *ExtractFilePathW(const wchar_t *FileName, wchar_t *FilePath)
-{
- wchar_t *p = (wchar_t *)FileName, *p0 = (wchar_t *)FileName;
-
- if ((FileName == 0) || (FilePath == 0))
- return 0;
-
- while (*FileName != 0) {
- if (*FileName == '\\')
- p = (wchar_t *)FileName + 1;
- FileName++;
- }
-
- while (p0 < p) {
- *FilePath = *p0;
- FilePath++;
- p0++;
- }
-
- *FilePath = 0;
-
- return FilePath;
-}
diff --git a/Source/Deprecated/Windows/fftp/minirtl/cmdline.h b/Source/Deprecated/Windows/fftp/minirtl/cmdline.h
deleted file mode 100644
index 310a4a5..0000000
--- a/Source/Deprecated/Windows/fftp/minirtl/cmdline.h
+++ /dev/null
@@ -1,35 +0,0 @@
-#ifndef _CMDLINEH_
-#define _CMDLINEH_
-
-BOOL GetCommandLineParamW(
- IN LPCWSTR CmdLine,
- IN ULONG ParamIndex,
- OUT LPWSTR Buffer,
- IN ULONG BufferSize,
- OUT PULONG ParamLen
- );
-
-BOOL GetCommandLineParamA(
- IN LPCSTR CmdLine,
- IN ULONG ParamIndex,
- OUT LPSTR Buffer,
- IN ULONG BufferSize,
- OUT PULONG ParamLen
- );
-
-char *ExtractFilePathA(const char *FileName, char *FilePath);
-wchar_t *ExtractFilePathW(const wchar_t *FileName, wchar_t *FilePath);
-
-#ifdef UNICODE
-
-#define ExtractFilePath ExtractFilePathW
-#define GetCommandLineParam GetCommandLineParamW
-
-#else // ANSI
-
-#define ExtractFilePath ExtractFilePathA
-#define GetCommandLineParam GetCommandLineParamA
-
-#endif
-
-#endif /* _CMDLINEH_ */
diff --git a/Source/Deprecated/Windows/fftp/minirtl/minirtl.h b/Source/Deprecated/Windows/fftp/minirtl/minirtl.h
deleted file mode 100644
index 17cf519..0000000
--- a/Source/Deprecated/Windows/fftp/minirtl/minirtl.h
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
-Module name:
- minirtl.h
-
-Description:
- header for string handling and conversion routines
-
-Date:
- 1 Mar 2015
-*/
-
-#ifndef _MINIRTL_
-#define _MINIRTL_
-
-// string copy/concat/length
-
-char *_strend_a(const char *s);
-wchar_t *_strend_w(const wchar_t *s);
-
-char *_strcpy_a(char *dest, const char *src);
-wchar_t *_strcpy_w(wchar_t *dest, const wchar_t *src);
-
-char *_strcat_a(char *dest, const char *src);
-wchar_t *_strcat_w(wchar_t *dest, const wchar_t *src);
-
-char *_strncpy_a(char *dest, size_t ccdest, const char *src, size_t ccsrc);
-wchar_t *_strncpy_w(wchar_t *dest, size_t ccdest, const wchar_t *src, size_t ccsrc);
-
-size_t _strlen_a(const char *s);
-size_t _strlen_w(const wchar_t *s);
-
-// comparing
-
-int _strcmp_a(const char *s1, const char *s2);
-int _strcmp_w(const wchar_t *s1, const wchar_t *s2);
-
-int _strncmp_a(const char *s1, const char *s2, size_t cchars);
-int _strncmp_w(const wchar_t *s1, const wchar_t *s2, size_t cchars);
-
-int _strcmpi_a(const char *s1, const char *s2);
-int _strcmpi_w(const wchar_t *s1, const wchar_t *s2);
-
-int _strncmpi_a(const char *s1, const char *s2, size_t cchars);
-int _strncmpi_w(const wchar_t *s1, const wchar_t *s2, size_t cchars);
-
-char *_strstr_a(const char *s, const char *sub_s);
-wchar_t *_strstr_w(const wchar_t *s, const wchar_t *sub_s);
-
-char *_strstri_a(const char *s, const char *sub_s);
-wchar_t *_strstri_w(const wchar_t *s, const wchar_t *sub_s);
-
-// conversion of integer types to string, returning string length
-
-size_t ultostr_a(unsigned long x, char *s);
-size_t ultostr_w(unsigned long x, wchar_t *s);
-
-size_t ultohex_a(unsigned long x, char *s);
-size_t ultohex_w(unsigned long x, wchar_t *s);
-
-size_t itostr_a(int x, char *s);
-size_t itostr_w(int x, wchar_t *s);
-
-size_t i64tostr_a(signed long long x, char *s);
-size_t i64tostr_w(signed long long x, wchar_t *s);
-
-size_t u64tostr_a(unsigned long long x, char *s);
-size_t u64tostr_w(unsigned long long x, wchar_t *s);
-
-size_t u64tohex_a(unsigned long long x, char *s);
-size_t u64tohex_w(unsigned long long x, wchar_t *s);
-
-// string to integers conversion
-
-unsigned long strtoul_a(char *s);
-unsigned long strtoul_w(wchar_t *s);
-
-unsigned long long strtou64_a(char *s);
-unsigned long long strtou64_w(wchar_t *s);
-
-unsigned long hextoul_a(char *s);
-unsigned long hextoul_w(wchar_t *s);
-
-int strtoi_a(char *s);
-int strtoi_w(wchar_t *s);
-
-signed long long strtoi64_a(char *s);
-signed long long strtoi64_w(wchar_t *s);
-
-unsigned long long hextou64_a(char *s);
-unsigned long long hextou64_w(wchar_t *s);
-
-/* =================================== */
-
-#ifdef UNICODE
-
-#define _strend _strend_w
-#define _strcpy _strcpy_w
-#define _strcat _strcat_w
-#define _strlen _strlen_w
-#define _strncpy _strncpy_w
-
-#define _strcmp _strcmp_w
-#define _strncmp _strncmp_w
-#define _strcmpi _strcmpi_w
-#define _strncmpi _strncmpi_w
-#define _strstr _strstr_w
-#define _strstri _strstri_w
-
-#define ultostr ultostr_w
-#define ultohex ultohex_w
-#define itostr itostr_w
-#define i64tostr i64tostr_w
-#define u64tostr u64tostr_w
-#define u64tohex u64tohex_w
-
-#define strtoul strtoul_w
-#define hextoul hextoul_w
-#define strtoi strtoi_w
-#define strtoi64 strtoi64_w
-#define strtou64 strtou64_w
-#define hextou64 hextou64_w
-
-#else // ANSI
-
-#define _strend _strend_a
-#define _strcpy _strcpy_a
-#define _strcat _strcat_a
-#define _strlen _strlen_a
-#define _strncpy _strncpy_a
-#define _strcmp _strcmp_a
-
-#define _strcmp _strcmp_a
-#define _strncmp _strncmp_a
-#define _strcmpi _strcmpi_a
-#define _strncmpi _strncmpi_a
-#define _strstr _strstr_a
-#define _strstri _strstri_a
-
-#define ultostr ultostr_a
-#define ultohex ultohex_a
-#define itostr itostr_a
-#define i64tostr i64tostr_a
-#define u64tostr u64tostr_a
-#define u64tohex u64tohex_a
-
-#define strtoul strtoul_a
-#define hextoul hextoul_a
-#define strtoi strtoi_a
-#define strtoi64 strtoi64_a
-#define strtou64 strtou64_a
-#define hextou64 hextou64_a
-
-#endif
-
-#endif /* _MINIRTL_ */
diff --git a/Source/Deprecated/Windows/fftp/minirtl/rtltypes.h b/Source/Deprecated/Windows/fftp/minirtl/rtltypes.h
deleted file mode 100644
index fbb8b2d..0000000
--- a/Source/Deprecated/Windows/fftp/minirtl/rtltypes.h
+++ /dev/null
@@ -1,43 +0,0 @@
-#ifndef _WCHAR_T_DEFINED
-typedef unsigned short wchar_t;
-#define _WCHAR_T_DEFINED
-#endif /* _WCHAR_T_DEFINED */
-
-#ifndef _SIZE_T_DEFINED
-#ifdef _WIN64
-typedef unsigned __int64 size_t;
-#else /* _WIN64 */
-typedef __w64 unsigned int size_t;
-#endif /* _WIN64 */
-#define _SIZE_T_DEFINED
-#endif /* _SIZE_T_DEFINED */
-
-__forceinline char locase_a(char c)
-{
- if ((c >= 'A') && (c <= 'Z'))
- return c + 0x20;
- else
- return c;
-}
-
-__forceinline wchar_t locase_w(wchar_t c)
-{
- if ((c >= 'A') && (c <= 'Z'))
- return c + 0x20;
- else
- return c;
-}
-
-__forceinline char byteabs(char x) {
- if (x < 0)
- return -x;
- return x;
-}
-
-__forceinline int _isdigit_a(char x) {
- return ((x >= '0') && (x <= '9'));
-}
-
-__forceinline int _isdigit_w(wchar_t x) {
- return ((x >= L'0') && (x <= L'9'));
-}
diff --git a/Source/Deprecated/Windows/fftp/minirtl/strtou64.c b/Source/Deprecated/Windows/fftp/minirtl/strtou64.c
deleted file mode 100644
index 1ec829c..0000000
--- a/Source/Deprecated/Windows/fftp/minirtl/strtou64.c
+++ /dev/null
@@ -1,39 +0,0 @@
-#include "rtltypes.h"
-
-unsigned long long strtou64_a(char *s)
-{
- unsigned long long a = 0;
- char c;
-
- if (s == 0)
- return 0;
-
- while (*s != 0) {
- c = *s;
- if (_isdigit_w(c))
- a = (a*10)+(c-'0');
- else
- break;
- s++;
- }
- return a;
-}
-
-unsigned long long strtou64_w(wchar_t *s)
-{
- unsigned long long a = 0;
- wchar_t c;
-
- if (s == 0)
- return 0;
-
- while (*s != 0) {
- c = *s;
- if (_isdigit_w(c))
- a = (a*10)+(c-L'0');
- else
- break;
- s++;
- }
- return a;
-}
diff --git a/Source/Deprecated/Windows/fftp/minirtl/strtoul.c b/Source/Deprecated/Windows/fftp/minirtl/strtoul.c
deleted file mode 100644
index 4fcd0bb..0000000
--- a/Source/Deprecated/Windows/fftp/minirtl/strtoul.c
+++ /dev/null
@@ -1,39 +0,0 @@
-#include "rtltypes.h"
-
-unsigned long strtoul_a(char *s)
-{
- unsigned long a = 0;
- char c;
-
- if (s == 0)
- return 0;
-
- while (*s != 0) {
- c = *s;
- if (_isdigit_a(c))
- a = (a*10)+(c-'0');
- else
- break;
- s++;
- }
- return a;
-}
-
-unsigned long strtoul_w(wchar_t *s)
-{
- unsigned long a = 0;
- wchar_t c;
-
- if (s == 0)
- return 0;
-
- while (*s != 0) {
- c = *s;
- if (_isdigit_w(c))
- a = (a*10)+(c-L'0');
- else
- break;
- s++;
- }
- return a;
-}
diff --git a/Source/Deprecated/Windows/fftp/minirtl/u64tostr.c b/Source/Deprecated/Windows/fftp/minirtl/u64tostr.c
deleted file mode 100644
index 24c4dba..0000000
--- a/Source/Deprecated/Windows/fftp/minirtl/u64tostr.c
+++ /dev/null
@@ -1,45 +0,0 @@
-#include "rtltypes.h"
-
-size_t u64tostr_a(unsigned long long x, char *s)
-{
- unsigned long long t = x;
- size_t i, r=1;
-
- while ( t >= 10 ) {
- t /= 10;
- r++;
- }
-
- if (s == 0)
- return r;
-
- for (i = r; i != 0; i--) {
- s[i-1] = (char)(x % 10) + '0';
- x /= 10;
- }
-
- s[r] = (char)0;
- return r;
-}
-
-size_t u64tostr_w(unsigned long long x, wchar_t *s)
-{
- unsigned long long t = x;
- size_t i, r=1;
-
- while ( t >= 10 ) {
- t /= 10;
- r++;
- }
-
- if (s == 0)
- return r;
-
- for (i = r; i != 0; i--) {
- s[i-1] = (wchar_t)(x % 10) + L'0';
- x /= 10;
- }
-
- s[r] = (wchar_t)0;
- return r;
-}
diff --git a/Source/Deprecated/Windows/fftp/minirtl/ultostr.c b/Source/Deprecated/Windows/fftp/minirtl/ultostr.c
deleted file mode 100644
index 457ccbb..0000000
--- a/Source/Deprecated/Windows/fftp/minirtl/ultostr.c
+++ /dev/null
@@ -1,45 +0,0 @@
-#include "rtltypes.h"
-
-size_t ultostr_a(unsigned long x, char *s)
-{
- unsigned long t=x;
- size_t i, r=1;
-
- while ( t >= 10 ) {
- t /= 10;
- r++;
- }
-
- if (s == 0)
- return r;
-
- for (i = r; i != 0; i--) {
- s[i-1] = (char)(x % 10) + '0';
- x /= 10;
- }
-
- s[r] = (char)0;
- return r;
-}
-
-size_t ultostr_w(unsigned long x, wchar_t *s)
-{
- unsigned long t=x;
- size_t i, r=1;
-
- while ( t >= 10 ) {
- t /= 10;
- r++;
- }
-
- if (s == 0)
- return r;
-
- for (i = r; i != 0; i--) {
- s[i-1] = (wchar_t)(x % 10) + L'0';
- x /= 10;
- }
-
- s[r] = (wchar_t)0;
- return r;
-}