commit 7b28a12220c7e1457051f8612c1005695f8e020b Author: LoRd_MuldeR Date: Fri Nov 21 17:11:57 2014 +0100 Initial commit. diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..df3644b --- /dev/null +++ b/.gitignore @@ -0,0 +1,13 @@ +*.exe +*.dll +*.opensdf +*.sdf +*.suo +*.user +*.dcu +*.ddp +*.local.* +/bin +/obj +/out +/tmp diff --git a/LICENSE.html b/LICENSE.html new file mode 100644 index 0000000..414611d --- /dev/null +++ b/LICENSE.html @@ -0,0 +1,616 @@ + + + + GNU Lesser General Public License v2.1 - GNU Project - Free Software Foundation (FSF) + + + +

GNU LESSER GENERAL PUBLIC LICENSE

+

+Version 2.1, February 1999 +

+ +
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+Everyone is permitted to copy and distribute verbatim copies
+of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL.  It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+ + +

Preamble

+ +

+ The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. +

+

+ This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. +

+

+ When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. +

+

+ To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. +

+

+ For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. +

+

+ We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. +

+

+ To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. +

+

+ Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. +

+

+ Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. +

+

+ When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. +

+

+ We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. +

+

+ For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. +

+

+ In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. +

+

+ Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. +

+

+ The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. +

+ +

TERMS AND CONDITIONS FOR COPYING, +DISTRIBUTION AND MODIFICATION

+ + +

+0. +This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". +

+

+ A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. +

+

+ The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) +

+

+ "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. +

+

+ Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. +

+

+1. +You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. +

+

+ You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. +

+

+2. +You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: +

+ + + +

+These requirements apply to the modified work as a whole. If identifiable +sections of that work are not derived from the Library, and can be +reasonably considered independent and separate works in themselves, then +this License, and its terms, do not apply to those sections when you +distribute them as separate works. But when you distribute the same +sections as part of a whole which is a work based on the Library, the +distribution of the whole must be on the terms of this License, whose +permissions for other licensees extend to the entire whole, and thus to +each and every part regardless of who wrote it. +

+

+Thus, it is not the intent of this section to claim rights or contest your +rights to work written entirely by you; rather, the intent is to exercise +the right to control the distribution of derivative or collective works +based on the Library. +

+

+In addition, mere aggregation of another work not based on the Library with +the Library (or with a work based on the Library) on a volume of a storage +or distribution medium does not bring the other work under the scope of +this License. +

+

+3. +You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. +

+

+ Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. +

+

+ This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. +

+

+4. +You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. +

+

+ If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. +

+

+5. +A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. +

+

+ However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. +

+

+ When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. +

+

+ If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) +

+

+ Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. +

+

+6. +As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. +

+

+ You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: +

+ + + +

+ For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. +

+

+ It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. +

+

+7. You may place library facilities that are a work +based on the Library side-by-side in a single library together with +other library facilities not covered by this License, and distribute +such a combined library, provided that the separate distribution of +the work based on the Library and of the other library facilities is +otherwise permitted, and provided that you do these two things: +

+ + + +

+8. You may not copy, modify, sublicense, link with, +or distribute the Library except as expressly provided under this +License. Any attempt otherwise to copy, modify, sublicense, link +with, or distribute the Library is void, and will automatically +terminate your rights under this License. However, parties who have +received copies, or rights, from you under this License will not have +their licenses terminated so long as such parties remain in full +compliance. +

+

+9. +You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. +

+

+10. +Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. +

+

+11. +If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. +

+

+If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. +

+

+It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. +

+

+This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. +

+

+12. +If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. +

+

+13. +The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. +

+

+Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. +

+

+14. +If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. +

+

+NO WARRANTY +

+

+15. +BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. +

+

+16. +IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. +

+ +

END OF TERMS AND CONDITIONS

+ +

How to Apply These Terms to Your New +Libraries

+

+ If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). +

+

+ To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. +

+ +
one line to give the library's name and an idea of what it does.
+Copyright (C) year  name of author
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+This library 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
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+ +

+Also add information on how to contact you by electronic and paper mail. +

+

+You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: +

+ +
Yoyodyne, Inc., hereby disclaims all copyright interest in
+the library `Frob' (a library for tweaking knobs) written
+by James Random Hacker.
+
+signature of Ty Coon, 1 April 1990
+Ty Coon, President of Vice
+
+ +

+That's all there is to it!

+ + + \ No newline at end of file diff --git a/MUtilities_VS2013.sln b/MUtilities_VS2013.sln new file mode 100644 index 0000000..18316ad --- /dev/null +++ b/MUtilities_VS2013.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2013 +VisualStudioVersion = 12.0.31101.0 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MUtilities_VS2013", "MUtilities_VS2013.vcxproj", "{55405FE1-149F-434C-9D72-4B64348D2A08}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release_Static|Win32 = Release_Static|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {55405FE1-149F-434C-9D72-4B64348D2A08}.Debug|Win32.ActiveCfg = Debug|Win32 + {55405FE1-149F-434C-9D72-4B64348D2A08}.Debug|Win32.Build.0 = Debug|Win32 + {55405FE1-149F-434C-9D72-4B64348D2A08}.Release_Static|Win32.ActiveCfg = Release_Static|Win32 + {55405FE1-149F-434C-9D72-4B64348D2A08}.Release_Static|Win32.Build.0 = Release_Static|Win32 + {55405FE1-149F-434C-9D72-4B64348D2A08}.Release|Win32.ActiveCfg = Release|Win32 + {55405FE1-149F-434C-9D72-4B64348D2A08}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/MUtilities_VS2013.vcxproj b/MUtilities_VS2013.vcxproj new file mode 100644 index 0000000..bac520c --- /dev/null +++ b/MUtilities_VS2013.vcxproj @@ -0,0 +1,145 @@ + + + + + Debug + Win32 + + + Release_Static + Win32 + + + Release + Win32 + + + + + + + + + + {55405FE1-149F-434C-9D72-4B64348D2A08} + Win32Proj + MUtilities + + + + StaticLibrary + true + v120_xp + Unicode + + + StaticLibrary + false + v120_xp + true + Unicode + + + StaticLibrary + false + v120_xp + true + Unicode + + + + + + + + + + + + + + + + $(SolutionDir)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\obj\$(Platform)\$(Configuration)\ + + + $(SolutionDir)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\obj\$(Platform)\$(Configuration)\ + + + $(SolutionDir)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\obj\$(Platform)\$(Configuration)\ + + + + + + Level3 + Disabled + WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) + MultiThreadedDebugDLL + NoExtensions + $(ProjectDir)\include;$(QTDIR)\include;$(QTDIR)\include\QtCore;$(QTDIR)\include\QtGui;%(AdditionalIncludeDirectories) + + + Windows + true + + + + + Level3 + + + Full + true + true + WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) + MultiThreadedDLL + NoExtensions + AnySuitable + Speed + true + false + Fast + false + $(ProjectDir)\include;$(QTDIR)\include;$(QTDIR)\include\QtCore;$(QTDIR)\include\QtGui;%(AdditionalIncludeDirectories) + + + Windows + true + true + true + + + + + Level3 + + + Full + true + true + WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) + MultiThreaded + NoExtensions + AnySuitable + Speed + true + false + Fast + false + $(ProjectDir)\include;$(QTDIR)\include;$(QTDIR)\include\QtCore;$(QTDIR)\include\QtGui;%(AdditionalIncludeDirectories) + + + Windows + true + true + true + + + + + + \ No newline at end of file diff --git a/MUtilities_VS2013.vcxproj.filters b/MUtilities_VS2013.vcxproj.filters new file mode 100644 index 0000000..cec3182 --- /dev/null +++ b/MUtilities_VS2013.vcxproj.filters @@ -0,0 +1,27 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Source Files + + + + + Header Files + + + \ No newline at end of file diff --git a/README.html b/README.html new file mode 100644 index 0000000..db5da66 --- /dev/null +++ b/README.html @@ -0,0 +1,32 @@ + + + + MUtilites + + + + +

MUtilities – MuldeR's Utilities for Qt

+

Copyright (C) 2004-2014 LoRd_MuldeR <MuldeR2@GMX.de>

+

Please visit http://muldersoft.com/ or https://github.com/lordmulder for more information!

+
+

+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +

+

https://www.gnu.org/licenses/lgpl-2.1.html

+
+

e.o.f.

+ + diff --git a/include/Mutils/UpdateChecker.h b/include/Mutils/UpdateChecker.h new file mode 100644 index 0000000..376e61b --- /dev/null +++ b/include/Mutils/UpdateChecker.h @@ -0,0 +1,122 @@ +/////////////////////////////////////////////////////////////////////////////// +// MuldeR's Utilities for Qt +// Copyright (C) 2004-2014 LoRd_MuldeR +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library 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 +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +// +// http://www.gnu.org/licenses/lgpl-2.1.txt +////////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include +#include + +/////////////////////////////////////////////////////////////////////////////// + +namespace MUtils { + + class UpdateCheckerInfo + { + friend class UpdateChecker; + + public: + UpdateCheckerInfo(void); + void resetInfo(void); + + const quint32 &getBuildNo(void) const { return m_buildNo; } + const QDate &getBuildDate(void) const { return m_buildDate; } + const QString &getDownloadSite(void) const { return m_downloadSite; } + const QString &getDownloadAddress(void) const { return m_downloadAddress; } + const QString &getDownloadFilename(void) const { return m_downloadFilename; } + const QString &getDownloadFilecode(void) const { return m_downloadFilecode; } + + private: + quint32 m_buildNo; + QDate m_buildDate; + QString m_downloadSite; + QString m_downloadAddress; + QString m_downloadFilename; + QString m_downloadFilecode; + }; + + // ---------------------------------------------------------------- + + class UpdateChecker : public QThread + { + Q_OBJECT + + public: + enum + { + UpdateStatus_NotStartedYet = 0, + UpdateStatus_CheckingConnection = 1, + UpdateStatus_FetchingUpdates = 2, + UpdateStatus_CompletedUpdateAvailable = 3, + UpdateStatus_CompletedNoUpdates = 4, + UpdateStatus_CompletedNewVersionOlder = 5, + UpdateStatus_ErrorNoConnection = 6, + UpdateStatus_ErrorConnectionTestFailed = 7, + UpdateStatus_ErrorFetchUpdateInfo = 8 + } + update_status_t; + + UpdateChecker(const QString &binWGet, const QString &binGnuPG, const QString &binKeys, const bool betaUpdates, const bool testMode = false); + ~UpdateChecker(void); + + const int getUpdateStatus(void) const { return m_status; } + const bool getSuccess(void) const { return m_success; }; + const int getMaximumProgress(void) const { return m_maxProgress; }; + const int getCurrentProgress(void) const { return m_progress; }; + const UpdateCheckerInfo *getUpdateInfo(void) const { return m_updateInfo; } + + protected: + void run(void); + void checkForUpdates(void); + void testKnownHosts(void); + + signals: + void statusChanged(const int status); + void progressChanged(const int progress); + void messageLogged(const QString &text); + + private: + const int m_maxProgress; + UpdateCheckerInfo *const m_updateInfo; + + const bool m_betaUpdates; + const bool m_testMode; + + const QString m_binaryWGet; + const QString m_binaryGnuPG; + const QString m_binaryKeys; + + volatile bool m_success; + + int m_status; + int m_progress; + + inline void setStatus(const int status); + inline void setProgress(const int progress); + inline void log(const QString &str1, const QString &str2 = QString(), const QString &str3 = QString(), const QString &str4 = QString()); + + bool getFile(const QString &url, const QString &outFile, unsigned int maxRedir = 5, bool *httpOk = NULL); + bool getUpdateInfo(const QString &url, const QString &outFileVers, const QString &outFileSign); + int tryContactHost(const QString &url); + bool tryUpdateMirror(UpdateCheckerInfo *updateInfo, const QString &url); + bool checkSignature(const QString &file, const QString &signature); + bool parseVersionInfo(const QString &file, UpdateCheckerInfo *updateInfo); + }; +} diff --git a/src/UpdateChecker.cpp b/src/UpdateChecker.cpp new file mode 100644 index 0000000..9b9de18 --- /dev/null +++ b/src/UpdateChecker.cpp @@ -0,0 +1,750 @@ +/////////////////////////////////////////////////////////////////////////////// +// MuldeR's Utilities for Qt +// Copyright (C) 2004-2014 LoRd_MuldeR +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library 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 +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +// +// http://www.gnu.org/licenses/lgpl-2.1.txt +////////////////////////////////////////////////////////////////////////////////// + +#include + +#include +#include +#include +#include +#include +#include +#include + +using namespace MUtils; + +/////////////////////////////////////////////////////////////////////////////// +// CONSTANTS +/////////////////////////////////////////////////////////////////////////////// + +static const char *header_id = "!Update"; +static const char *section_id = "LameXP"; + +static const char *mirror_url_postfix[] = +{ + "update.ver", + "update_beta.ver", + NULL +}; + +static const char *update_mirrors_prim[] = +{ + "http://muldersoft.com/", + "http://mulder.bplaced.net/", + "http://mulder.cwsurf.de/", + "http://mulder.6te.net/", + "http://mulder.webuda.com/", + "http://mulder.byethost13.com/", + "http://muldersoft.kilu.de/", + "http://mulder.pe.hu/", + "http://muldersoft.zxq.net/", + "http://lamexp.sourceforge.net/", + "http://lordmulder.github.io/LameXP/", + "http://lord_mulder.bitbucket.org/", + "http://www.tricksoft.de/", + NULL +}; + +static const char *update_mirrors_back[] = +{ + "http://mplayer.savedonthe.net/", + NULL +}; + +static const char *known_hosts[] = //Taken form: http://www.alexa.com/topsites !!! +{ + "http://www.163.com/", + "http://www.7-zip.org/", + "http://www.ac3filter.net/", + "http://www.amazon.com/", + "http://antergos.com/", + "http://www.aol.com/", + "http://www.apache.org/", + "http://www.apple.com/", + "http://www.adobe.com/", + "http://www.avidemux.org/", + "http://www.babylon.com/", + "http://www.baidu.com/", + "http://bandcamp.com/", + "http://www.bbc.co.uk/", + "http://www.berlios.de/", + "http://www.bing.com/", + "http://www.cnet.com/", + "http://cnzz.com/", + "http://www.codeplex.com/", + "http://qt.digia.com/", + "http://www.ebay.com/", + "http://www.equation.com/", + "http://fc2.com/", + "http://fedoraproject.org/", + "http://www.ffmpeg.org/", + "http://blog.flickr.net/en", + "http://free-codecs.com/", + "http://blog.gitorious.org/", + "http://git-scm.com/", + "http://www.gmx.net/", + "http://www.gnome.org/", + "http://www.gnu.org/", + "http://go.com/", + "http://code.google.com/", + "http://www.heise.de/", + "http://www.huffingtonpost.co.uk/", + "http://www.iana.org/", + "http://www.imdb.com/", + "http://www.imgburn.com/", + "http://imgur.com/", + "http://en.jd.com/", + "http://kannmanumdieuhrzeitschonnbierchentrinken.de/", + "http://mirrors.kernel.org/", + "http://lame.sourceforge.net/", + "http://www.libav.org/", + "http://www.linkedin.com/about-us", + "http://www.linuxmint.com/", + "http://www.livedoor.com/", + "http://www.livejournal.com/", + "http://go.mail.ru/", + "http://www.mediafire.com/", + "http://ftp.mozilla.org/", + "http://mplayerhq.hu/", + "http://www.msn.com/?st=1", + "http://oss.netfarm.it/", + "http://www.nytimes.com/", + "http://www.opera.com/", + "http://pastie.org/", + "http://www.portablefreeware.com/", + "http://qt-project.org/", + "http://www.quakelive.com/", + "http://www.seamonkey-project.org/", + "http://www.sina.com.cn/", + "http://www.sohu.com/", + "http://www.soso.com/", + "http://sourceforge.net/", + "http://www.spiegel.de/", + "http://tdm-gcc.tdragon.net/", + "http://www.tdrsmusic.com/", + "http://www.ubuntu.com/", + "http://status.twitter.com/", + "http://www.uol.com.br/", + "http://www.videohelp.com/", + "http://www.videolan.org/", + "http://virtualdub.org/", + "http://blog.virustotal.com/", + "http://weibo.com/login.php", + "http://www.wikipedia.org/", + "http://www.winamp.com/", + "http://wordpress.com/about/", + "http://xiph.org/", + "http://us.mail.yahoo.com/", + "http://www.yandex.ru/", + "http://www.youtube.com/yt/about/", + "http://www.zedo.com/", + "http://ffmpeg.zeranoe.com/", + NULL +}; + +static const int MIN_CONNSCORE = 8; +static const int VERSION_INFO_EXPIRES_MONTHS = 6; +static char *USER_AGENT_STR = "Mozilla/5.0 (X11; Linux i686; rv:7.0.1) Gecko/20111106 IceCat/7.0.1"; + +//Helper function +static int getMaxProgress(void) +{ + int counter = MIN_CONNSCORE + 2; + for(int i = 0; update_mirrors_prim[i]; i++) counter++; + for(int i = 0; update_mirrors_back[i]; i++) counter++; + return counter; +} + +//////////////////////////////////////////////////////////// +// Update Info Class +//////////////////////////////////////////////////////////// + +UpdateCheckerInfo::UpdateCheckerInfo(void) +{ + resetInfo(); +} + +void UpdateCheckerInfo::resetInfo(void) +{ + m_buildNo = 0; + m_buildDate.setDate(1900, 1, 1); + m_downloadSite.clear(); + m_downloadAddress.clear(); + m_downloadFilename.clear(); + m_downloadFilecode.clear(); +} + +//////////////////////////////////////////////////////////// +// Constructor & Destructor +//////////////////////////////////////////////////////////// + +UpdateChecker::UpdateChecker(const QString &binWGet, const QString &binGnuPG, const QString &binKeys, const bool betaUpdates, const bool testMode) +: + m_updateInfo(new UpdateCheckerInfo()), + m_binaryWGet(binWGet), + m_binaryGnuPG(binGnuPG), + m_binaryKeys(binKeys), + m_betaUpdates(betaUpdates), + m_testMode(testMode), + m_maxProgress(getMaxProgress()) +{ + m_success = false; + m_status = UpdateStatus_NotStartedYet; + m_progress = 0; + + if(m_binaryWGet.isEmpty() || m_binaryGnuPG.isEmpty() || m_binaryKeys.isEmpty()) + { + THROW("Tools not initialized correctly!"); + } +} + +UpdateChecker::~UpdateChecker(void) +{ + delete m_updateInfo; +} + +//////////////////////////////////////////////////////////// +// Protected functions +//////////////////////////////////////////////////////////// + +void UpdateChecker::run(void) +{ + qDebug("Update checker thread started!"); + + try + { + m_testMode ? testKnownHosts() : checkForUpdates(); + } + catch(const std::exception &error) + { + PRINT_ERROR("\nGURU MEDITATION !!!\n\nException error:\n%s\n", error.what()); + lamexp_fatal_exit("Unhandeled C++ exception error, application will exit!"); + } + catch(...) + { + PRINT_ERROR("\nGURU MEDITATION !!!\n\nUnknown exception error!\n"); + lamexp_fatal_exit("Unhandeled C++ exception error, application will exit!"); + } + + qDebug("Update checker thread completed."); +} + +void UpdateChecker::checkForUpdates(void) +{ + // ----- Initialization ----- // + + m_success = false; + m_updateInfo->resetInfo(); + setProgress(0); + + // ----- Test Internet Connection ----- // + + int connectionScore = 0; + int maxConnectTries = (3 * MIN_CONNSCORE) / 2; + + log("Checking internet connection..."); + setStatus(UpdateStatus_CheckingConnection); + + const int networkStatus = lamexp_network_status(); + if(networkStatus == lamexp_network_non) + { + log("", "Operating system reports that the computer is currently offline !!!"); + setProgress(m_maxProgress); + setStatus(UpdateStatus_ErrorNoConnection); + return; + } + + setProgress(1); + + // ----- Test Known Hosts Connectivity ----- // + + QStringList hostList; + for(int i = 0; known_hosts[i]; i++) + { + hostList << QString::fromLatin1(known_hosts[i]); + } + + lamexp_seed_rand(); + + while(!(hostList.isEmpty() || (connectionScore >= MIN_CONNSCORE) || (maxConnectTries < 1))) + { + switch(tryContactHost(hostList.takeAt(lamexp_rand() % hostList.count()))) + { + case 01: connectionScore += 1; break; + case 02: connectionScore += 2; break; + default: maxConnectTries -= 1; break; + } + setProgress(qBound(1, connectionScore + 1, MIN_CONNSCORE + 1)); + lamexp_sleep(64); + } + + if(connectionScore < MIN_CONNSCORE) + { + log("", "Connectivity test has failed: Internet connection appears to be broken!"); + setProgress(m_maxProgress); + setStatus(UpdateStatus_ErrorConnectionTestFailed); + return; + } + + // ----- Build Mirror List ----- // + + log("", "----", "", "Checking for updates online..."); + setStatus(UpdateStatus_FetchingUpdates); + + QStringList mirrorList; + for(int index = 0; update_mirrors_prim[index]; index++) + { + mirrorList << QString::fromLatin1(update_mirrors_prim[index]); + } + + lamexp_seed_rand(); + if(const int len = mirrorList.count()) + { + const int rounds = len * 1097; + for(int i = 0; i < rounds; i++) + { + mirrorList.swap(i % len, lamexp_rand() % len); + } + } + + for(int index = 0; update_mirrors_back[index]; index++) + { + mirrorList << QString::fromLatin1(update_mirrors_back[index]); + } + + // ----- Fetch Update Info From Server ----- // + + while(!mirrorList.isEmpty()) + { + QString currentMirror = mirrorList.takeFirst(); + setProgress(m_progress + 1); + if(!m_success) + { + if(tryUpdateMirror(m_updateInfo, currentMirror)) + { + m_success = true; + } + } + else + { + lamexp_sleep(64); + } + } + + setProgress(m_maxProgress); + + if(m_success) + { + if(m_updateInfo->m_buildNo > lamexp_version_build()) + { + setStatus(UpdateStatus_CompletedUpdateAvailable); + } + else if(m_updateInfo->m_buildNo == lamexp_version_build()) + { + setStatus(UpdateStatus_CompletedNoUpdates); + } + else + { + setStatus(UpdateStatus_CompletedNewVersionOlder); + } + } + else + { + setStatus(UpdateStatus_ErrorFetchUpdateInfo); + } +} + +void UpdateChecker::testKnownHosts(void) +{ + QStringList hostList; + for(int i = 0; known_hosts[i]; i++) + { + hostList << QString::fromLatin1(known_hosts[i]); + } + + qDebug("\n[Known Hosts]"); + log("Testing all known hosts...", "", "---"); + + int hostCount = hostList.count(); + while(!hostList.isEmpty()) + { + QString currentHost = hostList.takeFirst(); + qDebug("Testing: %s", currentHost.toLatin1().constData()); + log("", "Testing:", currentHost, ""); + QString outFile = QString("%1/%2.htm").arg(lamexp_temp_folder2(), lamexp_rand_str()); + bool httpOk = false; + if(!getFile(currentHost, outFile, 0, &httpOk)) + { + if(httpOk) + { + qWarning("\nConnectivity test was SLOW on the following site:\n%s\n", currentHost.toLatin1().constData()); + } + else + { + qWarning("\nConnectivity test FAILED on the following site:\n%s\n", currentHost.toLatin1().constData()); + } + } + log("", "---"); + QFile::remove(outFile); + } +} + +//////////////////////////////////////////////////////////// +// PRIVATE FUNCTIONS +//////////////////////////////////////////////////////////// + +void UpdateChecker::setStatus(const int status) +{ + if(m_status != status) + { + m_status = status; + emit statusChanged(status); + } +} + +void UpdateChecker::setProgress(const int progress) +{ + if(m_progress != progress) + { + m_progress = progress; + emit progressChanged(progress); + } +} + +void UpdateChecker::log(const QString &str1, const QString &str2, const QString &str3, const QString &str4) +{ + if(!str1.isNull()) emit messageLogged(str1); + if(!str2.isNull()) emit messageLogged(str2); + if(!str3.isNull()) emit messageLogged(str3); + if(!str4.isNull()) emit messageLogged(str4); +} + +int UpdateChecker::tryContactHost(const QString &url) +{ + int result = -1; bool httpOkay = false; + const QString outFile = QString("%1/%2.htm").arg(lamexp_temp_folder2(), lamexp_rand_str()); + log("", "Testing host:", url); + + if(getFile(url, outFile, 0, &httpOkay)) + { + log("Connection to host was established successfully."); + result = 2; + } + else + { + if(httpOkay) + { + log("Connection to host timed out after HTTP OK was received."); + result = 1; + } + else + { + log("Connection failed: The host could not be reached!"); + result = 0; + } + } + + QFile::remove(outFile); + return result; +} + +bool UpdateChecker::tryUpdateMirror(UpdateCheckerInfo *updateInfo, const QString &url) +{ + bool success = false; + log("", "Trying mirror:", url); + + const QString randPart = lamexp_rand_str(); + const QString outFileVers = QString("%1/%2.ver").arg(lamexp_temp_folder2(), randPart); + const QString outFileSign = QString("%1/%2.sig").arg(lamexp_temp_folder2(), randPart); + + if(getUpdateInfo(url, outFileVers, outFileSign)) + { + log("", "Download okay, checking signature:"); + if(checkSignature(outFileVers, outFileSign)) + { + log("", "Signature okay, parsing info:"); + success = parseVersionInfo(outFileVers, updateInfo); + } + else + { + log("", "Bad signature, take care!"); + } + } + else + { + log("", "Download has failed!"); + } + + QFile::remove(outFileVers); + QFile::remove(outFileSign); + + return success; +} + +bool UpdateChecker::getUpdateInfo(const QString &url, const QString &outFileVers, const QString &outFileSign) +{ + log("", "Downloading update info:"); + if(!getFile(QString("%1%2" ).arg(url, mirror_url_postfix[m_betaUpdates ? 1 : 0]), outFileVers)) + { + return false; + } + + log("", "Downloading signature:"); + if(!getFile(QString("%1%2.sig").arg(url, mirror_url_postfix[m_betaUpdates ? 1 : 0]), outFileSign)) + { + return false; + } + + return true; +} + +bool UpdateChecker::getFile(const QString &url, const QString &outFile, unsigned int maxRedir, bool *httpOk) +{ + QFileInfo output(outFile); + output.setCaching(false); + if(httpOk) *httpOk = false; + + if(output.exists()) + { + QFile::remove(output.canonicalFilePath()); + if(output.exists()) + { + return false; + } + } + + QProcess process; + lamexp_init_process(process, output.absolutePath()); + + QStringList args; + args << "-T" << "15" << "--no-cache" << "--no-dns-cache" << QString().sprintf("--max-redirect=%u", maxRedir); + args << QString("--referer=%1://%2/").arg(QUrl(url).scheme(), QUrl(url).host()) << "-U" << USER_AGENT_STR; + args << "-O" << output.fileName() << url; + + QEventLoop loop; + connect(&process, SIGNAL(error(QProcess::ProcessError)), &loop, SLOT(quit())); + connect(&process, SIGNAL(finished(int,QProcess::ExitStatus)), &loop, SLOT(quit())); + connect(&process, SIGNAL(readyRead()), &loop, SLOT(quit())); + + QTimer timer; + timer.setSingleShot(true); + timer.setInterval(25000); + connect(&timer, SIGNAL(timeout()), &loop, SLOT(quit())); + + const QRegExp httpResponseOK("200 OK$"); + + process.start(m_binaryWGet, args); + + if(!process.waitForStarted()) + { + return false; + } + + timer.start(); + + while(process.state() != QProcess::NotRunning) + { + loop.exec(); + const bool bTimeOut = (!timer.isActive()); + while(process.canReadLine()) + { + QString line = QString::fromLatin1(process.readLine()).simplified(); + if(line.contains(httpResponseOK)) + { + line.append(" [OK]"); + if(httpOk) *httpOk = true; + } + log(line); + } + if(bTimeOut) + { + qWarning("WGet process timed out <-- killing!"); + process.kill(); + process.waitForFinished(); + log("!!! TIMEOUT !!!"); + return false; + } + } + + timer.stop(); + timer.disconnect(&timer, SIGNAL(timeout()), &loop, SLOT(quit())); + + log(QString().sprintf("Exited with code %d", process.exitCode())); + return (process.exitCode() == 0) && output.exists() && output.isFile(); +} + +bool UpdateChecker::checkSignature(const QString &file, const QString &signature) +{ + if(QFileInfo(file).absolutePath().compare(QFileInfo(signature).absolutePath(), Qt::CaseInsensitive) != 0) + { + qWarning("CheckSignature: File and signature should be in same folder!"); + return false; + } + if(QFileInfo(file).absolutePath().compare(QFileInfo(m_binaryKeys).absolutePath(), Qt::CaseInsensitive) != 0) + { + qWarning("CheckSignature: File and keyring should be in same folder!"); + return false; + } + + QProcess process; + lamexp_init_process(process, QFileInfo(file).absolutePath()); + + QEventLoop loop; + connect(&process, SIGNAL(error(QProcess::ProcessError)), &loop, SLOT(quit())); + connect(&process, SIGNAL(finished(int,QProcess::ExitStatus)), &loop, SLOT(quit())); + connect(&process, SIGNAL(readyRead()), &loop, SLOT(quit())); + + process.start(m_binaryGnuPG, QStringList() << "--homedir" << "." << "--keyring" << QFileInfo(m_binaryKeys).fileName() << QFileInfo(signature).fileName() << QFileInfo(file).fileName()); + + if(!process.waitForStarted()) + { + return false; + } + + while(process.state() == QProcess::Running) + { + loop.exec(); + while(process.canReadLine()) + { + log(QString::fromLatin1(process.readLine()).simplified()); + } + } + + log(QString().sprintf("Exited with code %d", process.exitCode())); + return (process.exitCode() == 0); +} + +bool UpdateChecker::parseVersionInfo(const QString &file, UpdateCheckerInfo *updateInfo) +{ + QRegExp value("^(\\w+)=(.+)$"); + QRegExp section("^\\[(.+)\\]$"); + + QDate updateInfoDate; + updateInfo->resetInfo(); + + QFile data(file); + if(!data.open(QIODevice::ReadOnly)) + { + qWarning("Cannot open update info file for reading!"); + return false; + } + + bool inHeader = false; + bool inSection = false; + + while(!data.atEnd()) + { + QString line = QString::fromLatin1(data.readLine()).trimmed(); + if(section.indexIn(line) >= 0) + { + log(QString("Sec: [%1]").arg(section.cap(1))); + inSection = (section.cap(1).compare(section_id, Qt::CaseInsensitive) == 0); + inHeader = (section.cap(1).compare(header_id, Qt::CaseInsensitive) == 0); + continue; + } + if(inSection && (value.indexIn(line) >= 0)) + { + log(QString("Val: '%1' ==> '%2").arg(value.cap(1), value.cap(2))); + if(value.cap(1).compare("BuildNo", Qt::CaseInsensitive) == 0) + { + bool ok = false; + unsigned int temp = value.cap(2).toUInt(&ok); + if(ok) updateInfo->m_buildNo = temp; + } + else if(value.cap(1).compare("BuildDate", Qt::CaseInsensitive) == 0) + { + QDate temp = QDate::fromString(value.cap(2).trimmed(), Qt::ISODate); + if(temp.isValid()) updateInfo->m_buildDate = temp; + } + else if(value.cap(1).compare("DownloadSite", Qt::CaseInsensitive) == 0) + { + updateInfo->m_downloadSite = value.cap(2).trimmed(); + } + else if(value.cap(1).compare("DownloadAddress", Qt::CaseInsensitive) == 0) + { + updateInfo->m_downloadAddress = value.cap(2).trimmed(); + } + else if(value.cap(1).compare("DownloadFilename", Qt::CaseInsensitive) == 0) + { + updateInfo->m_downloadFilename = value.cap(2).trimmed(); + } + else if(value.cap(1).compare("DownloadFilecode", Qt::CaseInsensitive) == 0) + { + updateInfo->m_downloadFilecode = value.cap(2).trimmed(); + } + } + if(inHeader && (value.indexIn(line) >= 0)) + { + log(QString("Val: '%1' ==> '%2").arg(value.cap(1), value.cap(2))); + if(value.cap(1).compare("TimestampCreated", Qt::CaseInsensitive) == 0) + { + QDate temp = QDate::fromString(value.cap(2).trimmed(), Qt::ISODate); + if(temp.isValid()) updateInfoDate = temp; + } + } + } + + if(!updateInfoDate.isValid()) + { + updateInfo->resetInfo(); + log("WARNING: Version info timestamp is missing!"); + return false; + } + else if(updateInfoDate.addMonths(VERSION_INFO_EXPIRES_MONTHS) < lamexp_current_date_safe()) + { + updateInfo->resetInfo(); + log(QString::fromLatin1("WARNING: This version info has expired at %1!").arg(updateInfoDate.addMonths(VERSION_INFO_EXPIRES_MONTHS).toString(Qt::ISODate))); + return false; + } + else if(lamexp_current_date_safe() < updateInfoDate) + { + log("Version info is from the future, take care!"); + qWarning("Version info is from the future, take care!"); + } + + bool complete = true; + + if(!(updateInfo->m_buildNo > 0)) complete = false; + if(!(updateInfo->m_buildDate.year() >= 2010)) complete = false; + if(updateInfo->m_downloadSite.isEmpty()) complete = false; + if(updateInfo->m_downloadAddress.isEmpty()) complete = false; + if(updateInfo->m_downloadFilename.isEmpty()) complete = false; + if(updateInfo->m_downloadFilecode.isEmpty()) complete = false; + + if(!complete) + { + log("WARNING: Version info is incomplete!"); + } + + return complete; +} + +//////////////////////////////////////////////////////////// +// SLOTS +//////////////////////////////////////////////////////////// + +/*NONE*/ + +//////////////////////////////////////////////////////////// +// EVENTS +//////////////////////////////////////////////////////////// + +/*NONE*/