From 94e30af2ef983a919ccd49872a333819db228c28 Mon Sep 17 00:00:00 2001 From: Kirill Volinsky Date: Sun, 20 Jan 2013 19:55:35 +0000 Subject: HTTPServer adopted git-svn-id: http://svn.miranda-ng.org/main/trunk@3200 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- plugins/HTTPServer/HTTPServer_11.vcxproj | 215 +++ plugins/HTTPServer/HTTPServer_11.vcxproj.filters | 67 + plugins/HTTPServer/docs/Changelog.txt | 206 +++ plugins/HTTPServer/docs/data/Changelog.txt | 206 +++ plugins/HTTPServer/docs/data/HTTPMimeTypes | 478 ++++++ plugins/HTTPServer/docs/data/HTTPServer.dll | Bin 0 -> 55296 bytes plugins/HTTPServer/docs/data/HTTPServer.pdf | Bin 0 -> 117677 bytes plugins/HTTPServer/docs/data/HTTPServer.xsl | 35 + plugins/HTTPServer/docs/data/HTTPServerIndex.html | 34 + .../docs/data/htdocs/@settings/favicon.ico | Bin 0 -> 1406 bytes .../docs/data/htdocs/@settings/icons/document2.png | Bin 0 -> 702 bytes .../docs/data/htdocs/@settings/icons/empty.png | Bin 0 -> 357 bytes .../data/htdocs/@settings/icons/folder_gray.png | Bin 0 -> 3172 bytes .../docs/data/htdocs/@settings/icons/image2.png | Bin 0 -> 912 bytes .../docs/data/htdocs/@settings/icons/pdf.png | Bin 0 -> 747 bytes .../docs/data/htdocs/@settings/icons/sound.png | Bin 0 -> 771 bytes .../docs/data/htdocs/@settings/icons/source.png | Bin 0 -> 633 bytes .../docs/data/htdocs/@settings/icons/tar.png | Bin 0 -> 863 bytes .../docs/data/htdocs/@settings/icons/txt.png | Bin 0 -> 558 bytes .../docs/data/htdocs/@settings/icons/video.png | Bin 0 -> 784 bytes .../docs/data/htdocs/@settings/icons/win_apps.png | Bin 0 -> 944 bytes .../docs/data/htdocs/@settings/icons/www.png | Bin 0 -> 734 bytes .../docs/data/htdocs/@settings/index.xsl | 121 ++ .../docs/data/htdocs/@settings/placeholder.gif | Bin 0 -> 72 bytes plugins/HTTPServer/res/dis_srv.ico | Bin 0 -> 1406 bytes plugins/HTTPServer/res/resource.rc | 207 +++ plugins/HTTPServer/res/share_ne.ico | Bin 0 -> 1406 bytes plugins/HTTPServer/src/FileShareNode.cpp | 375 +++++ plugins/HTTPServer/src/FileShareNode.h | 103 ++ plugins/HTTPServer/src/Glob.h | 94 ++ plugins/HTTPServer/src/GuiElements.cpp | 1553 ++++++++++++++++++++ plugins/HTTPServer/src/GuiElements.h | 29 + plugins/HTTPServer/src/HttpUser.cpp | 888 +++++++++++ plugins/HTTPServer/src/HttpUser.h | 70 + plugins/HTTPServer/src/IndexCreation.h | 42 + plugins/HTTPServer/src/IndexHTML.cpp | 527 +++++++ plugins/HTTPServer/src/IndexXML.cpp | 255 ++++ plugins/HTTPServer/src/MimeHandling.cpp | 147 ++ plugins/HTTPServer/src/MimeHandling.h | 52 + plugins/HTTPServer/src/m_HTTPServer.h | 105 ++ plugins/HTTPServer/src/main.cpp | 974 ++++++++++++ plugins/HTTPServer/src/resource.h | 56 + 42 files changed, 6839 insertions(+) create mode 100644 plugins/HTTPServer/HTTPServer_11.vcxproj create mode 100644 plugins/HTTPServer/HTTPServer_11.vcxproj.filters create mode 100644 plugins/HTTPServer/docs/Changelog.txt create mode 100644 plugins/HTTPServer/docs/data/Changelog.txt create mode 100644 plugins/HTTPServer/docs/data/HTTPMimeTypes create mode 100644 plugins/HTTPServer/docs/data/HTTPServer.dll create mode 100644 plugins/HTTPServer/docs/data/HTTPServer.pdf create mode 100644 plugins/HTTPServer/docs/data/HTTPServer.xsl create mode 100644 plugins/HTTPServer/docs/data/HTTPServerIndex.html create mode 100644 plugins/HTTPServer/docs/data/htdocs/@settings/favicon.ico create mode 100644 plugins/HTTPServer/docs/data/htdocs/@settings/icons/document2.png create mode 100644 plugins/HTTPServer/docs/data/htdocs/@settings/icons/empty.png create mode 100644 plugins/HTTPServer/docs/data/htdocs/@settings/icons/folder_gray.png create mode 100644 plugins/HTTPServer/docs/data/htdocs/@settings/icons/image2.png create mode 100644 plugins/HTTPServer/docs/data/htdocs/@settings/icons/pdf.png create mode 100644 plugins/HTTPServer/docs/data/htdocs/@settings/icons/sound.png create mode 100644 plugins/HTTPServer/docs/data/htdocs/@settings/icons/source.png create mode 100644 plugins/HTTPServer/docs/data/htdocs/@settings/icons/tar.png create mode 100644 plugins/HTTPServer/docs/data/htdocs/@settings/icons/txt.png create mode 100644 plugins/HTTPServer/docs/data/htdocs/@settings/icons/video.png create mode 100644 plugins/HTTPServer/docs/data/htdocs/@settings/icons/win_apps.png create mode 100644 plugins/HTTPServer/docs/data/htdocs/@settings/icons/www.png create mode 100644 plugins/HTTPServer/docs/data/htdocs/@settings/index.xsl create mode 100644 plugins/HTTPServer/docs/data/htdocs/@settings/placeholder.gif create mode 100644 plugins/HTTPServer/res/dis_srv.ico create mode 100644 plugins/HTTPServer/res/resource.rc create mode 100644 plugins/HTTPServer/res/share_ne.ico create mode 100644 plugins/HTTPServer/src/FileShareNode.cpp create mode 100644 plugins/HTTPServer/src/FileShareNode.h create mode 100644 plugins/HTTPServer/src/Glob.h create mode 100644 plugins/HTTPServer/src/GuiElements.cpp create mode 100644 plugins/HTTPServer/src/GuiElements.h create mode 100644 plugins/HTTPServer/src/HttpUser.cpp create mode 100644 plugins/HTTPServer/src/HttpUser.h create mode 100644 plugins/HTTPServer/src/IndexCreation.h create mode 100644 plugins/HTTPServer/src/IndexHTML.cpp create mode 100644 plugins/HTTPServer/src/IndexXML.cpp create mode 100644 plugins/HTTPServer/src/MimeHandling.cpp create mode 100644 plugins/HTTPServer/src/MimeHandling.h create mode 100644 plugins/HTTPServer/src/m_HTTPServer.h create mode 100644 plugins/HTTPServer/src/main.cpp create mode 100644 plugins/HTTPServer/src/resource.h diff --git a/plugins/HTTPServer/HTTPServer_11.vcxproj b/plugins/HTTPServer/HTTPServer_11.vcxproj new file mode 100644 index 0000000000..0d5ecf7dc2 --- /dev/null +++ b/plugins/HTTPServer/HTTPServer_11.vcxproj @@ -0,0 +1,215 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {F7A70398-AFA0-4A58-B645-85268F9517DE} + HTTPServer + + + + DynamicLibrary + MultiByte + v110 + true + + + DynamicLibrary + MultiByte + v110 + true + + + DynamicLibrary + MultiByte + v110 + + + DynamicLibrary + MultiByte + v110 + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.40219.1 + $(SolutionDir)$(Configuration)\Plugins\ + $(SolutionDir)$(Configuration)\Obj\$(ProjectName)\ + $(SolutionDir)$(Configuration)\Plugins\ + $(SolutionDir)$(Configuration)\Obj\$(ProjectName)\ + true + + + $(SolutionDir)$(Configuration)64\Plugins\ + $(SolutionDir)$(Configuration)64\Obj\$(ProjectName)\ + + + $(SolutionDir)$(Configuration)64\Plugins\ + $(SolutionDir)$(Configuration)64\Obj\$(ProjectName)\ + + + + Disabled + ..\..\include;..\ExternalAPI;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + MultiThreadedDebugDLL + Level3 + EditAndContinue + Use + Glob.h + + + _DEBUG;%(PreprocessorDefinitions) + ..\..\include\msapi + + + $(ProfileDir)..\..\bin11\lib + true + 0x22500000 + $(IntDir)$(TargetName).lib + Windows + false + comctl32.lib;Ws2_32.lib;%(AdditionalDependencies) + + + + + Disabled + ..\..\include;..\ExternalAPI;%(AdditionalIncludeDirectories) + WIN64;_DEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + MultiThreadedDebugDLL + Level3 + Use + Glob.h + + + _DEBUG;%(PreprocessorDefinitions) + ..\..\include\msapi + + + $(ProfileDir)..\..\bin11\lib + true + 0x22500000 + $(IntDir)$(TargetName).lib + Windows + false + comctl32.lib;Ws2_32.lib;%(AdditionalDependencies) + + + + + Full + OnlyExplicitInline + ..\..\include;..\ExternalAPI;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true + true + Level3 + Size + Use + Glob.h + + + NDEBUG;%(PreprocessorDefinitions) + ..\..\include\msapi + + + /PDBALTPATH:%_PDB% %(AdditionalOptions) + comctl32.lib;Ws2_32.lib;%(AdditionalDependencies) + Windows + $(IntDir)$(TargetName).lib + $(ProfileDir)..\..\bin11\lib + true + true + true + false + 0x22500000 + + + + + Full + OnlyExplicitInline + ..\..\include;..\ExternalAPI;%(AdditionalIncludeDirectories) + WIN64;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true + true + Level3 + Size + Use + Glob.h + + + NDEBUG;%(PreprocessorDefinitions) + ..\..\include\msapi + + + /PDBALTPATH:%_PDB% %(AdditionalOptions) + comctl32.lib;Ws2_32.lib;%(AdditionalDependencies) + Windows + $(IntDir)$(TargetName).lib + $(ProfileDir)..\..\bin11\lib + true + true + true + false + 0x22500000 + + + + + + + + + + + + + + + + + + + Create + + + + + + + + + + \ No newline at end of file diff --git a/plugins/HTTPServer/HTTPServer_11.vcxproj.filters b/plugins/HTTPServer/HTTPServer_11.vcxproj.filters new file mode 100644 index 0000000000..adc7a96302 --- /dev/null +++ b/plugins/HTTPServer/HTTPServer_11.vcxproj.filters @@ -0,0 +1,67 @@ + + + + + {8a708544-2fc2-467e-8bf3-77362b20ae40} + cpp;c;cxx;rc;def;r;odl;idl;hpj;bat + + + {2b0034fb-2dba-462b-b88b-8800f2ed581e} + ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe + + + {dd12eb67-8352-411d-a553-86edc311c3e6} + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Resource Files + + + \ No newline at end of file diff --git a/plugins/HTTPServer/docs/Changelog.txt b/plugins/HTTPServer/docs/Changelog.txt new file mode 100644 index 0000000000..de682e0249 --- /dev/null +++ b/plugins/HTTPServer/docs/Changelog.txt @@ -0,0 +1,206 @@ + + +Version 0.0.1.0 + +This is a beta version. +Some features are not yet implemented. +A shared file will only be remove when the maximum downloads has been reached. +Suggestions and contributions are welcome. + + +Version 0.0.2.0 + +[+] You can change the default port used in Miranda options network "incoming connections" +[+] Popup the message dialog with link when new file is shared. +[!] Crash sometimes when share was about to be removed. +[*] xsl file changed so that it shows link to file. + + +Version 0.0.3.0 + +[+] Uses popup plugin if installed to show when the HTTP server is accessed. +[!] File path was not stored correctly, which meant that only files in the plugin folder could be shared. + + +Version 0.0.4.0 + +[!] Server did not use any port if you did not set a "incoming connections" port in the options. +[+] More error dialog boxes if there is something that failes when initilizing. e.i. unable to bind port + + +Version 0.0.4.1 + +[+] If the open file dialog in "HTTP Share new file" fails an error message is displayed +[!] Shutdown while file transfer is in progress is now handled correctly + + +Version 0.0.4.2 + +[!] "HTTP Share new file" only worked on Windows XP. + + +Version 0.0.5.0 + +[+] HTTP Server can now be accessed by multiply users simultaniously. +[+] HTTP Server "statistics view" includes shares and current useres accessing the server. +[+] Share can be removed from "statistics view" + + +Version 0.0.6.0 + +[!] Max downloads was not decreased so a share was never removed. +[!] First share could not be removed then max downloads got to zero. +[!] If a share was deleted while a download was in progress the download would not be stopped +[*] Outgoing connections options has been removed. +[+] Basic MIME support. Based on file extension. + + +Version 0.0.7.0 + +[+] In the "statistics view" you can copy a link to your shares. +[+] Correct handling of UTF-8 encoded URIs in GET requests.fixes spaces and none US-ASCII characters. +[!] Only masks 255.255.255.255 and 0.0.0.0 worked correctly any other was interpreted like 255.255.255.255. + + +Version 0.0.8.0 + +[+] Popup when a share is removed +[!] Fixed bug in UTF-8 handling. Basically %?? part of handling did not work +[!] Some spelling errors corrected. +[*] Homepage link in options updated +[*] Some internal Elements. + + +Version 0.0.9.0 + +[+] Downloads can be resumed. Tested with ( IE 6.0, Mozilla, wget and FlashGet ) +[+] You can drag and drop file to the "statistics view" +[+] Logs server requests to file ( optional default yes ) +[+] Right click on popup shows "statistics view" +[+] The HTTP server can be enabled and disable from the main menu +[+] The user list shows which Agent he is using. +[+] "New share" menu item added to Right click menu. +[+] "Edit share" menu item added to Right click menu. +[+] Experimental external ip detection (known not to work well under windows 98) +[+] Error dialogs when the link copy to clipboard fails +[*] Some internal Elements. +[!] Tab order in "statistics view" + + +Version 0.1.0.0 + +[+] Stores the position of the "statistics view" +[+] New button in the "share new file dialog" to toggle the mask between 0.0.0.0 and 255.255.255.255 +[+] You can drag and drop files to the lower part of the "share new file dialog" +[+] New button in option page to open the log file. +[+] The state of the HTTP server is keep between sessions. +[+] The popups can be disabled in the options. +[+] HTTP Error codes are returned for some errors.. +[*] Web based ip detection. ( see help ) +[*] When logging trailing new lines in GET request will be removed. +[!] Clicking "Set to default" did not enable apply button. +[!] Closed and Open the "statistics view" while downloads in progresse then auto update diden work. + + +Version 0.1.1.0 + +[+] Speed control, Set the maximum bandwidth that you wish the server shout use. +[+] Speed control can be set active only when your status is online. +[!] After a file had been accessed thru the server it was locked. Introduced in 1.0.0 +[!] Some missing translation was added +[!] Some people where unable to set another port then the default 80. + + +Version 0.1.1.1 + +[!] Unable to changed port realy fixed now. To make it short. + Now it works with both the Latest nightly and Miranda V.0.3.2. + + +Version 0.1.1.2 + +[!] With the Nightly build after 18 Jan. external ip detection diden work + + +Version 0.1.1.3 + +[!] Fixed the incorrect Content-Length header in HTTP 206 Partial Content responces + Now the download can be resumed in any download manager without getting an "incorrect file size" or "file size changed" messages. + + +Version 0.1.1.4 + +[+] Service MS_HTTP_ACCEPT_CONNECTIONS now accepts wParam. + By default it toggles HTTP server state. + Now you can force enable server passing wParam as TRUE. + + +Version 0.1.1.5 + +[+] Added possibility to share directories +[+] If no index.html exists a directory index is created + + +Version 0.1.1.6 + +[+] The generated index.html looks nicer and can be customized + + +Version 0.1.1.7 + +[!] Fixed some security issues +[+] Crystal Icon set included + Thanks to Everaldo Coelho (www.everaldo.com) who released them under GPL +[*] Fixed serveral bugs +[+] On Kennet's advice (and with his help) the index generation was rewritten. + The generated file is now an XML like the configuration file. It is easier to maintain + and more flexible. +[+] Applied chronon's modifications to make it work with his Send Screenshot plugin +[!] Only the shares which are accessible by a user are shown on the index +[+] Files and Folders starting with an @ are not shown in the index and create no popups + They are also hidden in the statistics view but can be revealed +[+] The column widths in statistics view are preserved + + +Version 0.1.1.9 + +[!] Fixed the disappearing statistics view bug +[!] Browsers display the right error message +[+] Maximum number of connections can be defined (total & per user) +[+] Index creation can be disabled now +[+] The user can decide now if the generated index shoud be a HTML or a XML + HTMLs are just for compatibility, it is recommended to use the XMLs + By default it sends XML to MSIE and Firefox and HTML to Opera and other browsers +[+] "Open in Browser" menu entry in statistics view +[!] External IP is updated if it is older than 10 minutes + + +Version 0.1.1.91 + +[!] When updating to a new version the shared files list is not cleared + + +Version 0.1.2.0 + +contributed by Vapik: +[+] The browser is now redirected when trying to access a directory without the trailing slash +[+] The error messages which are shown by the browser contain the version number of the plugin + + +Version 0.1.2.1 + +[!] Fixed several bugs (external IP generation, config files > 10kb,...) +[!] Made HTTP-"Not Modified" response work again +[+] Added [FileModified] and [FileCreated] tags to index (added the first one to the default templates) +[+] Enhanced the controls in the statistic view +[+] Multiple files can be selected & shared at once in the share new file dialog +[+] Multiple files can be dropped into the statistic view (the default settings are used) +[+] Fixed popup clicks (left opens the statistics view / right hides the popup) +[+] Share names & requests are automatically converted to lowercase (to make it case insensitive) +[+] Added "Default download limit" option +[-] Removed "detect brower" option (which tried to detect whether a browser supports XSLT) + + +Version 0.1.2.2 + +[!] Recompiled with new Miranda headers. diff --git a/plugins/HTTPServer/docs/data/Changelog.txt b/plugins/HTTPServer/docs/data/Changelog.txt new file mode 100644 index 0000000000..de682e0249 --- /dev/null +++ b/plugins/HTTPServer/docs/data/Changelog.txt @@ -0,0 +1,206 @@ + + +Version 0.0.1.0 + +This is a beta version. +Some features are not yet implemented. +A shared file will only be remove when the maximum downloads has been reached. +Suggestions and contributions are welcome. + + +Version 0.0.2.0 + +[+] You can change the default port used in Miranda options network "incoming connections" +[+] Popup the message dialog with link when new file is shared. +[!] Crash sometimes when share was about to be removed. +[*] xsl file changed so that it shows link to file. + + +Version 0.0.3.0 + +[+] Uses popup plugin if installed to show when the HTTP server is accessed. +[!] File path was not stored correctly, which meant that only files in the plugin folder could be shared. + + +Version 0.0.4.0 + +[!] Server did not use any port if you did not set a "incoming connections" port in the options. +[+] More error dialog boxes if there is something that failes when initilizing. e.i. unable to bind port + + +Version 0.0.4.1 + +[+] If the open file dialog in "HTTP Share new file" fails an error message is displayed +[!] Shutdown while file transfer is in progress is now handled correctly + + +Version 0.0.4.2 + +[!] "HTTP Share new file" only worked on Windows XP. + + +Version 0.0.5.0 + +[+] HTTP Server can now be accessed by multiply users simultaniously. +[+] HTTP Server "statistics view" includes shares and current useres accessing the server. +[+] Share can be removed from "statistics view" + + +Version 0.0.6.0 + +[!] Max downloads was not decreased so a share was never removed. +[!] First share could not be removed then max downloads got to zero. +[!] If a share was deleted while a download was in progress the download would not be stopped +[*] Outgoing connections options has been removed. +[+] Basic MIME support. Based on file extension. + + +Version 0.0.7.0 + +[+] In the "statistics view" you can copy a link to your shares. +[+] Correct handling of UTF-8 encoded URIs in GET requests.fixes spaces and none US-ASCII characters. +[!] Only masks 255.255.255.255 and 0.0.0.0 worked correctly any other was interpreted like 255.255.255.255. + + +Version 0.0.8.0 + +[+] Popup when a share is removed +[!] Fixed bug in UTF-8 handling. Basically %?? part of handling did not work +[!] Some spelling errors corrected. +[*] Homepage link in options updated +[*] Some internal Elements. + + +Version 0.0.9.0 + +[+] Downloads can be resumed. Tested with ( IE 6.0, Mozilla, wget and FlashGet ) +[+] You can drag and drop file to the "statistics view" +[+] Logs server requests to file ( optional default yes ) +[+] Right click on popup shows "statistics view" +[+] The HTTP server can be enabled and disable from the main menu +[+] The user list shows which Agent he is using. +[+] "New share" menu item added to Right click menu. +[+] "Edit share" menu item added to Right click menu. +[+] Experimental external ip detection (known not to work well under windows 98) +[+] Error dialogs when the link copy to clipboard fails +[*] Some internal Elements. +[!] Tab order in "statistics view" + + +Version 0.1.0.0 + +[+] Stores the position of the "statistics view" +[+] New button in the "share new file dialog" to toggle the mask between 0.0.0.0 and 255.255.255.255 +[+] You can drag and drop files to the lower part of the "share new file dialog" +[+] New button in option page to open the log file. +[+] The state of the HTTP server is keep between sessions. +[+] The popups can be disabled in the options. +[+] HTTP Error codes are returned for some errors.. +[*] Web based ip detection. ( see help ) +[*] When logging trailing new lines in GET request will be removed. +[!] Clicking "Set to default" did not enable apply button. +[!] Closed and Open the "statistics view" while downloads in progresse then auto update diden work. + + +Version 0.1.1.0 + +[+] Speed control, Set the maximum bandwidth that you wish the server shout use. +[+] Speed control can be set active only when your status is online. +[!] After a file had been accessed thru the server it was locked. Introduced in 1.0.0 +[!] Some missing translation was added +[!] Some people where unable to set another port then the default 80. + + +Version 0.1.1.1 + +[!] Unable to changed port realy fixed now. To make it short. + Now it works with both the Latest nightly and Miranda V.0.3.2. + + +Version 0.1.1.2 + +[!] With the Nightly build after 18 Jan. external ip detection diden work + + +Version 0.1.1.3 + +[!] Fixed the incorrect Content-Length header in HTTP 206 Partial Content responces + Now the download can be resumed in any download manager without getting an "incorrect file size" or "file size changed" messages. + + +Version 0.1.1.4 + +[+] Service MS_HTTP_ACCEPT_CONNECTIONS now accepts wParam. + By default it toggles HTTP server state. + Now you can force enable server passing wParam as TRUE. + + +Version 0.1.1.5 + +[+] Added possibility to share directories +[+] If no index.html exists a directory index is created + + +Version 0.1.1.6 + +[+] The generated index.html looks nicer and can be customized + + +Version 0.1.1.7 + +[!] Fixed some security issues +[+] Crystal Icon set included + Thanks to Everaldo Coelho (www.everaldo.com) who released them under GPL +[*] Fixed serveral bugs +[+] On Kennet's advice (and with his help) the index generation was rewritten. + The generated file is now an XML like the configuration file. It is easier to maintain + and more flexible. +[+] Applied chronon's modifications to make it work with his Send Screenshot plugin +[!] Only the shares which are accessible by a user are shown on the index +[+] Files and Folders starting with an @ are not shown in the index and create no popups + They are also hidden in the statistics view but can be revealed +[+] The column widths in statistics view are preserved + + +Version 0.1.1.9 + +[!] Fixed the disappearing statistics view bug +[!] Browsers display the right error message +[+] Maximum number of connections can be defined (total & per user) +[+] Index creation can be disabled now +[+] The user can decide now if the generated index shoud be a HTML or a XML + HTMLs are just for compatibility, it is recommended to use the XMLs + By default it sends XML to MSIE and Firefox and HTML to Opera and other browsers +[+] "Open in Browser" menu entry in statistics view +[!] External IP is updated if it is older than 10 minutes + + +Version 0.1.1.91 + +[!] When updating to a new version the shared files list is not cleared + + +Version 0.1.2.0 + +contributed by Vapik: +[+] The browser is now redirected when trying to access a directory without the trailing slash +[+] The error messages which are shown by the browser contain the version number of the plugin + + +Version 0.1.2.1 + +[!] Fixed several bugs (external IP generation, config files > 10kb,...) +[!] Made HTTP-"Not Modified" response work again +[+] Added [FileModified] and [FileCreated] tags to index (added the first one to the default templates) +[+] Enhanced the controls in the statistic view +[+] Multiple files can be selected & shared at once in the share new file dialog +[+] Multiple files can be dropped into the statistic view (the default settings are used) +[+] Fixed popup clicks (left opens the statistics view / right hides the popup) +[+] Share names & requests are automatically converted to lowercase (to make it case insensitive) +[+] Added "Default download limit" option +[-] Removed "detect brower" option (which tried to detect whether a browser supports XSLT) + + +Version 0.1.2.2 + +[!] Recompiled with new Miranda headers. diff --git a/plugins/HTTPServer/docs/data/HTTPMimeTypes b/plugins/HTTPServer/docs/data/HTTPMimeTypes new file mode 100644 index 0000000000..8860fdb930 --- /dev/null +++ b/plugins/HTTPServer/docs/data/HTTPMimeTypes @@ -0,0 +1,478 @@ +# This file is part of HTTPServer a Miranda IM plugin. +# The file is taken from the apache project. + +# This file controls what Internet media types are sent to the client for +# given file extension(s). Sending the correct media type to the client +# is important so they know how to handle the content of the file. +# Extra types can either be added here +# For more information about Internet media types, +# please read RFC 2045, 2046, 2047, 2048, and 2077. The Internet media type +# registry is at . + +# MIME type Extension +application/EDI-Consent +application/EDI-X12 +application/EDIFACT +application/activemessage +application/andrew-inset ez +application/applefile +application/atomicmail +application/batch-SMTP +application/beep+xml +application/cals-1840 +application/commonground +application/cybercash +application/dca-rft +application/dec-dx +application/dvcs +application/eshop +application/http +application/hyperstudio +application/iges +application/index +application/index.cmd +application/index.obj +application/index.response +application/index.vnd +application/iotp +application/ipp +application/isup +application/font-tdpfr +application/mac-binhex40 hqx +application/mac-compactpro cpt +application/macwriteii +application/marc +application/mathematica +application/mathematica-old +application/msword doc +application/news-message-id +application/news-transmission +application/ocsp-request +application/ocsp-response +application/octet-stream bin dms lha lzh exe class so dll +application/oda oda +application/parityfec +application/pdf pdf +application/pgp-encrypted +application/pgp-keys +application/pgp-signature +application/pkcs10 +application/pkcs7-mime +application/pkcs7-signature +application/pkix-cert +application/pkix-crl +application/pkixcmp +application/postscript ai eps ps +application/prs.alvestrand.titrax-sheet +application/prs.cww +application/prs.nprend +application/qsig +application/remote-printing +application/riscos +application/rtf +application/sdp +application/set-payment +application/set-payment-initiation +application/set-registration +application/set-registration-initiation +application/sgml +application/sgml-open-catalog +application/sieve +application/slate +application/smil smi smil +application/timestamp-query +application/timestamp-reply +application/vemmi +application/vnd.3M.Post-it-Notes +application/vnd.FloGraphIt +application/vnd.accpac.simply.aso +application/vnd.accpac.simply.imp +application/vnd.acucobol +application/vnd.aether.imp +application/vnd.anser-web-certificate-issue-initiation +application/vnd.anser-web-funds-transfer-initiation +application/vnd.audiograph +application/vnd.businessobjects +application/vnd.bmi +application/vnd.canon-cpdl +application/vnd.canon-lips +application/vnd.claymore +application/vnd.commerce-battelle +application/vnd.commonspace +application/vnd.comsocaller +application/vnd.contact.cmsg +application/vnd.cosmocaller +application/vnd.cups-postscript +application/vnd.cups-raster +application/vnd.cups-raw +application/vnd.ctc-posml +application/vnd.cybank +application/vnd.dna +application/vnd.dpgraph +application/vnd.dxr +application/vnd.ecdis-update +application/vnd.ecowin.chart +application/vnd.ecowin.filerequest +application/vnd.ecowin.fileupdate +application/vnd.ecowin.series +application/vnd.ecowin.seriesrequest +application/vnd.ecowin.seriesupdate +application/vnd.enliven +application/vnd.epson.esf +application/vnd.epson.msf +application/vnd.epson.quickanime +application/vnd.epson.salt +application/vnd.epson.ssf +application/vnd.ericsson.quickcall +application/vnd.eudora.data +application/vnd.fdf +application/vnd.ffsns +application/vnd.framemaker +application/vnd.fsc.weblaunch +application/vnd.fujitsu.oasys +application/vnd.fujitsu.oasys2 +application/vnd.fujitsu.oasys3 +application/vnd.fujitsu.oasysgp +application/vnd.fujitsu.oasysprs +application/vnd.fujixerox.ddd +application/vnd.fujixerox.docuworks +application/vnd.fujixerox.docuworks.binder +application/vnd.fut-misnet +application/vnd.grafeq +application/vnd.groove-account +application/vnd.groove-identity-message +application/vnd.groove-injector +application/vnd.groove-tool-message +application/vnd.groove-tool-template +application/vnd.groove-vcard +application/vnd.hhe.lesson-player +application/vnd.hp-HPGL +application/vnd.hp-PCL +application/vnd.hp-PCLXL +application/vnd.hp-hpid +application/vnd.hp-hps +application/vnd.httphone +application/vnd.hzn-3d-crossword +application/vnd.ibm.afplinedata +application/vnd.ibm.MiniPay +application/vnd.ibm.modcap +application/vnd.informix-visionary +application/vnd.intercon.formnet +application/vnd.intertrust.digibox +application/vnd.intertrust.nncp +application/vnd.intu.qbo +application/vnd.intu.qfx +application/vnd.irepository.package+xml +application/vnd.is-xpr +application/vnd.japannet-directory-service +application/vnd.japannet-jpnstore-wakeup +application/vnd.japannet-payment-wakeup +application/vnd.japannet-registration +application/vnd.japannet-registration-wakeup +application/vnd.japannet-setstore-wakeup +application/vnd.japannet-verification +application/vnd.japannet-verification-wakeup +application/vnd.koan +application/vnd.lotus-1-2-3 +application/vnd.lotus-approach +application/vnd.lotus-freelance +application/vnd.lotus-notes +application/vnd.lotus-organizer +application/vnd.lotus-screencam +application/vnd.lotus-wordpro +application/vnd.mcd +application/vnd.mediastation.cdkey +application/vnd.meridian-slingshot +application/vnd.mif mif +application/vnd.minisoft-hp3000-save +application/vnd.mitsubishi.misty-guard.trustweb +application/vnd.mobius.daf +application/vnd.mobius.dis +application/vnd.mobius.msl +application/vnd.mobius.plc +application/vnd.mobius.txf +application/vnd.motorola.flexsuite +application/vnd.motorola.flexsuite.adsi +application/vnd.motorola.flexsuite.fis +application/vnd.motorola.flexsuite.gotap +application/vnd.motorola.flexsuite.kmr +application/vnd.motorola.flexsuite.ttc +application/vnd.motorola.flexsuite.wem +application/vnd.mozilla.xul+xml +application/vnd.ms-artgalry +application/vnd.ms-asf +application/vnd.ms-excel xls +application/vnd.ms-lrm +application/vnd.ms-powerpoint ppt +application/vnd.ms-project +application/vnd.ms-tnef +application/vnd.ms-works +application/vnd.mseq +application/vnd.msign +application/vnd.music-niff +application/vnd.musician +application/vnd.netfpx +application/vnd.noblenet-directory +application/vnd.noblenet-sealer +application/vnd.noblenet-web +application/vnd.novadigm.EDM +application/vnd.novadigm.EDX +application/vnd.novadigm.EXT +application/vnd.osa.netdeploy +application/vnd.palm +application/vnd.pg.format +application/vnd.pg.osasli +application/vnd.powerbuilder6 +application/vnd.powerbuilder6-s +application/vnd.powerbuilder7 +application/vnd.powerbuilder7-s +application/vnd.powerbuilder75 +application/vnd.powerbuilder75-s +application/vnd.previewsystems.box +application/vnd.publishare-delta-tree +application/vnd.pvi.ptid1 +application/vnd.pwg-xhtml-print+xml +application/vnd.rapid +application/vnd.s3sms +application/vnd.seemail +application/vnd.shana.informed.formdata +application/vnd.shana.informed.formtemplate +application/vnd.shana.informed.interchange +application/vnd.shana.informed.package +application/vnd.sss-cod +application/vnd.sss-dtf +application/vnd.sss-ntf +application/vnd.street-stream +application/vnd.svd +application/vnd.swiftview-ics +application/vnd.triscape.mxs +application/vnd.trueapp +application/vnd.truedoc +application/vnd.tve-trigger +application/vnd.ufdl +application/vnd.uplanet.alert +application/vnd.uplanet.alert-wbxml +application/vnd.uplanet.bearer-choice-wbxml +application/vnd.uplanet.bearer-choice +application/vnd.uplanet.cacheop +application/vnd.uplanet.cacheop-wbxml +application/vnd.uplanet.channel +application/vnd.uplanet.channel-wbxml +application/vnd.uplanet.list +application/vnd.uplanet.list-wbxml +application/vnd.uplanet.listcmd +application/vnd.uplanet.listcmd-wbxml +application/vnd.uplanet.signal +application/vnd.vcx +application/vnd.vectorworks +application/vnd.vidsoft.vidconference +application/vnd.visio +application/vnd.vividence.scriptfile +application/vnd.wap.sic +application/vnd.wap.slc +application/vnd.wap.wbxml wbxml +application/vnd.wap.wmlc wmlc +application/vnd.wap.wmlscriptc wmlsc +application/vnd.webturbo +application/vnd.wrq-hp3000-labelled +application/vnd.wt.stf +application/vnd.xara +application/vnd.xfdl +application/vnd.yellowriver-custom-menu +application/whoispp-query +application/whoispp-response +application/wita +application/wordperfect5.1 +application/x-bcpio bcpio +application/x-cdlink vcd +application/x-chess-pgn pgn +application/x-compress +application/x-cpio cpio +application/x-csh csh +application/x-director dcr dir dxr +application/x-dvi dvi +application/x-futuresplash spl +application/x-gtar gtar +application/x-gzip +application/x-hdf hdf +application/x-javascript js +application/x-koan skp skd skt skm +application/x-latex latex +application/x-netcdf nc cdf +application/x-sh sh +application/x-shar shar +application/x-shockwave-flash swf +application/x-stuffit sit +application/x-sv4cpio sv4cpio +application/x-sv4crc sv4crc +application/x-tar tar +application/x-tcl tcl +application/x-tex tex +application/x-texinfo texinfo texi +application/x-troff t tr roff +application/x-troff-man man +application/x-troff-me me +application/x-troff-ms ms +application/x-ustar ustar +application/x-wais-source src +application/x400-bp +application/xhtml+xml xhtml xht +application/xml +application/xml-dtd +application/xml-external-parsed-entity +application/zip zip +audio/32kadpcm +audio/basic au snd +audio/g.722.1 +audio/l16 +audio/midi mid midi kar +audio/mp4a-latm +audio/mpa-robust +audio/mpeg mpga mp2 mp3 +audio/parityfec +audio/prs.sid +audio/telephone-event +audio/tone +audio/vnd.cisco.nse +audio/vnd.cns.anp1 +audio/vnd.cns.inf1 +audio/vnd.digital-winds +audio/vnd.everad.plj +audio/vnd.lucent.voice +audio/vnd.nortel.vbk +audio/vnd.nuera.ecelp4800 +audio/vnd.nuera.ecelp7470 +audio/vnd.nuera.ecelp9600 +audio/vnd.octel.sbc +audio/vnd.qcelp +audio/vnd.rhetorex.32kadpcm +audio/vnd.vmx.cvsd +audio/x-aiff aif aiff aifc +audio/x-mod mod +audio/x-mpegurl m3u +audio/x-pn-realaudio ram rm +audio/x-pn-realaudio-plugin rpm +audio/x-realaudio ra +audio/x-wav wav +chemical/x-pdb pdb +chemical/x-xyz xyz +image/bmp bmp +image/cgm +image/g3fax +image/gif gif +image/ief ief +image/jpeg jpeg jpg jpe +image/naplps +image/png png +image/prs.btif +image/prs.pti +image/tiff tiff tif +image/vnd.cns.inf2 +image/vnd.djvu djvu djv +image/vnd.dwg +image/vnd.dxf +image/vnd.fastbidsheet +image/vnd.fpx +image/vnd.fst +image/vnd.fujixerox.edmics-mmr +image/vnd.fujixerox.edmics-rlc +image/vnd.mix +image/vnd.net-fpx +image/vnd.svf +image/vnd.wap.wbmp wbmp +image/vnd.xiff +image/x-cmu-raster ras +image/x-portable-anymap pnm +image/x-portable-bitmap pbm +image/x-portable-graymap pgm +image/x-portable-pixmap ppm +image/x-rgb rgb +image/x-xbitmap xbm +image/x-xpixmap xpm +image/x-xwindowdump xwd +message/delivery-status +message/disposition-notification +message/external-body +message/http +message/news +message/partial +message/rfc822 +message/s-http +model/iges igs iges +model/mesh msh mesh silo +model/vnd.dwf +model/vnd.flatland.3dml +model/vnd.gdl +model/vnd.gs-gdl +model/vnd.gtw +model/vnd.mts +model/vnd.vtu +model/vrml wrl vrml +multipart/alternative +multipart/appledouble +multipart/byteranges +multipart/digest +multipart/encrypted +multipart/form-data +multipart/header-set +multipart/mixed +multipart/parallel +multipart/related +multipart/report +multipart/signed +multipart/voice-message +text/calendar +text/css css +text/directory +text/enriched +text/html html htm +text/parityfec +text/plain asc txt +text/prs.lines.tag +text/rfc822-headers +text/richtext rtx +text/rtf rtf +text/sgml sgml sgm +text/tab-separated-values tsv +text/t140 +text/uri-list +text/vnd.DMClientScript +text/vnd.IPTC.NITF +text/vnd.IPTC.NewsML +text/vnd.abc +text/vnd.curl +text/vnd.flatland.3dml +text/vnd.fly +text/vnd.fmi.flexstor +text/vnd.in3d.3dml +text/vnd.in3d.spot +text/vnd.latex-z +text/vnd.motorola.reflex +text/vnd.ms-mediapackage +text/vnd.wap.si +text/vnd.wap.sl +text/vnd.wap.wml wml +text/vnd.wap.wmlscript wmls +text/x-c++hdr hpp hxx hh +text/x-c++src cpp,cxx,cc +text/x-chdr h +text/x-csrc c +text/x-setext etx +text/xml xml xsl +text/xml-external-parsed-entity +video/mp4v-es +video/mpeg mpeg mpg mpe +video/parityfec +video/pointer +video/quicktime qt mov +video/vnd.fvt +video/vnd.motorola.video +video/vnd.motorola.videop +video/vnd.mpegurl mxu +video/vnd.mts +video/vnd.nokia.interleaved-multimedia +video/vnd.vivo +video/x-msvideo avi +video/x-sgi-movie movie +x-conference/x-cooltalk ice + diff --git a/plugins/HTTPServer/docs/data/HTTPServer.dll b/plugins/HTTPServer/docs/data/HTTPServer.dll new file mode 100644 index 0000000000..d315b17d8b Binary files /dev/null and b/plugins/HTTPServer/docs/data/HTTPServer.dll differ diff --git a/plugins/HTTPServer/docs/data/HTTPServer.pdf b/plugins/HTTPServer/docs/data/HTTPServer.pdf new file mode 100644 index 0000000000..7aed97ba6b Binary files /dev/null and b/plugins/HTTPServer/docs/data/HTTPServer.pdf differ diff --git a/plugins/HTTPServer/docs/data/HTTPServer.xsl b/plugins/HTTPServer/docs/data/HTTPServer.xsl new file mode 100644 index 0000000000..fc5006707e --- /dev/null +++ b/plugins/HTTPServer/docs/data/HTTPServer.xsl @@ -0,0 +1,35 @@ + + + + + + +

HTTP server configuration

+ + + + + + + + + + + + + + + + + +
NameFileMax downloadsIP addressIP mask
+ + + + +
+ + +
+
\ No newline at end of file diff --git a/plugins/HTTPServer/docs/data/HTTPServerIndex.html b/plugins/HTTPServer/docs/data/HTTPServerIndex.html new file mode 100644 index 0000000000..4fdc41940a --- /dev/null +++ b/plugins/HTTPServer/docs/data/HTTPServerIndex.html @@ -0,0 +1,34 @@ + + +Directory Listing of [DirectoryName] + + + + + + +[End] +[ForFilesDo][End] + + + + \ No newline at end of file diff --git a/plugins/HTTPServer/docs/data/htdocs/@settings/favicon.ico b/plugins/HTTPServer/docs/data/htdocs/@settings/favicon.ico new file mode 100644 index 0000000000..1bd45b98e4 Binary files /dev/null and b/plugins/HTTPServer/docs/data/htdocs/@settings/favicon.ico differ diff --git a/plugins/HTTPServer/docs/data/htdocs/@settings/icons/document2.png b/plugins/HTTPServer/docs/data/htdocs/@settings/icons/document2.png new file mode 100644 index 0000000000..f4d5bfd139 Binary files /dev/null and b/plugins/HTTPServer/docs/data/htdocs/@settings/icons/document2.png differ diff --git a/plugins/HTTPServer/docs/data/htdocs/@settings/icons/empty.png b/plugins/HTTPServer/docs/data/htdocs/@settings/icons/empty.png new file mode 100644 index 0000000000..bfe1d06e04 Binary files /dev/null and b/plugins/HTTPServer/docs/data/htdocs/@settings/icons/empty.png differ diff --git a/plugins/HTTPServer/docs/data/htdocs/@settings/icons/folder_gray.png b/plugins/HTTPServer/docs/data/htdocs/@settings/icons/folder_gray.png new file mode 100644 index 0000000000..ea7f314dba Binary files /dev/null and b/plugins/HTTPServer/docs/data/htdocs/@settings/icons/folder_gray.png differ diff --git a/plugins/HTTPServer/docs/data/htdocs/@settings/icons/image2.png b/plugins/HTTPServer/docs/data/htdocs/@settings/icons/image2.png new file mode 100644 index 0000000000..dbefd0ccfa Binary files /dev/null and b/plugins/HTTPServer/docs/data/htdocs/@settings/icons/image2.png differ diff --git a/plugins/HTTPServer/docs/data/htdocs/@settings/icons/pdf.png b/plugins/HTTPServer/docs/data/htdocs/@settings/icons/pdf.png new file mode 100644 index 0000000000..27faad6fc0 Binary files /dev/null and b/plugins/HTTPServer/docs/data/htdocs/@settings/icons/pdf.png differ diff --git a/plugins/HTTPServer/docs/data/htdocs/@settings/icons/sound.png b/plugins/HTTPServer/docs/data/htdocs/@settings/icons/sound.png new file mode 100644 index 0000000000..bfe6022c8c Binary files /dev/null and b/plugins/HTTPServer/docs/data/htdocs/@settings/icons/sound.png differ diff --git a/plugins/HTTPServer/docs/data/htdocs/@settings/icons/source.png b/plugins/HTTPServer/docs/data/htdocs/@settings/icons/source.png new file mode 100644 index 0000000000..14a9c6ee31 Binary files /dev/null and b/plugins/HTTPServer/docs/data/htdocs/@settings/icons/source.png differ diff --git a/plugins/HTTPServer/docs/data/htdocs/@settings/icons/tar.png b/plugins/HTTPServer/docs/data/htdocs/@settings/icons/tar.png new file mode 100644 index 0000000000..8bdfa8a0fc Binary files /dev/null and b/plugins/HTTPServer/docs/data/htdocs/@settings/icons/tar.png differ diff --git a/plugins/HTTPServer/docs/data/htdocs/@settings/icons/txt.png b/plugins/HTTPServer/docs/data/htdocs/@settings/icons/txt.png new file mode 100644 index 0000000000..b34ba0b892 Binary files /dev/null and b/plugins/HTTPServer/docs/data/htdocs/@settings/icons/txt.png differ diff --git a/plugins/HTTPServer/docs/data/htdocs/@settings/icons/video.png b/plugins/HTTPServer/docs/data/htdocs/@settings/icons/video.png new file mode 100644 index 0000000000..6c5f692d79 Binary files /dev/null and b/plugins/HTTPServer/docs/data/htdocs/@settings/icons/video.png differ diff --git a/plugins/HTTPServer/docs/data/htdocs/@settings/icons/win_apps.png b/plugins/HTTPServer/docs/data/htdocs/@settings/icons/win_apps.png new file mode 100644 index 0000000000..c22b0e24c9 Binary files /dev/null and b/plugins/HTTPServer/docs/data/htdocs/@settings/icons/win_apps.png differ diff --git a/plugins/HTTPServer/docs/data/htdocs/@settings/icons/www.png b/plugins/HTTPServer/docs/data/htdocs/@settings/icons/www.png new file mode 100644 index 0000000000..2bd96dd012 Binary files /dev/null and b/plugins/HTTPServer/docs/data/htdocs/@settings/icons/www.png differ diff --git a/plugins/HTTPServer/docs/data/htdocs/@settings/index.xsl b/plugins/HTTPServer/docs/data/htdocs/@settings/index.xsl new file mode 100644 index 0000000000..d8e8f4e872 --- /dev/null +++ b/plugins/HTTPServer/docs/data/htdocs/@settings/index.xsl @@ -0,0 +1,121 @@ + + + + + + + + + + my Miranda Webserver + + + + + + + Directory Listing of <xsl:value-of select="$dirname"/> + + + + + +
+

Directory Listing of [DirectoryName]

+[ForDirectoriesDo]
[DirectoryName]
+[IsFileType=jpg,jpeg,gif,png,bmp][End] +[IsFileType=zip,rar,ace,arj,lha,lhz,tar,gz][End] +[IsFileType=rtf,doc][End] +[IsFileType=txt,diz][End] +[IsFileType=pdf][End] +[IsFileType=exe,bat][End] +[IsFileType=html,htm,xml][End] +[IsFileType=avi,mpg][End] +[IsFileType=c,cpp,h][End] +[IsFileType=mp3,ogg,wav,mid,mod,xm][End] +[IsFileType=*][End][FileName][FileModified][FileSize]
+ + + + + + + + + + #EEEEFF + #DDDDEE + + + + + + 3 + 1 + + + + + + + + folder_gray.png + image2.png + tar.png + document2.png + txt.png + pdf.png + win_apps.png + www.png + video.png + source.png + sound.png + empty.png + + + + /icons/ + + + /placeholder.gif + 5 + + + + + . + / + + + . + + + + + + + + + + + + +
+

Directory Listing of

+
+ + + GB + + + MB + + + KB + + + Byte + + +
+ + + + + + + diff --git a/plugins/HTTPServer/docs/data/htdocs/@settings/placeholder.gif b/plugins/HTTPServer/docs/data/htdocs/@settings/placeholder.gif new file mode 100644 index 0000000000..213771dde3 Binary files /dev/null and b/plugins/HTTPServer/docs/data/htdocs/@settings/placeholder.gif differ diff --git a/plugins/HTTPServer/res/dis_srv.ico b/plugins/HTTPServer/res/dis_srv.ico new file mode 100644 index 0000000000..06647ecb18 Binary files /dev/null and b/plugins/HTTPServer/res/dis_srv.ico differ diff --git a/plugins/HTTPServer/res/resource.rc b/plugins/HTTPServer/res/resource.rc new file mode 100644 index 0000000000..20e5ae95d3 --- /dev/null +++ b/plugins/HTTPServer/res/resource.rc @@ -0,0 +1,207 @@ +// Microsoft Visual C++ generated resource script. +// +#include "..\src\resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "afxres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// Ðóññêèé (Ðîññèÿ) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_RUS) +LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT +#pragma code_page(1251) + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +IDI_DISABLE_SERVER ICON "dis_srv.ico" +IDI_SHARE_NEW_FILE ICON "share_ne.ico" + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_NEW_SHARE_PROPERTIES DIALOGEX 0, 0, 279, 57 +STYLE DS_SETFONT | DS_3DLOOK | DS_CONTROL | WS_CHILD | WS_CLIPSIBLINGS +EXSTYLE WS_EX_ACCEPTFILES +FONT 8, "MS Sans Serif", 0, 0, 0x1 +BEGIN + EDITTEXT IDC_SHARE_NAME,46,10,63,14,ES_AUTOHSCROLL + EDITTEXT IDC_MAX_DOWNLOADS,61,29,48,14,ES_AUTOHSCROLL + CONTROL "IPAddress1",IDC_ALLOWED_IPADDRESS,"SysIPAddress32",WS_TABSTOP,150,9,100,15 + CONTROL "IPAddress2",IDC_ALLOWED_IP_MASK,"SysIPAddress32",WS_TABSTOP,150,31,100,15 + LTEXT "Max downloads",IDC_STATIC,5,31,50,8 + LTEXT "Address",IDC_STATIC,120,12,26,8 + LTEXT "Mask",IDC_STATIC,120,34,18,8 + LTEXT "Share name",IDC_STATIC,5,12,39,8 + GROUPBOX "Allowed IP",IDC_STATIC,115,0,161,54 + PUSHBUTTON "",IDC_TOGGLE_MASK,257,31,13,15 +END + +IDD_STATISTICS_VIEW DIALOGEX 0, 0, 410, 198 +STYLE DS_SETFONT | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME +EXSTYLE WS_EX_ACCEPTFILES +CAPTION "HTTP Server statistics view" +FONT 8, "MS Sans Serif", 0, 0, 0x1 +BEGIN + CONTROL "List1",IDC_CURRENT_SHARES,"SysListView32",LVS_REPORT | WS_BORDER | WS_TABSTOP,7,20,396,86 + CONTROL "List1",IDC_CURRENT_USERS,"SysListView32",LVS_REPORT | WS_BORDER | WS_TABSTOP,7,111,396,80 + CONTROL "Display hidden shares",IDC_SHOWHIDDENSHARES,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,87,6,125,11 + PUSHBUTTON "New share",ID_SHARELIST_NEWSHARE,6,5,70,12 +END + +IDD_OPT_HTTP_SERVER DIALOGEX 0, 0, 314, 240 +STYLE DS_SETFONT | DS_3DLOOK | DS_FIXEDSYS | DS_CENTER | WS_CHILD | WS_VISIBLE +EXSTYLE WS_EX_CONTROLPARENT +FONT 8, "MS Shell Dlg", 0, 0, 0x1 +BEGIN + EDITTEXT IDC_EXTERNAL_SRV_NAME,35,73,244,21,ES_MULTILINE | ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN + CONTROL "Show HTTP server statistics",IDC_ADD_STATISTICS_MENU_ITEM, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,35,30,117,10 + PUSHBUTTON "Set to default",IDC_EXTERNAL_SRV_DEFAULT,224,55,56,14 + GROUPBOX "External server name",IDC_STATIC,30,47,254,106 + LTEXT "This is the link pasted to the message window",IDC_STATIC,35,61,186,8 + CONTROL "Write log file",IDC_WRITE_LOG_FILE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,162,31,66,10 + CONTROL "Enable / Disable HTTP server",IDC_ACCEPT_COM_MENU_ITEM, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,35,15,115,10 + GROUPBOX "Main menu items",IDC_STATIC,30,3,121,42 + PUSHBUTTON "Open log",IDC_OPEN_LOG,230,27,50,14 + CONTROL "Show popups",IDC_SHOW_POPUPS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,162,15,112,10 + LTEXT "Page keyword",IDC_STATIC,40,129,46,8 + LTEXT "URL address",IDC_STATIC,40,110,42,8 + GROUPBOX "%ExternalIP% variable",IDC_STATIC,35,96,244,51 + COMBOBOX IDC_URL_ADDRESS,94,108,180,30,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP + COMBOBOX IDC_PAGE_KEYWORD,93,127,123,30,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP + PUSHBUTTON "Test",IDC_TEST_EXTERNALIP,224,126,51,14 + EDITTEXT IDC_MAX_SPEED,35,181,24,12,ES_AUTOHSCROLL + LTEXT "Transfer limit (kb/sec)",IDC_STATIC,62,183,91,8 + CONTROL "No control when Away/NA",IDC_LIMIT_ONLY_WHEN_ONLINE, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,35,224,114,10 + GROUPBOX "Connection control",IDC_STATIC,30,155,127,81 + GROUPBOX "Index creation",IDC_STATIC,162,155,122,56 + CONTROL "Disable",IDC_INDEX_OFF,"Button",BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,169,168,105,10 + CONTROL "Create HTML (compatibility)",IDC_INDEX_HTML,"Button",BS_AUTORADIOBUTTON,169,182,105,10 + CONTROL "Create XML",IDC_INDEX_XML,"Button",BS_AUTORADIOBUTTON,169,196,105,10 + GROUPBOX "Notifications",IDC_STATIC,157,3,127,42 + LTEXT "Total connection limit",IDC_STATIC,62,197,93,8 + LTEXT "Connections per user limit",IDC_STATIC,62,211,92,8 + EDITTEXT IDC_MAX_CONN_TOTAL,35,195,24,12,ES_AUTOHSCROLL + EDITTEXT IDC_MAX_CONN_PER_USER,35,209,24,12,ES_AUTOHSCROLL + EDITTEXT IDC_DEFAULT_DOWNLOAD_LIMIT,35,167,24,12,ES_AUTOHSCROLL + LTEXT "Default download limit",IDC_STATIC,62,169,91,8 +END + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO +BEGIN + IDD_NEW_SHARE_PROPERTIES, DIALOG + BEGIN + LEFTMARGIN, 5 + VERTGUIDE, 109 + VERTGUIDE, 120 + BOTTOMMARGIN, 46 + HORZGUIDE, 31 + END + + IDD_STATISTICS_VIEW, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 403 + TOPMARGIN, 7 + BOTTOMMARGIN, 191 + END + + IDD_OPT_HTTP_SERVER, DIALOG + BEGIN + RIGHTMARGIN, 313 + VERTGUIDE, 30 + VERTGUIDE, 35 + VERTGUIDE, 40 + VERTGUIDE, 162 + VERTGUIDE, 274 + VERTGUIDE, 279 + VERTGUIDE, 284 + HORZGUIDE, 20 + HORZGUIDE, 36 + END +END +#endif // APSTUDIO_INVOKED + + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "..\\src\\resource.h\0" +END + +2 TEXTINCLUDE +BEGIN + "#include ""afxres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Menu +// + +IDR_MENU1 MENU +BEGIN + POPUP "1" + BEGIN + MENUITEM "&Edit share", ID_SHARELIST_EDITSHARE + MENUITEM "&Remove share", ID_SHARELIST_REMOVESHARE + MENUITEM SEPARATOR + MENUITEM "&Open in Browser", ID_SHARELIST_OPEN + MENUITEM "&Copy link", ID_SHARELIST_COPYLINK + END +END + +#endif // Ðóññêèé (Ðîññèÿ) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/plugins/HTTPServer/res/share_ne.ico b/plugins/HTTPServer/res/share_ne.ico new file mode 100644 index 0000000000..3ca16036b3 Binary files /dev/null and b/plugins/HTTPServer/res/share_ne.ico differ diff --git a/plugins/HTTPServer/src/FileShareNode.cpp b/plugins/HTTPServer/src/FileShareNode.cpp new file mode 100644 index 0000000000..d2e9f62731 --- /dev/null +++ b/plugins/HTTPServer/src/FileShareNode.cpp @@ -0,0 +1,375 @@ +//This file is part of HTTPServer a Miranda IM plugin +//Copyright (C)2002 Kennet Nielsen +// +//This program is free software; you can redistribute it and/or +//modify it under the terms of the GNU General Public License +//as published by the Free Software Foundation; either +//version 2 of the License, or (at your option) any later version. +// +//This program is distributed in the hope that it will be useful, +//but WITHOUT ANY WARRANTY; without even the implied warranty of +//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +//GNU General Public License for more details. +// +//You should have received a copy of the GNU General Public License +//along with this program; if not, write to the Free Software +//Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#include "Glob.h" + +CLFileShareNode * pclFirstNode = NULL; +CRITICAL_SECTION csFileShareListAccess; + + + +///////////////////////////////////////////////////////////////////// +// Member Function : CLShareUser +// Type : Private / Public / Protected +// Parameters : None +// Returns : +// Description : +// +// References : - +// Remarks : - +// Created : 030918, 18 september 2003 +// Developer : KN +///////////////////////////////////////////////////////////////////// + +CLShareUser::CLShareUser(HANDLE hCon, in_addr stAdd) { + hConnection = hCon; + stAddr = stAdd; + pclNext = NULL; + dwTotalSize = 0; + dwCurrentDL = 0; + dwSpeed = 0; +} + +///////////////////////////////////////////////////////////////////// +// Member Function : ~CLShareUser +// Type : Private / Public / Protected +// Parameters : None +// Returns : +// Description : +// +// References : - +// Remarks : - +// Created : 031124, 24 november 2003 +// Developer : KN +///////////////////////////////////////////////////////////////////// + +CLShareUser::~CLShareUser() { + if (hConnection) { + CloseSocket(); + Netlib_CloseHandle(hConnection); + } +} + + +///////////////////////////////////////////////////////////////////// +// Member Function : CloseSend +// Type : Private / Public / Protected +// Parameters : None +// Returns : void +// Description : +// +// References : - +// Remarks : - +// Created : 031124, 24 november 2003 +// Developer : KN +///////////////////////////////////////////////////////////////////// + +void CLShareUser::CloseSocket() { + SOCKET s = CallService(MS_NETLIB_GETSOCKET, (WPARAM) hConnection, 0); + if (s != INVALID_SOCKET) { + shutdown(s, SD_SEND); + int nBytesRead; + do { + char szBuf[100]; + nBytesRead = Netlib_Recv(hConnection, szBuf, sizeof(szBuf), 0); + } while (nBytesRead && nBytesRead != SOCKET_ERROR); + //shutdown( s, SD_RECEIVE ); + } +} + +///////////////////////////////////////////////////////////////////// +// Member Function : dwGetDownloadSpeed +// Type : Private / Public / Protected +// Parameters : None +// Returns : DWORD +// Description : +// +// References : - +// Remarks : - +// Created : 030918, 18 september 2003 +// Developer : KN +///////////////////////////////////////////////////////////////////// + +DWORD CLShareUser::dwGetDownloadSpeed() { + return dwSpeed; +} + + + +///////////////////////////////////////////////////////////////////// +// Member Function : CLFileShareNode +// Type : Private / Public / Protected +// Parameters : NULL - ? +// Returns : +// Description : +// +// References : - +// Remarks : - +// Created : 030826, 26 august 2003 +// Developer : KN +///////////////////////////////////////////////////////////////////// + +CLFileShareNode::CLFileShareNode(char * pszSrvPath, char * pszRealPath) { + memset(&st, 0, sizeof(STFileShareInfo)); + st.lStructSize = sizeof(STFileShareInfo); + pclNext = NULL; + pclCurrentUsers = NULL; + + bSetPaths(pszSrvPath, pszRealPath); +} + +///////////////////////////////////////////////////////////////////// +// Member Function : CLFileShareNode +// Type : Global +// Parameters : pstInfo - ? +// Returns : +// Description : +// +// References : - +// Remarks : - +// Created : 030829, 29 august 2003 +// Developer : KN +///////////////////////////////////////////////////////////////////// + +CLFileShareNode::CLFileShareNode(STFileShareInfo * pstInfo) { + memset(&st, 0, sizeof(STFileShareInfo)); + st.lStructSize = sizeof(STFileShareInfo); + pclNext = NULL; + pclCurrentUsers = NULL; + + bSetInfo(pstInfo); +} + +///////////////////////////////////////////////////////////////////// +// Member Function : ~CLFileShareNode +// Type : Private / Public / Protected +// Parameters : None +// Returns : +// Description : +// +// References : - +// Remarks : - +// Created : 030826, 26 august 2003 +// Developer : KN +///////////////////////////////////////////////////////////////////// + +CLFileShareNode::~CLFileShareNode() { + delete [] st.pszSrvPath; + delete [] st.pszRealPath; + + CLShareUser * pclCur = pclCurrentUsers; + while (pclCur) { + CLShareUser * pclNext = pclCur->pclNext; + delete pclCur; + pclCur = pclNext; + } +} + + +///////////////////////////////////////////////////////////////////// +// Member Function : bSetPaths +// Type : Private / Public / Protected +// Parameters : pszSrvPath - ? +// pszRealPath - ? +// Returns : Returns true if +// Description : +// +// References : - +// Remarks : - +// Created : 030829, 29 august 2003 +// Developer : KN +///////////////////////////////////////////////////////////////////// + +bool CLFileShareNode::bSetPaths(char * pszSrvPath, char * pszRealPath) { + /* This might be a problem !! + if( nDownloadsInProgress > 0 ) + return false; + */ + + if (!pszSrvPath || !pszRealPath) + return false; + + delete [] st.pszSrvPath; + delete [] st.pszRealPath; + + st.dwMaxSrvPath = strlen(pszSrvPath) + 1; + st.pszSrvPath = new char[ st.dwMaxSrvPath ]; + strcpy(st.pszSrvPath, pszSrvPath); + + int nRealLen = strlen(pszRealPath); + if (nRealLen <= 2 || !(pszRealPath[1] == ':' || + (pszRealPath[0] == '\\' && pszRealPath[1] == '\\'))) { + // Relative path + // we will prepend plugin path to avoid problems + st.dwMaxRealPath = nPluginPathLen + nRealLen + 1; + st.pszRealPath = new char[ st.dwMaxRealPath ]; + strcpy(st.pszRealPath, szPluginPath); + pszOrigRealPath = &st.pszRealPath[nPluginPathLen]; + } else { + st.dwMaxRealPath = nRealLen + 1; + st.pszRealPath = new char[ st.dwMaxRealPath ]; + pszOrigRealPath = st.pszRealPath; + } + strcpy(pszOrigRealPath, pszRealPath); + return true; +} + +///////////////////////////////////////////////////////////////////// +// Member Function : bSetInfo +// Type : Private / Public / Protected +// Parameters : pstInfo - ? +// Returns : Returns true if +// Description : +// +// References : - +// Remarks : - +// Created : 030829, 29 august 2003 +// Developer : KN +///////////////////////////////////////////////////////////////////// + +bool CLFileShareNode::bSetInfo(STFileShareInfo * pstInfo) { + if (! bSetPaths(pstInfo->pszSrvPath, pstInfo->pszRealPath)) + return false; + if (pstInfo->nMaxDownloads < -1) + return false; + + st.dwAllowedIP = pstInfo->dwAllowedIP; + st.dwAllowedMask = pstInfo->dwAllowedMask; + st.nMaxDownloads = pstInfo->nMaxDownloads; + st.dwOptions = pstInfo->dwOptions; + return true; +} + +/* +///////////////////////////////////////////////////////////////////// +// Member Function : bAddHttpUser +// Type : Private / Public / Protected +// Parameters : hConnection - ? +// stAddr - ? +// Returns : Returns true if +// Description : +// +// References : - +// Remarks : - +// Created : 030902, 02 september 2003 +// Developer : KN, Houdini +///////////////////////////////////////////////////////////////////// + +CLHttpUser * CLFileShareNode::pclAddHttpUser( HANDLE hConnection, in_addr stAddr ) +{ + CLHttpUser * pclCur = pclCurrentUsers; + while( pclCur ) + { + if( pclCur->hConnection == hConnection ) + { + return NULL; + } + pclCur = pclCur->pclNext; + } + pclCurrentUsers = new CLHttpUser( hConnection, stAddr, pclCurrentUsers ); + UpdateStatisticsView(); + return pclCurrentUsers; +} +*/ + +bool CLFileShareNode::bAddUser(CLShareUser * pclUser) { + // deny access + if (bIsOnline || !bLimitOnlyWhenOnline) { + int nConnectionCount = 0; + int nUserConnectionCount = 0; + + // iterate through all shares + CLFileShareNode * pclShare = pclFirstNode; + while (pclShare) { + // iterate through its users + CLShareUser * pclCur = pclShare->pclCurrentUsers; + while (pclCur) { + //strcmp(pclCur->szCurrentDLSrvPath, pclUser->szCurrentDLSrvPath) == 0) // same file + if (memcmp(&pclCur->stAddr, &pclUser->stAddr, sizeof(in_addr)) == 0) // same IP + nUserConnectionCount++; + + nConnectionCount++; + + pclCur = pclCur->pclNext; + } + pclShare = pclShare->pclNext; + } + + if (nMaxConnectionsTotal >= 0) + if (nConnectionCount + 1 > nMaxConnectionsTotal) + return false; + + if (nMaxConnectionsPerUser >= 0) + if (nUserConnectionCount + 1 > nMaxConnectionsPerUser) + return false; + } + + pclUser->pclNext = pclCurrentUsers; + pclCurrentUsers = pclUser; + UpdateStatisticsView(); + return true; +} + +///////////////////////////////////////////////////////////////////// +// Member Function : bRemoveUser +// Type : Private / Public / Protected +// Parameters : pclUser - ? +// Returns : Returns true if +// Description : +// +// References : - +// Remarks : - +// Created : 030918, 18 september 2003 +// Developer : KN +///////////////////////////////////////////////////////////////////// + +bool CLFileShareNode::bRemoveUser(CLShareUser * pclUser) { + CLShareUser **pclPrev = &pclCurrentUsers; + CLShareUser * pclCur = pclCurrentUsers; + while (pclCur) { + if (pclCur == pclUser) { + *pclPrev = pclCur->pclNext; + UpdateStatisticsView(); + return true; + } + pclPrev = &pclCur->pclNext; + pclCur = pclCur->pclNext; + } + return false; +} + +///////////////////////////////////////////////////////////////////// +// Member Function : CloseAllTransfers +// Type : Private / Public / Protected +// Parameters : None +// Returns : void +// Description : +// +// References : - +// Remarks : - +// Created : 030902, 02 september 2003 +// Developer : KN +///////////////////////////////////////////////////////////////////// + +void CLFileShareNode::CloseAllTransfers() { + CLShareUser * pclCur = pclCurrentUsers; + while (pclCur) { + pclCur->CloseSocket(); + pclCur = pclCur->pclNext; + } +} \ No newline at end of file diff --git a/plugins/HTTPServer/src/FileShareNode.h b/plugins/HTTPServer/src/FileShareNode.h new file mode 100644 index 0000000000..706a31f093 --- /dev/null +++ b/plugins/HTTPServer/src/FileShareNode.h @@ -0,0 +1,103 @@ +//This file is part of HTTPServer a Miranda IM plugin +//Copyright (C)2002 Kennet Nielsen +// +//This program is free software; you can redistribute it and/or +//modify it under the terms of the GNU General Public License +//as published by the Free Software Foundation; either +//version 2 of the License, or (at your option) any later version. +// +//This program is distributed in the hope that it will be useful, +//but WITHOUT ANY WARRANTY; without even the implied warranty of +//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +//GNU General Public License for more details. +// +//You should have received a copy of the GNU General Public License +//along with this program; if not, write to the Free Software +//Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +#ifndef FILE_SHARE_NODE_H +#define FILE_SHARE_NODE_H + +#include +#include "m_HTTPServer.h" + +class CLShareUser { +public: + CLShareUser(HANDLE hCon, in_addr stAdd); + virtual ~CLShareUser(); + CLShareUser * pclNext; + in_addr stAddr; + DWORD dwCurrentDL; + DWORD dwTotalSize; + char szCurrentDLSrvPath[MAX_PATH]; + virtual DWORD dwGetDownloadSpeed(); + virtual bool bCloseTransfers() = NULL; + virtual const char * pszCustomInfo() = NULL; + void CloseSocket(); +protected: + HANDLE hConnection; + DWORD dwSpeed; +}; + +class CLFileShareNode { +public://, DWORD dwAllowedIP, DWORD dwAllowedMask, int nMaxDownloads ); + CLFileShareNode(char * pszSrvPath, char * pszRealPath); + CLFileShareNode(STFileShareInfo * pstInfo); + ~CLFileShareNode(); + bool bSetPaths(char * pszSrvPath, char * pszRealPath); + bool bSetInfo(STFileShareInfo * pstInfo); + int nGetSrvPathLen() { + return st.dwMaxSrvPath -1; + } + bool bIsDirectory() { + return st.pszSrvPath[st.dwMaxSrvPath-2] == '/'; + } + + STFileShareInfo st; + char *pszOrigRealPath; + CLFileShareNode * pclNext; + //CLHttpUser * pclAddHttpUser( HANDLE hConnection, in_addr stAddr ); + //bool bRemoveHttpUser( CLHttpUser * pclUser ); + bool bAddUser(CLShareUser * pclUser); + bool bRemoveUser(CLShareUser * pclUser); + bool bAnyUsers() { + return pclCurrentUsers != 0; + } + void CloseAllTransfers(); + CLShareUser *pclGetUsers() { + return pclCurrentUsers; + } +private: + CLShareUser * pclCurrentUsers; + +}; + +extern CLFileShareNode * pclFirstNode; +extern CRITICAL_SECTION csFileShareListAccess; + +class CLFileShareListAccess { + bool bLocked; +public: + CLFileShareListAccess() { + bLocked = false; + Lock(); + } + ~CLFileShareListAccess() { + Unlock(); + } + void Lock() { + if (bLocked) + return; + EnterCriticalSection(&csFileShareListAccess); + bLocked = true; + } + void Unlock() { + if (!bLocked) + return; + LeaveCriticalSection(&csFileShareListAccess); + bLocked = false; + } + +}; + +#endif \ No newline at end of file diff --git a/plugins/HTTPServer/src/Glob.h b/plugins/HTTPServer/src/Glob.h new file mode 100644 index 0000000000..dbce7e44e2 --- /dev/null +++ b/plugins/HTTPServer/src/Glob.h @@ -0,0 +1,94 @@ +//This file is part of HTTPServer a Miranda IM plugin +//Copyright (C)2002 Kennet Nielsen +// +//This program is free software; you can redistribute it and/or +//modify it under the terms of the GNU General Public License +//as published by the Free Software Foundation; either +//version 2 of the License, or (at your option) any later version. +// +//This program is distributed in the hope that it will be useful, +//but WITHOUT ANY WARRANTY; without even the implied warranty of +//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +//GNU General Public License for more details. +// +//You should have received a copy of the GNU General Public License +//along with this program; if not, write to the Free Software +//Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +#ifndef HTTP_SERVER_GLOB_H +#define HTTP_SERVER_GLOB_H + +#define _CRT_SECURE_NO_DEPRECATE + +#include +#include +#include +#include +#include +#include +using namespace std; + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "m_HTTPServer.h" + +#include "FileShareNode.h" +#include "HttpUser.h" +#include "GuiElements.h" +#include "MimeHandling.h" +#include "resource.h" +#include "IndexCreation.h" + + +#define SD_RECEIVE 0x00 +#define SD_SEND 0x01 +#define SD_BOTH 0x02 + +#define MODULE "HTTPServer" +#define MSG_BOX_TITEL _T("Miranda (HTTPServer.dll)") + +#define SplitIpAddress( p ) (BYTE)(p>>24),(BYTE)(p>>16),(BYTE)(p>>8),(BYTE)(p) + +extern HINSTANCE hInstance; + +extern HANDLE hNetlibUser; + +extern bool bShutdownInProgress; +bool bWriteConfigurationFile(); + +void LogEvent(const char * pszTitle, const char * pszLog); +bool bOpenLogFile(); + +extern char szPluginPath[MAX_PATH]; +extern int nPluginPathLen; + +extern DWORD dwLocalIpAddress; +extern DWORD dwLocalPortUsed; +extern DWORD dwExternalIpAddress; + +extern int nMaxUploadSpeed; +extern int nMaxConnectionsTotal; +extern int nMaxConnectionsPerUser; +extern int nDefaultDownloadLimit; +extern bool bIsOnline; +extern bool bLimitOnlyWhenOnline; + +extern void* (*MirandaMalloc)(size_t); +extern void (*MirandaFree)(void*); + +extern char * pszVersion; + +#endif \ No newline at end of file diff --git a/plugins/HTTPServer/src/GuiElements.cpp b/plugins/HTTPServer/src/GuiElements.cpp new file mode 100644 index 0000000000..e4c922fd6d --- /dev/null +++ b/plugins/HTTPServer/src/GuiElements.cpp @@ -0,0 +1,1553 @@ +//This file is part of HTTPServer a Miranda IM plugin +//Copyright (C)2002 Kennet Nielsen +// +//This program is free software; you can redistribute it and/or +//modify it under the terms of the GNU General Public License +//as published by the Free Software Foundation; either +//version 2 of the License, or (at your option) any later version. +// +//This program is distributed in the hope that it will be useful, +//but WITHOUT ANY WARRANTY; without even the implied warranty of +//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +//GNU General Public License for more details. +// +//You should have received a copy of the GNU General Public License +//along with this program; if not, write to the Free Software +//Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#include "Glob.h" + +#define MS_SHARE_NEW_FILE "HTTPServer/ShareNewFile" +#define MS_SHOW_STATISTICS_VIEW "HTTPServer/ShowStatisticsView" + +#define WM_RELOAD_STATISTICS (WM_USER+10) + +static HANDLE hShareNewFileService = 0; +static HANDLE hShowStatisticsViewService = 0; + +static HANDLE hShareNewFileMenuItem = 0; +static HANDLE hShowStatisticsViewMenuItem = 0; + +static HANDLE hEventOptionsInitialize = 0; + +HWND hwndStatsticView = 0; +bool bLastAutoRefress = false; +HANDLE hMainThread; + +bool bShowPopups = true; + +#define szDefaultExternalSrvName "http://%ExternalIP%:%Port%%SrvPath%" + +#define szDefaultUrlAddress "http://checkip.dyndns.org" +#define szDefaultPageKeyword "Current IP Address: " + +string sUrlAddress = szDefaultUrlAddress; +string sPageKeyword = szDefaultPageKeyword; + + +///////////////////////////////////////////////////////////////////// +// Member Function : ReplaceAll +// Type : Global +// Parameters : sSrc - string to replace in +// pszReplace - what to replace +// sNew - the string to insert insted of pszReplace +// Returns : void +// Description : will replace all acurances of a string with another string +// used to replace %user%, and other user +// References : - +// Remarks : - +// Created : 020422, 22 April 2002 +// Developer : KN +///////////////////////////////////////////////////////////////////// + +void ReplaceAll(string &sSrc, const char * pszReplace, const string &sNew) { + string::size_type nCur = 0; + int nRepalceLen = strlen(pszReplace); + while ((nCur = sSrc.find(pszReplace, nCur)) != sSrc.npos) { + sSrc.replace(nCur, nRepalceLen, sNew); + nCur += sNew.size(); + } +} + +void ReplaceAll(string &sSrc, const char * pszReplace, const char * pszNew) { + string sNew = pszNew; + ReplaceAll(sSrc, pszReplace, sNew); +} + + +///////////////////////////////////////////////////////////////////// +// Member Function : DBGetString +// Type : Global +// Parameters : hContact - ? +// szModule - ? +// szSetting - ? +// pszError - ? +// Returns : string +// Description : Reads a string from the database +// Just like those in database.h +// References : - +// Remarks : - +// Created : 020422, 22 April 2002 +// Developer : KN +///////////////////////////////////////////////////////////////////// + +string DBGetString(HANDLE hContact, const char *szModule, const char *szSetting, const char * pszError) { + string ret; + DBVARIANT dbv = {0}; + if (! DBGetContactSetting(hContact, szModule, szSetting, &dbv)) { + if (dbv.type != DBVT_ASCIIZ) { + MessageBox(NULL, "DB: Attempt to get wrong type of value, string", MSG_BOX_TITEL, MB_OK); + ret = pszError; + } else { + ret = dbv.pszVal; + } + } else + ret = pszError; + DBFreeVariant(&dbv); + return ret; +} + + +///////////////////////////////////////////////////////////////////// +// Member Function : UpdateStatisticsView +// Type : Global +// Parameters : None +// Returns : void +// Description : +// +// References : - +// Remarks : - +// Created : 030904, 04 september 2003 +// Developer : KN +///////////////////////////////////////////////////////////////////// + +void UpdateStatisticsView() { + if (hwndStatsticView) { + PostMessage(hwndStatsticView, WM_RELOAD_STATISTICS, 0, 0); + } +} + + +///////////////////////////////////////////////////////////////////// +// Member Function : GetExternIP +// Type : Global +// Parameters : szURL - The url of the page where IP is written +// szPattern - The text before the IP in page (can be "") +// Returns : External IP or 0 if error +// Description : +// +// References : - +// Remarks : - +// Created : 031113, 13 november 2003 +// Developer : KN +///////////////////////////////////////////////////////////////////// + +unsigned long GetExternIP(const char *szURL, const char *szPattern) { + HCURSOR hPrevCursor = ::SetCursor(::LoadCursor(0, IDC_WAIT)); + + NETLIBHTTPREQUEST nlhr; + ZeroMemory(&nlhr, sizeof(nlhr)); + nlhr.cbSize = sizeof(nlhr); + nlhr.requestType = REQUEST_GET; + nlhr.flags = NLHRF_DUMPASTEXT; + nlhr.szUrl = (char*)szURL; + + IN_ADDR externIP; + externIP.s_addr = 0; + + NETLIBHTTPREQUEST *nlreply = (NETLIBHTTPREQUEST *) CallService(MS_NETLIB_HTTPTRANSACTION, (WPARAM) hNetlibUser, (LPARAM) & nlhr); + if (nlreply) { + if (nlreply->resultCode >= 200 && nlreply->resultCode < 300) { + nlreply->pData[nlreply->dataLength] = 0;// make sure its null terminated + char * pszIp = strstr(nlreply->pData, szPattern); + if (pszIp == NULL) + pszIp = nlreply->pData; + else + pszIp += strlen(szPattern); + while ((*pszIp < '0' || *pszIp > '9') && *pszIp) + pszIp++; + + char * pszEnd = pszIp; + while ((*pszEnd >= '0' && *pszEnd <= '9') || *pszEnd == '.') + pszEnd++; + *pszEnd = NULL; + + if ((externIP.s_addr = inet_addr(pszIp)) == INADDR_NONE) + externIP.s_addr = 0; + } + CallService(MS_NETLIB_FREEHTTPREQUESTSTRUCT, 0, (LPARAM) nlreply); + } + ::SetCursor(hPrevCursor); + return ntohl(externIP.s_addr); +} + + + +///////////////////////////////////////////////////////////////////// +// Member Function : sCreateLink +// Type : Global +// Parameters : pszSrvPath - ? +// pszIndexPath - ? +// Returns : string +// Description : +// +// References : - +// Remarks : - +// Created : 030915, 15 september 2003 +// Developer : KN +///////////////////////////////////////////////////////////////////// + +string sCreateLink(const char * pszSrvPath) { + char szTemp[30]; + string sLink = DBGetString(NULL, MODULE, "ExternalSrvName", szDefaultExternalSrvName); + _snprintf(szTemp, sizeof(szTemp), "%d.%d.%d.%d", SplitIpAddress(dwLocalIpAddress)); + ReplaceAll(sLink, "%LocalIP%", szTemp); + + if (sLink.find("%ExternalIP%") != sLink.npos) { + static DWORD dwExternalIpAddressGenerated = 0; + + // Get the IP again after 10 minutes + if (! dwExternalIpAddress || GetTickCount() - dwExternalIpAddressGenerated > 10 * 60 * 1000) { + dwExternalIpAddress = GetExternIP(sUrlAddress.c_str(), sPageKeyword.c_str()); + + dwExternalIpAddressGenerated = GetTickCount(); + } + + _snprintf(szTemp, sizeof(szTemp), "%d.%d.%d.%d", SplitIpAddress(dwExternalIpAddress)); + ReplaceAll(sLink, "%ExternalIP%", szTemp); + } + + _snprintf(szTemp, sizeof(szTemp), "%d", dwLocalPortUsed, szTemp); + ReplaceAll(sLink, "%Port%", szTemp); + + string sSrvPath = pszSrvPath; + ReplaceAll(sSrvPath, " ", "%20"); + ReplaceAll(sLink, "%SrvPath%", sSrvPath); + return sLink; +} + +///////////////////////////////////////////////////////////////////// +// Member Function : ShareNewFileDialogHook +// Type : Global +// Parameters : hdlg - ? +// uiMsg - ? +// wParam - ? +// parameter - ? +// Returns : UINT_PTR CALLBACK +// Description : +// +// References : - +// Remarks : - +// Created : 030829, 29 august 2003 +// Developer : KN, Houdini +///////////////////////////////////////////////////////////////////// + +UINT CALLBACK ShareNewFileDialogHook( + HWND hDlg, // handle to child dialog box + UINT uiMsg, // message identifier + WPARAM wParam, // message parameter + LPARAM lParam // message parameter +) { + static const char* pszShareDirStr = Translate("Share Current Directory"); + + static int nInit = 0; + + STFileShareInfo * pstShare = (STFileShareInfo *)GetWindowLongPtr(hDlg, GWLP_USERDATA); + switch (uiMsg) { + case WM_INITDIALOG: { + pstShare = (STFileShareInfo *)((OPENFILENAME *)lParam)->lCustData; + SetWindowLongPtr(hDlg, GWLP_USERDATA, (LPARAM)pstShare); + + SetDlgItemInt(hDlg, IDC_MAX_DOWNLOADS, pstShare->nMaxDownloads, true); + SendMessage(GetDlgItem(hDlg, IDC_ALLOWED_IPADDRESS), IPM_SETADDRESS, 0, pstShare->dwAllowedIP); + SendMessage(GetDlgItem(hDlg, IDC_ALLOWED_IP_MASK), IPM_SETADDRESS, 0, pstShare->dwAllowedMask); + + if (*pstShare->pszSrvPath) + nInit = 2; + else + nInit = 1; + + return false; + } + + case WM_NOTIFY: { + OFNOTIFY * pNotify = (OFNOTIFY*)lParam; + switch (pNotify->hdr.code) { + case CDN_FOLDERCHANGE: + case CDN_SELCHANGE: { + static char szSelection[MAX_PATH] = ""; + HWND hWndFileDlg = GetParent(hDlg); + + *szSelection = '/'; + CommDlg_OpenSave_GetSpec(hWndFileDlg, (LPARAM)(&szSelection[1]), _MAX_PATH); + + HWND hFileName = GetDlgItem(hWndFileDlg, edt1); + char pszFileName[MAX_PATH]; + SendMessage(hFileName, WM_GETTEXT, MAX_PATH, (LPARAM)pszFileName); + + if (strcmp(pstShare->pszSrvPath, szSelection) && + strcmp(pszFileName, pszShareDirStr)) { + // a file was selected + + // only reenable windows / set default values when a folder was selected before + if (pstShare->pszSrvPath[strlen(pstShare->pszSrvPath)-1] == '/') { + pNotify->lpOFN->Flags |= OFN_FILEMUSTEXIST; + EnableWindow(hFileName, TRUE); + EnableWindow(GetDlgItem(hDlg, IDC_MAX_DOWNLOADS), TRUE); + SetDlgItemInt(hDlg, IDC_MAX_DOWNLOADS, nDefaultDownloadLimit, true); + } + } else { + // a directory was selected + pNotify->lpOFN->Flags &= ~OFN_FILEMUSTEXIST; + strcpy(pNotify->lpOFN->lpstrFile, pszShareDirStr); + CommDlg_OpenSave_SetControlText(hWndFileDlg, edt1, pszShareDirStr); + EnableWindow(hFileName, FALSE); + EnableWindow(GetDlgItem(hDlg, IDC_MAX_DOWNLOADS), FALSE); + SetDlgItemInt(hDlg, IDC_MAX_DOWNLOADS, (UINT)-1, true); + + CommDlg_OpenSave_GetFolderPath(hWndFileDlg, szSelection, MAX_PATH); + char* pszFolder = szSelection; + char* pszTmp = szSelection; + while (*pszTmp != '\0') { + if (*pszTmp == '\\' && *(pszTmp + 1)) + pszFolder = pszTmp + 1; + pszTmp++; + } + + pszTmp = strchr(szSelection, ':'); + if (pszTmp != NULL) + *pszTmp = '\0'; + + memmove(&szSelection[1], pszFolder, strlen(pszFolder) + 1); + szSelection[0] = '/'; + if (szSelection[strlen(szSelection)-1] != '/') + strcat(szSelection, "/"); + + // only write to IDC_SHARE_NAME when a file / other folder was selected before + if (!strcmp(szSelection, pstShare->pszSrvPath)) + return false; + } + + if (nInit != 0) { + // when the dialog is created a CDN_FOLDERCHANGE and a CDN_SELCHANGE message + // is posted. When the dialog is used for editting make sure the right server + // path (not the auto generated) is written to IDC_SHARE_NAME + if (nInit == 2) + SetDlgItemText(hDlg, IDC_SHARE_NAME, pstShare->pszSrvPath); + + nInit--; + } else { + SetDlgItemText(hDlg, IDC_SHARE_NAME, szSelection); + } + + strcpy(pstShare->pszSrvPath, szSelection); + + return false; + } + + case CDN_FILEOK: { + GetDlgItemText(hDlg, IDC_SHARE_NAME, pstShare->pszSrvPath, _MAX_PATH); + + char* pszTmp = strstr(pstShare->pszRealPath, pszShareDirStr); + if (pszTmp) { + *pszTmp = '\0'; + if (pstShare->pszSrvPath[strlen(pstShare->pszSrvPath)-1] != '/') + strcat(pstShare->pszSrvPath, "/"); + } else { + if (pstShare->pszSrvPath[strlen(pstShare->pszSrvPath)-1] == '/') + pstShare->pszSrvPath[strlen(pstShare->pszSrvPath)-1] = '\0'; + } + + BOOL bTranslated = false; + pstShare->nMaxDownloads = GetDlgItemInt(hDlg, IDC_MAX_DOWNLOADS, &bTranslated, true); + if (pstShare->nMaxDownloads <= 0 && pstShare->nMaxDownloads != -1) + bTranslated = false; + + SendMessage(GetDlgItem(hDlg, IDC_ALLOWED_IPADDRESS), IPM_GETADDRESS, 0, (LPARAM)&(pstShare->dwAllowedIP)); + SendMessage(GetDlgItem(hDlg, IDC_ALLOWED_IP_MASK), IPM_GETADDRESS, 0, (LPARAM)&(pstShare->dwAllowedMask)); + + //if( ! (pstShare->dwAllowedIP & pstShare->dwAllowedMask) + + if (!bTranslated || (strlen(pstShare->pszSrvPath) <= 0)) { + SetWindowLongPtr(hDlg, DWLP_MSGRESULT, 1); + return true; + } + return false; + } + } + break; + } + + case WM_DROPFILES: { + HDROP hDrop = (HDROP)wParam; + char szDropedFile[MAX_PATH]; + int nLen = DragQueryFile(hDrop, 0, szDropedFile, sizeof(szDropedFile)); + if (nLen > 0) { + char * psz = strrchr(szDropedFile, '\\'); + if (psz) { + char oldNext = psz[1]; + psz[1] = '\0'; + // Fill in the directory + SendMessage(GetParent(hDlg), CDM_SETCONTROLTEXT, edt1, (LPARAM)szDropedFile); + // click on the OK button. to move to dir + SendMessage(GetParent(hDlg), WM_COMMAND, IDOK, 0); + psz[1] = oldNext; + // Fill in the file name this will cause a call to the CDN_SELCHANGE + // and there by set the share name + SendMessage(GetParent(hDlg), CDM_SETCONTROLTEXT, edt1, (LPARAM)&psz[1]); + } + } + DragFinish(hDrop); + return 0; + } + + case WM_COMMAND: { + switch (LOWORD(wParam)) { + case IDC_TOGGLE_MASK: { + DWORD dwCur; + SendMessage(GetDlgItem(hDlg, IDC_ALLOWED_IP_MASK), IPM_GETADDRESS, 0, (LPARAM)&dwCur); + SendMessage(GetDlgItem(hDlg, IDC_ALLOWED_IP_MASK), IPM_SETADDRESS, 0, (LPARAM) dwCur == 0xFFFFFFFF ? 0 : 0xFFFFFFFF); + return TRUE; + } + } + } + } + return false; +} + + +///////////////////////////////////////////////////////////////////// +// Member Function : bShowShareNewFileDlg +// Type : Global +// Parameters : pstNewShare - ? +// Returns : Returns true if +// Description : +// +// References : - +// Remarks : - +// Created : 031011, 11 oktober 2003 +// Developer : KN, Houdini +///////////////////////////////////////////////////////////////////// + +bool bShowShareNewFileDlg(HWND hwndOwner, STFileShareInfo * pstNewShare) { + OPENFILENAME ofn = {0}; + ofn.lStructSize = sizeof(OPENFILENAME); + ofn.lpstrFilter = _T("All Files (*.*)\0*.*\0"); + + ofn.lpstrFile = pstNewShare->pszRealPath; + ofn.nMaxFile = pstNewShare->dwMaxRealPath; + + char szInitialDir[MAX_PATH]; + if (ofn.lpstrFile[strlen(ofn.lpstrFile)-1] == '\\') { + ofn.lpstrInitialDir = szInitialDir; + strcpy(szInitialDir, ofn.lpstrFile); + *ofn.lpstrFile = '\0'; + } + + + ofn.Flags = /*OFN_DONTADDTORECENT |*/ OFN_NOREADONLYRETURN + | OFN_ENABLEHOOK | OFN_ENABLETEMPLATE | OFN_EXPLORER | OFN_ENABLESIZING + | OFN_ALLOWMULTISELECT; + ofn.hwndOwner = hwndOwner; + ofn.hInstance = hInstance; + ofn.lpstrTitle = TranslateT("Specify a file to share"); + ofn.lpTemplateName = MAKEINTRESOURCE(IDD_NEW_SHARE_PROPERTIES); + ofn.lpfnHook = (LPOFNHOOKPROC)ShareNewFileDialogHook; + ofn.lCustData = (LPARAM)pstNewShare; + + if (!GetOpenFileName(&ofn)) { + DWORD dwError = CommDlgExtendedError(); + if (dwError) { + char szTemp[200]; + _snprintf(szTemp, sizeof(szTemp), "Failed to create File Open dialog the error returned was %d", dwError); + MessageBox(NULL, szTemp, MSG_BOX_TITEL, MB_OK); + } + return false; + } + + if (strchr(pstNewShare->pszSrvPath, '"')) { + // multiple files selected + // Serverpath: "file1" "file2" "file3" + // move one after the other to front of string (in place) + // terminate it with \0 append to realpath and add the share + char* pszFileNamePos = pstNewShare->pszSrvPath; + char* szRealDirectoryEnd = + &pstNewShare->pszRealPath[strlen(pstNewShare->pszRealPath)]; + + *szRealDirectoryEnd = '\\'; + szRealDirectoryEnd++; + + while (pszFileNamePos && *pszFileNamePos) { + pszFileNamePos = strchr(pszFileNamePos, '"'); + if (pszFileNamePos) { + pszFileNamePos++; + char* start = pszFileNamePos; + pszFileNamePos = strchr(pszFileNamePos, '"'); + if (pszFileNamePos) { + char* end = pszFileNamePos; + memmove(pstNewShare->pszSrvPath+1, start, end - start); + *(end - (start - (pstNewShare->pszSrvPath+1)) ) = '\0'; + + int realPathLen = szRealDirectoryEnd - pstNewShare->pszRealPath; + strncpy(szRealDirectoryEnd, pstNewShare->pszSrvPath+1, + pstNewShare->dwMaxRealPath - realPathLen - 1); + pstNewShare->pszRealPath[pstNewShare->dwMaxRealPath] = '\0'; + + if (CallService(MS_HTTP_ADD_CHANGE_REMOVE, 0, (LPARAM)pstNewShare)) { + MessageBox(NULL, _T("Failed to share new file"), MSG_BOX_TITEL, MB_OK); + return false; + } + pszFileNamePos++; + } + } + } + + } else { + if (CallService(MS_HTTP_ADD_CHANGE_REMOVE, 0, (LPARAM)pstNewShare)) { + MessageBox(NULL, _T("Failed to share new file"), MSG_BOX_TITEL, MB_OK); + return false; + } + } + + UpdateStatisticsView(); + return true; +} + +///////////////////////////////////////////////////////////////////// +// Member Function : UpdateStatisticView +// Type : Global +// Parameters : hwndDlg - ? +// false - ? +// Returns : void +// Description : +// +// References : - +// Remarks : - +// Created : 030904, 04 september 2003 +// Developer : KN, Houdini +///////////////////////////////////////////////////////////////////// + +void UpdateStatisticView(HWND hwndDlg, bool bRefressUsersOnly = false) { + HWND hShareList = GetDlgItem(hwndDlg, IDC_CURRENT_SHARES); + HWND hUserList = GetDlgItem(hwndDlg, IDC_CURRENT_USERS); + bool bShowHiddenShares = IsDlgButtonChecked(hwndDlg, IDC_SHOWHIDDENSHARES) == BST_CHECKED; + + if (! bRefressUsersOnly) + ListView_DeleteAllItems(hShareList); + ListView_DeleteAllItems(hUserList); + + CLFileShareListAccess scCrit; + + char szTmp[50]; + in_addr stAddr; + + bool bAutoRefress = false; + + LVITEM sItem = { 0 }; + int nShareNr = 0; + int nUserNr = 0; + for (CLFileShareNode * pclCur = pclFirstNode; pclCur ; pclCur = pclCur->pclNext) { + if (! bRefressUsersOnly && + (bShowHiddenShares || !strstr(pclCur->st.pszRealPath, "\\@"))) { + sItem.mask = LVIF_TEXT /*| LVIF_PARAM | LVIF_IMAGE*/; + sItem.iItem = nShareNr; + sItem.iSubItem = 0; + sItem.pszText = pclCur->st.pszSrvPath; + ListView_InsertItem(hShareList, &sItem); + + + _snprintf(szTmp, sizeof(szTmp), "%d", pclCur->st.nMaxDownloads); + sItem.iSubItem = 1; + sItem.pszText = szTmp; + ListView_SetItem(hShareList, &sItem); + + stAddr.S_un.S_addr = htonl(pclCur->st.dwAllowedIP); + sItem.iSubItem = 2; + sItem.pszText = inet_ntoa(stAddr); + ListView_SetItem(hShareList, &sItem); + + stAddr.S_un.S_addr = htonl(pclCur->st.dwAllowedMask); + sItem.iSubItem = 3; + sItem.pszText = inet_ntoa(stAddr); + ListView_SetItem(hShareList, &sItem); + + sItem.iSubItem = 4; + sItem.pszText = pclCur->st.pszRealPath; + ListView_SetItem(hShareList, &sItem); + + nShareNr++; + } + + for (CLShareUser * pclCurUser = pclCur->pclGetUsers() ; pclCurUser ; pclCurUser = pclCurUser->pclNext) { + bAutoRefress = true; + + sItem.mask = LVIF_TEXT /*| LVIF_PARAM | LVIF_IMAGE*/; + sItem.iItem = nUserNr; + sItem.iSubItem = 0; + sItem.pszText = pclCurUser->szCurrentDLSrvPath; //pclCur->st.pszSrvPath; + ListView_InsertItem(hUserList, &sItem); + + sItem.iSubItem = 1; + sItem.pszText = inet_ntoa(pclCurUser->stAddr); + ListView_SetItem(hUserList, &sItem); + + sItem.iSubItem = 2; + sItem.pszText = (char*)pclCurUser->pszCustomInfo(); + ListView_SetItem(hUserList, &sItem); + + if (pclCurUser->dwTotalSize) { + _snprintf(szTmp, sizeof(szTmp), "%d %%", (pclCurUser->dwCurrentDL * 100) / pclCurUser->dwTotalSize); + } else { + strcpy(szTmp, "? %%"); + } + sItem.iSubItem = 3; + sItem.pszText = szTmp; + ListView_SetItem(hUserList, &sItem); + + DWORD dwSpeed = pclCurUser->dwGetDownloadSpeed(); + if (dwSpeed > 10000) { + dwSpeed += 512; // make sure we round ot down correctly. + dwSpeed /= 1024; + _snprintf(szTmp, sizeof(szTmp), "%d KB/Sec", dwSpeed); + } else { + _snprintf(szTmp, sizeof(szTmp), "%d B/Sec", dwSpeed); + } + sItem.iSubItem = 4; + sItem.pszText = szTmp; + ListView_SetItem(hUserList, &sItem); + + nUserNr++; + } + } + + if (bLastAutoRefress != bAutoRefress) { + if (bAutoRefress) + SetTimer(hwndDlg, 0, 1000, NULL); + else + KillTimer(hwndDlg, 0); + bLastAutoRefress = bAutoRefress; + } +} + +///////////////////////////////////////////////////////////////////// +// Member Function : SetWindowsCtrls +// Type : Global +// Parameters : hwndDlg - ? +// Returns : void +// Description : +// +// References : - +// Remarks : - +// Created : 030904, 04 september 2003 +// Developer : KN +///////////////////////////////////////////////////////////////////// + +void SetWindowsCtrls(HWND hwndDlg) { + RECT rNewSize; + GetClientRect(hwndDlg, &rNewSize); + + const int nSpacing = 8; + int nCtrlHight = (rNewSize.bottom - (nSpacing * 3)) / 3 - 20; + + SetWindowPos(GetDlgItem(hwndDlg, IDC_CURRENT_SHARES), 0 , + nSpacing, + 35, + rNewSize.right - (nSpacing * 2) , + nCtrlHight*2, + SWP_NOZORDER); + + SetWindowPos(GetDlgItem(hwndDlg, IDC_CURRENT_USERS), 0 , + nSpacing , + (nSpacing * 2) + nCtrlHight*2 + 25, + rNewSize.right - (nSpacing * 2) , + nCtrlHight + 35, + SWP_NOZORDER); +} + +///////////////////////////////////////////////////////////////////// +// Member Function : DlgProcStatsticView +// Type : Global +// Parameters : hwndDlg - ? +// msg - ? +// wParam - ? +// lParam - ? +// Returns : static BOOL CALLBACK +// Description : +// +// References : - +// Remarks : - +// Created : 030904, 04 september 2003 +// Developer : KN, Houdini +///////////////////////////////////////////////////////////////////// + +static INT_PTR CALLBACK DlgProcStatsticView(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) { + switch (msg) { + case WM_INITDIALOG: { + SendMessage(hwndDlg, WM_SETICON, ICON_BIG, + (LPARAM)LoadIcon(hInstance, MAKEINTRESOURCE(IDI_SHARE_NEW_FILE))); + + TranslateDialogDefault(hwndDlg); + + HWND hShareList = GetDlgItem(hwndDlg, IDC_CURRENT_SHARES); + HWND hUserList = GetDlgItem(hwndDlg, IDC_CURRENT_USERS); + + { // init adv. win styles + DWORD dw = ListView_GetExtendedListViewStyle(hShareList); + dw |= LVS_EX_HEADERDRAGDROP | LVS_EX_FULLROWSELECT; + ListView_SetExtendedListViewStyle(hShareList, dw /*| LVS_EX_LABELTIP*/); + } + { // init adv. win styles + DWORD dw = ListView_GetExtendedListViewStyle(hUserList); + dw |= LVS_EX_HEADERDRAGDROP | LVS_EX_FULLROWSELECT; + ListView_SetExtendedListViewStyle(hUserList, dw /*| LVS_EX_LABELTIP*/); + } + + LVCOLUMN cCol = { 0 }; + cCol.mask = LVCF_TEXT | LVCF_WIDTH; + cCol.cx = db_get_w(NULL, MODULE, "StatWnd_cx1", 126); + cCol.pszText = TranslateT("Share name"); + ListView_InsertColumn(hShareList, 0, &cCol); + cCol.cx = db_get_w(NULL, MODULE, "StatWnd_cx2", 48); + cCol.pszText = TranslateT("Max Downloads"); + ListView_InsertColumn(hShareList, 1, &cCol); + cCol.cx = db_get_w(NULL, MODULE, "StatWnd_cx3", 96); + cCol.pszText = TranslateT("Allowed IP"); + ListView_InsertColumn(hShareList, 2, &cCol); + cCol.cx = db_get_w(NULL, MODULE, "StatWnd_cx4", 104); + cCol.pszText = TranslateT("Allowed Mask"); + ListView_InsertColumn(hShareList, 3, &cCol); + cCol.cx = db_get_w(NULL, MODULE, "StatWnd_cx5", 252); + cCol.pszText = TranslateT("Real path"); + ListView_InsertColumn(hShareList, 4, &cCol); + + cCol.mask = LVCF_TEXT | LVCF_WIDTH; + cCol.cx = db_get_w(NULL, MODULE, "StatWnd_cx6", 142); + cCol.pszText = TranslateT("Share name"); + ListView_InsertColumn(hUserList, 0, &cCol); + cCol.cx = db_get_w(NULL, MODULE, "StatWnd_cx7", 111); + cCol.pszText = TranslateT("User"); + ListView_InsertColumn(hUserList, 1, &cCol); + cCol.cx = db_get_w(NULL, MODULE, "StatWnd_cx8", 100); + cCol.pszText = TranslateT("Agent"); + ListView_InsertColumn(hUserList, 2, &cCol); + cCol.cx = db_get_w(NULL, MODULE, "StatWnd_cx9", 100); + cCol.pszText = TranslateT("Completed"); + ListView_InsertColumn(hUserList, 3, &cCol); + cCol.cx = db_get_w(NULL, MODULE, "StatWnd_cx10", 100); + cCol.pszText = TranslateT("Speed"); + ListView_InsertColumn(hUserList, 4, &cCol); + + bool b = db_get_b(NULL, MODULE, "StatWnd_ShowHidden", 0) != 0; + CheckDlgButton(hwndDlg, IDC_SHOWHIDDENSHARES, b ? BST_CHECKED : BST_UNCHECKED); + + bLastAutoRefress = false; + UpdateStatisticView(hwndDlg); + Utils_RestoreWindowPosition(hwndDlg, 0, MODULE, "StatWnd_"); + SetWindowsCtrls(hwndDlg); + return TRUE; + } + + case WM_SIZE: + case WM_SIZING: { + SetWindowsCtrls(hwndDlg); + return TRUE; + } + + case WM_TIMER: { + UpdateStatisticView(hwndDlg, true); + return TRUE; + } + + case WM_RELOAD_STATISTICS: { + UpdateStatisticView(hwndDlg); + return TRUE; + } + + case WM_DESTROY: { + hwndStatsticView = NULL; + return 0; + } + + case WM_DROPFILES: { + HDROP hDrop = (HDROP)wParam; + char szDropedFile[MAX_PATH]; + char szServPath[MAX_PATH] = {0}; + + int nLen = DragQueryFile(hDrop, 0xFFFFFFFF, NULL, 0); + for (int i = 0; i < nLen; i++) { + DragQueryFile(hDrop, i, szDropedFile, sizeof(szDropedFile)); + + STFileShareInfo stNewShare = {0}; + stNewShare.lStructSize = sizeof(STFileShareInfo); + stNewShare.nMaxDownloads = nDefaultDownloadLimit; + stNewShare.pszRealPath = szDropedFile; + stNewShare.dwMaxRealPath = sizeof(szDropedFile); + stNewShare.pszSrvPath = szServPath; + stNewShare.dwMaxSrvPath = sizeof(szServPath); + + szServPath[0] = '/'; + char* fileName = strrchr(szDropedFile, '\\'); + if (fileName) + strncpy(&szServPath[1], fileName+1, MAX_PATH-2); + + if (CallService(MS_HTTP_ADD_CHANGE_REMOVE, 0, (LPARAM)&stNewShare)) { + MessageBox(NULL, _T("Failed to share new file"), MSG_BOX_TITEL, MB_OK); + return false; + } + } + + UpdateStatisticsView(); + DragFinish(hDrop); + return 0; + } + + case WM_CONTEXTMENU: { + if (wParam != (WPARAM)GetDlgItem(hwndDlg, IDC_CURRENT_SHARES)) + return FALSE; + + HWND hShareList = GetDlgItem(hwndDlg, IDC_CURRENT_SHARES); + if (ListView_GetNextItem(hShareList, -1, LVIS_SELECTED) == -1) + return FALSE; + + HMENU hMainMenu = LoadMenu(hInstance, MAKEINTRESOURCE(IDR_MENU1)); + if (hMainMenu) { + HMENU hMenu = GetSubMenu(hMainMenu, 0); + + POINT pt; + pt.x = (short)LOWORD(lParam); + pt.y = (short)HIWORD(lParam); + if (pt.x == -1 && pt.y == -1) { + HWND hMapUser = GetDlgItem(hwndDlg, IDC_CURRENT_SHARES); + int nFirst = ListView_GetNextItem(hMapUser, -1, LVNI_FOCUSED); + if (nFirst >= 0) { + ListView_GetItemPosition(hMapUser, nFirst, &pt); + } + + if (pt.y < 16) + pt.y = 16; + else { + RECT rUserList; + GetClientRect(hMapUser, &rUserList); + if (pt.y > rUserList.bottom - 16) + pt.y = rUserList.bottom - 16; + else + pt.y += 8; + } + pt.x = 8; + ClientToScreen(hMapUser, &pt); + } + + TranslateMenu(hMenu); + TrackPopupMenu(hMenu, TPM_TOPALIGN | TPM_LEFTALIGN | TPM_RIGHTBUTTON, + pt.x, pt.y, 0, hwndDlg, NULL); + + DestroyMenu(hMainMenu); + } + return TRUE; + } + + case WM_COMMAND: { + HWND hShareList = GetDlgItem(hwndDlg, IDC_CURRENT_SHARES); + char szTmp[MAX_PATH]; + LVITEM sItem = { 0 }; + sItem.mask = LVIF_TEXT; + sItem.pszText = szTmp; + sItem.cchTextMax = sizeof(szTmp); + + + switch (LOWORD(wParam)) { + case IDC_SHOWHIDDENSHARES: { + UpdateStatisticView(hwndDlg); + return TRUE; + } + + case ID_SHARELIST_NEWSHARE: { + CallService(MS_SHARE_NEW_FILE, 0, (long)hwndDlg); + return TRUE; + } + + case ID_SHARELIST_EDITSHARE: + case ID_SHARELIST_REMOVESHARE: { + STFileShareInfo stShareInfo = {0}; + stShareInfo.lStructSize = sizeof(STFileShareInfo); + stShareInfo.pszSrvPath = szTmp; + stShareInfo.dwMaxSrvPath = sizeof(szTmp); + + sItem.iItem = ListView_GetNextItem(hShareList, -1, LVIS_SELECTED); + while (sItem.iItem != -1) { + if (ListView_GetItem(hShareList, &sItem)) { + if (LOWORD(wParam) == ID_SHARELIST_REMOVESHARE) { + CallService(MS_HTTP_ADD_CHANGE_REMOVE, 0, (LPARAM)&stShareInfo); + } else { + char szRealPath[MAX_PATH]; + stShareInfo.pszRealPath = szRealPath; + stShareInfo.dwMaxRealPath = sizeof(szRealPath); + CallService(MS_HTTP_GET_SHARE, 0, (LPARAM)&stShareInfo); + bShowShareNewFileDlg(hwndDlg, &stShareInfo); + } + } + sItem.iItem = ListView_GetNextItem(hShareList, sItem.iItem, LVIS_SELECTED); + } + UpdateStatisticView(hwndDlg); + return TRUE; + } + + case ID_SHARELIST_OPEN: + case ID_SHARELIST_COPYLINK: { + sItem.iItem = ListView_GetNextItem(hShareList, -1, LVIS_SELECTED); + if (sItem.iItem != -1) { + if (ListView_GetItem(hShareList, &sItem)) { + string sLink = sCreateLink(sItem.pszText); + if (sLink.size() <= 0) { + MessageBox(hwndDlg, _T("Selected link size is 0"), MSG_BOX_TITEL, MB_OK); + return TRUE; + } + + if (LOWORD(wParam) == ID_SHARELIST_COPYLINK) { + if (!OpenClipboard(hwndDlg)) { + MessageBox(hwndDlg, _T("Failed to get access to clipboard"), MSG_BOX_TITEL, MB_OK); + return TRUE; + } + + if (!EmptyClipboard()) { + MessageBox(hwndDlg, _T("Failed to get close the clipboard"), MSG_BOX_TITEL, MB_OK); + return TRUE; + } + + HGLOBAL hglbCopy = GlobalAlloc(GMEM_MOVEABLE, sLink.size() + 1); + // Lock the handle and copy the text to the buffer. + char * lptstrCopy = (char *)GlobalLock(hglbCopy); + strcpy(lptstrCopy, sLink.c_str()); + GlobalUnlock(hglbCopy); + + // Place the handle on the clipboard. + + HANDLE hMyData = SetClipboardData(CF_TEXT, hglbCopy); + if (! hMyData) + MessageBox(hwndDlg, _T("Failed to set clipboard data"), MSG_BOX_TITEL, MB_OK); + + CloseClipboard(); + } else { + CallService(MS_UTILS_OPENURL, 0, (LPARAM)(const char*)sLink.c_str()); + } + } else { + MessageBox(hwndDlg, "ListView_GetItem failed", MSG_BOX_TITEL, MB_OK); + } + } else { + MessageBox(hwndDlg, Translate("No share selected"), MSG_BOX_TITEL, MB_OK); + } + return TRUE; + } + /* + case IDCANCEL: + case IDOK: + DestroyWindow(hwndDlg); + return TRUE;*/ + } + break; + } + + case WM_CLOSE: { + HWND hShareList = GetDlgItem(hwndDlg, IDC_CURRENT_SHARES); + HWND hUserList = GetDlgItem(hwndDlg, IDC_CURRENT_USERS); + + DBWriteContactSettingWord(NULL, MODULE, "StatWnd_cx1", (WORD)ListView_GetColumnWidth(hShareList, 0)); + DBWriteContactSettingWord(NULL, MODULE, "StatWnd_cx2", (WORD)ListView_GetColumnWidth(hShareList, 1)); + DBWriteContactSettingWord(NULL, MODULE, "StatWnd_cx3", (WORD)ListView_GetColumnWidth(hShareList, 2)); + DBWriteContactSettingWord(NULL, MODULE, "StatWnd_cx4", (WORD)ListView_GetColumnWidth(hShareList, 3)); + DBWriteContactSettingWord(NULL, MODULE, "StatWnd_cx5", (WORD)ListView_GetColumnWidth(hShareList, 4)); + DBWriteContactSettingWord(NULL, MODULE, "StatWnd_cx6", (WORD)ListView_GetColumnWidth(hUserList, 0)); + DBWriteContactSettingWord(NULL, MODULE, "StatWnd_cx7", (WORD)ListView_GetColumnWidth(hUserList, 1)); + DBWriteContactSettingWord(NULL, MODULE, "StatWnd_cx8", (WORD)ListView_GetColumnWidth(hUserList, 2)); + DBWriteContactSettingWord(NULL, MODULE, "StatWnd_cx9", (WORD)ListView_GetColumnWidth(hUserList, 3)); + DBWriteContactSettingWord(NULL, MODULE, "StatWnd_cx10", (WORD)ListView_GetColumnWidth(hUserList, 4)); + + bool b = IsDlgButtonChecked(hwndDlg, IDC_SHOWHIDDENSHARES) == BST_CHECKED; + db_set_b(NULL, MODULE, "StatWnd_ShowHidden", b); + + Utils_SaveWindowPosition(hwndDlg, 0, MODULE, "StatWnd_"); + DestroyWindow(hwndDlg); + return TRUE; + } + } + return FALSE; + //return DefDlgProc( hwndDlg, msg, wParam, lParam ); +} + + +///////////////////////////////////////////////////////////////////// +// Member Function : SendLinkToUser +// Type : Global +// Parameters : wParam - (WPARAM)(HANDLE)hContact +// lParam - ? +// Returns : static int +// Description : Send the link to the given contact +// +// References : - +// Remarks : - +// Created : 030826, 26 august 2003 +// Developer : Sérgio Rolanski +///////////////////////////////////////////////////////////////////// + +void SendLinkToUser(WPARAM wParam, char *pszSrvPath) { + string sLink = sCreateLink(pszSrvPath); + CallService(MS_MSG_SENDMESSAGE, (WPARAM)wParam, (LPARAM)sLink.c_str()); +} + +///////////////////////////////////////////////////////////////////// +// Member Function : nShareNewFile +// Type : Global +// Parameters : wParam - (WPARAM)(HANDLE)hContact +// lParam - ? +// Returns : static int + +// Description : Called when user selects my menu item +// +// References : - +// Remarks : - +// Created : 030826, 26 august 2003 +// Developer : KN, Houdini +///////////////////////////////////////////////////////////////////// + +static INT_PTR nShareNewFile(WPARAM wParam, LPARAM lParam) { + HANDLE hContact = (HANDLE)wParam; + + // used to be _MAX_PATH + // changed it since selecting multiple files requires a bigger buffer + char szNewFile[10000] = {0}; + char szSrvPath[10000] = {0}; + + STFileShareInfo stNewShare = {0}; + stNewShare.lStructSize = sizeof(STFileShareInfo); + stNewShare.nMaxDownloads = 1; + stNewShare.pszRealPath = szNewFile; + stNewShare.dwMaxRealPath = sizeof(szNewFile); + stNewShare.pszSrvPath = szSrvPath; + stNewShare.dwMaxSrvPath = sizeof(szSrvPath); + + if (hContact) { + // Try to locate an IP address. + DBVARIANT dbv = {0}; + if (! DBGetContactSetting(hContact, "Protocol", "p", &dbv)) { + if (dbv.type == DBVT_ASCIIZ) { + stNewShare.dwAllowedIP = db_get_dw(hContact, dbv.pszVal, "IP", 0); + if (! stNewShare.dwAllowedIP) + stNewShare.dwAllowedIP = db_get_dw(hContact, dbv.pszVal, "RealIP", 0); + if (! stNewShare.dwAllowedIP) + stNewShare.dwAllowedIP = db_get_dw(hContact, MODULE, "LastUsedIP", 0); + } + } + DBFreeVariant(&dbv); + + stNewShare.dwAllowedMask = db_get_dw(hContact, MODULE, "LastUsedMask", 0); + } + if (! stNewShare.dwAllowedMask) { + if (stNewShare.dwAllowedIP) + stNewShare.dwAllowedMask = 0xFFFFFFFF; + else + stNewShare.dwAllowedMask = 0; + } + + if (! bShowShareNewFileDlg((HWND)(lParam ? lParam : CallService(MS_CLUI_GETHWND, 0, 0)), &stNewShare)) + return 0; + + if (stNewShare.dwAllowedIP) + db_set_dw(hContact, MODULE, "LastUsedIP", stNewShare.dwAllowedIP); + else + db_unset(hContact, MODULE, "LastUsedIP"); + + if (stNewShare.dwAllowedMask && stNewShare.dwAllowedMask != 0xFFFFFFFF) + db_set_dw(hContact, MODULE, "LastUsedMask", stNewShare.dwAllowedMask); + else + db_unset(hContact, MODULE, "LastUsedMask"); + + SendLinkToUser((WPARAM)hContact, stNewShare.pszSrvPath); + return 0; +} + + +static INT_PTR nShowStatisticsView(WPARAM /*wParam*/, LPARAM /*lParam*/) { + if (hwndStatsticView) { + BringWindowToTop(hwndStatsticView); + return 0; + } + hwndStatsticView = CreateDialogParam(hInstance, MAKEINTRESOURCE(IDD_STATISTICS_VIEW), NULL, DlgProcStatsticView, (LPARAM)NULL); + ShowWindow(hwndStatsticView, SW_SHOWNORMAL); + return 0; +} + + +///////////////////////////////////////////////////////////////////// +// Member Function : OptionsDlgProc +// Type : Global +// Parameters : hwndDlg - ? +// msg - ? +// wParam - ? +// lParam - ? +// Returns : static BOOL CALLBACK +// Description : +// +// References : - +// Remarks : - +// Created : 030911, 11 september 2003 +// Developer : KN, Houdini +///////////////////////////////////////////////////////////////////// + +static INT_PTR CALLBACK OptionsDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) { + switch (msg) { + case WM_INITDIALOG: { + string sDefExt = DBGetString(NULL, MODULE, "ExternalSrvName", szDefaultExternalSrvName); + SetDlgItemText(hwndDlg, IDC_EXTERNAL_SRV_NAME, sDefExt.c_str()); + + bool b = db_get_b(NULL, MODULE, "AddStatisticsMenuItem", 1) != 0; + CheckDlgButton(hwndDlg, IDC_ADD_STATISTICS_MENU_ITEM, b ? BST_CHECKED : BST_UNCHECKED); + + b = db_get_b(NULL, MODULE, "AddAcceptConMenuItem", 1) != 0; + CheckDlgButton(hwndDlg, IDC_ACCEPT_COM_MENU_ITEM, b ? BST_CHECKED : BST_UNCHECKED); + + b = db_get_b(NULL, MODULE, "WriteLogFile", 0) != 0; + CheckDlgButton(hwndDlg, IDC_WRITE_LOG_FILE, b ? BST_CHECKED : BST_UNCHECKED); + + CheckDlgButton(hwndDlg, IDC_SHOW_POPUPS, bShowPopups ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_LIMIT_ONLY_WHEN_ONLINE, bLimitOnlyWhenOnline ? BST_CHECKED : BST_UNCHECKED); + + + {// Url Address + SetDlgItemText(hwndDlg, IDC_URL_ADDRESS, sUrlAddress.c_str()); + HWND hComboBox = GetDlgItem(hwndDlg, IDC_URL_ADDRESS); + SendMessage(hComboBox, CB_ADDSTRING, 0, (LPARAM)_T("http://checkip.dyndns.org")); + SendMessage(hComboBox, CB_ADDSTRING, 0, (LPARAM)_T("http://checkip.dyndns.org:8245/")); + SendMessage(hComboBox, CB_ADDSTRING, 0, (LPARAM)_T("http://dynamic.zoneedit.com/checkip.html")); + SendMessage(hComboBox, CB_ADDSTRING, 0, (LPARAM)_T("http://ipdetect.dnspark.com/")); + SendMessage(hComboBox, CB_ADDSTRING, 0, (LPARAM)_T("http://update.dynu.com/basic/ipcheck.asp")); + SendMessage(hComboBox, CB_ADDSTRING, 0, (LPARAM)_T("http://www.dnsart.com/myip.php")); + SendMessage(hComboBox, CB_ADDSTRING, 0, (LPARAM)_T("http://www.dnsart.com:7777/myip.php")); + } + + {// Page keyword + SetDlgItemText(hwndDlg, IDC_PAGE_KEYWORD, sPageKeyword.c_str()); + HWND hComboBox = GetDlgItem(hwndDlg, IDC_PAGE_KEYWORD); + SendMessage(hComboBox, CB_ADDSTRING, 0, (LPARAM)""); + SendMessage(hComboBox, CB_ADDSTRING, 0, (LPARAM)_T("Current IP Address: ")); + SendMessage(hComboBox, CB_ADDSTRING, 0, (LPARAM)_T("Current Address: ")); + SendMessage(hComboBox, CB_ADDSTRING, 0, (LPARAM)_T("IP Adress: ")); + SendMessage(hComboBox, CB_ADDSTRING, 0, (LPARAM)_T("You are browsing from")); + SendMessage(hComboBox, CB_ADDSTRING, 0, (LPARAM)_T("")); + } + + SetDlgItemInt(hwndDlg, IDC_MAX_SPEED, nMaxUploadSpeed >> 10, true); + SetDlgItemInt(hwndDlg, IDC_MAX_CONN_TOTAL, nMaxConnectionsTotal, true); + SetDlgItemInt(hwndDlg, IDC_MAX_CONN_PER_USER, nMaxConnectionsPerUser, true); + SetDlgItemInt(hwndDlg, IDC_DEFAULT_DOWNLOAD_LIMIT, nDefaultDownloadLimit, true); + + indexCreationMode = + (eIndexCreationMode)db_get_b(NULL, MODULE, "IndexCreationMode", 3); + + switch (indexCreationMode) { + case INDEX_CREATION_HTML: + CheckRadioButton(hwndDlg, IDC_INDEX_OFF, IDC_INDEX_DETECT, IDC_INDEX_HTML); + break; + case INDEX_CREATION_XML: + CheckRadioButton(hwndDlg, IDC_INDEX_OFF, IDC_INDEX_DETECT, IDC_INDEX_XML); + break; + case INDEX_CREATION_DETECT: + CheckRadioButton(hwndDlg, IDC_INDEX_OFF, IDC_INDEX_DETECT, IDC_INDEX_DETECT); + break; + default: // INDEX_CREATION_DISABLE + CheckRadioButton(hwndDlg, IDC_INDEX_OFF, IDC_INDEX_DETECT, IDC_INDEX_OFF); + break; + } + + TranslateDialogDefault(hwndDlg); + return TRUE; + } + case WM_COMMAND: { + switch (LOWORD(wParam)) { + case IDC_MAX_SPEED: + case IDC_MAX_CONN_PER_USER: + case IDC_MAX_CONN_TOTAL: + case IDC_EXTERNAL_SRV_NAME: { + if (HIWORD(wParam) == EN_CHANGE) + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + return TRUE; + } + case IDC_URL_ADDRESS: + case IDC_PAGE_KEYWORD: { + /*if( !bWindowTextSet ) + return TRUE;*/ + + if (HIWORD(wParam) == CBN_EDITUPDATE || HIWORD(wParam) == CBN_SELCHANGE) { + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + } + return TRUE; + } + + case IDC_INDEX_HTML: + case IDC_INDEX_OFF: + case IDC_INDEX_XML: + case IDC_INDEX_DETECT: + case IDC_LIMIT_ONLY_WHEN_ONLINE: + case IDC_SHOW_POPUPS: + case IDC_WRITE_LOG_FILE: + case IDC_ADD_STATISTICS_MENU_ITEM: + case IDC_ACCEPT_COM_MENU_ITEM: { + if (HIWORD(wParam) == BN_CLICKED) { + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + } + return TRUE; + } + case IDC_EXTERNAL_SRV_DEFAULT: { + if (HIWORD(wParam) == BN_CLICKED) { + SetDlgItemText(hwndDlg, IDC_EXTERNAL_SRV_NAME, szDefaultExternalSrvName); + SetDlgItemText(hwndDlg, IDC_URL_ADDRESS, szDefaultUrlAddress); + SetDlgItemText(hwndDlg, IDC_PAGE_KEYWORD, szDefaultPageKeyword); + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + } + return TRUE; + } + case IDC_OPEN_LOG: { + bOpenLogFile(); + return TRUE; + } + case IDC_TEST_EXTERNALIP: { + char szUrl[ 500 ]; + char szKeyWord[ 1000 ]; + GetDlgItemText(hwndDlg, IDC_URL_ADDRESS, szUrl, sizeof(szUrl)); + GetDlgItemText(hwndDlg, IDC_PAGE_KEYWORD, szKeyWord, sizeof(szKeyWord)); + DWORD dwExternalIP = GetExternIP(szUrl, szKeyWord); + + _snprintf(szKeyWord, sizeof(szKeyWord), Translate("You external ip was detected as %d.%d.%d.%d\r\nby: %s") , + SplitIpAddress(dwExternalIP) , + szUrl); + MessageBox(hwndDlg, szKeyWord, MSG_BOX_TITEL, MB_OK); + } + } + break; + } + case WM_NOTIFY: { + NMHDR * p = ((LPNMHDR)lParam); + switch (p->code) { + case PSN_APPLY: { + char szTemp[ 500 ]; + if (GetDlgItemText(hwndDlg, IDC_EXTERNAL_SRV_NAME, szTemp, sizeof(szTemp))) + db_set_s(NULL, MODULE, "ExternalSrvName", szTemp); + + bool b = db_get_b(NULL, MODULE, "AddStatisticsMenuItem", 1) != 0; + bool bNew = IsDlgButtonChecked(hwndDlg, IDC_ADD_STATISTICS_MENU_ITEM) == BST_CHECKED; + if (b != bNew) { + db_set_b(NULL, MODULE, "AddStatisticsMenuItem", bNew); + MessageBox(hwndDlg, TranslateT("You need to restart miranda to change the main menu"), MSG_BOX_TITEL, MB_OK); + } + + b = db_get_b(NULL, MODULE, "AddAcceptConMenuItem", 1) != 0; + bNew = IsDlgButtonChecked(hwndDlg, IDC_ACCEPT_COM_MENU_ITEM) == BST_CHECKED; + if (b != bNew) { + db_set_b(NULL, MODULE, "AddAcceptConMenuItem", bNew); + MessageBox(hwndDlg, TranslateT("You need to restart miranda to change the main menu"), MSG_BOX_TITEL, MB_OK); + } + + bNew = IsDlgButtonChecked(hwndDlg, IDC_WRITE_LOG_FILE) == BST_CHECKED; + db_set_b(NULL, MODULE, "WriteLogFile", bNew); + + bShowPopups = IsDlgButtonChecked(hwndDlg, IDC_SHOW_POPUPS) == BST_CHECKED; + db_set_b(NULL, MODULE, "ShowPopups", bShowPopups); + + GetDlgItemText(hwndDlg, IDC_URL_ADDRESS, szTemp, sizeof(szTemp)); + sUrlAddress = szTemp; + db_set_s(NULL, MODULE, "UrlAddress", sUrlAddress.c_str()); + + GetDlgItemText(hwndDlg, IDC_PAGE_KEYWORD, szTemp, sizeof(szTemp)); + sPageKeyword = szTemp; + db_set_s(NULL, MODULE, "PageKeyword", sPageKeyword.c_str()); + dwExternalIpAddress = 0; + + BOOL bTranslated = false; + int nTemp = GetDlgItemInt(hwndDlg, IDC_MAX_SPEED, &bTranslated, true); + if (bTranslated) { + nMaxUploadSpeed = nTemp << 10; + db_set_dw(NULL, MODULE, "MaxUploadSpeed", nMaxUploadSpeed); + } + + nTemp = GetDlgItemInt(hwndDlg, IDC_MAX_CONN_TOTAL, &bTranslated, true); + if (bTranslated) { + nMaxConnectionsTotal = nTemp; + db_set_dw(NULL, MODULE, "MaxConnectionsTotal", nMaxConnectionsTotal); + } + + nTemp = GetDlgItemInt(hwndDlg, IDC_MAX_CONN_PER_USER, &bTranslated, true); + if (bTranslated) { + nMaxConnectionsPerUser = nTemp; + db_set_dw(NULL, MODULE, "MaxConnectionsPerUser", nMaxConnectionsPerUser); + } + + nTemp = GetDlgItemInt(hwndDlg, IDC_DEFAULT_DOWNLOAD_LIMIT, &bTranslated, true); + if (bTranslated) { + nDefaultDownloadLimit = nTemp; + db_set_dw(NULL, MODULE, "DefaultDownloadLimit", nDefaultDownloadLimit); + } + + bLimitOnlyWhenOnline = IsDlgButtonChecked(hwndDlg, IDC_LIMIT_ONLY_WHEN_ONLINE) == BST_CHECKED; + db_set_b(NULL, MODULE, "LimitOnlyWhenOnline", bLimitOnlyWhenOnline); + + if (IsDlgButtonChecked(hwndDlg, IDC_INDEX_HTML) == BST_CHECKED || + IsDlgButtonChecked(hwndDlg, IDC_INDEX_DETECT) == BST_CHECKED) { + if (IsDlgButtonChecked(hwndDlg, IDC_INDEX_HTML) == BST_CHECKED) + indexCreationMode = INDEX_CREATION_HTML; + else + indexCreationMode = INDEX_CREATION_DETECT; + + if (!LoadIndexHTMLTemplate()) { + CheckRadioButton(hwndDlg, IDC_INDEX_OFF, IDC_INDEX_XML, IDC_INDEX_OFF); + indexCreationMode = INDEX_CREATION_DISABLE; + } + } else if (IsDlgButtonChecked(hwndDlg, IDC_INDEX_XML) == BST_CHECKED) { + FreeIndexHTMLTemplate(); + indexCreationMode = INDEX_CREATION_XML; + } else { + FreeIndexHTMLTemplate(); + indexCreationMode = INDEX_CREATION_DISABLE; + } + + db_set_b(NULL, MODULE, "IndexCreationMode", (BYTE)indexCreationMode); + + return TRUE; + } + } + break; + } + } + return FALSE; +} + + +///////////////////////////////////////////////////////////////////// +// Member Function : OptionsInitialize +// Type : Global +// Parameters : wParam - ? +// LPARAM - ? +// Returns : int +// Description : +// +// References : - +// Remarks : - +// Created : 030911, 11 september 2003 +// Developer : KN +///////////////////////////////////////////////////////////////////// + +int OptionsInitialize(WPARAM wParam, LPARAM /*lParam*/) { + OPTIONSDIALOGPAGE odp; + /* + bWindowTextSet = FALSE; + bUnaplyedChanges = FALSE; + */ + ZeroMemory(&odp, sizeof(odp)); + odp.cbSize = sizeof(odp); + odp.position = 900000000; + odp.hInstance = hInstance; + odp.pszTemplate = MAKEINTRESOURCE(IDD_OPT_HTTP_SERVER); + odp.flags = ODPF_BOLDGROUPS|ODPF_TCHAR; + odp.ptszTitle = LPGENT("HTTP Server"); + odp.ptszGroup = LPGENT("Network"); + odp.pfnDlgProc = OptionsDlgProc; + Options_AddPage(wParam,&odp); + return 0; +} + + + + +///////////////////////////////////////////////////////////////////// +// Member Function : MainThreadCallback +// Type : Global +// Parameters : dwParam - ? +// Returns : void CALLBACK +// Description : Called from main thread. +// Because MS_POPUP_ADDPOPUP may only be called from that +// ShowPopupWindow activates this method via APC +// References : - +// Remarks : - +// Created : 030902, 02 september 2003 +// Developer : KN +///////////////////////////////////////////////////////////////////// + +void CALLBACK MainThreadCallback(ULONG_PTR dwParam) { + POPUPDATA * pclData = (POPUPDATA *)dwParam; + if (db_get_b(NULL, MODULE, "WriteLogFile", 0) != 0) { + LogEvent(pclData->lpzContactName, pclData->lpzText); + } + CallService(MS_POPUP_ADDPOPUP, (WPARAM)pclData, 0); + delete pclData; +} + +///////////////////////////////////////////////////////////////////// +// Member Function : PopupWindowProc +// Type : Global +// Parameters : hWnd - ? +// message - ? +// wParam - ? +// lParam - ? +// Returns : LRESULT CALLBACK +// Description : +// +// References : - +// Remarks : - +// Created : 031011, 11 oktober 2003 +// Developer : KN, Houdini +///////////////////////////////////////////////////////////////////// + +void CALLBACK OpenStatisticViewFromPopupProc(ULONG_PTR /* dwParam */) { + nShowStatisticsView(0, 0); +} + +LRESULT CALLBACK PopupWindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { + PUGetPluginData(hWnd); + //HANDLE hData = (HANDLE)CallService(MS_POPUP_GETPLUGINDATA, (WPARAM)hWnd, (LPARAM)&hData); + + switch (message) { + //case WM_LBUTTONUP: + //case WM_LBUTTONDBLCLK: // These don't work I can't undestande why !! + case WM_LBUTTONDOWN: + + //nShowStatisticsView(0,0); + // has to be called from the right thread + //QueueUserAPC(OpenStatisticViewFromPopupProc, hMainThread, 0); + + QueueUserAPC(OpenStatisticViewFromPopupProc, hMainThread, 0); + PUDeletePopUp( hWnd ); + return 0; + + case WM_CONTEXTMENU: { + PUDeletePopUp( hWnd ); + return 0; + } + } + return DefWindowProc(hWnd, message, wParam, lParam); +} + + +///////////////////////////////////////////////////////////////////// +// Member Function : ShowPopupWindow +// Type : Global +// Parameters : pszText - ? +// Returns : void +// Description : +// +// References : - +// Remarks : - +// Created : 030831, 31 august 2003 +// Developer : KN +///////////////////////////////////////////////////////////////////// + +void ShowPopupWindow(const char * pszName, const char * pszText, COLORREF ColorBack /*= 0*/) { + if (! bShowPopups) + return; + + POPUPDATA * pclData = new POPUPDATA; + memset(pclData, 0, sizeof(POPUPDATA)); + pclData->lchIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_SHARE_NEW_FILE)); + strncpy(pclData->lpzContactName, pszName, sizeof(pclData->lpzContactName) - 1); // -1 so that there aways will be a null termination !! + strncpy(pclData->lpzText, pszText, sizeof(pclData->lpzText) - 1); + pclData->colorBack = ColorBack; + //ppd.colorText = colorText; + pclData->PluginWindowProc = PopupWindowProc; + //Now that every field has been filled, we want to see the popup. + + //CallService(MS_POPUP_ADDPOPUP, (WPARAM)&ppd, 0); + QueueUserAPC(MainThreadCallback, hMainThread, (ULONG_PTR)pclData); +} + +///////////////////////////////////////////////////////////////////// +// Member Function : InitGuiElements +// Type : Global +// Parameters : None +// Returns : void +// Description : +// +// References : - +// Remarks : - +// Created : 030902, 02 september 2003 +// Developer : KN +///////////////////////////////////////////////////////////////////// + +void InitGuiElements() { + INITCOMMONCONTROLSEX stInitCom; + stInitCom.dwSize = sizeof(INITCOMMONCONTROLSEX); + stInitCom.dwICC = ICC_INTERNET_CLASSES; + InitCommonControlsEx(&stInitCom); + + //hMainThread = GetCurrentThread(); + DuplicateHandle(GetCurrentProcess(), GetCurrentThread(), GetCurrentProcess(), &hMainThread, THREAD_SET_CONTEXT, FALSE, 0); + + + sUrlAddress = DBGetString(NULL, MODULE, "UrlAddress", szDefaultUrlAddress); + sPageKeyword = DBGetString(NULL, MODULE, "PageKeyword", szDefaultPageKeyword); + + hShareNewFileService = CreateServiceFunction(MS_SHARE_NEW_FILE, nShareNewFile); + if (! hShareNewFileService) { + MessageBox(NULL, _T("Failed to CreateServiceFunction MS_SHARE_NEW_FILE"), MSG_BOX_TITEL, MB_OK); + return; + } + + hShowStatisticsViewService = CreateServiceFunction(MS_SHOW_STATISTICS_VIEW, nShowStatisticsView); + if (! hShowStatisticsViewService) { + MessageBox(NULL, _T("Failed to CreateServiceFunction MS_SHOW_STATISTICS_VIEW"), MSG_BOX_TITEL, MB_OK); + return; + } + + CLISTMENUITEM mi; + ZeroMemory(&mi, sizeof(mi)); + mi.cbSize = sizeof(mi); + mi.flags = 0; + mi.pszContactOwner = NULL; //all contacts + mi.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_SHARE_NEW_FILE)); + mi.position = -2000019955; + mi.ptszName = LPGENT("HTTP Share new file"); + mi.pszService = MS_SHARE_NEW_FILE; + + hShareNewFileMenuItem = Menu_AddMainMenuItem(&mi); + if (!hShareNewFileMenuItem) { + MessageBox(NULL, _T("Failed to add contact menu item"), MSG_BOX_TITEL, MB_OK); + return; + } + + + if (db_get_b(NULL, MODULE, "AddStatisticsMenuItem", 1) != 0) { + mi.position = 1000085005; + mi.flags = CMIF_TCHAR; + //mi.hIcon=LoadIcon(hInstance,MAKEINTRESOURCE(IDI_SHARE_NEW_FILE)); + mi.pszContactOwner = NULL; + mi.ptszName = LPGENT("Show HTTP server statistics"); + mi.pszService = MS_SHOW_STATISTICS_VIEW; + hShowStatisticsViewMenuItem = Menu_AddMainMenuItem(&mi); + } + + + hEventOptionsInitialize = HookEvent(ME_OPT_INITIALISE, OptionsInitialize); + if (!hEventOptionsInitialize) + MessageBox(NULL, _T("Failed to HookEvent ME_OPT_INITIALISE"), MSG_BOX_TITEL, MB_OK); + + bShowPopups = db_get_b(NULL, MODULE, "ShowPopups", bShowPopups) != 0; + /* + #ifdef _DEBUG + nShowStatisticsView(0,0); + #endif*/ +} + + +///////////////////////////////////////////////////////////////////// +// Member Function : UninitGuiElements +// Type : Global +// Parameters : None +// Returns : void +// Description : +// +// References : - +// Remarks : - +// Created : 031011, 11 oktober 2003 +// Developer : KN +///////////////////////////////////////////////////////////////////// + +void UnInitGuiElements() { + CloseHandle(hMainThread); +} diff --git a/plugins/HTTPServer/src/GuiElements.h b/plugins/HTTPServer/src/GuiElements.h new file mode 100644 index 0000000000..0ce1d11814 --- /dev/null +++ b/plugins/HTTPServer/src/GuiElements.h @@ -0,0 +1,29 @@ +//This file is part of HTTPServer a Miranda IM plugin +//Copyright (C)2002 Kennet Nielsen +// +//This program is free software; you can redistribute it and/or +//modify it under the terms of the GNU General Public License +//as published by the Free Software Foundation; either +//version 2 of the License, or (at your option) any later version. +// +//This program is distributed in the hope that it will be useful, +//but WITHOUT ANY WARRANTY; without even the implied warranty of +//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +//GNU General Public License for more details. +// +//You should have received a copy of the GNU General Public License +//along with this program; if not, write to the Free Software +//Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +#ifndef GUI_ELEMENTS_H +#define GUI_ELEMENTS_H + +#include + +void InitGuiElements(); +void UnInitGuiElements(); +void UpdateStatisticsView(); +void ShowPopupWindow(const char * pszName, const char * pszText, COLORREF ColorBack = 0); +void SendLinkToUser(WPARAM wParam, char *pszSrvPath); // Add By Sergio Vieira Rolanski + +#endif \ No newline at end of file diff --git a/plugins/HTTPServer/src/HttpUser.cpp b/plugins/HTTPServer/src/HttpUser.cpp new file mode 100644 index 0000000000..fc0f24be3f --- /dev/null +++ b/plugins/HTTPServer/src/HttpUser.cpp @@ -0,0 +1,888 @@ +//This file is part of HTTPServer a Miranda IM plugin +//Copyright (C)2002 Kennet Nielsen +// +//This program is free software; you can redistribute it and/or +//modify it under the terms of the GNU General Public License +//as published by the Free Software Foundation; either +//version 2 of the License, or (at your option) any later version. +// +//This program is distributed in the hope that it will be useful, +//but WITHOUT ANY WARRANTY; without even the implied warranty of +//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +//GNU General Public License for more details. +// +//You should have received a copy of the GNU General Public License +//along with this program; if not, write to the Free Software +//Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +#include "Glob.h" + +///////////////////////////////////////////////////////////////////// +// Member Function : FileTimeToUnixTime +// Type : Global +// Parameters : pft - ? +// t - ? +// Returns : void +// Description : +// +// References : - +// Remarks : - +// Created : 030826, 26 august 2003 +// Developer : KN +///////////////////////////////////////////////////////////////////// + +void FileTimeToUnixTime(LPFILETIME pft, time_t* t) { + LONGLONG ll = ((LONGLONG)pft->dwHighDateTime) << 32; + ll = ll + pft->dwLowDateTime - 116444736000000000; + *t = (time_t)(ll / 10000000); +} + + +///////////////////////////////////////////////////////////////////// +// Function : nUnescapedURI +// Type : Local +// Parameters : pszURI - URI to convert buffer is modifyed !! +// Returns : length of the Unescaped URI +// Description : +// +// References : - +// Remarks : - +// Created : 030911, 11 september 2003 +// Developer : KN +///////////////////////////////////////////////////////////////////// + +static int nUnescapedURI(char * pszURI) { + if (! pszURI) + return 0; + + char * pszOrigURI = pszURI; + int sumb; + int more = -1; + char* pszCurInsert = pszURI; + + for (; *pszURI && pszURI[0] != ' ' ; pszURI++) { + int nNewChar; + if (pszURI[0] == '%') { + // we need to unescape the char + if (pszURI[1] == NULL || pszURI[2] == NULL || pszURI[1] == ' ' || pszURI[2] == ' ') + break; // handles error like "%2 " or "%a" + + if (sscanf(&pszURI[1], "%2X", &nNewChar) != 1) { + // can't convert to number + pszURI += 2; + continue; // we skip it !!! + } + pszURI += 2; + } + /*else if( pszURI[0] == '+' ) + { + nNewChar = ' '; + }*/ + else + nNewChar = (int)tolower(pszURI[0]); // also make the request lowercase + + if (nNewChar == '\\') + nNewChar = '/'; + + if ((nNewChar & 0x80) == 0x00) { // 0xxxxxxx (yields 7 bits) + more = -1; // this is to avoid sequence like %C3k%A6 will end up beeing "kæ" insted it will be "k" + *pszCurInsert = (char)nNewChar; + pszCurInsert++; + continue; + } + + if ((nNewChar & 0xc0) == 0x80) { // 10xxxxxx (continuation byte) + sumb = (sumb << 6) | (nNewChar & 0x3f) ; // Add 6 bits to sumb + more--; + if (more == 0) { + *pszCurInsert = (char)sumb; // here we just throw away all the fine UTF-8 encoding + pszCurInsert++; + } + } else if ((nNewChar & 0xe0) == 0xc0) { // 110xxxxx (yields 5 bits) + sumb = nNewChar & 0x1f; + more = 1; // Expect 1 more byte + } else if ((nNewChar & 0xf0) == 0xe0) { // 1110xxxx (yields 4 bits) + sumb = nNewChar & 0x0f; + more = 2; // Expect 2 more bytes + } else if ((nNewChar & 0xf8) == 0xf0) { // 11110xxx (yields 3 bits) + sumb = nNewChar & 0x07; + more = 3; // Expect 3 more bytes + } else if ((nNewChar & 0xfc) == 0xf8) { // 111110xx (yields 2 bits) + sumb = nNewChar & 0x03; + more = 4; // Expect 4 more bytes + } else /*if ((nNewChar & 0xfe) == 0xfc)*/ + { // 1111110x (yields 1 bit) + sumb = nNewChar & 0x01; + more = 5; // Expect 5 more bytes + } + } + return (pszCurInsert - pszOrigURI); +} + + +///////////////////////////////////////////////////////////////////// +// Member Function : CLHttpUser +// Type : Private / Public / Protected +// Parameters : hCon - ? +// stAdd - ? +// pcl - ? +// Returns : +// Description : +// +// References : - +// Remarks : - +// Created : 030918, 18 september 2003 +// Developer : KN +///////////////////////////////////////////////////////////////////// + +CLHttpUser::CLHttpUser(HANDLE hCon, in_addr stAdd) : CLShareUser(hCon, stAdd) { + memset(apszParam, 0, sizeof(apszParam)); + hFile = INVALID_HANDLE_VALUE; +} + + +///////////////////////////////////////////////////////////////////// +// Member Function : CLHttpUser +// Type : Private / Public / Protected +// Parameters : None +// Returns : +// Description : +// +// References : - +// Remarks : - +// Created : 031124, 24 november 2003 +// Developer : KN +///////////////////////////////////////////////////////////////////// + +CLHttpUser::~CLHttpUser() { + if (hFile != INVALID_HANDLE_VALUE) + CloseHandle(hFile); +} + +///////////////////////////////////////////////////////////////////// +// Member Function : bReadGetParameters +// Type : Private / Public / Protected +// Parameters : pszRequest - ? +// Returns : Returns true if +// Description : +// +// References : - +// Remarks : - +// Created : 030928, 28 september 2003 +// Developer : KN +///////////////////////////////////////////////////////////////////// + +bool CLHttpUser::bReadGetParameters(char * pszRequest) { + bool bRet = true; + for (; *pszRequest ; pszRequest++) { + if (pszRequest[0] != '\n') { + if (pszRequest[0] == '\r') + pszRequest[0] = 0; + continue; + } + pszRequest[0] = 0; + pszRequest++; + for (int nCur = 0; nCur < eLastParam ; nCur++) { + int nLen = strlen(szParmStr[nCur]); + if (strncmp(pszRequest, szParmStr[nCur], nLen) == 0) { + if (apszParam[nCur]) { + bRet = false; + // already set !! + } else { + pszRequest += nLen; + apszParam[nCur] = pszRequest; + pszRequest += strcspn(pszRequest, "\r\n") - 1; + char * psz = pszRequest; + while (*psz == ' ') { + psz[0] = 0;// owerwrite ' ' or '\r' or '\n' + psz--; + } + } + break; + } + } + } + return bRet; +} + +///////////////////////////////////////////////////////////////////// +// Member Function : SendError +// Type : Private / Public / Protected +// Parameters : iErrorCode - ? +// pszError - ? +// pszDescription - ? +// Returns : void +// Description : +// +// References : - +// Remarks : - +// Created : 031124, 24 november 2003 +// Developer : KN, Houdini +// Changed : 21 January 2006 by Vampik +///////////////////////////////////////////////////////////////////// + +void CLHttpUser::SendError(int iErrorCode, const char * pszError, const char * pszDescription) { + char szCurTime[ 100 ]; + time_t ltime; + time(<ime); + strftime(szCurTime, sizeof(szCurTime), "%a, %d %b %Y %H:%M:%S GMT", gmtime(<ime)); + + if (!pszDescription) + pszDescription = pszError; + + char szBuf[1000]; + DWORD dwBytesToWrite = _snprintf(szBuf, sizeof(szBuf) , + "HTTP/1.1 %i %s\r\n" + "Date: %s\r\n" + "Server: MirandaWeb/%s\r\n" + "Transfer-Encoding: chunked\r\n" + "Content-Type: text/html; charset=iso-8859-1\r\n" + "\r\n" + "10f\r\n" + "\n" + "\n" + "%i %s\n" + "\n" + "

%s

\n" + "%s

\n" + "


\n" + "
MirandaWeb/%s
\n" + "\n" + "\r\n" + "\r\n", + iErrorCode, pszError, szCurTime, pszVersion, iErrorCode, pszError, pszError, pszDescription, pszVersion); + + Netlib_Send(hConnection, szBuf, dwBytesToWrite, 0); +} + +///////////////////////////////////////////////////////////////////// +// Member Function : SendRedir +// Type : Private / Public / Protected +// Parameters : iErrorCode - ? +// pszError - ? +// pszDescription - ? +// pszRedirect - ? +// Returns : void +// Description : +// +// References : - +// Remarks : - +// Created : 21 january 2006 +// Developer : KN, Houdini, Vampik +///////////////////////////////////////////////////////////////////// + +void CLHttpUser::SendRedir(int iErrorCode, const char * pszError, const char * pszDescription, const char * pszRedirect) { + char szCurrTime[ 100 ]; + time_t ltime; + time(<ime); + strftime(szCurrTime, sizeof(szCurrTime), "%a, %d %b %Y %H:%M:%S GMT", gmtime(<ime)); + + if (!pszDescription) + pszDescription = pszError; + + char szBuff[1000]; + DWORD dwBytesToWrite = _snprintf(szBuff, sizeof(szBuff) , + "HTTP/1.1 %i %s\r\n" + "Date: %s\r\n" + "Server: MirandaWeb/%s\r\n" + "Location: %s/\r\n" + "Transfer-Encoding: chunked\r\n" + "Content-Type: text/html; charset=iso-8859-1\r\n" + "\r\n" + "10f\r\n" + "\n" + "\n" + "%i %s\n" + "\n" + "

%s

\n" + "%s

\n" + "


\n" + "
MirandaWeb/%s
\n" + "\n" + "\r\n" + "\r\n", + iErrorCode, pszError, szCurrTime, pszVersion, pszRedirect, iErrorCode, pszError, pszError, pszDescription, pszVersion); + + Netlib_Send(hConnection, szBuff, dwBytesToWrite, 0); +} + +///////////////////////////////////////////////////////////////////// +// Function : strmcat +// Type : Local +// Parameters : pszDest - ? +// pszSrc - ? +// MaxLength - ? +// Returns : +// Description : Fills pszDest until it is MaxLength long or +// pszSrc is finished - always appends a \0 +// References : - +// Remarks : - +// Created : +// Developer : Houdini +///////////////////////////////////////////////////////////////////// + +static void strmcat(char* pszDest, const char* pszSrc, int iMaxLength) { + int iLength = 0; + while (*pszDest != '\0') { + pszDest++; + iLength++; + } + + while (iLength < iMaxLength - 1 && *pszSrc != '\0') { + *pszDest = *pszSrc; + pszDest++; + pszSrc++; + iLength++; + } + + *pszDest = '\0'; +} + +///////////////////////////////////////////////////////////////////// +// Member Function : bProcessGetRequest +// Type : Global +// Parameters : hNewConnection - ? +// dwRemoteIP - ? +// pszRequest - ? +// Returns : Returns true if a file was send +// Description : +// +// References : - +// Remarks : - +// Created : 030813, 13 august 2003 +// Developer : KN, Houdini +// Changed : 27 January 2005 by Vampik +// Changed : 21 January 2006 by Vampik +///////////////////////////////////////////////////////////////////// + +bool CLHttpUser::bProcessGetRequest(char * pszRequest, bool bIsGetCommand) { + //LogEvent("Request", pszRequest); + + int nUriLength = nUnescapedURI(pszRequest); + if (nUriLength <= 0) + return false; + + CLFileShareListAccess clCritSection; + + if (bShutdownInProgress) + return false; + + static char szTempfile[MAX_PATH+1]; + szTempfile[0] = '\0'; + + if (!bReadGetParameters(pszRequest)) { + SendError(400, "Bad Request"); + return false; + } + + DWORD dwRemoteIP = ntohl(stAddr.S_un.S_addr); + for (CLFileShareNode * pclCur = pclFirstNode; pclCur ; pclCur = pclCur->pclNext) { + if ((pclCur->st.dwAllowedIP ^ dwRemoteIP) & pclCur->st.dwAllowedMask) + continue; // Not an allowed IP address + + if (!pclCur->bIsDirectory() && pclCur->nGetSrvPathLen() != nUriLength) + continue; // not the right length, quickly move on to the next. + + if (pclCur->bIsDirectory() ? + (strncmp(pclCur->st.pszSrvPath, pszRequest, pclCur->nGetSrvPathLen() - 1) == 0) : + (strncmp(pclCur->st.pszSrvPath, pszRequest, pclCur->nGetSrvPathLen()) == 0)) { + /*OutputDebugString( "Request for file OK : "); + OutputDebugString( pclCur->st.pszSrvPath ); + OutputDebugString( "\n" );*/ + + static char szSrvPath[MAX_PATH+1]; + static char szRealPath[MAX_PATH+1]; + char* pszSrvPath = pclCur->st.pszSrvPath; + char* pszRealPath = pclCur->st.pszRealPath; + + if (pclCur->bIsDirectory()) { + strcpy(szRealPath, pclCur->st.pszRealPath); + strcpy(szSrvPath, pclCur->st.pszSrvPath); + pszRealPath = szRealPath; + pszSrvPath = szSrvPath; + + if (nUriLength > MAX_PATH) + nUriLength = MAX_PATH; + + pszRequest[nUriLength] = '\0'; + + if (pclCur->nGetSrvPathLen() - nUriLength == 1) { + SendRedir(302, "Found", "The document has moved", pszRequest); + return false; + } else { + strmcat(pszRealPath, &pszRequest[pclCur->nGetSrvPathLen()], MAX_PATH); + strmcat(pszSrvPath, &pszRequest[pclCur->nGetSrvPathLen()], MAX_PATH); + } + pszRequest[nUriLength] = ' '; + + // hacker protection - should be removed by the browser + if (strstr(pszRealPath, "..")) { + SendError(404, "Not Found", "The requested URL was not found on this server."); + return false; + } + + char* pszTmp = pszRealPath; + while (pszTmp = strchr(pszTmp, '/')) + * pszTmp = '\\'; + + hFile = CreateFile(pszRealPath, GENERIC_READ , + FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + + if (hFile == INVALID_HANDLE_VALUE) { + if (pszSrvPath[strlen(pszSrvPath)-1] != '/') { + strmcat(pszRealPath, "\\", MAX_PATH); + strmcat(pszSrvPath, "/", MAX_PATH); + } + + // a directory with index.htm + strmcat(szRealPath, "index.htm", MAX_PATH); + + hFile = CreateFile(pszRealPath, GENERIC_READ , + FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_HIDDEN, NULL); + + if (hFile == INVALID_HANDLE_VALUE) { + // a directory with index.html + strmcat(szRealPath, "l", MAX_PATH); + + hFile = CreateFile(pszRealPath, GENERIC_READ , + FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_HIDDEN, NULL); + + if (hFile == INVALID_HANDLE_VALUE) { + // generate directory index in temporary file + if (*szTempfile == '\0') { + GetTempPath(MAX_PATH, szTempfile); + strmcat(szTempfile, "\\HttpServerTemp", MAX_PATH); + strmcat(szTempfile, pszSrvPath, MAX_PATH); + char* pszTmp = szTempfile; + while (pszTmp = strchr(pszTmp, '/')) + * pszTmp = '~'; + } + pszRealPath[strlen(pszRealPath) - 10] = '\0'; + + // detecting browser function removed + // every browser should support it by now + bool BrowserSupportsXML = true; + //(apszParam[eUserAgent] != NULL) && + // (strstr(apszParam[eUserAgent], "Firefox") || + // (strstr(apszParam[eUserAgent], "MSIE") && !strstr(apszParam[eUserAgent], "Opera"))); + + if ((indexCreationMode == INDEX_CREATION_XML || + (indexCreationMode == INDEX_CREATION_DETECT && BrowserSupportsXML)) && + bCreateIndexXML(pszRealPath, szTempfile, pszSrvPath, dwRemoteIP)) { + hFile = CreateFile(szTempfile, GENERIC_READ , + FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + + strcpy(szRealPath, "a.xml"); // restore .xml for mime type + } else if ((indexCreationMode == INDEX_CREATION_HTML || + indexCreationMode == INDEX_CREATION_DETECT) && + bCreateIndexHTML(pszRealPath, szTempfile, pszSrvPath, dwRemoteIP)) { + hFile = CreateFile(szTempfile, GENERIC_READ, + FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + + strcpy(szRealPath, "a.html"); // restore .html for mime type + } else { + continue; + } + } else { + strmcat(pszSrvPath, "index.html", MAX_PATH); + szTempfile[0] = '\0'; + } + } else { + strmcat(pszSrvPath, "index.htm", MAX_PATH); + szTempfile[0] = '\0'; + } + } else { + szTempfile[0] = '\0'; + } + } else { + hFile = CreateFile(pszRealPath, GENERIC_READ , + FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + + if (hFile == INVALID_HANDLE_VALUE) { + SendError(404, "Not Found", "HTTP server failed to open local file"); + return false; + } + } + + strcpy(this->szCurrentDLSrvPath, pszSrvPath); + + DWORD nDataSize = GetFileSize(hFile, NULL); + dwTotalSize = nDataSize; + + FILETIME stFileTime; + GetFileTime(hFile, NULL, NULL, &stFileTime); + + char szCurTime[ 100 ]; + time_t ltime; + time(<ime); + strftime(szCurTime, sizeof(szCurTime), "%a, %d %b %Y %H:%M:%S GMT", gmtime(<ime)); + + char szFileTime[ 100 ]; + FileTimeToUnixTime(&stFileTime, <ime); + strftime(szFileTime, sizeof(szFileTime), "%a, %d %b %Y %H:%M:%S GMT", gmtime(<ime)); + + if (apszParam[eIfModifiedSince] && strcmp(apszParam[eIfModifiedSince], szFileTime) == 0) { + SendError(304, "Not Modified" ); + return true; + } + + // we found match send file !! + if (bIsGetCommand) { + if (! pclCur->bAddUser(this)) { + SendError(403, "Forbidden", "Access has been denied because there are too many connections"); + return false; + } + } + + if (*(ULONG*)(&stAddr) != 0x0100007F && // do not show popup of 127.0.0.1 + strstr(pszRealPath, "\\@") == NULL) { // and of shares which start with an @ + ShowPopupWindow(inet_ntoa(stAddr), pszSrvPath); + } + + clCritSection.Unlock(); + + DWORD dwFileStart = 0; + DWORD dwDataToSend = nDataSize; + + char szETag[ 50 ]; + { + int nETagLen = _snprintf(szETag, sizeof(szETag), "\"%x-%x-%x\"", + nDataSize, stFileTime.dwHighDateTime, stFileTime.dwLowDateTime); + + if (!apszParam[eIfRange] || (strncmp(szETag, apszParam[eIfRange], nETagLen) == 0)) { + char * pszRange = apszParam[eRange]; + if (pszRange) { + if (strncmp(pszRange, "bytes=", 6) == 0) { + pszRange += 6; + // Do resume !!! + char *pszEnd; + if (pszRange[0] == '-') { + // its a suffix-byte-range-spec + DWORD dwLen = strtol(pszRange + 1, &pszEnd, 10); + if (dwLen < nDataSize) + dwFileStart = nDataSize - dwLen; + } else { + DWORD dwLen = strtol(pszRange, &pszEnd, 10); + if (*pszEnd == '-' && dwLen < nDataSize) { + dwFileStart = dwLen; + pszRange = pszEnd + 1; + if (*pszRange != 0) { + dwLen = strtol(pszEnd + 1, &pszEnd, 10); + if (dwLen > dwFileStart) + dwDataToSend = (dwLen + 1) - dwFileStart; + else + dwFileStart = 0; + } + } else { + SendError(400, "Bad Request"); + return false; + } + } + } + } + } + } + + if (dwFileStart >= nDataSize) + dwFileStart = 0; + + if (dwFileStart + dwDataToSend >= nDataSize) + dwDataToSend = nDataSize - dwFileStart; + + + DWORD dwBytesToWrite = 0; + // To optimize send speed it it ideal to always send larges size packages + // But this size depended on network media but on Ethernet it is 1518 bytes. + // Ethernet, IP and TCP headers use some of this space and leaves 1460 bytes + // for data transfer. + // We will use a multiply of this to always send optimal sized packages. + char szBuf[1460 * 4]; + + if (dwFileStart > 0 || dwDataToSend != nDataSize) { + if (SetFilePointer(hFile, dwFileStart, NULL, FILE_BEGIN) == INVALID_SET_FILE_POINTER) { + SendError(416, "Requested Range Not Satisfiable"); + return true; + } + + const char szHttpPartial[] = "HTTP/1.1 206 Partial Content\r\n" + "Connection: Keep-Alive\r\n" + "Date: %s\r\n" + "Server: MirandaWeb/%s\r\n" + "Accept-Ranges: bytes\r\n" + "ETag: %s\r\n" + "Content-Length: %d\r\n" + "Content-Type: %s\r\n" + "Content-Range: bytes %d-%d/%d\r\n" + "Last-Modified: %s\r\n" + "\r\n"; + + dwBytesToWrite = _snprintf(szBuf, sizeof(szBuf), szHttpPartial , + szCurTime , + pszVersion, + szETag , + dwDataToSend , + pszGetMimeType(pszRealPath), + dwFileStart, + (dwFileStart + dwDataToSend - 1), + nDataSize, + szFileTime); + } else { + const char szHttpOk[] = "HTTP/1.1 200 OK\r\n" + "Connection: Keep-Alive\r\n" + "Date: %s\r\n" + "Server: MirandaWeb/%s\r\n" + "Accept-Ranges: bytes\r\n" + "ETag: %s\r\n" + "Content-Length: %d\r\n" + "Content-Type: %s\r\n" + "Last-Modified: %s\r\n" + "\r\n"; + + dwBytesToWrite = _snprintf(szBuf, sizeof(szBuf), szHttpOk , + szCurTime , + pszVersion, + szETag , + nDataSize , + pszGetMimeType(pszRealPath), + szFileTime); + } + + Netlib_Send(hConnection, szBuf, dwBytesToWrite, 0); + + if (bIsGetCommand) { + static int nThreadCount = 0; + nThreadCount++; + + DWORD dwLastUpdate = GetTickCount(); + DWORD dwLastCurrentDL = 0; + /* + + dwLastDLSTickCount = dwCurTick; + dwCurrentDL;*/ + + //DWORD dwMaxSpeed = 8192;// Byte pr Sek + //DWORD dwMaxSpeed = 20000;// Byte pr Sek + //DWORD dwMaxSpeed = 163840;// Byte pr Sek + //DWORD dwMaxSpeed = 4096;// Byte pr Sek + + DWORD dwLastResetTime = GetTickCount(); + int nMaxBytesToSend = nMaxUploadSpeed / nThreadCount; + + for (;;) { + { + DWORD dwCurTick = GetTickCount(); + if (dwCurTick - dwLastUpdate >= 1000) {/* + char szTmp[200]; + _snprintf( szTmp, sizeof( szTmp ), "Bytes tr %d Time %d Tick %d\n", dwCurrentDL - dwLastCurrentDL, dwCurTick - dwLastUpdate, dwCurTick ); + OutputDebugString( szTmp ); + */ + dwSpeed = ((dwCurrentDL - dwLastCurrentDL) * 1000) / (dwCurTick - dwLastUpdate); + dwLastUpdate = dwCurTick; + dwLastCurrentDL = dwCurrentDL; + } + } + + if (nMaxUploadSpeed == 0) { + Sleep(1000); + continue; + } + + bool bSpeedLimit = (nMaxUploadSpeed >= 0) && (bIsOnline || !bLimitOnlyWhenOnline); + + DWORD dwCurOpr = sizeof(szBuf); + if (bSpeedLimit) + dwCurOpr = min(nMaxBytesToSend, sizeof(szBuf)); + + if (!ReadFile(hFile, szBuf, dwCurOpr, &dwBytesToWrite, NULL)) + break; + + if (dwBytesToWrite <= 0) + break; + + if (dwCurrentDL + dwBytesToWrite > dwDataToSend) + dwBytesToWrite = dwDataToSend - dwCurrentDL; + + if (bSpeedLimit) + nMaxBytesToSend -= dwBytesToWrite; + + DWORD dwSend = Netlib_Send(hConnection, szBuf, dwBytesToWrite, MSG_NODUMP); + if (dwSend == SOCKET_ERROR) + break; + dwCurrentDL += dwSend; + if (dwSend != dwBytesToWrite) + break; + + if (dwCurrentDL >= dwDataToSend) + break; + + if (bSpeedLimit && nMaxBytesToSend <= 0) { + // we have reached the limmit + DWORD dwTimeUsed = GetTickCount() - dwLastResetTime; + if (dwTimeUsed < 1000) + Sleep(1000 - dwTimeUsed); + dwLastResetTime = GetTickCount(); + nMaxBytesToSend = nMaxUploadSpeed / nThreadCount; + } + /* + char szTmp[200]; + _snprintf( szTmp, sizeof( szTmp ), "Current status : %d %% pos %d size %d\n", (dwCurrentDL * 100) / dwTotalSize, dwCurrentDL , dwTotalSize ); + OutputDebugString( szTmp ); + */ + } + + // file is always closed in destructor + if (szTempfile[0] != '\0') { + // and here - since it is a temporary index which as to be deleted + CloseHandle(hFile); + hFile = INVALID_HANDLE_VALUE; + + DeleteFile(szTempfile); + } + /* + { + char szBuf[200]; + _snprintf( szBuf, sizeof( szBuf ), "File Transfer stoped %d transfer complete %d\n", GetTickCount(), dwCurrentDL == nDataSize); + OutputDebugString( szBuf ); + } + */ + clCritSection.Lock(); + nThreadCount--; + + bool bNeedToWriteConfig = false; + + if (dwCurrentDL == nDataSize) { + if (pclCur->st.nMaxDownloads > 0) { + pclCur->st.nMaxDownloads--; + bNeedToWriteConfig = true; + } + } + + pclCur->bRemoveUser(this); + + // nMaxDownloads can have been decreesed by another thread. + // Therefore we test it even if we did'en decreese it + if (pclCur->st.nMaxDownloads == 0 && !pclCur->bAnyUsers()) { + CLFileShareNode **pclPrev = &pclFirstNode; + for (CLFileShareNode * pcl = pclFirstNode ; pcl ; pcl = pcl->pclNext) { + if (pcl == pclCur) { + *pclPrev = pclCur->pclNext; + ShowPopupWindow(Translate("Share removed"), pclCur->st.pszSrvPath, RGB(255, 189, 189)); + delete pclCur; + bNeedToWriteConfig = true; + break; + } + pclPrev = &pcl->pclNext; + } + } + + if (bNeedToWriteConfig) { + bWriteConfigurationFile(); + } + } + + return true; + } + } + + +#ifdef _DEBUG + OutputDebugString("########### Request Failed ###########\n"); + OutputDebugString(pszRequest); +#endif + + pszRequest[nUriLength] = 0; + + if ((nUriLength != 12 || strncmp(pszRequest, "/favicon.ico", nUriLength)) && // do not show popup of favicon.ico + *(ULONG*)(&stAddr) != 0x0100007F) { // do not show popup of 127.0.0.1 + ShowPopupWindow(inet_ntoa(stAddr), pszRequest, RGB(255, 189, 189)); + } + + SendError(404, "Not Found", "The requested URL was not found on this server."); + + return false; +} + + +void CLHttpUser::HandleNewConnection() { + +/* + { + SOCKET s = CallService(MS_NETLIB_GETSOCKET, (WPARAM) hConnection, 0); + sockaddr_in MyAddr; + int nSize = sizeof( MyAddr ); + getsockname( s, (sockaddr*)&MyAddr, &nSize ); + ShowPopupWindow( "My IP address", inet_ntoa( MyAddr.sin_addr ) ); + //OutputDebugString( ); + }*/ + /* + { + LINGER li; + int nLenght = sizeof( li ); + int ret = getsockopt( s, IPPROTO_TCP, SO_LINGER, (char *)&li, &nLenght ); + if( ret ) + { + DWORD error = WSAGetLastError(); + if( error + WSANOTINITIALISED + WSAENETDOWN The network subsystem has failed. + WSAEFAULT One of the optval or the optlen parameters is not a valid part of the user address space, or the optlen parameter is too small. + WSAEINPROGRESS A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function. + WSAEINVAL The level parameter is unknown or invalid. + WSAENOPROTOOPT The option is unknown or unsupported by the indicated protocol family. + WSAENOTSOCK + } + nLenght = sizeof( li ); + li.l_onoff = 1; + li.l_linger = 0;// time is default + ret = setsockopt( s, IPPROTO_TCP, SO_LINGER, (const char *)&li, nLenght ); + if( ret ) + { + // error + } + int nLenght = sizeof( li ); + int ret = getsockopt( s, IPPROTO_TCP, SO_LINGER, (char *)&li, &nLenght ); + } + */ + + char szBuf[1000]; + int nCurPos = 0; + while (sizeof(szBuf) - nCurPos > 10 && !bShutdownInProgress) { + int nBytesRead = Netlib_Recv(hConnection, &szBuf[nCurPos], sizeof(szBuf) - nCurPos, 0); + if (! nBytesRead) { + // socket closed gracefully + break; + } + if (nBytesRead == SOCKET_ERROR) { + // socket closed with error + // WSAGetLastError(); + break; + } + int nOldCurPos = nCurPos; + nCurPos += nBytesRead; + if (nCurPos <= 5) + continue; + + bool bIsGetCommand = memcmp(szBuf, "GET ", 4) == 0; + if (!bIsGetCommand && memcmp(szBuf, "HEAD ", 5) != 0) { + SendError(501, "Not Implemented"); + break; // We only support GET and HEAD commands !! + } + + if (nOldCurPos < 4) + nOldCurPos = 4; // scan forward from end of "GET " to locate the next space ' ' + + bool bBreakWhile = false; + for (; nOldCurPos < nCurPos; nOldCurPos++) { + if (szBuf[nOldCurPos-2] == '\n' && szBuf[nOldCurPos-1] == '\r' && szBuf[nOldCurPos] == '\n') { + // we have a walid request !!! scan to see if we have this file + szBuf[nOldCurPos] = NULL; + bProcessGetRequest(&szBuf[bIsGetCommand?4:5], bIsGetCommand); + + bBreakWhile = true; + break; + } + } + if (bBreakWhile) + break; + } +} diff --git a/plugins/HTTPServer/src/HttpUser.h b/plugins/HTTPServer/src/HttpUser.h new file mode 100644 index 0000000000..00b43a76eb --- /dev/null +++ b/plugins/HTTPServer/src/HttpUser.h @@ -0,0 +1,70 @@ +//This file is part of HTTPServer a Miranda IM plugin +//Copyright (C)2002 Kennet Nielsen +// +//This program is free software; you can redistribute it and/or +//modify it under the terms of the GNU General Public License +//as published by the Free Software Foundation; either +//version 2 of the License, or (at your option) any later version. +// +//This program is distributed in the hope that it will be useful, +//but WITHOUT ANY WARRANTY; without even the implied warranty of +//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +//GNU General Public License for more details. +// +//You should have received a copy of the GNU General Public License +//along with this program; if not, write to the Free Software +//Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +#ifndef HTTP_USER_H +#define HTTP_USER_H + +#include +#include "m_HTTPServer.h" +#include "FileShareNode.h" + +enum ENParamTypes { + eFirstParam = 0, + eRange = 0, + eIfRange, + eUnlessModifiedSince, + eIfModifiedSince, + eUserAgent, + eHost, + eLastParam +}; + +static char * szParmStr[eLastParam] = { + "Range: ", + "If-Range: ", + "Unless-Modified-Since: ", + "If-Modified-Since: ", + "User-Agent: ", + "Host: " +}; + + +class CLHttpUser : public CLShareUser { +public: + CLHttpUser(HANDLE hCon, in_addr stAdd); + virtual ~CLHttpUser(); + + bool bReadGetParameters(char * pszRequest); + + //bool bSendFile( HANDLE hFile , + bool bCloseTransfers() { + return true; + } + bool bProcessGetRequest(char * pszRequest, bool bIsGetCommand); + const char * pszCustomInfo() { + return apszParam[eUserAgent]; + } + void HandleNewConnection(); +private: + HANDLE hFile; + char *apszParam[eLastParam]; + + void SendError(int iErrorCode, const char * pszError, const char * pszDescription = NULL); + void SendRedir(int iErrorCode, const char * pszError, const char * pszDescription = NULL, const char * pszRedirect = NULL); +}; + +#endif \ No newline at end of file diff --git a/plugins/HTTPServer/src/IndexCreation.h b/plugins/HTTPServer/src/IndexCreation.h new file mode 100644 index 0000000000..c3892c4308 --- /dev/null +++ b/plugins/HTTPServer/src/IndexCreation.h @@ -0,0 +1,42 @@ + +//This file is part of HTTPServer a Miranda IM plugin +//Copyright (C)2002 Kennet Nielsen +// +//This program is free software; you can redistribute it and/or +//modify it under the terms of the GNU General Public License +//as published by the Free Software Foundation; either +//version 2 of the License, or (at your option) any later version. +// +//This program is distributed in the hope that it will be useful, +//but WITHOUT ANY WARRANTY; without even the implied warranty of +//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +//GNU General Public License for more details. +// +//You should have received a copy of the GNU General Public License +//along with this program; if not, write to the Free Software +//Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +#ifndef HTTP_INDEXCREATION_H +#define HTTP_INDEXCREATION_H + +#include +#include "m_HTTPServer.h" +#include "FileShareNode.h" + +const char szIndexHTMLTemplateFile[] = "HTTPServerIndex.html"; + +enum eIndexCreationMode { + INDEX_CREATION_DISABLE = 0, + INDEX_CREATION_HTML = 1, + INDEX_CREATION_XML = 2, + INDEX_CREATION_DETECT = 4 +}; + +extern eIndexCreationMode indexCreationMode; + +bool bCreateIndexXML(const char * pszRealPath, const char * pszIndexPath, const char * pszSrvPath, DWORD dwRemoteIP); +bool bCreateIndexHTML(const char * pszRealPath, const char * pszIndexPath, const char * pszSrvPath, DWORD dwRemoteIP); +void FreeIndexHTMLTemplate(); +bool LoadIndexHTMLTemplate(); + +#endif \ No newline at end of file diff --git a/plugins/HTTPServer/src/IndexHTML.cpp b/plugins/HTTPServer/src/IndexHTML.cpp new file mode 100644 index 0000000000..2a5f70f341 --- /dev/null +++ b/plugins/HTTPServer/src/IndexHTML.cpp @@ -0,0 +1,527 @@ +//This file is part of HTTPServer a Miranda IM plugin +//Copyright (C)2002 Kennet Nielsen +// +//This program is free software; you can redistribute it and/or +//modify it under the terms of the GNU General Public License +//as published by the Free Software Foundation; either +//version 2 of the License, or (at your option) any later version. +// +//This program is distributed in the hope that it will be useful, +//but WITHOUT ANY WARRANTY; without even the implied warranty of +//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +//GNU General Public License for more details. +// +//You should have received a copy of the GNU General Public License +//along with this program; if not, write to the Free Software +//Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +#include "Glob.h" + +eIndexCreationMode indexCreationMode; + +static char* szIndexHTMLTemplate = NULL; +static const int MAX_PARAM_LENGTH = 5; + +// signs below 32 are not used anyway +enum Symbol { + SY_END = 15, + SY_FOR_DIRS, + SY_DIR_URL, + SY_DIR_NAME, + SY_FOR_FILES, + SY_FILE_URL, + SY_FILE_NAME, + SY_FILE_SIZE, + SY_FILE_CREATE_TIME, + SY_FILE_MODIFY_TIME, + SY_IS_EVEN, + SY_IS_ODD, + SY_IS_FILE_TYPE +}; + +///////////////////////////////////////////////////////////////////// +// Member Function : LoadIndexHTMLTemplate +// Type : Global +// Parameters : - +// Returns : +// Description : +// +// References : - +// Remarks : - +// Created : 050901, 05 august 2005 +// Developer : Houdini +///////////////////////////////////////////////////////////////////// + +bool LoadIndexHTMLTemplate() { + if (szIndexHTMLTemplate != NULL) + return true; + + char szBuf[10000]; + char* pszBuf = szBuf; + + char szDestBuf[10000]; + char* pszDestBuf = szDestBuf; + + strcpy(pszBuf, szPluginPath); + strcat(pszBuf, szIndexHTMLTemplateFile); + + HANDLE hFile = CreateFile(pszBuf, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + if (hFile == INVALID_HANDLE_VALUE) { + MessageBox(NULL, "HTTPServerIndex.html not found in Plugin Path", MSG_BOX_TITEL, MB_OK); + return false; + } + + DWORD dwBytesRead = 0; + if (ReadFile(hFile, pszBuf, sizeof(szBuf), &dwBytesRead, NULL) || dwBytesRead <= 0) { + while (dwBytesRead > (DWORD)(pszBuf - szBuf)) { + if (*pszBuf == '[') { + char* pszKeywordBegin = pszBuf + 1; + bool bHasParameters = false; + + do { + pszBuf++; + } while (*pszBuf != ']' && *pszBuf != '\0' && *pszBuf != '='); + + if (*pszBuf == '\0') + break; + + if (*pszBuf == '=') + bHasParameters = true; + + *pszBuf = '\0'; + *pszDestBuf = '#'; + + // signs below 32 are not used anyway + if (!strcmp(pszKeywordBegin, "End")) *pszDestBuf = SY_END; + else if (!strcmp(pszKeywordBegin, "ForDirectoriesDo")) *pszDestBuf = SY_FOR_DIRS; + else if (!strcmp(pszKeywordBegin, "DirectoryUrl")) *pszDestBuf = SY_DIR_URL; + else if (!strcmp(pszKeywordBegin, "DirectoryName")) *pszDestBuf = SY_DIR_NAME; + else if (!strcmp(pszKeywordBegin, "ForFilesDo")) *pszDestBuf = SY_FOR_FILES; + else if (!strcmp(pszKeywordBegin, "FileUrl")) *pszDestBuf = SY_FILE_URL; + else if (!strcmp(pszKeywordBegin, "FileName")) *pszDestBuf = SY_FILE_NAME; + else if (!strcmp(pszKeywordBegin, "FileSize")) *pszDestBuf = SY_FILE_SIZE; + else if (!strcmp(pszKeywordBegin, "FileCreated")) *pszDestBuf = SY_FILE_CREATE_TIME; + else if (!strcmp(pszKeywordBegin, "FileModified")) *pszDestBuf = SY_FILE_MODIFY_TIME; + else if (!strcmp(pszKeywordBegin, "IsEven")) *pszDestBuf = SY_IS_EVEN; + else if (!strcmp(pszKeywordBegin, "IsOdd")) *pszDestBuf = SY_IS_ODD; + else if (!strcmp(pszKeywordBegin, "IsFileType")) *pszDestBuf = SY_IS_FILE_TYPE; + else { + LogEvent("Error in index template", "Unknown Tag"); + // unknown tag + } + + // remove some useless returns + if (*pszDestBuf == SY_END) + while (*(pszBuf + 1) == '\r' || *(pszBuf + 1) == '\n') + pszBuf++; + + pszDestBuf++; + + // these tags require an End - reserve space for relative jump address (2 byte) + switch (*(pszDestBuf - 1)) { + case SY_FOR_DIRS: + case SY_FOR_FILES: + case SY_IS_EVEN: + case SY_IS_ODD: + case SY_IS_FILE_TYPE: { + *((WORD*)(pszDestBuf)) = 0x7070; + pszDestBuf += 2; + } + } + + if (bHasParameters) { + // max MAX_PARAM_LENGTH chars per param (terminated with : when shorter than MAX_PARAM_LENGTH) + byte iParamCount = 1; + char* pcParamCount = (pszDestBuf++); + char* pszParameterBegin = pszBuf + 1; + + do { + if (*pszBuf == ',') { + *pszBuf = ':'; + strncpy(pszDestBuf, pszParameterBegin, MAX_PARAM_LENGTH); + pszDestBuf += MAX_PARAM_LENGTH; + + pszParameterBegin = pszBuf + 1; + iParamCount++; + } + pszBuf++; + } while (*pszBuf != ']' && *pszBuf != '\0'); + + if (*pszBuf == '\0') + break; + + *pszBuf = ':'; + strncpy(pszDestBuf, pszParameterBegin, MAX_PARAM_LENGTH); + pszDestBuf += MAX_PARAM_LENGTH; + + *pcParamCount = iParamCount; + } + } else { + *(pszDestBuf++) = *pszBuf; + } + + pszBuf++; + } + + *(pszDestBuf) = '\0'; + + pszBuf = szDestBuf; + + while (*pszBuf != '\0') { + byte iLevel = 0; + switch (*pszBuf) { + // these tags require an End - precalculate address of End + case SY_FOR_DIRS: + case SY_FOR_FILES: + case SY_IS_EVEN: + case SY_IS_ODD: + case SY_IS_FILE_TYPE: + iLevel++; + break; + } + + pszBuf++; + + // begin of iLevel - find End of iLevel + if (iLevel > 0) { + char* pszLevelEnd = pszBuf + 2; // skip for address reserved bytes + + // skip parameters of IsFileType + if (*(pszBuf - 1) == SY_IS_FILE_TYPE) { + pszLevelEnd++; + pszLevelEnd += *(pszLevelEnd - 1) * MAX_PARAM_LENGTH; + } + + while (*pszLevelEnd != '\0' && iLevel > 0) { + switch (*pszLevelEnd) { + case SY_FOR_DIRS: + case SY_FOR_FILES: + case SY_IS_EVEN: + case SY_IS_ODD: + iLevel++; + pszLevelEnd += 2; + break; + + case SY_IS_FILE_TYPE: + iLevel++; + pszLevelEnd += 2; + pszLevelEnd += 1; + pszLevelEnd += *(pszLevelEnd) * MAX_PARAM_LENGTH; + break; + + case SY_END: + iLevel--; + break; + } + + pszLevelEnd++; + } + + if (*pszLevelEnd == '\0') { + LogEvent("Error in index template", "End is missing"); + break; // Error - End missing + } + + //char Temp[100]; + //sprintf(Temp, "Tag: %i Begin: %i End: %i", *(pszBuf-1), pszBuf-szDestBuf, pszBuf-szDestBuf+pszLevelEnd-pszBuf); + //LogEvent("Jump", Temp); + + // write jump address + *((WORD*)(pszBuf)) = (WORD)((pszLevelEnd - pszBuf - 1) | 0x8000); + pszBuf += 2; + } + } + + *(pszBuf) = '\0'; + + //LogEvent("Template", szDestBuf); + + szIndexHTMLTemplate = new char[strlen(szDestBuf)+1]; + strcpy(szIndexHTMLTemplate, szDestBuf); + } + + CloseHandle(hFile); + return true; +} + +///////////////////////////////////////////////////////////////////// +// Member Function : FreeIndexHTMLTemplate +// Type : Global +// Parameters : - +// Returns : +// Description : +// +// References : - +// Remarks : - +// Created : 050901, 05 august 2005 +// Developer : Houdini +///////////////////////////////////////////////////////////////////// + +void FreeIndexHTMLTemplate() { + if (szIndexHTMLTemplate != NULL) { + delete[] szIndexHTMLTemplate; + szIndexHTMLTemplate = NULL; + } +} + +///////////////////////////////////////////////////////////////////// +// Member Function : bCreateIndexHTML +// Type : Global +// Parameters : pszRealPath - ? +// Returns : +// Description : +// +// References : - +// Remarks : - +// Created : 050821, 05 august 2005 +// Developer : Houdini +///////////////////////////////////////////////////////////////////// + +bool bCreateIndexHTML(const char * pszRealPath, const char * pszIndexPath, + const char * pszSrvPath, DWORD /* dwRemoteIP */) { +#define RelativeJump(begin) { pszPos += *((WORD*)(begin+1)) & 0x7FFF; } + + if (szIndexHTMLTemplate == NULL) + return false; + + // check if directory exists + char szMask[MAX_PATH]; + strcpy(szMask, pszRealPath); + strcat(szMask, "*"); + + WIN32_FIND_DATAA fdFindFileData; + HANDLE hFind = FindFirstFile(szMask, &fdFindFileData); + + if (hFind == INVALID_HANDLE_VALUE) + return FALSE; + + FindClose(hFind); + hFind = 0; + + HANDLE hFile = CreateFile(pszIndexPath, GENERIC_WRITE, FILE_SHARE_READ , + NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_TEMPORARY, NULL); + + if (hFile == INVALID_HANDLE_VALUE) + return FALSE; + + char szBuffer[10000]; + char* pszBuffer = szBuffer; + DWORD dwBytesWritten = 0; + + char* pszPos = szIndexHTMLTemplate; + + byte iCurrentAction = 0; + char* pszLevelBegin[50]; + byte iLevel = 0; + + char szName[1000] = ""; + char szURL[1000] = ""; + int iFileSize = 0; + FILETIME ftFileCreateTime; + FILETIME ftFileModifyTime; + bool bEvenOdd = 0; + bool bKnownFileType = false; + + strcpy(szBuffer, pszSrvPath); + char* pszTemp = strrchr(szBuffer, '/'); + if (pszTemp) + *pszTemp = '\0'; + + pszTemp = strrchr(szBuffer, '/'); + if (pszTemp) + strcpy(szName, pszTemp + 1); + + if (strlen(szName) == 0) + strcpy(szName, "my Miranda Webserver"); + + do { + switch (*pszPos) { + case SY_FOR_FILES: + case SY_FOR_DIRS: { + if (hFind == 0) { + pszLevelBegin[iLevel++] = pszPos; + iCurrentAction = *pszPos; + + hFind = FindFirstFile(szMask, &fdFindFileData); + if (hFind == 0) { + iCurrentAction = 0; + RelativeJump(pszLevelBegin[iLevel-1]); + break; + } + } else { + if (!FindNextFile(hFind, &fdFindFileData)) { + FindClose(hFind); + hFind = 0; + iCurrentAction = 0; + RelativeJump(pszLevelBegin[iLevel-1]); + break; + } + } + + while (!strcmp(fdFindFileData.cFileName, ".") || + !strncmp(fdFindFileData.cFileName, "@", 1) || + (!strcmp(fdFindFileData.cFileName, "..") && !strcmp(pszSrvPath, "/")) || // hide .. in root + ((*pszPos == 19) == ((fdFindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0))) { + if (!FindNextFile(hFind, &fdFindFileData)) { + FindClose(hFind); + hFind = 0; + iCurrentAction = 0; + RelativeJump(pszLevelBegin[iLevel-1]); + break; + } + } + + if (hFind) { + strcpy(szName, fdFindFileData.cFileName); + strcpy(szURL, fdFindFileData.cFileName); + /*char* pszTmp = szURL; + while(pszTmp = strchr(pszTmp, ' ')) + *pszTmp = '+';*/ + + if (*pszPos == SY_FOR_DIRS) { // For Directories + strcat(szURL, "/"); + } else { // For Files + iFileSize = fdFindFileData.nFileSizeLow; + ftFileCreateTime = fdFindFileData.ftCreationTime; + ftFileModifyTime = fdFindFileData.ftLastWriteTime; + } + + bKnownFileType = false; + bEvenOdd = !bEvenOdd; + pszPos += 2; + } + + break; + } + + case SY_END: { // End + if (iLevel <= 0) + break; // Error + + if (iCurrentAction == SY_FOR_DIRS || iCurrentAction == SY_FOR_FILES) { // For loops + pszPos = pszLevelBegin[iLevel-1] - 1; // jump to begin + } else { + iLevel--; + if (iLevel > 0) + iCurrentAction = *pszLevelBegin[iLevel-1]; + else + iCurrentAction = 0; + } + + break; + } + + case SY_FILE_NAME: + case SY_DIR_NAME: { + pszBuffer += _snprintf(pszBuffer, 250, "%s", szName); + break; + } + + case SY_DIR_URL: { + case SY_FILE_URL: + pszBuffer += _snprintf(pszBuffer, 250, "%s", szURL); + break; + } + + case SY_FILE_CREATE_TIME: + case SY_FILE_MODIFY_TIME: { + SYSTEMTIME systemTime; + FileTimeToSystemTime( + (*pszPos == SY_FILE_CREATE_TIME) ? &ftFileCreateTime : &ftFileModifyTime, + &systemTime); + + pszBuffer += _snprintf(pszBuffer, 100, "%i/%02i/%02i %i:%02i:%02i", + systemTime.wYear, systemTime.wMonth, systemTime.wDay, systemTime.wHour, + systemTime.wMinute, systemTime.wSecond); + break; + } + + case SY_FILE_SIZE: { + if ((iFileSize >> 10) == 0) + pszBuffer += _snprintf(pszBuffer, 100, "%i Byte", iFileSize); + else if ((iFileSize >> 20) == 0) + pszBuffer += _snprintf(pszBuffer, 100, "%.1f KB", (float)(iFileSize) / 1024.0f); + else + pszBuffer += _snprintf(pszBuffer, 100, "%.1f MB", (float)(iFileSize) / (1024.0f * 1024.0f)); + break; + } + + case SY_IS_EVEN: + case SY_IS_ODD: { + pszLevelBegin[iLevel++] = pszPos; + iCurrentAction = *pszPos; + + if (bEvenOdd != (*pszPos - SY_IS_EVEN == 1)) { // SY_IS_EVEN+1 == SY_IS_ODD + RelativeJump(pszLevelBegin[iLevel-1]); + } else { + pszPos += 2; + } + break; + } + + case SY_IS_FILE_TYPE: { + pszLevelBegin[iLevel++] = pszPos; + iCurrentAction = *pszPos; + + byte iParamCount = *(pszPos + 3); + char* pszParam = pszPos + 4; + bool bSkip = true; + + if (bKnownFileType == false) { + if (*pszParam == '*') { + bSkip = false; + } else { + for (byte i = 0; i < iParamCount; i++) { + char szParam[MAX_PARAM_LENGTH+1]; + strncpy(szParam, pszParam, MAX_PARAM_LENGTH); + szParam[MAX_PARAM_LENGTH] = '\0'; + char* pszTmp = strchr(szParam, ':'); + if (pszTmp) + *pszTmp = '\0'; + + char* pszExt = strrchr(szName, '.'); + + if (pszExt && !_stricmp(pszExt + 1, szParam)) { + bSkip = false; + break; + } + pszParam += MAX_PARAM_LENGTH; + } + } + } + + if (bSkip) { + RelativeJump(pszLevelBegin[iLevel-1]); + } else { + bKnownFileType = true; + pszPos += 2; + pszPos += 1; + pszPos += *(pszPos) * MAX_PARAM_LENGTH; + } + break; + } + + default: { + *(pszBuffer++) = *pszPos; + } + } + + pszPos++; + + // flush the buffer from time to time + if (*pszPos == '\0' || pszBuffer - szBuffer > 8000) { + if (!WriteFile(hFile, szBuffer, pszBuffer - szBuffer, &dwBytesWritten, NULL)) + break; + + pszBuffer = szBuffer; + } + } while (*pszPos != '\0'); + + if (hFind != 0) + FindClose(hFind); + + SetEndOfFile(hFile); + CloseHandle(hFile); + return TRUE; +} \ No newline at end of file diff --git a/plugins/HTTPServer/src/IndexXML.cpp b/plugins/HTTPServer/src/IndexXML.cpp new file mode 100644 index 0000000000..15c86c5c40 --- /dev/null +++ b/plugins/HTTPServer/src/IndexXML.cpp @@ -0,0 +1,255 @@ +//This file is part of HTTPServer a Miranda IM plugin +//Copyright (C)2002 Kennet Nielsen +// +//This program is free software; you can redistribute it and/or +//modify it under the terms of the GNU General Public License +//as published by the Free Software Foundation; either +//version 2 of the License, or (at your option) any later version. +// +//This program is distributed in the hope that it will be useful, +//but WITHOUT ANY WARRANTY; without even the implied warranty of +//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +//GNU General Public License for more details. +// +//You should have received a copy of the GNU General Public License +//along with this program; if not, write to the Free Software +//Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +#include "Glob.h" + +static const char szXmlHeader1[] = "\r\n" + "\r\n" + "\r\n"; + +static const char szXmlTail[] = ""; + + +static void ReplaceSign(char* pszSrc, int MaxLength, const char pszReplace, + const char * pszNew) { + static char szBuffer[1024]; + char* pszSign = strchr(pszSrc, pszReplace); + + if (pszSign) { + strcpy(szBuffer, pszSrc); + + do { + strcpy(szBuffer + (pszSign - pszSrc), pszNew); + strcpy(szBuffer + (pszSign - pszSrc) + strlen(pszNew), pszSign + 1); + *pszSign = ' '; + + } while (pszSign = strchr(pszSrc, pszReplace)); + + strncpy(pszSrc, szBuffer, MaxLength); + + pszSrc[MaxLength-1] = '\0'; + } +} + + +///////////////////////////////////////////////////////////////////// +// Member Function : bCreateIndexXML +// Type : Global +// Parameters : pszRealPath - ? +// Returns : +// Description : +// +// References : - +// Remarks : - +// Created : 050821, 05 august 2005 +// Developer : Houdini +///////////////////////////////////////////////////////////////////// + +bool bCreateIndexXML(const char * pszRealPath, const char * pszIndexPath, + const char * pszSrvPath, DWORD dwRemoteIP) { + char szMask[MAX_PATH+1]; + strcpy(szMask, pszRealPath); + strcat(szMask, "*"); + + WIN32_FIND_DATAA fdFindFileData; + HANDLE hFind = FindFirstFile(szMask, &fdFindFileData); + + if (hFind == INVALID_HANDLE_VALUE) + return FALSE; + + HANDLE hFile = CreateFile(pszIndexPath, GENERIC_WRITE, FILE_SHARE_READ, NULL, + OPEN_ALWAYS, FILE_ATTRIBUTE_TEMPORARY, NULL); + + if (hFile == INVALID_HANDLE_VALUE) { + FindClose(hFind); + return FALSE; + } + + const int BUFFER_SIZE = 1000; + char szBuffer[BUFFER_SIZE+1]; + char* pszBuffer = szBuffer; + char szFileName[MAX_PATH+1] = ""; + char* pszExt; + DWORD dwBytesWritten = 0; + + // Generate Dirname + strcpy(szBuffer, pszSrvPath); + char* pszTemp = strrchr(szBuffer, '/'); + if (pszTemp) + *pszTemp = '\0'; + + pszTemp = strrchr(szBuffer, '/'); + if (pszTemp) + strcpy(szFileName, pszTemp + 1); + + // Write Header + WriteFile(hFile, szXmlHeader1, sizeof(szXmlHeader1) - 1, &dwBytesWritten, NULL); + + // check if a index.xsl exists in the same directory otherwise use the global + strcpy(szMask, pszRealPath); + strcat(szMask, "index.xsl"); + + HANDLE hFileExists = CreateFile(szMask, GENERIC_READ, + FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, NULL); + + if (hFileExists == INVALID_HANDLE_VALUE) { + strcpy(szBuffer, "/index.xsl"); + } else { + CloseHandle(hFileExists); + strcpy(szBuffer, "index.xsl"); + } + + WriteFile(hFile, szBuffer, strlen(szBuffer), &dwBytesWritten, NULL); + + WriteFile(hFile, szXmlHeader2, sizeof(szXmlHeader2) - 1, &dwBytesWritten, NULL); + + // Write dirname + ReplaceSign(szFileName, MAX_PATH, '&', "&"); + pszBuffer += _snprintf(pszBuffer, BUFFER_SIZE - (pszBuffer - szBuffer), + " %s\r\n", szFileName); + WriteFile(hFile, szBuffer, pszBuffer - szBuffer, &dwBytesWritten, NULL); + + // Find files and directories + do { + if (strcmp(fdFindFileData.cFileName, ".") && + strncmp(fdFindFileData.cFileName, "@", 1) && + (strcmp(fdFindFileData.cFileName, "..") || strcmp(pszSrvPath, "/"))) { // hide .. in root + pszBuffer = szBuffer; + + strcpy(szFileName, fdFindFileData.cFileName); + ReplaceSign(szFileName, MAX_PATH, '&', "&"); + + if (fdFindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { + pszBuffer += _snprintf(pszBuffer, BUFFER_SIZE - (pszBuffer - szBuffer), + " \r\n", szFileName); + } else { + pszExt = strrchr(szFileName, '.'); + + if (pszExt != NULL) { + *pszExt = '\0'; + pszExt++; + } + + pszBuffer += _snprintf(pszBuffer, BUFFER_SIZE - (pszBuffer - szBuffer), + " \r\n"); + } + + if (!WriteFile(hFile, szBuffer, pszBuffer - szBuffer, &dwBytesWritten, NULL)) + break; + } + + } while (FindNextFile(hFind, &fdFindFileData)); + + if (hFind != 0) + FindClose(hFind); + + // Add other shared files & directories + for (CLFileShareNode * pclCur = pclFirstNode; pclCur ; pclCur = pclCur->pclNext) { + if (!((pclCur->st.dwAllowedIP ^ dwRemoteIP) & pclCur->st.dwAllowedMask) && // hide inaccessible shares + (size_t)(pclCur->nGetSrvPathLen()) > strlen(pszSrvPath) && + !strstr(pclCur->st.pszRealPath, "\\@") && + !strncmp(pclCur->st.pszSrvPath, pszSrvPath, strlen(pszSrvPath))) { + pszBuffer = szBuffer; + + strcpy(szFileName, &pclCur->st.pszSrvPath[strlen(pszSrvPath)]); + ReplaceSign(szFileName, MAX_PATH, '&', "&"); + + if (pclCur->bIsDirectory()) { + szFileName[strlen(szFileName)-1] = '\0'; + if (!strchr(szFileName, '/')) { // only one level deeper + pszBuffer += _snprintf(pszBuffer, BUFFER_SIZE - (pszBuffer - szBuffer), + " \r\n", szFileName); + + if (!WriteFile(hFile, szBuffer, pszBuffer - szBuffer, &dwBytesWritten, NULL)) + break; + } + } else { + if (!strchr(szFileName, '/') && // only one level deeper + strncmp(pszRealPath, pclCur->st.pszRealPath, strlen(pszRealPath))) { // no duplicates + pszExt = strrchr(szFileName, '.'); + + if (pszExt != NULL) { + *pszExt = '\0'; + pszExt++; + } + + DWORD dwFileSize = 0; + FILETIME ftFileCreateTime; + FILETIME ftFileAccessTime; + FILETIME ftFileModifyTime; + HANDLE hFileS = CreateFile(pclCur->st.pszRealPath, GENERIC_READ, + FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + if (hFileS != INVALID_HANDLE_VALUE) { + dwFileSize = GetFileSize(hFileS, NULL); + GetFileTime(hFileS, &ftFileCreateTime, &ftFileAccessTime, &ftFileModifyTime); + CloseHandle(hFileS); + } + + pszBuffer += _snprintf(pszBuffer, BUFFER_SIZE - (pszBuffer - szBuffer), + " \r\n"); + + if (!WriteFile(hFile, szBuffer, pszBuffer - szBuffer, &dwBytesWritten, NULL)) + break; + } + } + } + } + + WriteFile(hFile, szXmlTail, sizeof(szXmlTail) - 1, &dwBytesWritten, NULL); + + SetEndOfFile(hFile); + CloseHandle(hFile); + + return TRUE; +} \ No newline at end of file diff --git a/plugins/HTTPServer/src/MimeHandling.cpp b/plugins/HTTPServer/src/MimeHandling.cpp new file mode 100644 index 0000000000..42964bfeb3 --- /dev/null +++ b/plugins/HTTPServer/src/MimeHandling.cpp @@ -0,0 +1,147 @@ +#include "Glob.h" + +/* MIME type/ext map */ +ContentTypeDB MIME = NULL; +/* Default Mime type when recognition fails */ +char DefaultMime[] = "application/octet-stream"; + +int bInitMimeHandling() { + FILE *mimeDB; + char line[LINE_MAX_SIZE]; + char *tok = NULL; + int lenght; + ContentType *pDBCell = NULL; + ContentTypeDB pDB = NULL; + ExtensionList extListCur = NULL; + ExtensionListCell *pExtCell = NULL; + char szBuf[10000]; + + strcpy(szBuf, szPluginPath); + strcat(szBuf, szMimeTypeConfigFile); + mimeDB = fopen(szBuf, "r"); + + if (mimeDB != NULL) { + while (fgets(line, LINE_MAX_SIZE, mimeDB)) { + /*filter junk lines assuming Mime type start with letter + (convention ?) */ + if ((line[0] <= 'z' && line[0] >= 'a') + || (line[0] <= 'Z' && line[0] >= 'A')) { + /*remove comments trailing comments*/ + tok = strrchr(line, '#'); + if (tok != NULL) { + *tok = '\0'; + } + /* remove trailing \n */ + lenght = strlen(line); + if (lenght > 0 && line[lenght - 1] == '\n') { + line[lenght - 1] = '\0'; + } + /* first token = mime type */ + tok = (char*)strtok(line, " \t"); + /*create and fill a cell*/ + pDBCell = (ContentType*)malloc(sizeof(ContentType)); + pDBCell->mimeType = (char*)malloc(strlen(tok) + 1); + strcpy(pDBCell->mimeType, tok); + pDBCell->extList = NULL; + pDBCell->next = NULL; + /* looking for extensions */ + tok = (char*)strtok(NULL, " \t"); + while (tok != NULL) { + /*create and fill a cell*/ + pExtCell = (ExtensionListCell*)malloc(sizeof(ExtensionListCell)); + pExtCell->ext = (char*)malloc(strlen(tok) + 1); + strcpy(pExtCell->ext, tok); + pExtCell->next = NULL; + /*link*/ + if (pDBCell->extList == NULL) { + pDBCell->extList = pExtCell; + } else { + extListCur->next = pExtCell; + } + extListCur = pExtCell; + tok = (char*)strtok(NULL, " \t"); + } + /* link */ + if (pDBCell->extList != NULL) { /*extension(s) found*/ + if (MIME == NULL) { + MIME = pDBCell; + } else { + pDB->next = pDBCell; + } + pDB = pDBCell; + } else { /*no extension found, freeing memory*/ + free(pDBCell->mimeType); + free(pDBCell); + } + } + } + + fclose(mimeDB); + } + if (MIME == NULL) { + return 0; + } + return 1; +} + +const char * pszGetMimeType(const char * pszFileName) { + ContentTypeDB courMIME; + ExtensionList courEXT; + const char* ext; + + ext = strrchr(pszFileName, '.'); + + if (ext != NULL) { + if (ext[1] == '\0') { + /*empty extension */ + return DefaultMime; + } else { + /*remove the "."*/ + ext = ext + 1; + } + + courMIME = MIME; + while (courMIME != NULL) { + courEXT = courMIME->extList; + while (courEXT != NULL) { + if (!_stricmp(courEXT->ext, ext)) { + return courMIME->mimeType; + } + courEXT = courEXT->next; + } + courMIME = courMIME->next; + } + /*extension unknown*/ + return DefaultMime; + } else { + /*no extension*/ + return DefaultMime; + } +} + + +#ifdef TEST +void printDB() { + ContentTypeDB courMIME; + ExtensionList courEXT; + + courMIME = MIME; + while (courMIME != NULL) { + printf("%s", courMIME->mimeType); + courEXT = courMIME->extList; + while (courEXT != NULL) { + printf(" %s", courEXT->ext); + courEXT = courEXT->next; + } + courMIME = courMIME->next; + printf("\n"); + } +} + +int main(int argc, char* argv[]) { + bInitMimeHandling(); + printDB(); + printf("%s\n", pszGetMimeType(argv[1])); + return 0; +} +#endif diff --git a/plugins/HTTPServer/src/MimeHandling.h b/plugins/HTTPServer/src/MimeHandling.h new file mode 100644 index 0000000000..f40fdf94c8 --- /dev/null +++ b/plugins/HTTPServer/src/MimeHandling.h @@ -0,0 +1,52 @@ +#define LINE_MAX_SIZE 512 + +#ifdef __cplusplus +extern "C" { +#endif + +#define szMimeTypeConfigFile "HTTPMimeTypes" + + /* MIME DB Data structure + + ---------- ---------- + | mimeType | | mimeType | + |----------| |----------| + ----| next -----------------| next | + |----------| |----------| + | extList --- | extList --- + ---------- | ---------- | + --|--- --|--- + | ext | | ext | + |------| |------| + | next | | next | + --|--- ------ + --|--- + | ext | + |------| + | next | + ------ + */ + + typedef struct _ExtensionListCell { + char* ext; + struct _ExtensionListCell* next; + } ExtensionListCell ; + + + typedef struct _ContentType { + char* mimeType; + ExtensionListCell* extList; + struct _ContentType* next; + } ContentType ; + + typedef ContentType* ContentTypeDB; + typedef ExtensionListCell* ExtensionList; + + + + extern int bInitMimeHandling(); + extern const char * pszGetMimeType(const char * pszFileName); + +#ifdef __cplusplus +} +#endif diff --git a/plugins/HTTPServer/src/m_HTTPServer.h b/plugins/HTTPServer/src/m_HTTPServer.h new file mode 100644 index 0000000000..6cb6549ee0 --- /dev/null +++ b/plugins/HTTPServer/src/m_HTTPServer.h @@ -0,0 +1,105 @@ +//This file is part of HTTPServer a Miranda IM plugin +//Copyright (C)2002 Kennet Nielsen +// +//This program is free software; you can redistribute it and/or +//modify it under the terms of the GNU General Public License +//as published by the Free Software Foundation; either +//version 2 of the License, or (at your option) any later version. +// +//This program is distributed in the hope that it will be useful, +//but WITHOUT ANY WARRANTY; without even the implied warranty of +//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +//GNU General Public License for more details. +// +//You should have received a copy of the GNU General Public License +//along with this program; if not, write to the Free Software +//Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#ifndef M_HTTP_SERVER_H +#define M_HTTP_SERVER_H + + +#define OPT_SEND_LINK 0x1 + + +typedef struct { + DWORD lStructSize; // Set to sizeof(STFileShareInfo) + char * pszSrvPath; // Server path + DWORD dwMaxSrvPath; // Buffer allocated for Server path only used when information is requested from HTTP server. + char * pszRealPath; // Real path can be relative or complete + DWORD dwMaxRealPath;// Buffer allocated for Real path only used when information is requested from HTTP server. + DWORD dwAllowedIP; // The IP address which is allowed to access this share + DWORD dwAllowedMask; // A mask which is applied to IP address to allow other IP addresses + int nMaxDownloads; // The maximum number of download which can be made on this share. + DWORD dwOptions; // Use OPT_SEND_LINK to open a message window with the link to file +} STFileShareInfo, * LPSTFileShareInfo; + +// dwMaxSrvPath Specifies the size, in chars, of the buffer pointed to by pszSrvPath. +// The buffer must be large enough to store the path and file name string, +// including the terminating null character. + + +///////////////////////////////////////////// +/// Service MS_HTTP_ADD_CHANGE_REMOVE /// +///////////////////////////////////////////// +// +// wParam = (WPARAM)0 +// lParam = (LPARAM)LPSTFileShareInfo; +// Server path is the key when working with FileShareInfo. +// Two files can not be shared with the same "Server path" in the HTTP server. +// If the server path does not exists it will be added. +// If it does exists the action depends on what real path is. +// If real path is empty the entity will be removed else it +// will just be updated with the new settings. + +// +// returns 0 on success, nonzero on failure +#define MS_HTTP_ADD_CHANGE_REMOVE "HTTPServer/AddChangeRemove" + + +///////////////////////////////////////////// +////// Service MS_HTTP_GET_SHARE ////// +///////////////////////////////////////////// +// +// wParam = (WPARAM)0; +// lParam = (LPARAM)LPSTFileShareInfo; +// Returns the information for a share +// Server path must be set the the share you wish information for. +// +// returns 0 on success, nonzero on failure + +#define MS_HTTP_GET_SHARE "HTTPServer/GetShare" + + + +///////////////////////////////////////////// +/// Service MS_HTTP_ACCEPT_CONNECTIONS /// +///////////////////////////////////////////// +// +// wParam = (WPARAM)boolean(true/false); +// lParam = (LPARAM)0; +// Toggles the HTTP server state if wParam is FALSE +// Force enable HTTP server if wParam is TRUE +// returns 0 on success, nonzero on failure + +#define MS_HTTP_ACCEPT_CONNECTIONS "HTTPServer/AcceptConnections" + +///////////////////////////////////////////// +//// Service MS_HTTP_GET_ALL_SHARES ///// +///////////////////////////////////////////// +// +// wParam = (WPARAM)0; +// lParam = (LPARAM)&LPSTFileShareInfo; +// Returns an array of all currently shared files in the HTTP Server +// LPSTFileShareInfo points to the first share. +// You must free the memory returned by using the miranda MS_SYSTEM_GET_MMI +// and calling MM_INTERFACE->free( LPSTFileShareInfo ) +// +// returns the count of shares in the buffer pointed to by LPSTFileShareInfo + +#define MS_HTTP_GET_ALL_SHARES "HTTPServer/GetAllShares" + + + +#endif diff --git a/plugins/HTTPServer/src/main.cpp b/plugins/HTTPServer/src/main.cpp new file mode 100644 index 0000000000..44ff4279c8 --- /dev/null +++ b/plugins/HTTPServer/src/main.cpp @@ -0,0 +1,974 @@ +//This file is part of HTTPServer a Miranda IM plugin +//Copyright (C)2002 Kennet Nielsen +// +//This program is free software; you can redistribute it and/or +//modify it under the terms of the GNU General Public License +//as published by the Free Software Foundation; either +//version 2 of the License, or (at your option) any later version. +// +//This program is distributed in the hope that it will be useful, +//but WITHOUT ANY WARRANTY; without even the implied warranty of +//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +//GNU General Public License for more details. +// +//You should have received a copy of the GNU General Public License +//along with this program; if not, write to the Free Software +//Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#include "Glob.h" + +#define szConfigFile "HTTPServer.xml" + +const char szXmlHeader[] = "\r\n" + "\r\n" + "\r\n"; + +const char szXmlData[] = "\t\r\n" + "\t\t%s\r\n" + "\t\t%s\r\n" + "\t\t%d\r\n" + "\t\t%d.%d.%d.%d\r\n" + "\t\t%d.%d.%d.%d\r\n" + "\t\r\n"; + +const char szXmlTail[] = ""; + +const char* pszDefaultShares[] = { + "htdocs\\@settings\\favicon.ico", "/favicon.ico", + "htdocs\\@settings\\index.xsl", "/index.xsl", + "htdocs\\@settings\\placeholder.gif", "/placeholder.gif", + "htdocs\\@settings\\icons\\", "/icons/", + "htdocs\\", "/", + 0, 0 +}; + +void ConnectionOpen(HANDLE hNewConnection, DWORD dwRemoteIP); +int PreShutdown(WPARAM /*wparam*/, LPARAM /*lparam*/); + +HANDLE hNetlibUser; +HANDLE hDirectBoundPort; + +HINSTANCE hInstance = NULL; + +string sLogFilePath; + +// static so they can not be used from other modules ( sourcefiles ) +static HANDLE hEventSystemInit = 0; +static HANDLE hPreShutdown = 0; + +static HANDLE hHttpAcceptConnectionsService = 0; +static HANDLE hHttpAddChangeRemoveService = 0; +static HANDLE hHttpGetShareService = 0; +static HANDLE hHttpGetAllShares = 0; + +static HANDLE hAcceptConnectionsMenuItem = 0; + +char szPluginPath[MAX_PATH] = {0}; +int nPluginPathLen = 0; + +DWORD dwLocalIpAddress = 0; +DWORD dwLocalPortUsed = 0; +DWORD dwExternalIpAddress = 0; + +int nMaxUploadSpeed = -1; +int nMaxConnectionsTotal = -1; +int nMaxConnectionsPerUser = -1; +int nDefaultDownloadLimit = -1; + +bool bIsOnline = true; +static HANDLE hEventProtoAck = 0; + +bool bLimitOnlyWhenOnline = true; + +bool bShutdownInProgress = false; + +int hLangpack = 0; + +char* pszVersion = "0.1.2.2"; + +PLUGININFOEX pluginInfo = { + sizeof(PLUGININFOEX), + MODULE, + PLUGIN_MAKE_VERSION(0, 1, 2, 2), + "HTTP Server\r\n" + "HTTP Web Server plugin for Miranda", + "Kennet Nielsen, modified by Vampik, Houdini", + "", + "© 2003-2009 Kennet Nielsen, Vampik, Houdini", + "http://addons.miranda-im.org/details.php?action=viewfile&id=2304", + UNICODE_AWARE, + // {67848B07-83D2-49e9-8844-7E3DE268E304} + { 0x67848b07, 0x83d2, 0x49e9, { 0x88, 0x44, 0x7e, 0x3d, 0xe2, 0x68, 0xe3, 0x4 } } +}; + + + +///////////////////////////////////////////////////////////////////// +// Member Function : bOpenLogFile +// Type : Global +// Parameters : None +// Returns : Returns alway true +// Description : Open the log file in default program assoaitated +// with .log files +// References : - +// Remarks : - +// Created : 031020, 20 oktober 2003 +// Developer : KN +///////////////////////////////////////////////////////////////////// + +bool bOpenLogFile() { + SHELLEXECUTEINFO st = {0}; + st.cbSize = sizeof(st); + st.fMask = SEE_MASK_INVOKEIDLIST; + st.hwnd = NULL; + st.lpFile = sLogFilePath.c_str(); + st.nShow = SW_SHOWDEFAULT; + ShellExecuteEx(&st); + return true; +} + + +bool bWriteToFile(HANDLE hFile, const char * pszSrc, int nLen = -1) { + if (nLen < 0) + nLen = strlen(pszSrc); + DWORD dwBytesWritten; + return WriteFile(hFile, pszSrc, nLen, &dwBytesWritten, NULL) && (dwBytesWritten == (DWORD)nLen); +} + + +///////////////////////////////////////////////////////////////////// +// Member Function : LogEvent +// Type : Global +// Parameters : title - ? +// logme - ? +// Returns : void +// Description : +// +// References : - +// Remarks : - +// Created : 030928, 28 september 2003 +// Developer : KN +///////////////////////////////////////////////////////////////////// + +void LogEvent(const char * pszTitle, const char * pszLog) { + HANDLE hFile = CreateFile(sLogFilePath.c_str(), GENERIC_WRITE, FILE_SHARE_READ, 0, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + if (hFile == INVALID_HANDLE_VALUE) { + MessageBox(NULL, _T("Failed to open or create log file"), MSG_BOX_TITEL, MB_OK); + return; + } + if (SetFilePointer(hFile, 0, 0, FILE_END) == INVALID_SET_FILE_POINTER) { + MessageBox(NULL, _T("Failed to move to the end of the log file"), MSG_BOX_TITEL, MB_OK); + CloseHandle(hFile); + return; + } + + char szTmp[128]; + time_t now; + time(&now); + int nLen = strftime(szTmp, sizeof(szTmp), "%d-%m-%Y %H:%M:%S -- ", localtime(&now)); + + int nLogLen = strlen(pszLog); + while (nLogLen > 0 && (pszLog[nLogLen-1] == '\r' || pszLog[nLogLen-1] == '\n')) + nLogLen--; + + if (!bWriteToFile(hFile, szTmp, nLen) || + !bWriteToFile(hFile, pszTitle) || + !bWriteToFile(hFile, " : ") || + !bWriteToFile(hFile, pszLog, nLogLen) || + !bWriteToFile(hFile, "\r\n")) { + MessageBox(NULL, _T("Failed to write some part of the log file"), MSG_BOX_TITEL, MB_OK); + } + CloseHandle(hFile); +} + + + +///////////////////////////////////////////////////////////////////// +// Member Function : dwReadIPAddress +// Type : Global +// Parameters : pszStr - ? +// Returns : DWORD +// Description : +// +// References : - +// Remarks : - +// Created : 030826, 26 august 2003 +// Developer : KN +///////////////////////////////////////////////////////////////////// + +DWORD dwReadIPAddress(char * pszStr, bool &bError) { + DWORD ip = 0; + char *pszEnd; + for (int n = 0 ; n < 4 ; n++) { + int nVal = strtol(pszStr, &pszEnd, 10); + if (pszEnd <= pszStr || (n != 3 && pszEnd[0] != '.') || (nVal < 0 || nVal > 255)) { + bError = true; + return 0; + } + pszStr = pszEnd + 1; + ip |= nVal << ((3 - n) * 8); + } + return ip; +} + +///////////////////////////////////////////////////////////////////// +// Member Function : bReadConfigurationFile +// Type : Global +// Parameters : None +// Returns : Returns true if +// Description : +// +// References : - +// Remarks : - +// Created : 030823, 23 august 2003 +// Developer : KN +///////////////////////////////////////////////////////////////////// + +bool bReadConfigurationFile() { + CLFileShareListAccess clCritSection; + + CLFileShareNode * pclLastNode = NULL; + + char szBuf[1000]; + strcpy(szBuf, szPluginPath); + strcat(szBuf, szConfigFile); + HANDLE hFile = CreateFile(szBuf, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + if (hFile == INVALID_HANDLE_VALUE) + return false; + + char *pszCurPos = szBuf; + + bool bEof = false; + while (!bEof) { + DWORD dwBytesInBuffer = 0; + + // move rest of buffer to front + if (pszCurPos && pszCurPos != szBuf) { + dwBytesInBuffer = sizeof(szBuf) - (pszCurPos - szBuf); + memmove(szBuf, pszCurPos, dwBytesInBuffer); + } + + // append data to buffer + DWORD dwBytesRead = 0; + bEof = !ReadFile(hFile, &szBuf[dwBytesInBuffer], sizeof(szBuf) - dwBytesInBuffer, + &dwBytesRead, NULL) || dwBytesRead <= 0; + pszCurPos = szBuf; + + if (pszCurPos) { + while (pszCurPos && (pszCurPos = strstr(pszCurPos, "")) != NULL) { + pszCurPos += 7; + + char * pszColData[5] = {NULL}; + for (int n = 0 ; n < 5 ; n++) { + pszColData[n] = strstr(pszCurPos, ">"); + if (!pszColData[n]) + break; + pszColData[n] += 1; + + pszCurPos = strstr(pszColData[n], ""); + + if (!pszCurPos) + break; + pszCurPos += 1; + } + if (!pszColData[4]) + continue; + + CLFileShareNode * pcl = new CLFileShareNode(pszColData[0], pszColData[1]); + + bool bError = false; + char * pszEnd; + + pcl->st.nMaxDownloads = strtol(pszColData[2], &pszEnd, NULL); + if (!pszEnd || *pszEnd != NULL) + bError = true; + + pcl->st.dwAllowedIP = dwReadIPAddress(pszColData[3], bError); + pcl->st.dwAllowedMask = dwReadIPAddress(pszColData[4], bError); + if (bError) { + delete pcl; + continue; + } + + if (! pclLastNode) { + pclLastNode = pclFirstNode = pcl; + } else { + pclLastNode->pclNext = pcl; + pclLastNode = pcl; + } + + // refill buffer + if (!bEof && pszCurPos - szBuf > sizeof(szBuf) / 2) + break; + } + } + } + CloseHandle(hFile); + return true; +} + + +///////////////////////////////////////////////////////////////////// +// Member Function : bWriteConfigurationFile +// Type : Global +// Parameters : None +// Returns : Returns true if +// Description : +// +// References : - +// Remarks : - +// Created : 030826, 26 august 2003 +// Developer : KN +///////////////////////////////////////////////////////////////////// + +bool bWriteConfigurationFile() { + CLFileShareListAccess clCritSection; + char szBuf[1000]; + strcpy(szBuf, szPluginPath); + strcat(szBuf, szConfigFile); + HANDLE hFile = CreateFile(szBuf, GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + if (hFile == INVALID_HANDLE_VALUE) { + MessageBox(NULL, _T("Failed to open or create file ") szConfigFile, MSG_BOX_TITEL, MB_OK); + return false; + } + + DWORD dwBytesWriten = 0; + if (! WriteFile(hFile, szXmlHeader, sizeof(szXmlHeader) - 1, &dwBytesWriten, NULL)) { + MessageBox(NULL, _T("Failed to write xml header to file ") szConfigFile, MSG_BOX_TITEL, MB_OK); + } else { + CLFileShareNode * pclCur = pclFirstNode; + while (pclCur) { + DWORD dwBytesToWrite = _snprintf(szBuf, sizeof(szBuf), szXmlData , + pclCur->st.pszSrvPath, + pclCur->pszOrigRealPath, + pclCur->st.nMaxDownloads, + SplitIpAddress(pclCur->st.dwAllowedIP), + SplitIpAddress(pclCur->st.dwAllowedMask)); + + if (! WriteFile(hFile, szBuf, dwBytesToWrite, &dwBytesWriten, NULL)) { + MessageBox(NULL, _T("Failed to write xml data to file ") szConfigFile, MSG_BOX_TITEL, MB_OK); + break; + } + pclCur = pclCur->pclNext; + } + + if (! WriteFile(hFile, szXmlTail, sizeof(szXmlTail) - 1, &dwBytesWriten, NULL)) { + MessageBox(NULL, _T("Failed to write xml tail to file ") szConfigFile, MSG_BOX_TITEL, MB_OK); + } + } + SetEndOfFile(hFile); + CloseHandle(hFile); + return true; +} + + +///////////////////////////////////////////////////////////////////// +// Member Function : nAddChangeRemoveShare +// Type : Global +// Parameters : wParam - Contact handle +// lParam - ? +// Returns : static int +// Description : +// +// References : - +// Remarks : - +// Created : 030826, 26 august 2003 +// Developer : KN, Houdini, changed By Sergio Vieira Rolanski +///////////////////////////////////////////////////////////////////// + +static INT_PTR nAddChangeRemoveShare(WPARAM wParam, LPARAM lParam) { + if (!lParam) + return 1001; + + STFileShareInfo * pclNew = (STFileShareInfo*)lParam; + + // make the server path lowercase + char* pszPos = pclNew->pszSrvPath; + while (*pszPos) { + *pszPos = (char)tolower(*pszPos); + pszPos++; + } + + if (pclNew->lStructSize != sizeof(STFileShareInfo)) + return 1002; + + CLFileShareListAccess clCritSection; + bool bIsDirectory = (pclNew->pszSrvPath[strlen(pclNew->pszSrvPath)-1] == '/'); + + CLFileShareNode **pclPrev = &pclFirstNode; + CLFileShareNode * pclCur = pclFirstNode; + + // insert files after directories + if (!bIsDirectory) { + while (pclCur && pclCur->bIsDirectory()) { + pclPrev = &pclCur->pclNext; + pclCur = pclCur->pclNext; + } + } + + while (pclCur) { + if (_stricmp(pclCur->st.pszSrvPath, pclNew->pszSrvPath) == 0) { + if (pclCur->bAnyUsers()) { + // Some downloads are in progress we will try an terminate them !! + // we try for 5 sec. + pclCur->CloseAllTransfers(); + int nTryCount = 0; + do { + nTryCount++; + if (nTryCount >= 100) + return 1004; + clCritSection.Unlock(); + Sleep(50); + clCritSection.Lock(); + } while (pclCur->bAnyUsers()); + } + + if (!pclNew->pszRealPath || pclNew->pszRealPath[0] == 0) { + // remove this one + *pclPrev = pclCur->pclNext; + delete pclCur; + } else { + // update info !! + if (! pclCur->bSetInfo(pclNew)) + return 1003; + } + return !bWriteConfigurationFile(); + } + pclPrev = &pclCur->pclNext; + pclCur = pclCur->pclNext; + } + + // Node was not found we will add a new one. + CLFileShareNode* pclNewNode = new CLFileShareNode(pclNew); + pclNewNode->pclNext = *pclPrev; + *pclPrev = pclNewNode; + + /* Add by Sérgio Vieira Rolanski */ + if (pclNew->dwOptions & OPT_SEND_LINK) + SendLinkToUser(wParam, pclNew->pszSrvPath); + + return !bWriteConfigurationFile(); +} + +///////////////////////////////////////////////////////////////////// +// Member Function : nGetShare +// Type : Global +// Parameters : WPARAM - ? +// lParam - ? +// Returns : static int +// Description : +// +// References : - +// Remarks : - +// Created : 031011, 11 oktober 2003 +// Developer : KN +///////////////////////////////////////////////////////////////////// + +static INT_PTR nGetShare(WPARAM /*wParam*/, LPARAM lParam) { + if (!lParam) + return 1001; + + CLFileShareListAccess clCritSection; + + STFileShareInfo * pclShare = (STFileShareInfo*)lParam; + CLFileShareNode * pclCur = pclFirstNode; + while (pclCur) { + if (strcmp(pclCur->st.pszSrvPath, pclShare->pszSrvPath) == 0) { + if (pclShare->dwMaxRealPath <= strlen(pclCur->st.pszRealPath) + 1) + return 1003; + strcpy(pclShare->pszRealPath, pclCur->st.pszRealPath); + pclShare->dwAllowedIP = pclCur->st.dwAllowedIP; + pclShare->dwAllowedMask = pclCur->st.dwAllowedMask; + pclShare->nMaxDownloads = pclCur->st.nMaxDownloads; + pclShare->dwOptions = pclCur->st.dwOptions; + return 0; + } + pclCur = pclCur->pclNext; + } + return 1002; +} + + +///////////////////////////////////////////////////////////////////// +// Member Function : nAddChangeRemoveShare +// Type : Global +// Parameters : WPARAM - ? +// lParam - ? +// Returns : static int +// Description : +// +// References : - +// Remarks : - +// Created : 030903, 03 september 2003 +// Developer : KN +///////////////////////////////////////////////////////////////////// + +static INT_PTR nHttpGetAllShares(WPARAM /*wParam*/, LPARAM /*lParam*/) {/* + STFileShareInfo ** pTarget = (STFileShareInfo**)lParam; + CLFileShareNode * pclCur; + + CLFileShareListAccess clCritSection; + + int nShareCount = 0; + for( pclCur = pclFirstNode; pclCur ; pclCur = pclCur->pclNext) + nShareCount++; + + int nCount = 0; + *pTarget = (STFileShareInfo*)MirandaMalloc( sizeof( STFileShareInfo) * nShareCount ); + for( pclCur = pclFirstNode; pclCur ; pclCur = pclCur->pclNext) + { + // this code is not good !!! + // we need to alloc and copy psz strings also !! + memcpy( &((*pTarget)[nCount]), pclCur, sizeof( STFileShareInfo)); + nCount++; + } + */ + return 0; +} + + +///////////////////////////////////////////////////////////////////// +// Member Function : HandleNewConnection +// Type : Global +// Parameters : ch - ? +// Returns : void +// Description : +// +// References : - +// Remarks : - +// Created : 030903, 03 september 2003 +// Developer : KN +///////////////////////////////////////////////////////////////////// + +void HandleNewConnection(void *ch) { + CLHttpUser * pclUser = (CLHttpUser *)ch; + pclUser->HandleNewConnection(); + delete pclUser; +} + +///////////////////////////////////////////////////////////////////// +// Member Function : ConnectionOpen +// Type : Global +// Parameters : hNewConnection - ? +// dwRemoteIP - ? +// Returns : void +// Description : +// +// References : - +// Remarks : - +// Created : 030813, 13 august 2003 +// Developer : KN +///////////////////////////////////////////////////////////////////// + +void ConnectionOpen(HANDLE hNewConnection, DWORD dwRemoteIP) { + in_addr stAddr; + stAddr.S_un.S_addr = htonl(dwRemoteIP); + + CLHttpUser * pclUser = new CLHttpUser(hNewConnection, stAddr); + forkthread(HandleNewConnection, 0, (void*)pclUser); +} + + +///////////////////////////////////////////////////////////////////// +// Member Function : nProtoAck +// Type : Global +// Parameters : wParam - ? +// lParam - ? +// Returns : static int +// Description : +// +// References : - +// Remarks : - +// Created : 031213, 13 december 2003 +// Developer : KN +///////////////////////////////////////////////////////////////////// + +static int nProtoAck(WPARAM /*wParam*/, LPARAM lParam) { + //todo: ignore weather protos + ACKDATA *ack = (ACKDATA *)lParam; + if (ack->type != ACKTYPE_STATUS || //only send for statuses + ack->result != ACKRESULT_SUCCESS) //only successful ones + return 0; + + bIsOnline = ((int)ack->lParam != ID_STATUS_AWAY && (int)ack->lParam != ID_STATUS_NA); + /* + char szTmp[200]; + _snprintf( szTmp, sizeof( szTmp ), "%s New status %d\n" ,ack->szModule, (int)bIsOnline); + OutputDebugString( szTmp );*/ + return 0; +} + + +///////////////////////////////////////////////////////////////////// +// Member Function : nToggelAcceptConnections +// Type : Global +// Parameters : WPARAM - ? +// LPARAM - ? +// Returns : int +// Description : +// +// References : - +// Remarks : - +// Created : 031011, 11 oktober 2003 +// Developer : KN +///////////////////////////////////////////////////////////////////// + +INT_PTR nToggelAcceptConnections(WPARAM wparam, LPARAM /*lparam*/) { + CLISTMENUITEM mi = { 0 }; + mi.cbSize = sizeof(mi); + mi.flags = CMIM_NAME | CMIM_ICON; + + if (!hDirectBoundPort) { + NETLIBUSERSETTINGS nus = { 0 }; + nus.cbSize = sizeof(nus); + if (! CallService(MS_NETLIB_GETUSERSETTINGS, (WPARAM) hNetlibUser, (LPARAM) &nus)) { + Netlib_LogfT(hNetlibUser, _T("Failed to get NETLIBUSERSETTINGS using MS_NETLIB_GETUSERSETTINGS")); + } + + NETLIBBIND nlb = { 0 }; + nlb.cbSize = sizeof(NETLIBBIND); + nlb.pfnNewConnection = ConnectionOpen; + if (nus.specifyIncomingPorts && nus.szIncomingPorts && nus.szIncomingPorts[0]) + nlb.wPort = 0; + else { + //MessageBox( NULL, "Debug message using default port!", MSG_BOX_TITEL, MB_OK ); + nlb.wPort = 80; + } + hDirectBoundPort = (HANDLE) CallService(MS_NETLIB_BINDPORT, (WPARAM) hNetlibUser, (LPARAM) & nlb); + if (!hDirectBoundPort) { + char szTemp[200]; + _snprintf(szTemp, sizeof(szTemp), _T("Failed to bind to port %s\r\nThis is most likely because another program or service is using this port") , + nlb.wPort == 80 ? "80" : nus.szIncomingPorts); + MessageBox(NULL, szTemp, MSG_BOX_TITEL, MB_OK); + return 1001; + } + dwLocalPortUsed = nlb.wPort; + dwLocalIpAddress = nlb.dwInternalIP; + + mi.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_DISABLE_SERVER)); + mi.ptszName = LPGENT("Disable HTTP server"); + Netlib_Logf(hNetlibUser, mi.pszName); + } else if (hDirectBoundPort && wparam == 0) { + Netlib_CloseHandle(hDirectBoundPort); + hDirectBoundPort = 0; + mi.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_SHARE_NEW_FILE)); + mi.ptszName = LPGENT("Enable HTTP server"); + Netlib_Logf(hNetlibUser, mi.pszName); + } else { + return 0; // no changes; + } + + if (hAcceptConnectionsMenuItem) + CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hAcceptConnectionsMenuItem, (LPARAM)&mi); + + if (! bShutdownInProgress) + db_set_b(NULL, MODULE, "AcceptConnections", hDirectBoundPort != 0); + + return 0; +} + +///////////////////////////////////////////////////////////////////// +// Member Function : DllMain +// Type : Global +// Parameters : hinst - ? +// fdwReason - ? +// lpvReserved - ? +// Returns : BOOL WINAPI +// Description : +// +// References : - +// Remarks : - +// Created : 020422, 22 April 2002 +// Developer : KN +///////////////////////////////////////////////////////////////////// + +BOOL WINAPI DllMain(HINSTANCE hinst, DWORD /*fdwReason*/, LPVOID /*lpvReserved*/) { + hInstance = hinst; + return 1; +} + +///////////////////////////////////////////////////////////////////// +// Member Function : MainInit +// Type : Global +// Parameters : wparam - ? +// lparam - ? +// Returns : int +// Description : Called when system modules has been loaded +// +// References : - +// Remarks : - +// Created : 020422, 22 April 2002 +// Developer : KN +///////////////////////////////////////////////////////////////////// + +int MainInit(WPARAM /*wparam*/, LPARAM /*lparam*/) { + /* + STFileShareInfo * pShares = (STFileShareInfo *)5; + CallService(MS_HTTP_GET_ALL_SHARES, 0, (LPARAM) &pShares); + MirandaFree( pShares );*/ + + if (! bReadConfigurationFile()) { + //MessageBox( NULL, "Failed to read configuration file : " szConfigFile, MSG_BOX_TITEL, MB_OK ); + + char szRealPath[MAX_PATH]; + char szSrvPath[MAX_PATH] = {0}; + STFileShareInfo share; + + const char** p = pszDefaultShares; + while (*p) { + memset(&share, 0, sizeof(share)); + share.lStructSize = sizeof(share); + share.dwAllowedIP = 0; + share.dwAllowedMask = 0; + share.nMaxDownloads = -1; + + share.pszRealPath = szRealPath; + share.dwMaxRealPath = sizeof(szRealPath); + strcpy(share.pszRealPath, p[0]); + + share.pszSrvPath = szSrvPath; + share.dwMaxSrvPath = sizeof(szSrvPath); + strcpy(share.pszSrvPath, p[1]); + + if (CallService(MS_HTTP_ADD_CHANGE_REMOVE, 0, (LPARAM)&share)) + break; + + p += 2; + } + + bWriteConfigurationFile(); + } + + + NETLIBUSER nlu = { 0 }; + nlu.cbSize = sizeof(nlu); + nlu.flags = NUF_OUTGOING | NUF_INCOMING | NUF_TCHAR; + nlu.szSettingsModule = MODULE; + nlu.ptszDescriptiveName = _T("HTTP Server"); + hNetlibUser = (HANDLE) CallService(MS_NETLIB_REGISTERUSER, 0, (LPARAM) & nlu); + if (!hNetlibUser) { + MessageBox(NULL, _T("Failed to register NetLib user"), MSG_BOX_TITEL, MB_OK); + return 0; + } + + if (db_get_b(NULL, MODULE, "AcceptConnections", 1)) + nToggelAcceptConnections(0, 0); + + InitGuiElements(); + + return 0; +} + +///////////////////////////////////////////////////////////////////// +// Member Function : PreShutdown +// Type : Global +// Parameters : WPARAM - ? +// LPARAM - ? +// Returns : int +// Description : +// +// References : - +// Remarks : - +// Created : 030811, 11 august 2003 +// Developer : KN +///////////////////////////////////////////////////////////////////// + +int PreShutdown(WPARAM /*wparam*/, LPARAM /*lparam*/) { + { + CLFileShareListAccess clCrit; + bShutdownInProgress = true; + + for (CLFileShareNode * pclCur = pclFirstNode; pclCur ; pclCur = pclCur->pclNext) { + pclCur->CloseAllTransfers(); + } + } + + if (hDirectBoundPort) + nToggelAcceptConnections(0, 0); + + Netlib_CloseHandle(hNetlibUser); + + return 0; +} + +///////////////////////////////////////////////////////////////////// +// Member Function : nSystemShutdown +// Type : Global +// Parameters : wparam - 0 +// lparam - 0 +// Returns : int +// Description : +// +// References : - +// Remarks : - +// Created : 020428, 28 April 2002 +// Developer : KN +///////////////////////////////////////////////////////////////////// + +int nSystemShutdown(WPARAM /*wparam*/, LPARAM /*lparam*/) { + if (hEventProtoAck) + UnhookEvent(hEventProtoAck); + + while (pclFirstNode) { + CLFileShareNode * pclCur = pclFirstNode; + pclFirstNode = pclFirstNode->pclNext; + delete pclCur; + } + pclFirstNode = NULL; + + if (hEventSystemInit) { + UnhookEvent(hEventSystemInit); + hEventSystemInit = 0; + } + UnInitGuiElements(); + + db_set_b(NULL, MODULE, "IndexCreationMode", (BYTE)indexCreationMode); + FreeIndexHTMLTemplate(); + + return 0; +} + + ///////////////////////////////////////////////////////////////////// + // Member Function : MirandaPluginInfoEx & MirandaPluginInterfaces + // Type : Global + // Parameters : mirandaVersion - ? + // Returns : + // Description : + // + // References : - + // Remarks : - + // Created : 020422, 22 April 2002 + // Developer : KN, Houdini + ///////////////////////////////////////////////////////////////////// + + extern "C" __declspec(dllexport) PLUGININFOEX* MirandaPluginInfoEx(DWORD /*mirandaVersion*/) { + return &pluginInfo; + } + + ///////////////////////////////////////////////////////////////////// + // Member Function : Load + // Type : Global + // Parameters : link - ? + // Returns : int + // Description : + // + // References : - + // Remarks : - + // Created : 020422, 22 April 2002 + // Developer : KN + ///////////////////////////////////////////////////////////////////// + + extern "C" __declspec(dllexport) int Load() { + mir_getLP(&pluginInfo); + InitializeCriticalSection(&csFileShareListAccess); + + hHttpAcceptConnectionsService = CreateServiceFunction(MS_HTTP_ACCEPT_CONNECTIONS, nToggelAcceptConnections); + if (! hHttpAcceptConnectionsService) { + MessageBox(NULL, _T("Failed to CreateServiceFunction MS_HTTP_ACCEPT_CONNECTIONS"), MSG_BOX_TITEL, MB_OK); + return 0; + } + + hHttpAddChangeRemoveService = CreateServiceFunction(MS_HTTP_ADD_CHANGE_REMOVE, nAddChangeRemoveShare); + if (! hHttpAddChangeRemoveService) { + MessageBox(NULL, _T("Failed to CreateServiceFunction MS_HTTP_ADD_CHANGE_REMOVE"), MSG_BOX_TITEL, MB_OK); + return 0; + } + + hHttpGetShareService = CreateServiceFunction(MS_HTTP_GET_SHARE, nGetShare); + if (! hHttpGetShareService) { + MessageBox(NULL, _T("Failed to CreateServiceFunction MS_HTTP_GET_SHARE"), MSG_BOX_TITEL, MB_OK); + return 0; + } + + hHttpGetAllShares = CreateServiceFunction(MS_HTTP_GET_ALL_SHARES, nHttpGetAllShares); + if (! hHttpGetAllShares) { + MessageBox(NULL, _T("Failed to CreateServiceFunction MS_HTTP_GET_ALL_SHARES"), MSG_BOX_TITEL, MB_OK); + return 0; + } + + + hEventSystemInit = HookEvent(ME_SYSTEM_MODULESLOADED, MainInit); + if (!hEventSystemInit) { + MessageBox(NULL, _T("Failed to HookEvent ME_SYSTEM_MODULESLOADED"), MSG_BOX_TITEL, MB_OK); + return 0; + } + + hPreShutdown = HookEvent(ME_SYSTEM_PRESHUTDOWN, PreShutdown); + if (!hPreShutdown) { + MessageBox(NULL, _T("Failed to HookEvent ME_SYSTEM_PRESHUTDOWN"), MSG_BOX_TITEL, MB_OK); + return 0; + } + + szPluginPath[0] = 0; + if (GetModuleFileName(hInstance, szPluginPath, sizeof(szPluginPath))) { + char *str2 = strrchr(szPluginPath, '\\'); + if (str2 != NULL) { + str2[1] = NULL; + } + } + nPluginPathLen = strlen(szPluginPath); + + sLogFilePath = szPluginPath; + sLogFilePath += "HTTPServer.log"; + + if (! bInitMimeHandling()) { + MessageBox(NULL, "Failed to read configuration file : " szMimeTypeConfigFile, MSG_BOX_TITEL, MB_OK); + } + + // Plugin sweeper support + db_set_s(NULL, "Uninstall", "HTTPServer", MODULE); + + nMaxUploadSpeed = db_get_dw(NULL, MODULE, "MaxUploadSpeed", nMaxUploadSpeed); + nMaxConnectionsTotal = db_get_dw(NULL, MODULE, "MaxConnectionsTotal", nMaxConnectionsTotal); + nMaxConnectionsPerUser = db_get_dw(NULL, MODULE, "MaxConnectionsPerUser", nMaxConnectionsPerUser); + bLimitOnlyWhenOnline = db_get_b(NULL, MODULE, "LimitOnlyWhenOnline", bLimitOnlyWhenOnline) != 0; + indexCreationMode = (eIndexCreationMode) db_get_b(NULL, MODULE, "IndexCreationMode", 2); + + if (db_get_b(NULL, MODULE, "AddAcceptConMenuItem", 1)) { + CLISTMENUITEM mi; + ZeroMemory(&mi, sizeof(mi)); + mi.cbSize = sizeof(mi); + mi.flags = CMIF_TCHAR; + mi.pszContactOwner = NULL; //all contacts + mi.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_SHARE_NEW_FILE)); + mi.position = 1000085000; + mi.pszName = LPGENT("Enable HTTP server"); + mi.pszService = MS_HTTP_ACCEPT_CONNECTIONS; + hAcceptConnectionsMenuItem = Menu_AddMainMenuItem(&mi); + } + + if (indexCreationMode == INDEX_CREATION_HTML || + indexCreationMode == INDEX_CREATION_DETECT) + if (!LoadIndexHTMLTemplate()) { + indexCreationMode = INDEX_CREATION_DISABLE; + db_set_b(NULL, MODULE, "IndexCreationMode", (BYTE)indexCreationMode); + } + + hEventProtoAck = HookEvent(ME_PROTO_ACK, nProtoAck); + return 0; + } + + ///////////////////////////////////////////////////////////////////// + // Member Function : Unload + // Type : Global + // Parameters : none + // Returns : + // Description : + // + // References : - + // Remarks : - + // Created : 020422, 22 April 2002 + // Developer : KN + ///////////////////////////////////////////////////////////////////// + + extern "C" __declspec(dllexport) int Unload() { + nSystemShutdown(0, 0); + return 0; + } \ No newline at end of file diff --git a/plugins/HTTPServer/src/resource.h b/plugins/HTTPServer/src/resource.h new file mode 100644 index 0000000000..940253e98e --- /dev/null +++ b/plugins/HTTPServer/src/resource.h @@ -0,0 +1,56 @@ +//{{NO_DEPENDENCIES}} +// Âêëþ÷àåìûé ôàéë, ñîçäàííûé â Microsoft Visual C++. +// Èñïîëüçóåòñÿ D:\MNG_orig\plugins\HTTPServer\res\resource.rc +// +#define IDD_NEW_SHARE_PROPERTIES 101 +#define IDI_DISABLE_SERVER 101 +#define IDI_SHARE_NEW_FILE 102 +#define IDD_STATISTICS_VIEW 123 +#define IDR_MENU1 124 +#define IDD_OPT_HTTP_SERVER 999 +#define IDC_SPELL_TEXT 1066 +#define IDC_MAX_DOWNLOADS 1067 +#define IDC_ALLOWED_IPADDRESS 1068 +#define IDC_ALLOWED_IP_MASK 1069 +#define IDC_SHARE_NAME 1070 +#define IDC_CURRENT_SHARES 1071 +#define IDC_CURRENT_USERS 1072 +#define IDC_EXTERNAL_SRV_NAME 1073 +#define IDC_ADD_STATISTICS_MENU_ITEM 1074 +#define IDC_EXTERNAL_SRV_DEFAULT 1075 +#define IDC_WRITE_LOG_FILE 1076 +#define IDC_ACCEPT_COM_MENU_ITEM 1078 +#define IDC_TOGGLE_MASK 1080 +#define IDC_OPEN_LOG 1081 +#define IDC_SHOW_POPUPS 1082 +#define IDC_URL_ADDRESS 1085 +#define IDC_PAGE_KEYWORD 1087 +#define IDC_TEST_EXTERNALIP 1088 +#define IDC_MAX_SPEED 1090 +#define IDC_LIMIT_ONLY_WHEN_ONLINE 1091 +#define IDC_BUTTON1 1092 +#define IDC_MAX_SPEED2 1092 +#define IDC_DEFAULT_DOWNLOAD_LIMIT 1092 +#define IDC_SHOWHIDDENSHARES 1093 +#define IDC_INDEX_OFF 1094 +#define IDC_INDEX_HTML 1095 +#define IDC_INDEX_XML 1096 +#define IDC_INDEX_DETECT 1097 +#define IDC_MAX_CONN_TOTAL 1098 +#define IDC_MAX_CONN_PER_USER 1099 +#define ID_SHARELIST_OPEN 40004 +#define ID_SHARELIST_REMOVESHARE 40005 +#define ID_SHARELIST_COPYLINK 40006 +#define ID_SHARELIST_NEWSHARE 40007 +#define ID_SHARELIST_EDITSHARE 40008 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 126 +#define _APS_NEXT_COMMAND_VALUE 40009 +#define _APS_NEXT_CONTROL_VALUE 1095 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif -- cgit v1.2.3