summaryrefslogtreecommitdiffstats
path: root/util/install/package/main.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'util/install/package/main.cpp')
-rw-r--r--util/install/package/main.cpp397
1 files changed, 397 insertions, 0 deletions
diff --git a/util/install/package/main.cpp b/util/install/package/main.cpp
new file mode 100644
index 0000000..39c71db
--- /dev/null
+++ b/util/install/package/main.cpp
@@ -0,0 +1,397 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the utils of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "qarchive.h"
+#include <qapplication.h>
+#include <qfileinfo.h>
+#include "keyinfo.h"
+#if defined(Q_OS_WIN32)
+#include <windows.h>
+#endif
+
+class ConsoleOutput : public QObject
+{
+ Q_OBJECT
+public:
+ ConsoleOutput() : QObject() { }
+ ~ConsoleOutput() { }
+public slots:
+ void updateProgress( const QString& str) { qDebug("%s", str.latin1()); }
+};
+
+static int usage(const char *argv0, const char *un=NULL) {
+ if(un)
+ fprintf(stderr, "Unknown command: %s\n", un);
+ else
+ fprintf(stderr, "Usage:\n");
+ fprintf(stderr, "%s [options] [keyinfo] files...\n", argv0);
+
+ fprintf(stderr, "\nOptions:\n");
+ fprintf(stderr, " -o file : Outputs archive to file\n");
+ fprintf(stderr, " -n : Follow symbolic links, do not archive the link\n");
+ fprintf(stderr, " -s : Quiet mode, will not output process\n");
+ fprintf(stderr, " -desc text : Add the description text to the archive (e.g. \"Qt 3.0.0\")\n");
+ fprintf(stderr, " -extra k v : Adds the extra value v with the key k to the archive\n");
+ fprintf(stderr, " -h : This help\n");
+
+ fprintf(stderr, "\nKey Info:\n");
+ fprintf(stderr, " -win : Windows Archive\n");
+ fprintf(stderr, " -unix : Unix Archive\n");
+ fprintf(stderr, " -mac : Mac OS X Archive\n");
+ fprintf(stderr, " -embedded : Embedded Archive\n");
+
+ fprintf(stderr, "\nThe following options are not for packaging and can't be\n" );
+ fprintf(stderr, "combined with the options above or any other option:\n\n" );
+ fprintf(stderr, " -unpack file : Unpack the archive file to the current directory\n");
+ fprintf(stderr, " -getdesc file : Print the description text of the archive file\n");
+ fprintf(stderr, " -getextra k file : Print the extra value for the key k of the archive file\n");
+#if defined(Q_OS_WIN32)
+ fprintf(stderr, " -res file1 file2 : Add the archive file1 as the binary resource\n");
+ fprintf(stderr, " QT_ARQ to the excutable file2\n");
+ fprintf(stderr, " -getres file : Get the binary resource QT_ARQ from the executable\n" );
+ fprintf(stderr, " file and store it under qt.arq\n");
+ fprintf(stderr, " -namedres RES_NAME file1 file2:\n");
+ fprintf(stderr, " Add the file1 as the binary resource\n");
+ fprintf(stderr, " RES_NAME to the excutable file2\n");
+ fprintf(stderr, " -license LICENSE file2:\n");
+ fprintf(stderr, " Add the license LICENSE as the binary resource\n");
+ fprintf(stderr, " LICENSE to the excutable file2\n");
+ fprintf(stderr, " -license-us LICENSE-US file2:\n");
+ fprintf(stderr, " Add the license LICENSE-US as the binary resource\n");
+ fprintf(stderr, " LICENSE-US to the excutable file2\n");
+#endif
+ return 665;
+}
+
+static int unpack( const char *filename, bool verbose )
+{
+ QArchive arq( filename );
+ ConsoleOutput output;
+ if ( verbose )
+ output.connect( &arq, SIGNAL(operationFeedback(const QString&)), SLOT(updateProgress(const QString&)) );
+ if ( !arq.open( IO_ReadOnly ) ) {
+ fprintf(stderr, "Can't open the archive %s file to unpack", filename);
+ return 42;
+ }
+ if ( !arq.readArchive( ".", "G87A-QJFE-DQF9" ) ) {
+ fprintf(stderr, "Couldn't unpack the archive %s", filename);
+ return 42;
+ }
+ return 0;
+}
+
+static int getdesc( const char *filename )
+{
+ QArchive arq( filename );
+ ConsoleOutput output;
+ output.connect( &arq, SIGNAL(operationFeedback(const QString&)), SLOT(updateProgress(const QString&)) );
+ if ( !arq.open( IO_ReadOnly ) ) {
+ fprintf(stderr, "Can't open the archive %s file to get description", filename);
+ return 42;
+ }
+ QArchiveHeader *header = arq.readArchiveHeader();
+ if ( !header ) {
+ fprintf(stderr, "Can't find the header in the archive %s file", filename);
+ return 42;
+ }
+ if ( !header->description().isNull() ) {
+ fprintf(stdout, header->description().latin1() );
+ }
+ return 0;
+}
+
+static int getextra( const char *key, const char *filename )
+{
+ QArchive arq( filename );
+ ConsoleOutput output;
+ output.connect( &arq, SIGNAL(operationFeedback(const QString&)), SLOT(updateProgress(const QString&)) );
+ if ( !arq.open( IO_ReadOnly ) ) {
+ fprintf(stderr, "Can't open the archive %s file to get description", filename);
+ return 42;
+ }
+ QArchiveHeader *header = arq.readArchiveHeader();
+ if ( !header ) {
+ fprintf(stderr, "Can't find the header in the archive %s file", filename);
+ return 42;
+ }
+ QString extraData = header->findExtraData(key);
+ if ( !extraData.isNull() ) {
+ fprintf(stdout, extraData.latin1() );
+ }
+ return 0;
+}
+
+
+int main( int argc, char** argv )
+{
+ uint features = 0;
+ bool output = true, doSyms = true;
+ QString desc;
+ QString dest;
+ QMap<QString,QString> extra;
+#if defined(Q_OS_WIN32)
+ QString arq, exe;
+ QString resName;
+ bool doRes = false;
+ bool doLicense = false;
+ bool doLicenseUs = false;
+ bool getRes = false;
+#endif
+ QStringList files;
+ int i;
+ for( i = 1; i < argc; i++ ) {
+ //options
+ if(!strcmp(argv[i], "-o")) {
+ if ( ++i < argc )
+ dest = argv[i];
+ else
+ return usage(argv[0]);
+ } else if(!strcmp(argv[i], "-n")) {
+ doSyms = false;
+ } else if(!strcmp(argv[i], "-s")) {
+ output = false;
+ } else if(!strcmp(argv[i], "-desc")) {
+ if ( ++i < argc )
+ desc = argv[i];
+ else
+ return usage(argv[0]);
+ } else if(!strcmp(argv[i], "-extra")) {
+ QString key, value;
+ if ( ++i < argc )
+ key = argv[i];
+ else
+ return usage(argv[0]);
+ if ( ++i < argc )
+ value = argv[i];
+ else
+ return usage(argv[0]);
+ extra.insert( key, value );
+ } else if(!strcmp(argv[i], "-h")) {
+ return usage(argv[0]);
+ //keyinfo
+ } else if(!strcmp(argv[i], "-unix")) {
+ features |= Feature_Unix;
+ } else if(!strcmp(argv[i], "-win")) {
+ features |= Feature_Windows;
+ } else if(!strcmp(argv[i], "-mac")) {
+ features |= Feature_Mac;
+ } else if(!strcmp(argv[i], "-embedded")) {
+ features |= Feature_Embedded;
+ //unpack
+ } else if(!strcmp(argv[i], "-unpack")) {
+ if ( ++i < argc )
+ return unpack( argv[i], output );
+ //getdesc
+ } else if(!strcmp(argv[i], "-getdesc")) {
+ if ( ++i < argc )
+ return getdesc( argv[i] );
+ //getextra
+ } else if(!strcmp(argv[i], "-getextra")) {
+ if ( ++i < argc ) {
+ if ( ++i < argc )
+ return getextra( argv[i-1], argv[i] );
+ }
+#if defined(Q_OS_WIN32)
+ //res (Windows only)
+ } else if(!strcmp(argv[i], "-res")) {
+ doRes = true;
+ if ( ++i < argc )
+ arq = argv[i];
+ if ( ++i < argc )
+ exe = argv[i];
+ //getres (Windows only)
+ } else if(!strcmp(argv[i], "-getres")) {
+ getRes = true;
+ if ( ++i < argc )
+ exe = argv[i];
+ //res (Windows only)
+ } else if(!strcmp(argv[i], "-namedres")) {
+ doRes = true;
+ if ( ++i < argc )
+ resName = argv[i];
+ if ( ++i < argc )
+ arq = argv[i];
+ if ( ++i < argc )
+ exe = argv[i];
+ //license (Windows only)
+ } else if(!strcmp(argv[i], "-license")) {
+ doLicense = true;
+ if ( ++i < argc )
+ arq = argv[i];
+ if ( ++i < argc )
+ exe = argv[i];
+ //licenseUs (Windows only)
+ } else if(!strcmp(argv[i], "-license-us")) {
+ doLicenseUs = true;
+ if ( ++i < argc )
+ arq = argv[i];
+ if ( ++i < argc )
+ exe = argv[i];
+#endif
+ //files
+ } else if(*(argv[i]) != '-') {
+ files.append(argv[i]);
+ //unknown
+ } else {
+ return usage(argv[0], argv[i]);
+ }
+ }
+#if defined(Q_OS_WIN32)
+ if ( doRes || doLicense || doLicenseUs ) {
+ if ( arq.isEmpty() || exe.isEmpty() )
+ return usage(argv[0], argv[i]);
+ QFile fArq( arq );
+ if ( !fArq.open( IO_ReadOnly ) ) {
+ if ( doRes ) {
+ fprintf(stderr, "Could not open archive %s", arq.latin1() );
+ } else {
+ fprintf(stderr, "Could not open license %s", arq.latin1() );
+ }
+ return -1;
+ }
+ QByteArray ba = fArq.readAll();
+ // ignore wide character versions (this is for internal use only)
+ HANDLE hExe = BeginUpdateResourceA( exe.latin1(), false );
+ if ( hExe == 0 ) {
+ fprintf(stderr, "Could not load executable %s\n", exe.latin1() );
+ qSystemWarning( "" );
+ return -1;
+ }
+ if ( resName.isEmpty() ) {
+ if ( doRes ) {
+ resName = "QT_ARQ";
+ } else if ( doLicense ){
+ resName = "LICENSE";
+ } else {
+ resName = "LICENSE-US";
+ }
+ }
+ if ( !UpdateResourceA(hExe,RT_RCDATA,resName.latin1(),0,ba.data(),ba.count()) ) {
+ EndUpdateResource( hExe, true );
+ fprintf(stderr, "Could not update executable %s\n", exe.latin1() );
+ qSystemWarning( "" );
+ return -1;
+ }
+ if ( !EndUpdateResource(hExe,false) ) {
+ fprintf(stderr, "Could not update executable %s\n", exe.latin1() );
+ qSystemWarning( "" );
+ return -1;
+ }
+ return 0;
+ }
+ if ( getRes ) {
+ if ( exe.isEmpty() )
+ return usage(argv[0], argv[i]);
+ arq = "qt.arq";
+ QFile fArq( arq );
+ if ( !fArq.open( IO_WriteOnly ) ) {
+ fprintf(stderr, "Could not open archive %s\n", arq.latin1() );
+ return -1;
+ }
+ // ignore wide character versions (this is for internal use only)
+ HMODULE hExe = LoadLibraryA( exe.latin1() );
+ if ( hExe == NULL ) {
+ fprintf(stderr, "Could not load executable %s\n", exe.latin1() );
+ qSystemWarning( "" );
+ return -1;
+ }
+ HRSRC resource = FindResource( hExe, "QT_ARQ", RT_RCDATA );
+ HGLOBAL hglobal = LoadResource( hExe, resource );
+ int arSize = SizeofResource( hExe, resource );
+ if ( arSize == 0 ) {
+ fprintf(stderr, "Could not get size of resource\n" );
+ qSystemWarning( "" );
+ return -1;
+ }
+ char *arData = (char*)LockResource( hglobal );
+ if ( arData == 0 ) {
+ fprintf(stderr, "Could not lock resource\n" );
+ qSystemWarning( "" );
+ return -1;
+ }
+ fArq.writeBlock( arData, arSize );
+ FreeLibrary( hExe );
+ return 0;
+ }
+#endif
+ if(!files.isEmpty()) {
+ if(dest.isEmpty()) {
+ qDebug("Please specify an output package");
+ return 666;
+ }
+
+ QArchive archive;
+ ConsoleOutput out;
+ if(output) {
+ QObject::connect( &archive, SIGNAL( operationFeedback( const QString& ) ),
+ &out, SLOT( updateProgress( const QString& ) ) );
+ archive.setVerbosity( QArchive::Destination | QArchive::Verbose );
+ }
+ archive.setSymbolicLinks(doSyms);
+ archive.setPath( dest );
+ if( !archive.open( IO_WriteOnly ) ) {
+ qDebug("Failed to open output %s", dest.latin1());
+ return 666;
+ }
+ QArchiveHeader header( features, desc );
+ QMap<QString,QString>::Iterator exIt;
+ for ( exIt = extra.begin(); exIt != extra.end(); ++exIt ) {
+ header.addExtraData( exIt.key(), exIt.data() );
+ }
+ archive.writeHeader( header );
+ for(QStringList::Iterator it = files.begin(); it != files.end(); ++it) {
+ QFileInfo f((*it));
+ if(!f.exists()) {
+ qDebug("Failed to open %s", (*it).latin1());
+ continue;
+ }
+ if(f.isDir())
+ archive.writeDir( (*it), true, (*it) );
+ else
+ archive.writeFile( (*it), (*it) );
+ }
+ archive.close();
+ } else {
+ return usage(argv[0]);
+ }
+ return 0;
+}
+
+#include "main.moc"