diff options
| author | Petr Mrázek <peterix@gmail.com> | 2020-05-19 15:13:16 +0200 |
|---|---|---|
| committer | Petr Mrázek <peterix@gmail.com> | 2020-05-19 15:13:16 +0200 |
| commit | e7f79c90764e03b3ba41af8352bdd167cd1db2b2 (patch) | |
| tree | 8664088d5bd72377feb862c6a6b7f013ebe1008a | |
| parent | 9eaa636908076d7b767e05e4dea4d579cfbbfd4b (diff) | |
| download | PrismLauncher-e7f79c90764e03b3ba41af8352bdd167cd1db2b2.tar.gz PrismLauncher-e7f79c90764e03b3ba41af8352bdd167cd1db2b2.tar.bz2 PrismLauncher-e7f79c90764e03b3ba41af8352bdd167cd1db2b2.zip | |
Remove some old forge hacks
Forge apparently removed all `.pack.xz` files without warning.
It broke a bunch of stuff, as always. But it also means we don't need some ugly code anymore.
This is removed:
- Support for 'forge-pack-xz' and the forge-specific file download compression.
- The pack200 library we no longer need.
This stays:
- The LZMA decompression library - we may still want to use it.
26 files changed, 10 insertions, 10528 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index d02dfc8b..747ec5c8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -248,7 +248,6 @@ add_subdirectory(libraries/launcher) # java based launcher part for Minecraft add_subdirectory(libraries/javacheck) # java compatibility checker add_subdirectory(libraries/xz-embedded) # xz compression add_subdirectory(libraries/quazip) # zip manipulation library -add_subdirectory(libraries/pack200) # java pack200 compression add_subdirectory(libraries/rainbow) # Qt extension for colors add_subdirectory(libraries/iconfix) # fork of Qt's QIcon loader add_subdirectory(libraries/LocalPeer) # fork of a library from Qt solutions @@ -128,35 +128,6 @@ This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL -# Pack200 - - The GNU General Public License (GPL) - - Version 2, June 1991 - - + "CLASSPATH" EXCEPTION TO THE GPL - - Certain source files distributed by Oracle America and/or its affiliates are - subject to the following clarification and special exception to the GPL, but - only where Oracle has expressly included in the particular source file's header - the words "Oracle designates this particular file as subject to the "Classpath" - exception as provided by Oracle in the LICENSE file that accompanied this code." - - Linking this library statically or dynamically with other modules is making - a combined work based on this library. Thus, the terms and conditions of - the GNU General Public License cover the whole combination. - - As a special exception, the copyright holders of this library give you - permission to link this library with independent modules to produce an - executable, regardless of the license terms of these independent modules, - and to copy and distribute the resulting executable under terms of your - choice, provided that you also meet, for each linked independent module, - the terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. If - you modify this library, you may extend this exception to your version of - the library, but you are not obligated to do so. If you do not wish to do - so, delete this exception statement from your version. - # Quazip Copyright (C) 2005-2011 Sergey A. Tachenov diff --git a/api/logic/CMakeLists.txt b/api/logic/CMakeLists.txt index 995c9d4e..50c2cb6e 100644 --- a/api/logic/CMakeLists.txt +++ b/api/logic/CMakeLists.txt @@ -305,10 +305,6 @@ set(MINECRAFT_SOURCES minecraft/AssetsUtils.h minecraft/AssetsUtils.cpp - # Forge and all things forge related - minecraft/forge/ForgeXzDownload.h - minecraft/forge/ForgeXzDownload.cpp - # Skin upload utilities minecraft/SkinUpload.cpp minecraft/SkinUpload.h @@ -495,7 +491,7 @@ set_target_properties(MultiMC_logic PROPERTIES CXX_VISIBILITY_PRESET hidden VISI generate_export_header(MultiMC_logic) # Link -target_link_libraries(MultiMC_logic xz-embedded MultiMC_unpack200 systeminfo MultiMC_quazip MultiMC_classparser ${NBT_NAME} ${ZLIB_LIBRARIES}) +target_link_libraries(MultiMC_logic systeminfo MultiMC_quazip MultiMC_classparser ${NBT_NAME} ${ZLIB_LIBRARIES}) target_link_libraries(MultiMC_logic Qt5::Core Qt5::Xml Qt5::Network Qt5::Concurrent) # Mark and export headers diff --git a/api/logic/minecraft/Library.cpp b/api/logic/minecraft/Library.cpp index a56e8110..9ff8dcdc 100644 --- a/api/logic/minecraft/Library.cpp +++ b/api/logic/minecraft/Library.cpp @@ -3,7 +3,6 @@ #include <net/Download.h> #include <net/ChecksumValidator.h> -#include <minecraft/forge/ForgeXzDownload.h> #include <Env.h> #include <FileSystem.h> @@ -88,26 +87,19 @@ QList< std::shared_ptr< NetAction > > Library::getDownloads( { options |= Net::Download::Option::AcceptLocalFiles; } - if (isForge()) + + if(sha1.size()) { - qDebug() << "XzDownload for:" << rawName() << "storage:" << storage << "url:" << url; - out.append(ForgeXzDownload::make(url, storage, entry)); + auto rawSha1 = QByteArray::fromHex(sha1.toLatin1()); + auto dl = Net::Download::makeCached(url, entry, options); + dl->addValidator(new Net::ChecksumValidator(QCryptographicHash::Sha1, rawSha1)); + qDebug() << "Checksummed Download for:" << rawName() << "storage:" << storage << "url:" << url; + out.append(dl); } else { - if(sha1.size()) - { - auto rawSha1 = QByteArray::fromHex(sha1.toLatin1()); - auto dl = Net::Download::makeCached(url, entry, options); - dl->addValidator(new Net::ChecksumValidator(QCryptographicHash::Sha1, rawSha1)); - qDebug() << "Checksummed Download for:" << rawName() << "storage:" << storage << "url:" << url; - out.append(dl); - } - else - { - out.append(Net::Download::makeCached(url, entry, options)); - qDebug() << "Download for:" << rawName() << "storage:" << storage << "url:" << url; - } + out.append(Net::Download::makeCached(url, entry, options)); + qDebug() << "Download for:" << rawName() << "storage:" << storage << "url:" << url; } return true; }; @@ -243,11 +235,6 @@ bool Library::isAlwaysStale() const return m_hint == "always-stale"; } -bool Library::isForge() const -{ - return m_hint == "forge-pack-xz"; -} - void Library::setStoragePrefix(QString prefix) { m_storagePrefix = prefix; diff --git a/api/logic/minecraft/MinecraftUpdate.cpp b/api/logic/minecraft/MinecraftUpdate.cpp index 00558e37..f9ff114d 100644 --- a/api/logic/minecraft/MinecraftUpdate.cpp +++ b/api/logic/minecraft/MinecraftUpdate.cpp @@ -14,7 +14,6 @@ */ #include "Env.h" -#include <minecraft/forge/ForgeXzDownload.h> #include "MinecraftUpdate.h" #include "MinecraftInstance.h" diff --git a/api/logic/minecraft/forge/ForgeXzDownload.cpp b/api/logic/minecraft/forge/ForgeXzDownload.cpp deleted file mode 100644 index c6465469..00000000 --- a/api/logic/minecraft/forge/ForgeXzDownload.cpp +++ /dev/null @@ -1,393 +0,0 @@ -/* Copyright 2013-2019 MultiMC Contributors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "Env.h" -#include "ForgeXzDownload.h" -#include <FileSystem.h> - -#include <QCryptographicHash> -#include <QFileInfo> -#include <QDateTime> -#include <QDir> -#include <QDebug> - -ForgeXzDownload::ForgeXzDownload(QString url, QString relative_path, MetaEntryPtr entry) : NetAction() -{ - m_entry = entry; - m_target_path = entry->getFullPath(); - m_pack200_xz_file.setFileTemplate("./dl_temp.XXXXXX"); - m_status = Job_NotStarted; - m_url_path = relative_path; - m_url = url + ".pack.xz"; -} - -void ForgeXzDownload::start() -{ - if(m_status == Job_Aborted) - { - qWarning() << "Attempt to start an aborted Download:" << m_url.toString(); - emit aborted(m_index_within_job); - return; - } - m_status = Job_InProgress; - if (!m_entry->isStale()) - { - m_status = Job_Finished; - emit succeeded(m_index_within_job); - return; - } - // can we actually create the real, final file? - if (!FS::ensureFilePathExists(m_target_path)) - { - m_status = Job_Failed; - emit failed(m_index_within_job); - return; - } - - qDebug() << "Downloading " << m_url.toString(); - QNetworkRequest request(m_url); - request.setRawHeader(QString("If-None-Match").toLatin1(), m_entry->getETag().toLatin1()); - request.setHeader(QNetworkRequest::UserAgentHeader, "MultiMC/5.0 (Cached)"); - - QNetworkReply *rep = ENV.qnam().get(request); - - m_reply.reset(rep); - connect(rep, SIGNAL(downloadProgress(qint64, qint64)), SLOT(downloadProgress(qint64, qint64))); - connect(rep, SIGNAL(finished()), SLOT(downloadFinished())); - connect(rep, SIGNAL(error(QNetworkReply::NetworkError)), SLOT(downloadError(QNetworkReply::NetworkError))); - connect(rep, SIGNAL(readyRead()), SLOT(downloadReadyRead())); -} - -void ForgeXzDownload::downloadProgress(qint64 bytesReceived, qint64 bytesTotal) -{ - m_total_progress = bytesTotal; - m_progress = bytesReceived; - emit netActionProgress(m_index_within_job, bytesReceived, bytesTotal); -} - -void ForgeXzDownload::downloadError(QNetworkReply::NetworkError error) -{ - if(error == QNetworkReply::OperationCanceledError) - { - qCritical() << "Aborted " << m_url.toString(); - m_status = Job_Aborted; - } - else - { - // error happened during download. - qCritical() << "Failed " << m_url.toString() << " with reason " << error; - m_status = Job_Failed; - } -} - -void ForgeXzDownload::failAndTryNextMirror() -{ - m_status = Job_Failed; - emit failed(m_index_within_job); -} - -void ForgeXzDownload::downloadFinished() -{ - // if the download succeeded - if (m_status != Job_Failed && m_status != Job_Aborted) - { - // nothing went wrong... - m_status = Job_Finished; - if (m_pack200_xz_file.isOpen()) - { - // we actually downloaded something! process and isntall it - decompressAndInstall(); - return; - } - else - { - // something bad happened -- on the local machine! - m_status = Job_Failed; - m_pack200_xz_file.remove(); - m_reply.reset(); - emit failed(m_index_within_job); - return; - } - } - else if(m_status == Job_Aborted) - { - m_pack200_xz_file.remove(); - m_reply.reset(); - emit failed(m_index_within_job); - emit aborted(m_index_within_job); - return; - } - // else the download failed - else - { - m_status = Job_Failed; - m_pack200_xz_file.close(); - m_pack200_xz_file.remove(); - m_reply.reset(); - failAndTryNextMirror(); - return; - } -} - -void ForgeXzDownload::downloadReadyRead() -{ - - if (!m_pack200_xz_file.isOpen()) - { - if (!m_pack200_xz_file.open()) - { - /* - * Can't open the file... the job failed - */ - m_reply->abort(); - emit failed(m_index_within_job); - return; - } - } - m_pack200_xz_file.write(m_reply->readAll()); -} - -#include "xz.h" -#include "unpack200.h" -#include <stdexcept> -#include <unistd.h> - -const size_t buffer_size = 8196; - -// NOTE: once this gets here, it can't be aborted anymore. we don't care. -void ForgeXzDownload::decompressAndInstall() -{ - // rewind the downloaded temp file - m_pack200_xz_file.seek(0); - // de-xz'd file - QTemporaryFile pack200_file("./dl_temp.XXXXXX"); - pack200_file.open(); - - bool xz_success = false; - // first, de-xz - { - uint8_t in[buffer_size]; - uint8_t out[buffer_size]; - struct xz_buf b; - struct xz_dec *s; - enum xz_ret ret; - xz_crc32_init(); - xz_crc64_init(); - s = xz_dec_init(XZ_DYNALLOC, 1 << 26); - if (s == nullptr) - { - xz_dec_end(s); - failAndTryNextMirror(); - return; - } - b.in = in; - b.in_pos = 0; - b.in_size = 0; - b.out = out; - b.out_pos = 0; - b.out_size = buffer_size; - while (!xz_success) - { - if (b.in_pos == b.in_size) - { - b.in_size = m_pack200_xz_file.read((char *)in, sizeof(in)); - b.in_pos = 0; - } - - ret = xz_dec_run(s, &b); - - if (b.out_pos == sizeof(out)) - { - auto wresult = pack200_file.write((char *)out, b.out_pos); - if (wresult < 0 || size_t(wresult) != b.out_pos) - { - // msg = "Write error\n"; - xz_dec_end(s); - failAndTryNextMirror(); - return; - } - - b.out_pos = 0; - } - - if (ret == XZ_OK) - continue; - - if (ret == XZ_UNSUPPORTED_CHECK) - { - // unsupported check. this is OK, but we should log this - continue; - } - - auto wresult = pack200_file.write((char *)out, b.out_pos); - if (wresult < 0 || size_t(wresult) != b.out_pos) - { - // write error - pack200_file.close(); - xz_dec_end(s); - return; - } - - switch (ret) - { - case XZ_STREAM_END: - xz_dec_end(s); - xz_success = true; - break; - - case XZ_MEM_ERROR: - qCritical() << "Memory allocation failed\n"; - xz_dec_end(s); - failAndTryNextMirror(); - return; - - case XZ_MEMLIMIT_ERROR: - qCritical() << "Memory usage limit reached\n"; - xz_dec_end(s); - failAndTryNextMirror(); - return; - - case XZ_FORMAT_ERROR: - qCritical() << "Not a .xz file\n"; - xz_dec_end(s); - failAndTryNextMirror(); - return; - - case XZ_OPTIONS_ERROR: - qCritical() << "Unsupported options in the .xz headers\n"; - xz_dec_end(s); - failAndTryNextMirror(); - return; - - case XZ_DATA_ERROR: - case XZ_BUF_ERROR: - qCritical() << "File is corrupt\n"; - xz_dec_end(s); - failAndTryNextMirror(); - return; - - default: - qCritical() << "Bug!\n"; - xz_dec_end(s); - failAndTryNextMirror(); - return; - } - } - } - m_pack200_xz_file.remove(); - - // revert pack200 - pack200_file.seek(0); - int handle_in = pack200_file.handle(); - // FIXME: dispose of file handles, pointers and the like. Ideally wrap in objects. - if(handle_in == -1) - { - qCritical() << "Error reopening " << pack200_file.fileName(); - failAndTryNextMirror(); - return; - } - int handle_in_dup = dup (handle_in); - if(handle_in_dup == -1) - { - qCritical() << "Error reopening " << pack200_file.fileName(); - failAndTryNextMirror(); - return; - } - FILE *file_in = fdopen (handle_in_dup, "rb"); - if(!file_in) - { - qCritical() << "Error reopening " << pack200_file.fileName(); - failAndTryNextMirror(); - return; - } - QFile qfile_out(m_target_path); - if(!qfile_out.open(QIODevice::WriteOnly)) - { - qCritical() << "Error opening " << qfile_out.fileName(); - failAndTryNextMirror(); - return; - } - int handle_out = qfile_out.handle(); - if(handle_out == -1) - { - qCritical() << "Error opening " << qfile_out.fileName(); - failAndTryNextMirror(); - return; - } - int handle_out_dup = dup (handle_out); - if(handle_out_dup == -1) - { - qCritical() << "Error reopening " << qfile_out.fileName(); - failAndTryNextMirror(); - return; - } - FILE *file_out = fdopen (handle_out_dup, "wb"); - if(!file_out) - { - qCritical() << "Error opening " << qfile_out.fileName(); - failAndTryNextMirror(); - return; - } - try - { - // NOTE: this takes ownership of both FILE pointers. That's why we duplicate them above. - unpack_200(file_in, file_out); - } - catch (const std::runtime_error &err) - { - m_status = Job_Failed; - qCritical() << "Error unpacking " << pack200_file.fileName() << " : " << err.what(); - QFile f(m_target_path); - if (f.exists()) - f.remove(); - failAndTryNextMirror(); - return; - } - pack200_file.remove(); - - QFile jar_file(m_target_path); - - if (!jar_file.open(QIODevice::ReadOnly)) - { - jar_file.remove(); - failAndTryNextMirror(); - return; - } - auto hash = QCryptographicHash::hash(jar_file.readAll(), QCryptographicHash::Md5); - m_entry->setMD5Sum(hash.toHex().constData()); - jar_file.close(); - - QFileInfo output_file_info(m_target_path); - m_entry->setETag(m_reply->rawHeader("ETag").constData()); - m_entry->setLocalChangedTimestamp(output_file_info.lastModified().toUTC().toMSecsSinceEpoch()); - m_entry->setStale(false); - ENV.metacache()->updateEntry(m_entry); - - m_reply.reset(); - emit succeeded(m_index_within_job); -} - -bool ForgeXzDownload::abort() -{ - if(m_reply) - m_reply->abort(); - m_status = Job_Aborted; - return true; -} - -bool ForgeXzDownload::canAbort() -{ - return true; -} diff --git a/api/logic/minecraft/forge/ForgeXzDownload.h b/api/logic/minecraft/forge/ForgeXzDownload.h deleted file mode 100644 index 63e75f71..00000000 --- a/api/logic/minecraft/forge/ForgeXzDownload.h +++ /dev/null @@ -1,61 +0,0 @@ -/* Copyright 2013-2019 MultiMC Contributors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include "net/NetAction.h" -#include "net/HttpMetaCache.h" -#include <QFile> -#include <QTemporaryFile> - -typedef std::shared_ptr<class ForgeXzDownload> ForgeXzDownloadPtr; - -class ForgeXzDownload : public NetAction -{ - Q_OBJECT -public: - MetaEntryPtr m_entry; - /// if saving to file, use the one specified in this string - QString m_target_path; - /// this is the output file, if any - QTemporaryFile m_pack200_xz_file; - /// path relative to the mirror base - QString m_url_path; - -public: - explicit ForgeXzDownload(QString url, QString relative_path, MetaEntryPtr entry); - static ForgeXzDownloadPtr make(QString url, QString relative_path, MetaEntryPtr entry) - { - return ForgeXzDownloadPtr(new ForgeXzDownload(url, relative_path, entry)); - } - virtual ~ForgeXzDownload(){}; - bool canAbort() override; - -protected -slots: - void downloadProgress(qint64 bytesReceived, qint64 bytesTotal) override; - void downloadError(QNetworkReply::NetworkError error) override; - void downloadFinished() override; - void downloadReadyRead() override; - -public -slots: - void start() override; - bool abort() override; - -private: - void decompressAndInstall(); - void failAndTryNextMirror(); -}; diff --git a/libraries/pack200/CMakeLists.txt b/libraries/pack200/CMakeLists.txt deleted file mode 100644 index 31eb0f73..00000000 --- a/libraries/pack200/CMakeLists.txt +++ /dev/null @@ -1,50 +0,0 @@ -cmake_minimum_required(VERSION 3.1) - -project(MultiMC_unpack200) - -option(PACK200_BUILD_BINARY "Build a tiny utility that decompresses pack200 streams" OFF) - -# Find ZLIB for quazip -find_package(ZLIB REQUIRED) - -set(PACK200_SRC - include/unpack200.h - src/bands.cpp - src/bands.h - src/bytes.cpp - src/bytes.h - src/coding.cpp - src/coding.h - src/constants.h - src/defines.h - src/unpack200.cpp - src/unpack.cpp - src/unpack.h - src/utils.cpp - src/utils.h - src/zip.cpp - src/zip.h -) - -if (Qt5_POSITION_INDEPENDENT_CODE) - SET(CMAKE_POSITION_INDEPENDENT_CODE ON) -endif() - -add_library(MultiMC_unpack200 SHARED ${PACK200_SRC}) -target_include_directories(MultiMC_unpack200 PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include" "${CMAKE_CURRENT_BINARY_DIR}" PRIVATE ${ZLIB_INCLUDE_DIRS} "${CMAKE_CURRENT_SOURCE_DIR}/src") -target_link_libraries(MultiMC_unpack200 ${ZLIB_LIBRARIES}) - -set_target_properties(MultiMC_unpack200 PROPERTIES CXX_VISIBILITY_PRESET hidden VISIBILITY_INLINES_HIDDEN 1) -generate_export_header(MultiMC_unpack200) - -# Install it -install( - TARGETS MultiMC_unpack200 - RUNTIME DESTINATION ${LIBRARY_DEST_DIR} - LIBRARY DESTINATION ${LIBRARY_DEST_DIR} -) - -if(PACK200_BUILD_BINARY) - add_executable(anti200 anti200.cpp) - target_link_libraries(anti200 MultiMC_unpack200) -endif() diff --git a/libraries/pack200/LICENSE b/libraries/pack200/LICENSE deleted file mode 100644 index b40a0f45..00000000 --- a/libraries/pack200/LICENSE +++ /dev/null @@ -1,347 +0,0 @@ -The GNU General Public License (GPL) - -Version 2, June 1991 - -Copyright (C) 1989, 1991 Free Software Foundation, Inc. -59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -Everyone is permitted to copy and distribute verbatim copies of this license -document, but changing it is not allowed. - -Preamble - -The licenses for most software are designed to take away your freedom to share -and change it. By contrast, the GNU General Public License is intended to -guarantee your freedom to share and change free software--to make sure the -software is free for all its users. This General Public License applies to -most of the Free Software Foundation's software and to any other program whose -authors commit to using it. (Some other Free Software Foundation software is -covered by the GNU Library General Public License instead.) You can apply it to -your programs, too. - -When we speak of free software, we are referring to freedom, 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 or use pieces of it in new free programs; and that you know you -can do these things. - -To protect your rights, we need to make restrictions that forbid anyone to deny -you these rights or to ask you to surrender the rights. These restrictions -translate to certain responsibilities for you if you distribute copies of the -software, or if you modify it. - -For example, if you distribute copies of such a program, whether gratis or for -a fee, you must give the recipients all the rights that you have. You must -make sure that they, too, receive or can get the source code. And you must -show them these terms so they know their rights. - -We protect your rights with two steps: (1) copyright the software, and (2) -offer you this license which gives you legal permission to copy, distribute -and/or modify the software. - -Also, for each author's protection and ours, we want to make certain that -everyone understands that there is no warranty for this free software. If the -software is modified by someone else and passed on, we want its recipients to -know that what they have is not the original, so that any problems introduced -by others will not reflect on the original authors' reputations. - -Finally, any free program is threatened constantly by software patents. We -wish to avoid the danger that redistributors of a free program will -individually obtain patent licenses, in effect making the program proprietary. -To prevent this, we have made it clear that any patent must be licensed for -everyone's free use or not licensed at all. - -The precise terms and conditions for copying, distribution and modification -follow. - -TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - -0. This License applies to any program or other work which contains a notice -placed by the copyright holder saying it may be distributed under the terms of -this General Public License. The "Program", below, refers to any such program -or work, and a "work based on the Program" means either the Program or any -derivative work under copyright law: that is to say, a work containing the -Program or a portion of it, either verbatim or with modifications and/or -translated into another language. (Hereinafter, translation is included -without limitation in the term "modification".) Each licensee is addressed as -"you". - -Activities other than copying, distribution and modification are not covered by -this License; they are outside its scope. The act of running the Program is -not restricted, and the output from the Program is covered only if its contents -constitute a work based on the Program (independent of having been made by -running the Program). Whether that is true depends on what the Program does. - -1. You may copy and distribute verbatim copies of the Program's 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 give any other recipients of the -Program a copy of this License along with the Program. - -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 Program or any portion of it, thus -forming a work based on the Program, and copy and distribute such modifications -or work under the terms of Section 1 above, provided that you also meet all of -these conditions: - - a) You must cause the modified files to carry prominent notices stating - that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in whole or - in part contains or is derived from the Program or any part thereof, to be - licensed as a whole at no charge to all third parties under the terms of - this License. - - c) If the modified program normally reads commands interactively when run, - you must cause it, when started running for such interactive use in the - most ordinary way, to print or display an announcement including an - appropriate copyright notice and a notice that there is no warranty (or - else, saying that you provide a warranty) and that users may redistribute - the program under these conditions, and telling the user how to view a copy - of this License. (Exception: if the Program itself is interactive but does - not normally print such an announcement, your work based on the Program is - not required to print an announcement.) - -These requirements apply to the modified work as a whole. If identifiable -sections of that work are not derived from the Program, 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 Program, 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 Program. - -In addition, mere aggregation of another work not based on the Pr |
