diff --git a/mozilla/toolkit/mozapps/installer/unix/Makefile.in b/mozilla/toolkit/mozapps/installer/unix/Makefile.in new file mode 100644 index 00000000000..1922c7cbc38 --- /dev/null +++ b/mozilla/toolkit/mozapps/installer/unix/Makefile.in @@ -0,0 +1,32 @@ +# +# The contents of this file are subject to the Mozilla Public +# License Version 1.1 (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.mozilla.org/MPL/ +# +# Software distributed under the License is distributed on an "AS +# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +# implied. See the License for the specific language governing +# rights and limitations under the License. +# +# The Original Code is mozilla.org code +# +# The Initial Developer of the Original Code is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 2001 Netscape Communications Corporation. All +# Rights Reserved. +# +# Contributor(s): +# + +DEPTH = ../../../.. +topsrcdir = @top_srcdir@ +srcdir = @srcdir@ +VPATH = @srcdir@ + +include $(DEPTH)/config/autoconf.mk + +DIRS = wizard + +include $(topsrcdir)/config/rules.mk + diff --git a/mozilla/toolkit/mozapps/installer/unix/wizard/Makefile.in b/mozilla/toolkit/mozapps/installer/unix/wizard/Makefile.in new file mode 100644 index 00000000000..e7d1769f090 --- /dev/null +++ b/mozilla/toolkit/mozapps/installer/unix/wizard/Makefile.in @@ -0,0 +1,87 @@ +# +# The contents of this file are subject to the Netscape Public +# License Version 1.1 (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.mozilla.org/NPL/ +# +# Software distributed under the License is distributed on an "AS +# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +# implied. See the License for the specific language governing +# rights and limitations under the License. +# +# The Original Code is Mozilla Communicator client code, +# released March 31, 1998. +# +# The Initial Developer of the Original Code is Netscape Communications +# Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All +# Rights Reserved. +# +# Contributor(s): +# Samir Gehani +# + +DEPTH = ../../../../.. +topsrcdir = @top_srcdir@ +srcdir = @srcdir@ +VPATH = @srcdir@ + +include $(DEPTH)/config/autoconf.mk + +PROGRAM = mozilla-installer-bin +REQUIRES = xpcom \ + jar \ + xpnet \ + $(NULL) + +CPPSRCS = \ + nsINIParser.cpp \ + nsXInstallerDlg.cpp \ + nsComponent.cpp \ + nsSetupType.cpp \ + nsComponentList.cpp \ + nsRunApp.cpp \ + nsLicenseDlg.cpp \ + nsWelcomeDlg.cpp \ + nsSetupTypeDlg.cpp \ + nsComponentsDlg.cpp \ + nsInstallDlg.cpp \ + nsZipExtractor.cpp \ + nsXIOptions.cpp \ + nsXIContext.cpp \ + nsXInstaller.cpp \ + nsXIEngine.cpp \ + $(NULL) + +LIBS = \ + $(TK_LIBS) \ + $(DIST)/lib/$(LIB_PREFIX)jar50_s.$(LIB_SUFFIX) \ + $(DIST)/lib/$(LIB_PREFIX)xpnet_s.$(LIB_SUFFIX) \ + -lpthread \ + $(NULL) + +EXTRA_DEPS = \ + $(DIST)/lib/$(LIB_PREFIX)jar50_s.$(LIB_SUFFIX) \ + $(DIST)/lib/$(LIB_PREFIX)xpnet_s.$(LIB_SUFFIX) \ + $(NULL) + +NO_DIST_INSTALL = 1 + +include $(topsrcdir)/config/rules.mk + +CXXFLAGS += $(TK_CFLAGS) +LOCAL_INCLUDES = -I$(topsrcdir)/xpinstall/stub + +WIZARD_FILES = \ + mozilla-installer \ + $(PROGRAM) \ + installer.ini \ + watermark.xpm \ + header.xpm \ + $(NULL) + +libs:: $(WIZARD_FILES) + $(INSTALL) $^ $(DIST)/install + +install:: $(WIZARD_FILES) + $(INSTALL) $^ $(DESTDIR)$(mozappdir)/install diff --git a/mozilla/toolkit/mozapps/installer/unix/wizard/XIDefines.h b/mozilla/toolkit/mozapps/installer/unix/wizard/XIDefines.h new file mode 100644 index 00000000000..a319cc528df --- /dev/null +++ b/mozilla/toolkit/mozapps/installer/unix/wizard/XIDefines.h @@ -0,0 +1,182 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* + * The contents of this file are subject to the Netscape Public + * License Version 1.1 (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.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is Mozilla Communicator client code, + * released March 31, 1998. + * + * The Initial Developer of the Original Code is Netscape Communications + * Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + * Samir Gehani + */ + +#ifndef _XIDEFINES_H_ +#define _XIDEFINES_H_ + +#include "XIErrors.h" +#include + + +/*--------------------------------------------------------------------* + * Limits + *--------------------------------------------------------------------*/ +#define MAX_COMPONENTS 64 +#define MAX_SETUP_TYPES 4 +#define MAX_URLS 32 +#define MAX_URL_LEN 1024 +#define MAX_DEPENDEE_KEY_LEN 16 + + +/*--------------------------------------------------------------------* + * Widget Dims + *--------------------------------------------------------------------*/ +#define XI_WIN_HEIGHT 320 +#define XI_WIN_WIDTH 550 + + +/*--------------------------------------------------------------------* + * Parse Keys + *--------------------------------------------------------------------*/ +#define GENERAL "General" +#define DEFAULT_LOCATION "Default Location" +#define PROGRAM_NAME "Program Name" + +#define DLG_WELCOME "Dialog Welcome" +#define SHOW_DLG "Show Dialog" +#define WATERMARK "Watermark" +#define TITLE "Title" +#define SUBTITLE "Sub Title" + +#define MSGWELCOME "MessageWelcome" +#define PRODUCT_NAME "Product Name" +#define README "Readme File" +#define HEADER_IMAGE "Header Image" + +#define DLG_LICENSE "Dialog License" +#define LICENSE "License File" + +#define DLG_SETUP_TYPE "Dialog Setup Type" +#define MSG0 "Message0" +#define MSG1 "Message1" +#define MSG2 "Message2" +#define SETUP_TYPE "Setup Type" +#define SETUP_TYPEd "Setup Type%d" +#define DESC_SHORT "Description Short" +#define DESC_LONG "Description Long" +#define MSGEXISTING "MessageExistingInstall" + +#define DLG_COMPONENTS "Dialog Select Components" +#define COMPONENT "Component" +#define COMPONENTd "Component%d" +#define Cd "C%d" +#define ARCHIVE "Archive" +#define URLd "URL%d" +#define INSTALL_SIZE "Install Size" +#define ARCHIVE_SIZE "Install Size Archive" +#define DEPENDENCYd "Dependency%d" +#define DEPENDEEd "Dependee%d" +#define ATTRIBUTES "Attributes" +#define SELECTED_ATTR "SELECTED" +#define INVISIBLE_ATTR "INVISIBLE" +#define LAUNCHAPP_ATTR "LAUNCHAPP" +#define DOWNLOAD_ONLY_ATTR "DOWNLOAD_ONLY" +#define MAIN_COMPONENT_ATTR "MAIN_COMPONENT" + +#define RUNAPPd "RunApp%d" +#define TARGET "Target" +#define ARGS "Arguments" + +#define DLG_START_INSTALL "Dialog Start Install" +#define XPINSTALL_ENGINE "XPInstall Engine" + + +/*--------------------------------------------------------------------* + * Macros + *--------------------------------------------------------------------*/ +#define TMP_EXTRACT_SUBDIR "bin" +#define XPI_DIR "./xpi" + +#define XPISTUB "libxpistub.so" +#define FN_INIT "XPI_Init" +#define FN_INSTALL "XPI_Install" +#define FN_EXIT "XPI_Exit" + +#define XI_IF_DELETE(_object) \ +do { \ + if (_object) \ + delete _object; \ + _object = NULL; \ +} while(0); + +#define XI_IF_FREE(_ptr) \ +do { \ + if (_ptr) \ + free(_ptr); \ + _ptr = NULL; \ +} while(0); + +#define XI_GTK_IF_FREE(_gtkWidgetPtr) \ +do { \ + if (_gtkWidgetPtr && GTK_IS_WIDGET(_gtkWidgetPtr)) \ + gtk_widget_destroy(_gtkWidgetPtr); \ + _gtkWidgetPtr = NULL; \ +} while(0); + +#define XI_ERR_BAIL(_function) \ +do { \ + err = _function; \ + if (err != OK) \ + { \ + ErrorHandler(err); \ + goto BAIL; \ + } \ +} while (0); + +#define XI_VERIFY(_ptr) \ +do { \ + if (!_ptr) \ + return ErrorHandler(E_INVALID_PTR); \ +} while (0); + +#if defined(DEBUG_sgehani) || defined(DEBUG_druidd) || defined(DEBUG_root) +#define XI_ASSERT(_expr, _msg) \ +do { \ + if (!(_expr)) \ + printf("%s %d: ASSERTION FAILED! %s \n", __FILE__, __LINE__, _msg); \ +} while(0); +#else +#define XI_ASSERT(_expr, _msg) +#endif + +#define XI_GTK_UPDATE_UI() \ +do { \ + while (gtk_events_pending()) \ + gtk_main_iteration(); \ +} while (0); + + +#ifndef TRUE +#define TRUE 1 +#endif + +#ifndef FALSE +#define FALSE 0 +#endif + +#ifndef NULL +#define NULL 0 +#endif + +#endif /* _XIDEFINES_H_ */ diff --git a/mozilla/toolkit/mozapps/installer/unix/wizard/XIErrors.h b/mozilla/toolkit/mozapps/installer/unix/wizard/XIErrors.h new file mode 100644 index 00000000000..615ac87d1ac --- /dev/null +++ b/mozilla/toolkit/mozapps/installer/unix/wizard/XIErrors.h @@ -0,0 +1,72 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* + * The contents of this file are subject to the Netscape Public + * License Version 1.1 (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.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is Mozilla Communicator client code, + * released March 31, 1998. + * + * The Initial Developer of the Original Code is Netscape Communications + * Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + * Samir Gehani + */ + +#ifndef _XI_ERRORS_H_ +#define _XI_ERRORS_H_ + +#include +#include +#include +#include +#include +#include + +/*------------------------------------------------------------------* + * X Installer Errors + *------------------------------------------------------------------*/ + enum + { + OK = 0, + E_MEM = -601, /* out of memory */ + E_PARAM = -602, /* invalid param */ + E_NO_MEMBER = -603, /* invalid member variable */ + E_INVALID_PTR = -604, /* invalid pointer */ + E_INVALID_KEY = -605, /* parse key has no value */ + E_EMPTY_README = -606, /* failed to read readme */ + E_EMPTY_LICENSE = -607, /* failed to read license */ + E_OUT_OF_BOUNDS = -608, /* out of bounds of comp/st list */ + E_REF_COUNT = -609, /* mismatched ref counts: mem leak */ + E_NO_COMPONENTS = -610, /* no components in the INI file */ + E_NO_SETUPTYPES = -611, /* no setup types in the INI file */ + E_URL_ALREADY = -612, /* URL at this index already exists */ + E_DIR_CREATE = -613, /* couldn't create the directory (tmp) */ + E_BAD_FTP_URL = -614, /* ftp url malformed */ + E_NO_DOWNLOAD = -615, /* download failed */ + E_EXTRACTION = -616, /* extraction of xpcom failed */ + E_FORK_FAILED = -617, /* failed to fork a process */ + E_LIB_OPEN = -618, /* couldn't open stub lib */ + E_LIB_SYM = -619, /* couldn't get symbol in lib */ + E_XPI_FAIL = -620, /* a xpistub call failed */ + E_INSTALL = -621, /* a .xpi failed to install */ + E_CP_FAIL = -622, /* copy of a xpi failed */ + E_NO_DEST = -623, /* destination dir doesn't exist */ + E_MKDIR_FAIL = -624, /* can't make destination dir */ + E_OLD_INST = -625, /* old instllation exists */ + E_NO_PERMS = -626, /* don't have rwx perms on selected dir */ + E_NO_DISK_SPACE = -627, /* not eough disk space to install */ + E_CRC_FAILED = -628, /* CRC failed */ + E_USAGE_SHOWN = -629 /* showed the usage message */ + }; + +#endif /* _XI_ERRORS_H_ */ diff --git a/mozilla/toolkit/mozapps/installer/unix/wizard/check_off.xpm b/mozilla/toolkit/mozapps/installer/unix/wizard/check_off.xpm new file mode 100644 index 00000000000..aa157ec64cc --- /dev/null +++ b/mozilla/toolkit/mozapps/installer/unix/wizard/check_off.xpm @@ -0,0 +1,22 @@ +/* XPM */ +static char * check_off_xpm[] = { +"15 15 4 1", +" c None", +". c #000000", +"+ c #FFFFFF", +"@ c #FEFEFE", +"...............", +"...............", +"..+@+++++++++..", +"..+++++++++++..", +"..+++++++++++..", +"..+++++++++++..", +"..+++++++++++..", +"..+++++++++++..", +"..+++++++++++..", +"..+++++++++++..", +"..+++++++++++..", +"..+++++++++++..", +"..+++++++++++..", +"...............", +"..............."}; diff --git a/mozilla/toolkit/mozapps/installer/unix/wizard/check_on.xpm b/mozilla/toolkit/mozapps/installer/unix/wizard/check_on.xpm new file mode 100644 index 00000000000..79539924450 --- /dev/null +++ b/mozilla/toolkit/mozapps/installer/unix/wizard/check_on.xpm @@ -0,0 +1,23 @@ +/* XPM */ +static char * check_on_xpm[] = { +"15 15 5 1", +" c None", +". c #000000", +"+ c #FFFFFF", +"@ c #FEFEFE", +"# c #FDFDFD", +"...............", +"...............", +"..+@+++++++++..", +"..+.+++++++.+..", +"..++.+++++.@+..", +"..+++.+++.@++..", +"..++++.+.++++..", +"..+++++.+++++..", +"..++++.@.++++..", +"..+++.+++.+++..", +"..+#.++++@.++..", +"..+.@++++++.+..", +"..+++++++++++..", +"...............", +"..............."}; diff --git a/mozilla/toolkit/mozapps/installer/unix/wizard/header.xpm b/mozilla/toolkit/mozapps/installer/unix/wizard/header.xpm new file mode 100644 index 00000000000..a6bd48041e2 --- /dev/null +++ b/mozilla/toolkit/mozapps/installer/unix/wizard/header.xpm @@ -0,0 +1,88 @@ +/* XPM */ +static char * header_xpm[] = { +"599 55 30 1", +" c None", +". c #FFFFFF", +"+ c #000000", +"@ c #060606", +"# c #1F2020", +"$ c #2C2D2D", +"% c #F6F6F6", +"& c #C5C5C5", +"* c #898989", +"= c #3E3E3E", +"- c #FCFCFC", +"; c #010304", +"> c #D8D8D8", +", c #040B0C", +"' c #5E5F5F", +") c #EDEDED", +"! c #E3E4E4", +"~ c #141414", +"{ c #130100", +"] c #250401", +"^ c #070000", +"/ c #72150A", +"( c #9D1F0F", +"_ c #C82B16", +": c #EA351D", +"< c #3A0803", +"[ c #FE3D22", +"} c #F4381E", +"| c #530E06", +"1 c #0D0C0C", +".......................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................", +".......................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................", +"......................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................+@+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++....................................................", +"......................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................+@+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++....................................................", +"......................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................+#.........................................................++....................................................", +"......................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................+$.........................................................++....................................................", +"......................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................+$.........................................................++....................................................", +"......................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................+$.........................................................++....................................................", +"......................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................+$...................%&*=#$*%-.............................;+....................................................", +"......................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................+$................->*$,;+;@@#'&>%.%)!!)%...................;+....................................................", +"......................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................+$...............>*~+++{{]]^+++#'*'$,,#'&..................++....................................................", +"......................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................+$.............%*#+++]/(_::(/<]+++@{<<<+$&.................++....................................................", +"......................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................+$............>'@++{/:[[[}}[[}|^{|(///(]+=)................;+....................................................", +"......................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................+$...........&#+++|_[[}(/|<(}:/(__(|^++]+@*................;+....................................................", +"......................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................+$.........-'1+++|:[}:|^+^|_}_((/<;{|]++++*................++....................................................", +"......................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................+$........>';;++|[[}}/+++([[:/{+;+<(/{++++*................++....................................................", +"......................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................+$.......&$++++{__([_]/^]_[}((__/+((=$++++1*%..............;+....................................................", +"......................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................+$......&#++++++]]_}__:<]_[[(]/[_{((11=$<<++=&-............;+....................................................", +"......................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................+$.....*@++++++++([::}[(<:_|]+{/[(|_/{1@{(/^+,=&)-.........++....................................................", +"......................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................+$...)*;+~#~++++/[}::::}}:({+^/_:::(|/|<]|:_<{++$*>).......++....................................................", +"......................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................+$..)'~='&*#++++([::::}[_<^+++|[(<([(<*&.-*1++++]_[:::}:_/|///||_:|^/[[:_:}::}[[:(<]@@=&)...;+....................................................", +"......................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................+$.----!';+++++<:[::[_|_[[[}[}::}_|+|:[[:::::::}[[_(<++*%..++....................................................", +"......................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................+$....&=+++++^^]_[:}}/|}::::::}[(__]+<([}::::::::}[[_]+1!..++....................................................", +"......................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................+$...&#+~'~+^|(<([:}:]/[:::::::[//[|++{/:[:::::::::[({+1!..;+....................................................", +"......................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................+$..&~~*&'@+^([__}:}:+|[}:::::}[/<(]++++<([}::::::[_]++1!..;+....................................................", +"......................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................+$.>=*>)'@+++|[}}::}:{{_[:::::}}/+{^+++++{/:[}::::[:<<],!..++....................................................", +"......................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................+$.%!.>=;$$++<}}:::}:]^|}[:::::[(+++++++++;](}[}}}:}((|1!..++....................................................", +"......................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................+$...>=~*&#++{_[:::}_+++/}}::::[_]++^^+++~$;^](:}[[[[:|1!..;+....................................................", +"......................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................+$..)''%)=++++|[}::[(^<<^(}[:::}[({+]/]++~~+@1;{|/(__:|;!..;+....................................................", +"......................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................+$..)!.)=++~++{_[::}:]|}(((_[::::[_]+/(<^+++;#~~^^++^<{~!..++....................................................", +"......................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................+$..--%'+#*=+++<:[::}_]/[[/]_[}:::}_(/:[_/<++;+$,#~~#~+'%..++....................................................", +"......................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................+$....*~'&&#;+++/}}::[_|_}:]]([[[}[[[[:_(:}(/<^+;11~#~+&-..;+....................................................", +"......................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................+$...)**.%$+@+++{_}:::[__}[_^{|(:}_(//|<+](:[:_(|;++++$)...;+....................................................", +"......................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................+$...%-.)=$'@+++]_[::::}}::[(++{<<]^+++++++]|(_:|++$'=&-...++....................................................", +"......................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................+$.....-*'&=++++([}:::::::::[(]++++++~'**'$+++]{+1'>)).-...++....................................................", +"......................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................+$.....%&!*~'~+{_[}:::::::::}[(^+++1'&%..-)&*'=$'&-........;+....................................................", +"......................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................+$.......%*&=@+{(_(_:::::::}}|^+++$&)........-%%)-.........;+....................................................", +"......................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................+$.........>$++++{|:}:::::}[/{]+;$>-.......................++....................................................", +"......................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................+$........>'~++]|(:}::::}::}/((^;&.........................++....................................................", +"......................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................+$........>$++-.........................++....................................................", +"......................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................+$............)*;+<(}[}:}_ +BACK=< Back +CANCEL=Cancel +ACCEPT=Accept +DECLINE=Decline +INSTALL=Install +PAUSE=Pause +RESUME=Resume +DEFAULT_TITLE=Mozilla Installer +DEST_DIR=Destination Directory +BROWSE=Change... +SELECT_DIR=Select a directory +DOESNT_EXIST=Directory %s doesn't exist. Create it? +YES_LABEL=Yes +NO_LABEL=No +OK_LABEL=OK +DELETE_LABEL=Delete Directory +CANCEL_LABEL=Cancel +ERROR=Error [%d]: %s +FATAL_ERROR=Fatal error [%d]: %s +DESCRIPTION=Description +WILL_INSTALL=Setup will install the following components: +TO_LOCATION=to the following location: +PREPARING=Preparing %s... +EXTRACTING=Extracting %s... +INSTALLING_XPI=Installing %s... +PROCESSING_FILE=Processing file %d of %d... +NO_PERMS=Choose another directory because you do not have permission to install to: %s +DL_SETTINGS=Download Settings +SAVE_MODULES=Save installer modules upon download +PROXY_SETTINGS=Proxy Settings... +PS_LABEL0=Proxy Host [required]: +PS_LABEL1=Proxy Port [required]: +PS_LABEL2=Proxy Username [optional]: +PS_LABEL3=Proxy Password [optional]: +ERROR_TITLE=Error! +DS_AVAIL=Disk Space Available = %ld KB +DS_REQD=Disk Space Required = %ld KB +NO_DISK_SPACE=Please select a directory on a disk with enough space to install or free some disk space on the selected disk. +CXN_DROPPED=A network connection failure occured. Please check your network connection and press the 'Resume' button. Alternatively, press the 'Cancel' button to quit the installer. +CRC_CHECK=Some files failed to download correctly. Retrying. +CRC_FAILED=Installation has failed due to multiple CRC failures. +DOWNLOADING=Downloading: +FROM=From: +TO=To: +STATUS=Status: +DL_STATUS_STR=%d KB of %d KB (at %d KB/sec) +USAGE_MSG=Usage: %s [options]%s [options] can be any of the following combination:%s -h: This help.%s -ma: Run setup in Auto mode: show progress UI,%s but assume defaults without user intervention.%s -ms: Run setup in Silent mode: show no UI and have%s no user intervention.%s -ira: Ignore the [RunAppX] sections%s +UNKNOWN=Unknown + +;------------------------------------------------------------------------------ +; Error strings +;------------------------------------------------------------------------------ + +-601=Out of memory +-602=Invalid param +-603=Invalid member variable +-604=Invalid pointer +-605=Parse key has no value +-606=Failed to read readme +-607=Failed to read license +-608=Out of bounds in Component/Setup Type list +-609=Mismatched ref counts +-610=No components in the INI file +-611=No setup types in the INI file +-612=URL at this index already exists +-613=Couldn't create the directory +-614=FTP URL malformed +-615=Download failed +-616=Extraction of XPCOM failed +-617=Failed to fork a process +-618=Couldn't open xpistub library +-619=Couldn't get symbol in library +-620=A xpistub call failed +-621=An Installer module %s (.xpi) failed to install +-622=Copy of an installer module (.xpi) failed +-623=Destination directory doesn't exist +-624=Can't make destination directory. Please try another directory. +-625=A previous installation exists. +-626=Insufficient permission +-627=Insufficient disk space +-628=Multiple CRC Failure + diff --git a/mozilla/toolkit/mozapps/installer/unix/wizard/mozilla-installer b/mozilla/toolkit/mozapps/installer/unix/wizard/mozilla-installer new file mode 100755 index 00000000000..b8287ceaf5e --- /dev/null +++ b/mozilla/toolkit/mozapps/installer/unix/wizard/mozilla-installer @@ -0,0 +1,57 @@ +#!/bin/sh +# +# The contents of this file are subject to the Netscape Public +# License Version 1.1 (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.mozilla.org/NPL/ +# +# Software distributed under the License is distributed on an "AS +# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +# implied. See the License for the specific language governing +# rights and limitations under the License. +# +# The Original Code is Mozilla Communicator client code, +# released March 31, 1998. +# +# The Initial Developer of the Original Code is Netscape Communications +# Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All +# Rights Reserved. +# +# Contributor(s): +# Samir Gehani +# + +#===================================================================== +# +# Mozilla Installer +# +# Shell script to set up environment before running the +# mozilla-installer-bin GTK based binary installer. +# +# The mozilla-installer-bin binary is an install wizard that +# collects user preferences about modules to install and where to +# install them. The program then proceeds to install Mozilla. +# +#===================================================================== + + +LD_LIBRARY_PATH=.${LD_LIBRARY_PATH+":$LD_LIBRARY_PATH"} +LIBPATH=.${LIBPATH+":$LIBPATH"} +export LD_LIBRARY_PATH LIBPATH +unset MOZILLA_FIVE_HOME + +PATH=.${PATH+":$PATH"} +export PATH + +BASEDIR=`dirname $0` +BINNAME=`basename $0` + +if [ "$BASEDIR" = "" ]; then + echo "dirname is not in your PATH" + ./${BINNAME}-bin $@ +else + cd ${BASEDIR:-.} + ./${BINNAME}-bin $@ +fi + diff --git a/mozilla/toolkit/mozapps/installer/unix/wizard/nsComponent.cpp b/mozilla/toolkit/mozapps/installer/unix/wizard/nsComponent.cpp new file mode 100644 index 00000000000..ab1a7a9dfa1 --- /dev/null +++ b/mozilla/toolkit/mozapps/installer/unix/wizard/nsComponent.cpp @@ -0,0 +1,501 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* + * The contents of this file are subject to the Netscape Public + * License Version 1.1 (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.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is Mozilla Communicator client code, + * released March 31, 1998. + * + * The Initial Developer of the Original Code is Netscape Communications + * Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + * Samir Gehani + */ + +#include "nsComponent.h" +#include + +nsComponent::nsComponent() : + mDescShort(NULL), + mDescLong(NULL), + mArchive(NULL), + mInstallSize(0), + mArchiveSize(0), + mNextDependeeIdx(0), + mAttributes(NO_ATTR), + mNext(NULL), + mIndex(-1), + mRefCount(0), + mDepRefCount(0), + mResPos(0), + mDownloaded(FALSE) +{ + int i; + + for (i = 0; i < MAX_URLS; i++) + mURL[i] = NULL; + for (i = 0; i < MAX_COMPONENTS; i++) + mDependees[i] = NULL; +} + +nsComponent::~nsComponent() +{ + int i; + + XI_IF_FREE(mDescShort); + XI_IF_FREE(mDescLong); + XI_IF_FREE(mArchive); + for (i = 0; i < MAX_URLS; i++) + XI_IF_FREE(mURL[i]); + for (i = 0; i < MAX_COMPONENTS; i++) + XI_IF_FREE(mDependees[i]); +} + +nsComponent * +nsComponent::Duplicate() +{ + nsComponent *zdup = new nsComponent(); + *zdup = *this; + zdup->InitRefCount(); + zdup->InitNext(); + + return zdup; +} + +int +nsComponent::SetDescShort(char *aDescShort) +{ + if (!aDescShort) + return E_PARAM; + + mDescShort = aDescShort; + + return OK; +} + +char * +nsComponent::GetDescShort() +{ + if (mDescShort) + return mDescShort; + + return NULL; +} + +int +nsComponent::SetDescLong(char *aDescLong) +{ + if (!aDescLong) + return E_PARAM; + + mDescLong = aDescLong; + + return OK; +} + +char * +nsComponent::GetDescLong() +{ + if (mDescLong) + return mDescLong; + + return NULL; +} + +int +nsComponent::SetArchive(char *aArchive) +{ + if (!aArchive) + return E_PARAM; + + mArchive = aArchive; + + return OK; +} + +char * +nsComponent::GetArchive() +{ + if (mArchive) + return mArchive; + + return NULL; +} + +int +nsComponent::SetInstallSize(int aInstallSize) +{ + mInstallSize = aInstallSize; + + return OK; +} + +int +nsComponent::GetInstallSize() +{ + if (mInstallSize >= 0) + return mInstallSize; + + return 0; +} + +int +nsComponent::SetArchiveSize(int aArchiveSize) +{ + mArchiveSize = aArchiveSize; + + return OK; +} + +int +nsComponent::GetArchiveSize() +{ + if (mArchiveSize >= 0) + return mArchiveSize; + + return 0; +} + +int +nsComponent::GetCurrentSize() +{ + // assumes cwd is the same as the installer binary location + + char path[MAXPATHLEN]; + struct stat stbuf; + + if (!mArchive) + return 0; + + sprintf(path, "./xpi/%s", mArchive); + if (0 != stat(path, &stbuf)) + return 0; + + return (stbuf.st_size/1024); // return size in KB +} + +int +nsComponent::SetURL(char *aURL, int aIndex) +{ + if (!aURL) + return E_PARAM; + if (mURL[aIndex]) + return E_URL_ALREADY; + + mURL[aIndex] = aURL; + + return OK; +} + +char * +nsComponent::GetURL(int aIndex) +{ + if (aIndex < 0 || aIndex >= MAX_URLS) + return NULL; + + return mURL[aIndex]; +} + +int +nsComponent::AddDependee(char *aDependee) +{ + if (!aDependee) + return E_PARAM; + + mDependees[mNextDependeeIdx] = aDependee; + mDependees[++mNextDependeeIdx] = NULL; + + return OK; +} + +int +nsComponent::ResolveDependees(int aBeingSelected, nsComponentList *aComps) +{ + int i; + nsComponent *currComp = NULL; + + // param check + if (!aComps) + return E_PARAM; + + // loop over all dependees + for (i = 0; i < mNextDependeeIdx; i++) + { + if (!mDependees[i]) + break; + + currComp = aComps->GetCompByShortDesc(mDependees[i]); + if (!currComp) + continue; + + if (aBeingSelected) + currComp->DepAddRef(); + else + currComp->DepRelease(); + } + + return OK; +} + +int +nsComponent::SetSelected() +{ + mAttributes |= nsComponent::SELECTED; + + return OK; +} + +int +nsComponent::SetUnselected() +{ + if (IsSelected()) + mAttributes &= ~nsComponent::SELECTED; + mDepRefCount = 0; + + return OK; +} + +int +nsComponent::IsSelected() +{ + if (mAttributes & nsComponent::SELECTED) + return TRUE; + + return FALSE; +} + +int +nsComponent::SetInvisible() +{ + mAttributes |= nsComponent::INVISIBLE; + + return OK; +} + +int +nsComponent::SetVisible() +{ + if (IsInvisible()) + mAttributes &= ~nsComponent::INVISIBLE; + + return OK; +} + +int +nsComponent::IsInvisible() +{ + if (mAttributes & nsComponent::INVISIBLE) + return TRUE; + + return FALSE; +} + +int +nsComponent::SetLaunchApp() +{ + mAttributes |= nsComponent::LAUNCHAPP; + + return OK; +} + +int +nsComponent::SetDontLaunchApp() +{ + if (IsLaunchApp()) + mAttributes &= ~nsComponent::LAUNCHAPP; + + return OK; +} + +int +nsComponent::IsLaunchApp() +{ + if (mAttributes & nsComponent::LAUNCHAPP) + return TRUE; + + return FALSE; +} + +int +nsComponent::SetDownloadOnly() +{ + mAttributes |= nsComponent::DOWNLOAD_ONLY; + + return OK; +} + +int +nsComponent::IsDownloadOnly() +{ + if (mAttributes & nsComponent::DOWNLOAD_ONLY) + return TRUE; + + return FALSE; +} + +int +nsComponent::SetMainComponent() +{ + mAttributes |= nsComponent::MAIN_COMPONENT; + + return OK; +} + +int +nsComponent::IsMainComponent() +{ + if (mAttributes & nsComponent::MAIN_COMPONENT) + return TRUE; + + return FALSE; +} + +int +nsComponent::SetNext(nsComponent *aComponent) +{ + if (!aComponent) + return E_PARAM; + + mNext = aComponent; + + return OK; +} + +int +nsComponent::InitNext() +{ + mNext = NULL; + + return OK; +} + +nsComponent * +nsComponent::GetNext() +{ + if (mNext) + return mNext; + + return NULL; +} + +int +nsComponent::SetIndex(int aIndex) +{ + if (aIndex < 0 || aIndex > MAX_COMPONENTS) + return E_OUT_OF_BOUNDS; + + mIndex = aIndex; + + return OK; +} + +int +nsComponent::GetIndex() +{ + if (mIndex < 0 || mIndex > MAX_COMPONENTS) + return E_OUT_OF_BOUNDS; + + return mIndex; +} + +int +nsComponent::AddRef() +{ + mRefCount++; + + return OK; +} + +int +nsComponent::Release() +{ + mRefCount--; + + if (mRefCount < 0) + return E_REF_COUNT; + + if (mRefCount == 0) + delete this; + + return OK; +} + +int +nsComponent::InitRefCount() +{ + mRefCount = 1; + + return OK; +} + +int +nsComponent::DepAddRef() +{ + if (mDepRefCount == 0) + SetSelected(); + + mDepRefCount++; + + return OK; +} + +int +nsComponent::DepRelease() +{ + mDepRefCount--; + + if (mDepRefCount < 0) + mDepRefCount = 0; + + if (mDepRefCount == 0) + SetUnselected(); + + return OK; +} + +int +nsComponent::DepGetRefCount() +{ + return mDepRefCount; +} + +int +nsComponent::SetResumePos(int aResPos) +{ + mResPos = aResPos; + + return OK; +} + +int +nsComponent::GetResumePos() +{ + if (mResPos > 0) + return mResPos; + + return 0; +} + +int +nsComponent::SetDownloaded( int which ) +{ + mDownloaded = which; + + return OK; +} + +int +nsComponent::IsDownloaded() +{ + return mDownloaded; +} diff --git a/mozilla/toolkit/mozapps/installer/unix/wizard/nsComponent.h b/mozilla/toolkit/mozapps/installer/unix/wizard/nsComponent.h new file mode 100644 index 00000000000..eb8a2860bf2 --- /dev/null +++ b/mozilla/toolkit/mozapps/installer/unix/wizard/nsComponent.h @@ -0,0 +1,123 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* + * The contents of this file are subject to the Netscape Public + * License Version 1.1 (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.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is Mozilla Communicator client code, + * released March 31, 1998. + * + * The Initial Developer of the Original Code is Netscape Communications + * Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + * Samir Gehani + */ + +#ifndef _NS_COMPONENT_H_ +#define _NS_COMPONENT_H_ + +#include "XIDefines.h" +#include "XIErrors.h" +#include + +#include "nsComponentList.h" + +class nsComponent +{ +public: + nsComponent(); + ~nsComponent(); + + nsComponent * Duplicate(); + +/*--------------------------------------------------------------* + * Accessors/Mutators + *--------------------------------------------------------------*/ + int SetDescShort(char *aDescShort); + char * GetDescShort(); + int SetDescLong(char *aDescLong); + char * GetDescLong(); + int SetArchive(char *aAcrhive); + char * GetArchive(); + int SetInstallSize(int aInstallSize); + int GetInstallSize(); + int SetArchiveSize(int aArchiveSize); + int GetArchiveSize(); + int GetCurrentSize(); + int SetURL(char *aURL, int aIndex); + char * GetURL(int aIndex); + int AddDependee(char *aDependee); + int ResolveDependees(int aBeingSelected, + nsComponentList *aComps); + int SetSelected(); + int SetUnselected(); + int IsSelected(); + int SetInvisible(); + int SetVisible(); + int IsInvisible(); + int SetLaunchApp(); + int SetDontLaunchApp(); + int IsLaunchApp(); + int SetDownloadOnly(); + int IsDownloadOnly(); + int SetMainComponent(); + int IsMainComponent(); + int SetNext(nsComponent *aComponent); + int InitNext(); + nsComponent *GetNext(); + int SetIndex(int aIndex); + int GetIndex(); + int AddRef(); + int Release(); + int InitRefCount(); + + // used for `dependee' tracking + int DepAddRef(); + int DepRelease(); + int DepGetRefCount(); + int SetResumePos(int aResPos); + int GetResumePos(); + int SetDownloaded(int which); + int IsDownloaded(); + +/*---------------------------------------------------------------* + * Attributes + *---------------------------------------------------------------*/ + enum + { + NO_ATTR = 0x00000000, + SELECTED = 0x00000001, + INVISIBLE = 0x00000010, + LAUNCHAPP = 0x00000100, + DOWNLOAD_ONLY = 0x00001000, + MAIN_COMPONENT = 0x00010000 + }; + +private: + char *mDescShort; + char *mDescLong; + char *mArchive; + int mInstallSize; + int mArchiveSize; + char *mURL[MAX_URLS]; + char *mDependees[MAX_COMPONENTS]; + int mNextDependeeIdx; + int mAttributes; + nsComponent *mNext; + int mIndex; + int mRefCount; + int mDepRefCount; + int mResPos; + int mDownloaded; +}; + +#endif /* _NS_COMPONENT_H_ */ diff --git a/mozilla/toolkit/mozapps/installer/unix/wizard/nsComponentList.cpp b/mozilla/toolkit/mozapps/installer/unix/wizard/nsComponentList.cpp new file mode 100644 index 00000000000..05b5308fbdb --- /dev/null +++ b/mozilla/toolkit/mozapps/installer/unix/wizard/nsComponentList.cpp @@ -0,0 +1,295 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* + * The contents of this file are subject to the Netscape Public + * License Version 1.1 (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.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is Mozilla Communicator client code, + * released March 31, 1998. + * + * The Initial Developer of the Original Code is Netscape Communications + * Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + * Samir Gehani + */ + +#include "nsComponentList.h" +#include "nsComponent.h" + +nsComponentList::nsComponentList() : + mHead(NULL), + mTail(NULL), + mNext(NULL), + mLength(0) +{ +} + +nsComponentList::~nsComponentList() +{ + nsComponent *curr = mHead; + nsComponent *next = NULL; + + while (curr) + { + next = NULL; + next = curr->GetNext(); + curr->Release(); + curr = next; + } + + mHead = NULL; + mTail = NULL; + mLength = 0; +} + +nsComponent * +nsComponentList::GetHead() +{ + if (mHead) + { + mNext = mHead->GetNext(); + return mHead; + } + + return NULL; +} + +nsComponent * +nsComponentList::GetNext() +{ + nsComponent *curr = mNext; + + if (mNext) + { + mNext = mNext->GetNext(); + return curr; + } + + return NULL; +} + +nsComponent * +nsComponentList::GetTail() +{ + if (mTail) + return mTail; + + return NULL; +} + +int +nsComponentList::GetLength() +{ + return mLength; +} + +int +nsComponentList::GetLengthVisible() +{ + int numVisible = 0; + nsComponent *curr; + + curr = mHead; + if (!curr) return 0; + + while (curr) + { + if (!curr->IsInvisible()) + numVisible++; + curr = curr->GetNext(); + } + + return numVisible; +} + +int +nsComponentList::GetLengthSelected() +{ + int numSelected = 0; + nsComponent *curr; + + /* NOTE: + * ---- + * If copies of components are help by this list rather than pointers + * then this method will return an inaccurate number. Due to + * architecture be very careful when using this method. + */ + + curr = mHead; + if (!curr) return 0; + + while (curr) + { + if (!curr->IsSelected()) + numSelected++; + curr = curr->GetNext(); + } + + return numSelected; +} + +int +nsComponentList::AddComponent(nsComponent *aComponent) +{ + if (!aComponent) + return E_PARAM; + + // empty list: head and tail are the same -- the new comp + if (!mHead) + { + mHead = aComponent; + mHead->InitNext(); + mTail = mHead; + aComponent->AddRef(); + mLength = 1; + mHead->SetIndex(0); + + return OK; + } + + // non-empty list: the new comp is tacked on and tail is updated + mTail->SetNext(aComponent); + mTail = aComponent; + mTail->InitNext(); + aComponent->AddRef(); + mLength++; + mTail->SetIndex(mLength - 1); + + return OK; +} + +int +nsComponentList::RemoveComponent(nsComponent *aComponent) +{ + int err = OK; + nsComponent *curr = GetHead(); + nsComponent *last = NULL; + + if (!aComponent) + return E_PARAM; + + while (curr) + { + if (aComponent == curr) + { + // remove and link last to next while deleting current + if (last) + { + last->SetNext(curr->GetNext()); + } + else + { + mHead = curr->GetNext(); + if (mTail == curr) + mTail = NULL; + } + + aComponent->Release(); + mLength--; + + return OK; + } + else + { + // move on to next + last = curr; + curr = GetNext(); + } + } + + return err; +} + +nsComponent * +nsComponentList::GetCompByIndex(int aIndex) +{ + nsComponent *comp = GetHead(); + int i; + + // param check + if (!comp || mLength == 0) return NULL; + + for (i=0; iGetIndex()) + return comp; + + comp = GetNext(); + if (!comp) break; + } + + return NULL; +} + +nsComponent * +nsComponentList::GetCompByArchive(char *aArchive) +{ + nsComponent *comp = GetHead(); + int i; + + // param check + if (!comp || mLength == 0 || !aArchive) return NULL; + + for (i=0; iGetArchive(), strlen(aArchive))) + return comp; + + comp = GetNext(); + if (!comp) break; + } + + return NULL; +} + +nsComponent * +nsComponentList::GetCompByShortDesc(char *aShortDesc) +{ + nsComponent *comp = GetHead(); + int i; + + // param check + if (!comp || mLength == 0 || !aShortDesc) return NULL; + + for (i=0; iGetDescShort(), + strlen(aShortDesc))) + return comp; + + comp = GetNext(); + if (!comp) break; + } + + return NULL; +} + +nsComponent * +nsComponentList::GetFirstVisible() +{ + int i; + nsComponent *comp = GetHead(); + + // param check + if (mLength == 0) return NULL; + + for (i=0; iIsInvisible()) + return comp; + + comp = GetNext(); + if (!comp) break; + } + + return NULL; +} diff --git a/mozilla/toolkit/mozapps/installer/unix/wizard/nsComponentList.h b/mozilla/toolkit/mozapps/installer/unix/wizard/nsComponentList.h new file mode 100644 index 00000000000..a74f5a4e39c --- /dev/null +++ b/mozilla/toolkit/mozapps/installer/unix/wizard/nsComponentList.h @@ -0,0 +1,166 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* + * The contents of this file are subject to the Netscape Public + * License Version 1.1 (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.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is Mozilla Communicator client code, + * released March 31, 1998. + * + * The Initial Developer of the Original Code is Netscape Communications + * Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + * Samir Gehani + */ + +#ifndef _NS_COMPONENTLIST_H_ +#define _NS_COMPONENTLIST_H_ + +#include "XIErrors.h" + +class nsComponent; + +class nsComponentList +{ +public: + nsComponentList(); + ~nsComponentList(); + + /** + * GetHead + * + * Initializes the next ptr to the second item and + * returns the head item. + * + * @return mHead the head of the singly-linked list + */ + nsComponent * GetHead(); + + /** + * GetNext + * + * Returns the next available item. GetHead() has to have + * been called prior calling this and after the last time + * the entire list was iterated over. + * + * @return mNext the next available component + */ + nsComponent * GetNext(); + + /** + * GetTail + * + * Returns the tail item of the list. + * + * @return mTail the tail item of the list + */ + nsComponent * GetTail(); + + /** + * GetLength + * + * Returns the number of components held by this list. + * + * @return mLength the size of this list + */ + int GetLength(); + + /** + * GetLengthVisible + * + * Returns the number of visible components held by this list. + * + * @return numVisible the number of visible components + */ + int GetLengthVisible(); + + /** + * GetLengthSelected + * + * Returns the number of selected components held by this list. + * + * @return numSleected the number of selected components + */ + int GetLengthSelected(); + + /** + * AddComponent + * + * Adds the supplied component to the list's tail. + * + * @param aComponent the component to add + * @return err integer err code (zero means OK) + */ + int AddComponent(nsComponent *aComponent); + + /** + * RemoveComponent + * + * Searches the list and removes the first component that + * matches the supplied component. + * + * @param aComponent the component to remove + * @return err integer error code (zero means OK) + */ + int RemoveComponent(nsComponent *aComponent); + + /** + * GetCompByIndex + * + * Searches the list and returns the first component that + * matches the supplied index. + * + * @param aIndex the index of the component being sought + * @return comp the component matching the index + */ + nsComponent *GetCompByIndex(int aIndex); + + /** + * GetCompByArchive + * + * Searches the list and returns the first component that matches + * the archive name supplied. + * + * @param aArchive the archive name of the component + * @return comp the component matching the archive + */ + nsComponent *GetCompByArchive(char *aArchive); + + /** + * GetCompByShortDesc + * + * Searches the list and returns the first component that matches + * the short description supplied. + * + * @param aShortDesc the short description of the component + * @return comp the component matching the short description + */ + nsComponent *GetCompByShortDesc(char *aShortDesc); + + /** + * GetFirstVisible + * + * Returns the first component that doesn't have the invisible + * attribute set. + * + * @return comp the first visible component in this list + */ + nsComponent *GetFirstVisible(); + +private: + nsComponent *mHead; + nsComponent *mTail; + nsComponent *mNext; + int mLength; +}; + +#endif /* _NS_COMPONENTLIST_H_ */ diff --git a/mozilla/toolkit/mozapps/installer/unix/wizard/nsComponentsDlg.cpp b/mozilla/toolkit/mozapps/installer/unix/wizard/nsComponentsDlg.cpp new file mode 100644 index 00000000000..7ce68ad135e --- /dev/null +++ b/mozilla/toolkit/mozapps/installer/unix/wizard/nsComponentsDlg.cpp @@ -0,0 +1,420 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* + * The contents of this file are subject to the Netscape Public + * License Version 1.1 (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.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is Mozilla Communicator client code, + * released March 31, 1998. + * + * The Initial Developer of the Original Code is Netscape Communications + * Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + * Samir Gehani + */ + +#include "nsComponentsDlg.h" +#include "nsXInstaller.h" +#include "check_on.xpm" +#include "check_off.xpm" +#include + +static nsSetupType *sCustomST; // cache a pointer to the custom setup type +static GtkWidget *sDescLong; +static gint sCurrRowSelected; + +nsComponentsDlg::nsComponentsDlg() : + mMsg0(NULL), + mCompList(NULL) +{ +} + +nsComponentsDlg::~nsComponentsDlg() +{ + XI_IF_FREE(mMsg0); + XI_IF_DELETE(mCompList); +} + +void +nsComponentsDlg::Back(GtkWidget *aWidget, gpointer aData) +{ + DUMP("Back"); + if (aData != gCtx->cdlg) return; + + // hide this notebook page + gCtx->cdlg->Hide(nsXInstallerDlg::BACKWARD_MOVE); + + // disconnect this dlg's nav btn signal handlers + gtk_signal_disconnect(GTK_OBJECT(gCtx->back), gCtx->backID); + gtk_signal_disconnect(GTK_OBJECT(gCtx->next), gCtx->nextID); + + gCtx->sdlg->Show(nsXInstallerDlg::BACKWARD_MOVE); +} + +void +nsComponentsDlg::Next(GtkWidget *aWidget, gpointer aData) +{ + DUMP("Next"); + if (aData != gCtx->cdlg) return; + + if (OK != nsSetupTypeDlg::VerifyDiskSpace()) + return; + + // hide this notebook page + gCtx->cdlg->Hide(nsXInstallerDlg::FORWARD_MOVE); + + // disconnect this dlg's nav btn signal handlers + gtk_signal_disconnect(GTK_OBJECT(gCtx->back), gCtx->backID); + gtk_signal_disconnect(GTK_OBJECT(gCtx->next), gCtx->nextID); + + // show the next dlg + gCtx->idlg->Show(nsXInstallerDlg::FORWARD_MOVE); +} + +int +nsComponentsDlg::Parse(nsINIParser *aParser) +{ + int err = OK; + char *showDlg = NULL; + int bufsize = 0; + + char *currSec = (char *) malloc(strlen(COMPONENT) + 3); + if (!currSec) return E_MEM; + XI_VERIFY(gCtx); + + /* optional keys */ + err = aParser->GetStringAlloc(DLG_COMPONENTS, MSG0, &mMsg0, &bufsize); + if (err != OK && err != nsINIParser::E_NO_KEY) goto BAIL; else err = OK; + + bufsize = 5; + err = aParser->GetStringAlloc(DLG_COMPONENTS, SHOW_DLG, &showDlg, &bufsize); + if (err != OK && err != nsINIParser::E_NO_KEY) goto BAIL; else err = OK; + if (bufsize != 0 && showDlg) + { + if (0 == strncmp(showDlg, "TRUE", 4)) + mShowDlg = nsXInstallerDlg::SHOW_DIALOG; + else if (0 == strncmp(showDlg, "FALSE", 5)) + mShowDlg = nsXInstallerDlg::SKIP_DIALOG; + } + + bufsize = 0; + err = aParser->GetStringAlloc(DLG_COMPONENTS, TITLE, &mTitle, &bufsize); + if (err != OK && err != nsINIParser::E_NO_KEY) goto BAIL; else err = OK; + if (bufsize == 0) + XI_IF_FREE(mTitle); + +BAIL: + XI_IF_FREE(currSec); + + return err; +} + +int +nsComponentsDlg::Show(int aDirection) +{ + int err = OK; + int customSTIndex = 0, i; + int numRows = 0; + int currRow = 0; + GtkWidget *hbox = NULL; + + XI_VERIFY(gCtx); + XI_VERIFY(gCtx->notebook); + + if (mWidgetsInit == FALSE) + { + customSTIndex = gCtx->sdlg->GetNumSetupTypes(); + sCustomST = gCtx->sdlg->GetSetupTypeList(); + for (i=1; iGetNext(); + DUMP(sCustomST->GetDescShort()); + + // create a new table and add it as a page of the notebook + mTable = gtk_table_new(5, 1, FALSE); + gtk_notebook_append_page(GTK_NOTEBOOK(gCtx->notebook), mTable, NULL); + mPageNum = gtk_notebook_get_current_page(GTK_NOTEBOOK(gCtx->notebook)); + gtk_widget_show(mTable); + + // 1st row: a label (msg0) + // insert a static text widget in the first row + GtkWidget *msg0 = gtk_label_new(mMsg0); + hbox = gtk_hbox_new(FALSE, 0); + gtk_box_pack_start(GTK_BOX(hbox), msg0, FALSE, FALSE, 0); + gtk_widget_show(hbox); + gtk_table_attach(GTK_TABLE(mTable), hbox, 0, 1, 1, 2, + static_cast(GTK_FILL | GTK_EXPAND), + GTK_FILL, 20, 20); + gtk_widget_show(msg0); + + // 2nd row: a CList with a check box for each row (short desc) + GtkWidget *list = NULL; + GtkWidget *scrollwin = NULL; + GtkStyle *style = NULL; + GdkBitmap *ch_mask = NULL; + GdkPixmap *checked = NULL; + GdkBitmap *un_mask = NULL; + GdkPixmap *unchecked = NULL; + gchar *dummy = ""; + nsComponent *currComp = sCustomST->GetComponents()->GetHead(); + GtkWidget *descLongTable = NULL; + GtkWidget *frame = NULL; + + scrollwin = gtk_scrolled_window_new(NULL, NULL); + gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrollwin), + GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); + + list = gtk_clist_new(2); + gtk_clist_set_selection_mode(GTK_CLIST(list), GTK_SELECTION_BROWSE); + gtk_clist_column_titles_hide(GTK_CLIST(list)); + gtk_clist_set_column_auto_resize(GTK_CLIST(list), 0, TRUE); + gtk_clist_set_column_auto_resize(GTK_CLIST(list), 1, TRUE); + + // determine number of rows we'll need + numRows = sCustomST->GetComponents()->GetLengthVisible(); + for (i = 0; i < numRows; i++) + gtk_clist_append(GTK_CLIST(list), &dummy); + + style = gtk_widget_get_style(gCtx->window); + checked = gdk_pixmap_create_from_xpm_d(gCtx->window->window, &ch_mask, + &style->bg[GTK_STATE_NORMAL], (gchar **)check_on_xpm); + unchecked = gdk_pixmap_create_from_xpm_d(gCtx->window->window, &un_mask, + &style->bg[GTK_STATE_NORMAL], (gchar **)check_off_xpm); + + while ((currRow < numRows) && currComp) // paranoia! + { + if (!currComp->IsInvisible()) + { + if (currComp->IsSelected()) + gtk_clist_set_pixmap(GTK_CLIST(list), currRow, 0, + checked, ch_mask); + else + gtk_clist_set_pixmap(GTK_CLIST(list), currRow, 0, + unchecked, un_mask); + + gtk_clist_set_text(GTK_CLIST(list), currRow, 1, + currComp->GetDescShort()); + currRow++; + } + + currComp = currComp->GetNext(); + } + + // by default, first row selected upon Show() + sCurrRowSelected = 0; + + gtk_signal_connect(GTK_OBJECT(list), "select_row", + GTK_SIGNAL_FUNC(RowSelected), NULL); + gtk_signal_connect(GTK_OBJECT(list), "key_press_event", + GTK_SIGNAL_FUNC(KeyPressed), NULL); + gtk_container_add(GTK_CONTAINER(scrollwin), list); + gtk_widget_show(list); + gtk_widget_show(scrollwin); + + hbox = gtk_hbox_new(FALSE, 0); + gtk_box_pack_start(GTK_BOX(hbox), scrollwin, TRUE, TRUE, 0); + gtk_widget_show(hbox); + gtk_table_attach(GTK_TABLE(mTable), hbox, 0, 1, 2, 3, + static_cast(GTK_FILL | GTK_EXPAND), + static_cast(GTK_EXPAND | GTK_FILL), + 20, 0); + + // XXX 3rd row: labels for ds avail and ds reqd + + // 4th row: a frame with a label (long desc) + descLongTable = gtk_table_new(1, 1, FALSE); + gtk_widget_show(descLongTable); + + gtk_table_attach(GTK_TABLE(mTable), descLongTable, 0, 1, 4, 5, + static_cast(GTK_EXPAND | GTK_FILL), + static_cast(GTK_EXPAND | GTK_FILL), + 20, 20); + frame = gtk_frame_new(gCtx->Res("DESCRIPTION")); + gtk_table_attach_defaults(GTK_TABLE(descLongTable), frame, 0, 1, 0, 1); + gtk_widget_show(frame); + + sDescLong = gtk_label_new( + sCustomST->GetComponents()->GetFirstVisible()->GetDescLong()); + gtk_label_set_line_wrap(GTK_LABEL(sDescLong), TRUE); + hbox = gtk_hbox_new(FALSE, 0); + gtk_box_pack_start(GTK_BOX(hbox), sDescLong, FALSE, FALSE, 20); + gtk_widget_show(hbox); + + gtk_table_attach_defaults(GTK_TABLE(descLongTable), hbox, 0, 1, 0, 1); + gtk_widget_show(sDescLong); + + mWidgetsInit = TRUE; + } + else + { + gtk_notebook_set_page(GTK_NOTEBOOK(gCtx->notebook), mPageNum); + gtk_widget_show(mTable); + } + + // signal connect the buttons + gCtx->backID = gtk_signal_connect(GTK_OBJECT(gCtx->back), "clicked", + GTK_SIGNAL_FUNC(nsComponentsDlg::Back), gCtx->cdlg); + gCtx->nextID = gtk_signal_connect(GTK_OBJECT(gCtx->next), "clicked", + GTK_SIGNAL_FUNC(nsComponentsDlg::Next), gCtx->cdlg); + + // show back btn again after setup type dlg where we couldn't go back + gtk_widget_set_sensitive(gCtx->back, TRUE); + + if (aDirection == nsXInstallerDlg::BACKWARD_MOVE) // from install dlg + gtk_button_set_label(GTK_BUTTON(gCtx->next), GTK_STOCK_GO_FORWARD); + + return err; +} + +int +nsComponentsDlg::Hide(int aDirection) +{ + gtk_widget_hide(mTable); + + return OK; +} + +int +nsComponentsDlg::SetMsg0(char *aMsg) +{ + if (!aMsg) + return E_PARAM; + + mMsg0 = aMsg; + + return OK; +} + +char * +nsComponentsDlg::GetMsg0() +{ + if (mMsg0) + return mMsg0; + + return NULL; +} + +int +nsComponentsDlg::SetCompList(nsComponentList *aCompList) +{ + if (!aCompList) + return E_PARAM; + + mCompList = aCompList; + + return OK; +} + +nsComponentList * +nsComponentsDlg::GetCompList() +{ + if (mCompList) + return mCompList; + + return NULL; +} + +void +nsComponentsDlg::RowSelected(GtkWidget *aWidget, gint aRow, gint aColumn, + GdkEventButton *aEvent, gpointer aData) +{ + DUMP("RowSelected"); + + sCurrRowSelected = aRow; + + // only toggle row selection state for clicks on the row + if (aColumn == -1 && !aEvent) + return; + + ToggleRowSelection(aWidget, aRow, + (aColumn == 0 && aEvent->button == 1)); +} + +void +nsComponentsDlg::KeyPressed(GtkWidget *aWidget, GdkEventKey *aEvent, + gpointer aData) +{ + DUMP("KeyPressed"); + + if (aEvent->keyval == GDK_space) + ToggleRowSelection(aWidget, sCurrRowSelected, TRUE); +} + +void +nsComponentsDlg::ToggleRowSelection(GtkWidget *aWidget, gint aRow, + gboolean aToggleState) +{ + int numRows = 0, currRow = 0; + GtkStyle *style = NULL; + GdkBitmap *ch_mask = NULL; + GdkPixmap *checked = NULL; + GdkBitmap *un_mask = NULL; + GdkPixmap *unchecked = NULL; + nsComponent *currComp = sCustomST->GetComponents()->GetHead(); + + style = gtk_widget_get_style(gCtx->window); + checked = gdk_pixmap_create_from_xpm_d(gCtx->window->window, &ch_mask, + &style->bg[GTK_STATE_NORMAL], (gchar **)check_on_xpm); + unchecked = gdk_pixmap_create_from_xpm_d(gCtx->window->window, &un_mask, + &style->bg[GTK_STATE_NORMAL], (gchar **)check_off_xpm); + + numRows = sCustomST->GetComponents()->GetLengthVisible(); + while ((currRow < numRows) && currComp) // paranoia! + { + if (!currComp->IsInvisible()) + { + if (aRow == currRow) + { + // update long desc + gtk_label_set_text(GTK_LABEL(sDescLong), + currComp->GetDescLong()); + gtk_widget_show(sDescLong); + + if (aToggleState) { + if (currComp->IsSelected()) { + DUMP("Toggling off..."); + currComp->SetUnselected(); + } else { + DUMP("Toggling on..."); + currComp->SetSelected(); + } + } + currComp->ResolveDependees(currComp->IsSelected(), + sCustomST->GetComponents()); + break; + } + currRow++; + } + currComp = currComp->GetNext(); + } + + // after resolving dependees redraw all checkboxes in one fell swoop + currRow = 0; + currComp = sCustomST->GetComponents()->GetHead(); + while ((currRow < numRows) && currComp) // paranoia! + { + if (!currComp->IsInvisible()) + { + if (currComp->IsSelected()) + { + gtk_clist_set_pixmap(GTK_CLIST(aWidget), currRow, 0, + checked, ch_mask); + } + else + { + gtk_clist_set_pixmap(GTK_CLIST(aWidget), currRow, 0, + unchecked, un_mask); + } + currRow++; + } + currComp = currComp->GetNext(); + } +} diff --git a/mozilla/toolkit/mozapps/installer/unix/wizard/nsComponentsDlg.h b/mozilla/toolkit/mozapps/installer/unix/wizard/nsComponentsDlg.h new file mode 100644 index 00000000000..d5a72c0a3cc --- /dev/null +++ b/mozilla/toolkit/mozapps/installer/unix/wizard/nsComponentsDlg.h @@ -0,0 +1,74 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* + * The contents of this file are subject to the Netscape Public + * License Version 1.1 (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.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is Mozilla Communicator client code, + * released March 31, 1998. + * + * The Initial Developer of the Original Code is Netscape Communications + * Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + * Samir Gehani + */ + +#ifndef _NS_COMPONENTSDLG_H_ +#define _NS_COMPONENTSDLG_H_ + +#include "XIErrors.h" + +#include "nsXInstallerDlg.h" +#include "nsComponentList.h" +#include "nsSetupType.h" + +class nsComponentsDlg : public nsXInstallerDlg +{ +public: + nsComponentsDlg(); + ~nsComponentsDlg(); + +/*--------------------------------------------------------------------* + * Navigation + *--------------------------------------------------------------------*/ + static void Back(GtkWidget *aWidget, gpointer aData); + static void Next(GtkWidget *aWidget, gpointer aData); + + int Parse(nsINIParser* aParser); + + int Show(int aDirection); + int Hide(int aDirection); + + static void RowSelected(GtkWidget *aWidget, gint aRow, gint aColumn, + GdkEventButton *aEvent, gpointer aData); + static void KeyPressed(GtkWidget *aWidget, GdkEventKey *aEvent, + gpointer aData); + static void ToggleRowSelection(GtkWidget *aEvent, gint aRow, + gboolean aToggleState); + +/*--------------------------------------------------------------------* + * INI Properties + *--------------------------------------------------------------------*/ + int SetMsg0(char *aMsg); + char *GetMsg0(); + + int SetCompList(nsComponentList *aCompList); + nsComponentList *GetCompList(); + +private: + int ParseDependees(char *aCurrSec, nsComponent *aCurrComp, + nsINIParser *aParser); + char *mMsg0; + nsComponentList *mCompList; +}; + +#endif /* _NS_COMPONENTSDLG_H_ */ diff --git a/mozilla/toolkit/mozapps/installer/unix/wizard/nsINIParser.cpp b/mozilla/toolkit/mozapps/installer/unix/wizard/nsINIParser.cpp new file mode 100644 index 00000000000..d2b53632b3c --- /dev/null +++ b/mozilla/toolkit/mozapps/installer/unix/wizard/nsINIParser.cpp @@ -0,0 +1,319 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* + * The contents of this file are subject to the Netscape Public + * License Version 1.1 (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.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is Mozilla Communicator client code, + * released March 31, 1998. + * + * The Initial Developer of the Original Code is Netscape Communications + * Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + * Samir Gehani + */ + + +#include "nsINIParser.h" + +nsINIParser::nsINIParser(char *aFilename) +{ + FILE *fd = NULL; + long eofpos = 0; + int rd = 0; + + mFileBuf = NULL; + mFileBufSize = 0; + mError = OK; + DUMP("nsINIParser"); + + /* param check */ + if (!aFilename) + { + mError = E_PARAM; + return; + } + + /* open the file */ + fd = fopen(aFilename, "r"); + if (!fd) + goto bail; + + /* get file size */ + if (fseek(fd, 0, SEEK_END) != 0) + goto bail; + eofpos = ftell(fd); + if (eofpos == 0) + goto bail; + + /* malloc an internal buf the size of the file */ + mFileBuf = (char *) malloc(eofpos + 1); + if (!mFileBuf) + { + mError = E_MEM; + return; + } + mFileBufSize = eofpos; + + /* read the file in one swoop */ + if (fseek(fd, 0, SEEK_SET) != 0) + goto bail; + rd = fread((void *)mFileBuf, 1, eofpos, fd); + if (!rd) + goto bail; + mFileBuf[mFileBufSize] = '\0'; + + /* close file */ + fclose(fd); + + /* Make sure the buffer is null-terminated. */ + mFileBuf[eofpos] = '\0'; + + return; + +bail: + mError = E_READ; + return; +} + +nsINIParser::~nsINIParser() +{ + DUMP("~nsINIParser"); +} + +int +nsINIParser::GetString( char *aSection, char *aKey, + char *aValBuf, int *aIOValBufSize ) +{ + char *secPtr = NULL; + mError = OK; + DUMP("GetString"); + + /* param check */ + if ( !aSection || !aKey || !aValBuf || + !aIOValBufSize || (*aIOValBufSize <= 0) ) + return E_PARAM; + + /* find the section if it exists */ + mError = FindSection(aSection, &secPtr); + if (mError != OK) + return mError; + + /* find the key if it exists in the valid section we found */ + mError = FindKey(secPtr, aKey, aValBuf, aIOValBufSize); + + return mError; +} + +int +nsINIParser::GetStringAlloc( char *aSection, char *aKey, + char **aOutBuf, int *aOutBufSize ) +{ + char buf[MAX_VAL_SIZE]; + int bufsize = MAX_VAL_SIZE; + mError = OK; + DUMP("GetStringAlloc"); + + mError = GetString(aSection, aKey, buf, &bufsize); + if (mError != OK) + return mError; + + *aOutBuf = (char *) malloc(bufsize + 1); + strncpy(*aOutBuf, buf, bufsize); + *(*aOutBuf + bufsize) = 0; + *aOutBufSize = bufsize + 1; + + return mError; +} + +int +nsINIParser::GetError() +{ + DUMP("GetError"); + return mError; +} + +char * +nsINIParser::ResolveName(char *aINIRoot) +{ + char *resolved = NULL; + char *locale = NULL; + struct stat st_exists; + + /* param check */ + if (!aINIRoot) + return NULL; + + locale = setlocale(LC_CTYPE, NULL); + if (!locale) + return NULL; + + /* resolved string: ".ini.\0" */ + resolved = (char *) malloc(strlen(aINIRoot) + 5 + strlen(locale) + 1); + if (!resolved) + return NULL; + + /* locale specific ini file name */ + sprintf(resolved, "%s.ini.%s", aINIRoot, locale); + if (0 == stat(resolved, &st_exists)) + return resolved; + + /* fallback to general ini file name */ + sprintf(resolved, "%s.ini", aINIRoot); + if (0 == stat(resolved, &st_exists)) + return resolved; + + /* neither existed so error returned */ + return NULL; +} + +int +nsINIParser::FindSection(char *aSection, char **aOutSecPtr) +{ + char *currChar = mFileBuf; + char *nextSec = NULL; + char *secClose = NULL; + char *nextNL = NULL; + int aSectionLen = strlen(aSection); + mError = E_NO_SEC; + DUMP("FindSection"); + + // param check + if (!aSection || !aOutSecPtr) + { + mError = E_PARAM; + return mError; + } + + while (currChar < (mFileBuf + mFileBufSize)) + { + // look for first '[' + nextSec = NULL; + nextSec = strchr(currChar, '['); + if (!nextSec) + break; + + currChar = nextSec + 1; + + // extract section name till first ']' + secClose = NULL; nextNL = NULL; + secClose = strchr(currChar, ']'); + nextNL = strchr(currChar, NL); + if ((!nextNL) || (nextNL < secClose)) + { + currChar = nextNL; + continue; + } + + // if section name matches we succeeded + if (strncmp(aSection, currChar, aSectionLen) == 0 + && secClose-currChar == aSectionLen) + { + *aOutSecPtr = secClose + 1; + mError = OK; + break; + } + } + + return mError; +} + +int +nsINIParser::FindKey(char *aSecPtr, char *aKey, char *aVal, int *aIOValSize) +{ + char *nextNL = NULL; + char *secEnd = NULL; + char *currLine = aSecPtr; + char *nextEq = NULL; + int aKeyLen = strlen(aKey); + mError = E_NO_KEY; + DUMP("FindKey"); + + // param check + if (!aSecPtr || !aKey || !aVal || !aIOValSize || (*aIOValSize <= 0)) + { + mError = E_PARAM; + return mError; + } + + // determine the section end + secEnd = aSecPtr; +find_end: + if (secEnd) + secEnd = strchr(secEnd, '['); // search for next sec start + if (!secEnd) + { + secEnd = strchr(aSecPtr, '\0'); // else search for file end + if (!secEnd) + { + mError = E_SEC_CORRUPT; // else this data is corrupt + return mError; + } + } + + // handle start section token ('[') in values for i18n + if (*secEnd == '[' && !(secEnd == aSecPtr || *(secEnd-1) == NL)) + { + secEnd++; + goto find_end; + } + + while (currLine < secEnd) + { + nextNL = NULL; + nextNL = strchr(currLine, NL); + if (!nextNL) + nextNL = mFileBuf + mFileBufSize; + + // ignore commented lines (starting with ;) + if (currLine == strchr(currLine, ';')) + { + currLine = nextNL + 1; + continue; + } + + // extract key before '=' + nextEq = NULL; + nextEq = strchr(currLine, '='); + if (!nextEq || nextEq > nextNL) + { + currLine = nextNL + 1; + continue; + } + + // if key matches we succeeded + if (strncmp(currLine, aKey, aKeyLen) == 0 + && nextEq-currLine == aKeyLen) + { + // extract the value and return + if (*aIOValSize < nextNL - nextEq) + { + mError = E_SMALL_BUF; + *aVal = '\0'; + *aIOValSize = 0; + return mError; + } + + *aIOValSize = nextNL - (nextEq + 1); + strncpy(aVal, (nextEq + 1), *aIOValSize); + *(aVal + *aIOValSize) = 0; // null terminate + mError = OK; + return mError; + } + else + { + currLine = nextNL + 1; + } + } + + return mError; +} diff --git a/mozilla/toolkit/mozapps/installer/unix/wizard/nsINIParser.h b/mozilla/toolkit/mozapps/installer/unix/wizard/nsINIParser.h new file mode 100644 index 00000000000..812c06c84b6 --- /dev/null +++ b/mozilla/toolkit/mozapps/installer/unix/wizard/nsINIParser.h @@ -0,0 +1,148 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* + * The contents of this file are subject to the Netscape Public + * License Version 1.1 (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.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is Mozilla Communicator client code, + * released March 31, 1998. + * + * The Initial Developer of the Original Code is Netscape Communications + * Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + * Samir Gehani + */ + +#ifndef _NS_INIPARSER_H_ +#define _NS_INIPARSER_H_ + +#include +#include +#include +#include +#include + +class nsINIParser +{ +public: + + /** + * nsINIParser + * + * Construct a new INI parser for the file specified. + * + * @param aFilename path to INI file + */ + nsINIParser(char *aFilename); + ~nsINIParser(); + + /** + * GetString + * + * Gets the value of the specified key in the specified section + * of the INI file represented by this instance. The value is stored + * in the supplied buffer. The buffer size is provided as input and + * the actual bytes used by the value is set in the in/out size param. + * + * @param aSection section name + * @param aKey key name + * @param aValBuf user supplied buffer + * @param aIOValBufSize buf size on input; actual buf used on output + * + * @return mError operation success code + */ + int GetString( char *aSection, char *aKey, + char *aValBuf, int *aIOValBufSize ); + + /** + * GetStringAlloc + * + * Same as GetString() except the buffer is allocated to the exact + * size of the value. Useful when the buffer is allocated everytime + * rather than reusing the same buffer when calling this function + * multiple times. + * + * @param aSection section name + * @param aKey key name + * @param aOutBuf buffer to be allocated + * @param aOutBufSize size of newly allocated buffer + * + * @return mError operation success code + */ + int GetStringAlloc( char *aSection, char *aKey, + char **aOutBuf, int *aOutBufSize ); + + /** + * GetError + * + * Exposes the last error on this instance. Useful for checking + * the state of the object after construction since the INI file + * is parsed once at object-allocation time. + * + * @return mError last error on ops on this object + */ + int GetError(); + + /** + * ResolveName + * + * Given a "root" name we append the runtime locale of the + * current system to the .ini. If such a file exists we + * return this as the name else simply return .ini. + * + * NOTE: Returned string is allocated and caller is responsible + * ---- for its deallocation. + * + * @param aINIRoot the "root" of the INI file name + * @return resolved the resolved INI file name + * (NULL if neither exist) + */ + static char *ResolveName(char *aINIRoot); + +/*--------------------------------------------------------------------* + * Errors + *--------------------------------------------------------------------*/ + enum + { + OK = 0, + E_READ = -701, + E_MEM = -702, + E_PARAM = -703, + E_NO_SEC = -704, + E_NO_KEY = -705, + E_SEC_CORRUPT = -706, + E_SMALL_BUF = -707 + }; + +private: + int FindSection(char *aSection, char **aOutSecPtr); + int FindKey(char *aSecPtr, char *aKey, char *aVal, int *aIOValSize); + + char *mFileBuf; + int mFileBufSize; + int mError; +}; + +#define NL '\n' +#define MAX_VAL_SIZE 4096 + +#if defined(DUMP) +#undef DUMP +#endif +#if defined(DEBUG_sgehani) || defined(DEBUG_druidd) || defined(DEBUG_root) +#define DUMP(_msg) printf("%s %d: %s \n", __FILE__, __LINE__, _msg); +#else +#define DUMP(_msg) +#endif + + +#endif /*_NS_INIPARSER_H_ */ diff --git a/mozilla/toolkit/mozapps/installer/unix/wizard/nsInstallDlg.cpp b/mozilla/toolkit/mozapps/installer/unix/wizard/nsInstallDlg.cpp new file mode 100644 index 00000000000..6884b58765b --- /dev/null +++ b/mozilla/toolkit/mozapps/installer/unix/wizard/nsInstallDlg.cpp @@ -0,0 +1,1438 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* + * The contents of this file are subject to the Netscape Public + * License Version 1.1 (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.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is Mozilla Communicator client code, + * released March 31, 1998. + * + * The Initial Developer of the Original Code is Netscape Communications + * Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + * Samir Gehani + */ + +#include "nsSocket.h" +#include "nsHTTPConn.h" +#include "nsInstallDlg.h" +#include "nsXInstaller.h" +#include "nsXIEngine.h" +#include +#include +#include + +#define NUM_PS_ENTRIES 4 + +typedef struct _DLProgress +{ + // progress widgets + GtkWidget *vbox; + GtkWidget *compName; + GtkWidget *URL; + GtkWidget *localPath; + GtkWidget *status; + GtkWidget *progBar; + + // progress info + int downloadedBytes; + int totalKB; +} +DLProgress; + +static char *sXPInstallEngine; +static nsRunApp *sRunAppList = NULL; +static DLProgress sDLProgress; + +static GtkWidget *sDLTable = NULL; +static GtkWidget *sMsg0Label; +static GtkWidget *sTextBox; +static GtkWidget *sMajorLabel; +static GtkWidget *sMinorLabel; +static GtkWidget *sRateLabel; +static GtkWidget *sMajorProgBar; +static GtkWidget *sMinorProgBar; +static GtkWidget *sPSTextEntry[NUM_PS_ENTRIES]; + +static int bDownload = FALSE; +static struct timeval sDLStartTime; +static int bDLPause = FALSE; +static int bDLCancel = FALSE; + +nsInstallDlg::nsInstallDlg() : + mMsg0(NULL) +{ +} + +nsInstallDlg::~nsInstallDlg() +{ + XI_IF_FREE(mMsg0); +} + +void +nsInstallDlg::Back(GtkWidget *aWidget, gpointer aData) +{ + DUMP("Back"); + if (aData != gCtx->idlg) return; + + // hide this notebook page + gCtx->idlg->Hide(nsXInstallerDlg::BACKWARD_MOVE); + + // disconnect this dlg's nav btn signal handlers + gtk_signal_disconnect(GTK_OBJECT(gCtx->back), gCtx->backID); + gtk_signal_disconnect(GTK_OBJECT(gCtx->next), gCtx->nextID); + + // show the last dlg + if (gCtx->opt->mSetupType == (gCtx->sdlg->GetNumSetupTypes() - 1)) + gCtx->cdlg->Show(nsXInstallerDlg::BACKWARD_MOVE); + else + gCtx->sdlg->Show(nsXInstallerDlg::BACKWARD_MOVE); +} + +void +nsInstallDlg::Next(GtkWidget *aWidget, gpointer aData) +{ + DUMP("Next"); + int bCus; + nsComponentList *comps = NULL; + + if (aData != gCtx->idlg) return; + + bCus = (gCtx->opt->mSetupType == (gCtx->sdlg->GetNumSetupTypes() - 1)); + comps = gCtx->sdlg->GetSelectedSetupType()->GetComponents(); + + // initialize progress bar cleanly + int totalComps = 0; + if (nsXIEngine::ExistAllXPIs(bCus, comps, &totalComps)) + bDownload = FALSE; + else + bDownload = TRUE; + + if (gCtx->opt->mMode != nsXIOptions::MODE_SILENT) { + gtk_progress_set_activity_mode(GTK_PROGRESS(sMajorProgBar), FALSE); + gtk_progress_bar_update(GTK_PROGRESS_BAR(sMajorProgBar), (gfloat) 0); + gtk_label_set_text(GTK_LABEL(sMajorLabel), ""); + + if (bDownload) + { + InitDLProgress( TRUE ); + + gtk_button_set_label(GTK_BUTTON(gCtx->back), gCtx->Res("PAUSE")); + gtk_button_set_label(GTK_BUTTON(gCtx->next), gCtx->Res("RESUME")); + + gtk_signal_disconnect(GTK_OBJECT(gCtx->back), gCtx->backID); + gtk_signal_disconnect(GTK_OBJECT(gCtx->next), gCtx->nextID); + gtk_signal_disconnect(GTK_OBJECT(gCtx->cancel), gCtx->cancelID); + + // disable resume button + gtk_widget_set_sensitive(gCtx->next, FALSE); + + XI_GTK_UPDATE_UI(); + + // hook up buttons with callbacks + gCtx->backID = gtk_signal_connect(GTK_OBJECT(gCtx->back), "clicked", + GTK_SIGNAL_FUNC(DLPause), NULL); + gCtx->nextID = gtk_signal_connect(GTK_OBJECT(gCtx->next), "clicked", + GTK_SIGNAL_FUNC(DLResume), NULL); + gCtx->cancelID = gtk_signal_connect(GTK_OBJECT(gCtx->cancel), "clicked", + GTK_SIGNAL_FUNC(DLCancel), NULL); + } + else + { + gtk_widget_show(sMajorLabel); + gtk_widget_show(sMajorProgBar); + + gtk_widget_set_sensitive(gCtx->back, FALSE); + gtk_widget_set_sensitive(gCtx->next, FALSE); + gtk_widget_set_sensitive(gCtx->cancel, FALSE); + } + + gtk_widget_hide(sMsg0Label); + gtk_widget_hide(sTextBox); + if (bDownload && sDLTable) + gtk_widget_hide(sDLTable); + XI_GTK_UPDATE_UI(); + } + + PerformInstall(); + // mode auto has no call to gtk_main() + if (gCtx->opt->mMode == nsXIOptions::MODE_DEFAULT) + gtk_main_quit(); + + return; +} + +int +nsInstallDlg::Parse(nsINIParser *aParser) +{ + int err = OK; + int bufsize = 0; + char *showDlg = NULL; + char secName[64]; + int i; + char *app = NULL, *args = NULL; + nsRunApp *newRunApp = NULL; + + /* compulsory keys */ + XI_ERR_BAIL(aParser->GetStringAlloc(DLG_START_INSTALL, XPINSTALL_ENGINE, + &sXPInstallEngine, &bufsize)); + if (bufsize == 0 || !sXPInstallEngine) + return E_INVALID_KEY; + + /* optional keys */ + err = aParser->GetStringAlloc(DLG_START_INSTALL, TITLE, &mTitle, &bufsize); + if (err != OK && err != nsINIParser::E_NO_KEY) goto BAIL; else err = OK; + if (bufsize == 0) + XI_IF_FREE(mTitle); + + aParser->GetStringAlloc(DLG_START_INSTALL, SUBTITLE, &mSubTitle, &bufsize); + if (bufsize == 0) + XI_IF_FREE(mSubTitle); + + bufsize = 0; + err = aParser->GetStringAlloc(DLG_START_INSTALL, MSG0, &mMsg0, &bufsize); + if (err != OK && err != nsINIParser::E_NO_KEY) goto BAIL; else err = OK; + + bufsize = 5; + XI_ERR_BAIL(aParser->GetStringAlloc(DLG_START_INSTALL, SHOW_DLG, + &showDlg, &bufsize)); + if (bufsize != 0 && showDlg) + { + if (0 == strncmp(showDlg, "TRUE", 4)) + mShowDlg = nsXInstallerDlg::SHOW_DIALOG; + else if (0 == strncmp(showDlg, "FALSE", 5)) + mShowDlg = nsXInstallerDlg::SKIP_DIALOG; + } + + bufsize = 0; + XI_ERR_BAIL(aParser->GetStringAlloc(DLG_START_INSTALL, TITLE, + &mTitle, &bufsize)); + if (bufsize == 0) + XI_IF_FREE(mTitle); + + for (i = 0; err == OK; i++) + { + /* construct RunAppX section name */ + sprintf(secName, RUNAPPd, i); + err = aParser->GetStringAlloc(secName, TARGET, &app, &bufsize); + if (err == OK && bufsize > 0) + { + /* "args" is optional: this may return E_NO_KEY which we ignore */ + err = aParser->GetStringAlloc(secName, ARGS, &args, &bufsize); + newRunApp = new nsRunApp(app, args); + if (!newRunApp) + return E_MEM; + err = AppendRunApp(newRunApp); + } + } + err = OK; /* reset error since RunAppX sections are optional + and we could have gotten a parse error (E_NO_SEC) */ + + return err; + +BAIL: + return err; +} + +int +nsInstallDlg::AppendRunApp(nsRunApp *aNewRunApp) +{ + int err = OK; + nsRunApp *currRunApp = NULL, *nextRunApp = NULL; + + /* param check */ + if (!aNewRunApp) + return E_PARAM; + + /* special case: list is empty */ + if (!sRunAppList) + { + sRunAppList = aNewRunApp; + return OK; + } + + /* list has at least one element */ + currRunApp = sRunAppList; + while (currRunApp) + { + if (!(nextRunApp = currRunApp->GetNext())) + { + currRunApp->SetNext(aNewRunApp); + break; + } + currRunApp = nextRunApp; + } + return err; +} + +void +nsInstallDlg::FreeRunAppList() +{ + nsRunApp *currRunApp = NULL, *nextRunApp = NULL; + + currRunApp = sRunAppList; + while (currRunApp) + { + nextRunApp = currRunApp->GetNext(); + delete currRunApp; + currRunApp = nextRunApp; + } +} + +void +nsInstallDlg::RunApps() +{ + nsRunApp *currRunApp = sRunAppList; + char *argv[3], *dest; + char apppath[MAXPATHLEN]; + extern char **environ; /* globally available to all processes */ + int pid; + + dest = gCtx->opt->mDestination; + if (chdir(dest) < 0) + fprintf(stderr,"chdir(%s): %s\n",dest,strerror(errno)); + + while (currRunApp) + { + /* run application with supplied args */ + if ((pid = fork()) == 0) + { + /* child */ + + if (*(dest + strlen(dest)) == '/') /* trailing slash */ + sprintf(apppath, "%s%s", dest, currRunApp->GetApp()); + else /* no trailing slash */ + sprintf(apppath, "%s/%s", dest, currRunApp->GetApp()); + + argv[0] = apppath; + argv[1] = currRunApp->GetArgs(); + argv[2] = NULL; /* null-terminate arg vector */ + execve(apppath, argv, environ); + + /* shouldn't reach this but in case execve fails we will */ + exit(0); + } + /* parent continues running to finish installation */ + + currRunApp = currRunApp->GetNext(); + } +} + +int +nsInstallDlg::Show(int aDirection) +{ + int err = OK; + int totalComps = 0; + GtkWidget *hbox = NULL; + GtkWidget *vbox = NULL; + GtkWidget *dlFrame, *dlCheckbox, *dlProxyBtn; + + XI_VERIFY(gCtx); + XI_VERIFY(gCtx->notebook); + + if (mWidgetsInit == FALSE) + { + int bCus = + (gCtx->opt->mSetupType == (gCtx->sdlg->GetNumSetupTypes() - 1)); + nsComponentList *comps = + gCtx->sdlg->GetSelectedSetupType()->GetComponents(); + + // create a new table and add it as a page of the notebook + mTable = gtk_table_new(5, 1, FALSE); + gtk_notebook_append_page(GTK_NOTEBOOK(gCtx->notebook), mTable, NULL); + mPageNum = gtk_notebook_get_current_page(GTK_NOTEBOOK(gCtx->notebook)); + gtk_widget_show(mTable); + + // Show the text: + // Setup will now install the following components: + // [component1] + // [component2] + // to the following location: + // [install path] + // + // Click next to continue. + + sTextBox = gtk_vbox_new(FALSE, 6); + gtk_container_set_border_width(GTK_CONTAINER(sTextBox), 12); + gtk_table_attach(GTK_TABLE(mTable), sTextBox, 0, 1, 0, 1, + GtkAttachOptions(GTK_FILL | GTK_EXPAND), + GtkAttachOptions(0), 0, 0); + + GtkWidget *msg = gtk_label_new(gCtx->Res("WILL_INSTALL")); + gtk_misc_set_alignment(GTK_MISC(msg), 0.0, 0.5); + gtk_box_pack_start(GTK_BOX(sTextBox), msg, FALSE, FALSE, 0); + + nsComponent *currComp; + for (currComp = comps->GetHead(); currComp; + currComp = comps->GetNext()) { + + if (currComp->IsMainComponent() || + (!currComp->IsInvisible() && currComp->IsSelected())) { + msg = gtk_label_new(currComp->GetDescShort()); + gtk_misc_set_alignment(GTK_MISC(msg), 0.0, 0.5); + gtk_misc_set_padding(GTK_MISC(msg), 20, 0); + gtk_box_pack_start(GTK_BOX(sTextBox), msg, FALSE, FALSE, 0); + } + } + + msg = gtk_label_new(gCtx->Res("TO_LOCATION")); + gtk_misc_set_alignment(GTK_MISC(msg), 0.0, 0.5); + gtk_box_pack_start(GTK_BOX(sTextBox), msg, FALSE, FALSE, 0); + + msg = gtk_label_new(gCtx->opt->mDestination); + gtk_misc_set_alignment(GTK_MISC(msg), 0.0, 0.5); + gtk_misc_set_padding(GTK_MISC(msg), 20, 0); + gtk_box_pack_start(GTK_BOX(sTextBox), msg, FALSE, FALSE, 0); + + gtk_widget_show_all(sTextBox); + + if (!nsXIEngine::ExistAllXPIs(bCus, comps, &totalComps)) + { + // insert a [ x ] heterogenous table + sDLTable = gtk_table_new(2, 2, FALSE); + gtk_widget_show(sDLTable); + + gtk_table_attach(GTK_TABLE(mTable), sDLTable, 0, 1, 1, 4, + static_cast(GTK_FILL | GTK_EXPAND), + GtkAttachOptions(0), 20, 20); + + // download settings groupbox + dlFrame = gtk_frame_new(gCtx->Res("DL_SETTINGS")); + gtk_table_attach_defaults(GTK_TABLE(sDLTable), dlFrame, 0, 2, 0, 2); + gtk_widget_show(dlFrame); + + // save installer modules checkbox and label + dlCheckbox = gtk_check_button_new_with_label( + gCtx->Res("SAVE_MODULES")); + gtk_widget_show(dlCheckbox); + gtk_table_attach(GTK_TABLE(sDLTable), dlCheckbox, 0, 2, 0, 1, + GTK_FILL, GTK_FILL, 10, 20); + gtk_signal_connect(GTK_OBJECT(dlCheckbox), "toggled", + GTK_SIGNAL_FUNC(SaveModulesToggled), NULL); + + // proxy settings button + dlProxyBtn = gtk_button_new_with_label(gCtx->Res("PROXY_SETTINGS")); + gtk_widget_show(dlProxyBtn); + gtk_table_attach(GTK_TABLE(sDLTable), dlProxyBtn, 0, 1, 1, 2, + GTK_FILL, GTK_FILL, 10, 10); + gtk_signal_connect(GTK_OBJECT(dlProxyBtn), "clicked", + GTK_SIGNAL_FUNC(ShowProxySettings), NULL); + } + + // vbox with two widgets packed in: label0 / progmeter0 (major) + vbox = gtk_vbox_new(FALSE, 0); + hbox = gtk_hbox_new(FALSE, 0); + sMajorLabel = gtk_label_new(""); + sRateLabel = gtk_label_new(""); + gtk_box_pack_start(GTK_BOX(hbox), sMajorLabel, FALSE, FALSE, 0); + gtk_box_pack_start(GTK_BOX(hbox), sRateLabel, FALSE, FALSE, 0); + gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); + gtk_widget_show(hbox); + gtk_widget_show(sMajorLabel); + gtk_widget_show(sRateLabel); + + sMajorProgBar = gtk_progress_bar_new(); + gtk_box_pack_start(GTK_BOX(vbox), sMajorProgBar, FALSE, FALSE, 0); + // gtk_widget_show(sMajorProgBar); + + gtk_table_attach(GTK_TABLE(mTable), vbox, 0, 1, 2, 3, + static_cast(GTK_FILL | GTK_EXPAND), + GtkAttachOptions(0), 20, 20); + gtk_widget_show(vbox); + + // vbox with two widgets packed in: label1 / progmeter1 (minor) + vbox = gtk_vbox_new(FALSE, 0); + hbox = gtk_hbox_new(FALSE, 0); + sMinorLabel = gtk_label_new(""); + gtk_box_pack_start(GTK_BOX(hbox), sMinorLabel, FALSE, FALSE, 0); + gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); + gtk_widget_show(hbox); + gtk_widget_show(sMinorLabel); + + sMinorProgBar = gtk_progress_bar_new(); + gtk_box_pack_start(GTK_BOX(vbox), sMinorProgBar, FALSE, FALSE, 0); + // gtk_widget_show(sMinorProgBar); + + gtk_table_attach(GTK_TABLE(mTable), vbox, 0, 1, 3, 4, + static_cast(GTK_FILL | GTK_EXPAND), + GtkAttachOptions(0), 20, 20); + gtk_widget_show(vbox); + + vbox = gtk_vbox_new(FALSE, 0); + sMsg0Label = gtk_label_new(mMsg0); + gtk_misc_set_alignment(GTK_MISC(sMsg0Label), 0.0, 1.0); + gtk_misc_set_padding(GTK_MISC(sMsg0Label), 6, 12); + gtk_box_pack_start(GTK_BOX(vbox), sMsg0Label, TRUE, TRUE, 0); + gtk_table_attach(GTK_TABLE(mTable), vbox, 0, 1, 4, 5, + static_cast(GTK_FILL | GTK_EXPAND), + GtkAttachOptions(GTK_FILL | GTK_EXPAND), 0, 0); + gtk_widget_show(sMsg0Label); + gtk_widget_show(vbox); + + + mWidgetsInit = TRUE; + } + else + { + gtk_notebook_set_page(GTK_NOTEBOOK(gCtx->notebook), mPageNum); + gtk_widget_show(mTable); + } + + // title\0 + char *titleBuf = new char[strlen(mTitle) + 9]; + sprintf(titleBuf, "%s", mTitle); + + gtk_label_set_markup(GTK_LABEL(gCtx->header_title), titleBuf); + gtk_label_set_text(GTK_LABEL(gCtx->header_subtitle), mSubTitle); + + delete[] titleBuf; + + // signal connect the buttons + gCtx->backID = gtk_signal_connect(GTK_OBJECT(gCtx->back), "clicked", + GTK_SIGNAL_FUNC(nsInstallDlg::Back), gCtx->idlg); + gCtx->nextID = gtk_signal_connect(GTK_OBJECT(gCtx->next), "clicked", + GTK_SIGNAL_FUNC(nsInstallDlg::Next), gCtx->idlg); + + if (gCtx->opt->mSetupType != (gCtx->sdlg->GetNumSetupTypes() - 1)) + gtk_widget_set_sensitive(gCtx->back, TRUE); + + // always change title of next button to "Install" + gtk_button_set_label(GTK_BUTTON(gCtx->next), gCtx->Res("INSTALL")); + + return err; +} + +int +nsInstallDlg::Hide(int aDirection) +{ + gtk_widget_hide(mTable); + + return OK; +} + +int +nsInstallDlg::ShowTable() +{ + if (!mTable) + return E_PARAM; + + gtk_widget_show(mTable); + + return OK; +} + +int +nsInstallDlg::HideTable() +{ + if (!mTable) + return E_PARAM; + + gtk_widget_hide(mTable); + + return OK; +} + +int +nsInstallDlg::SetMsg0(char *aMsg) +{ + if (!aMsg) + return E_PARAM; + + mMsg0 = aMsg; + + return OK; +} + +char * +nsInstallDlg::GetMsg0() +{ + if (mMsg0) + return mMsg0; + + return NULL; +} + +int +nsInstallDlg::PerformInstall() +{ + DUMP("PerformInstall"); + + int err = OK; + + // perform the installation + nsXIEngine *engine = new nsXIEngine(); + if (!engine) + { + ErrorHandler(E_MEM); + return E_MEM; + } + + // get the component list for the current setup type + nsComponentList *comps = NULL; + nsComponent *xpiengine = NULL; + int bCus = (gCtx->opt->mSetupType == (gCtx->sdlg->GetNumSetupTypes() - 1)); + comps = gCtx->sdlg->GetSelectedSetupType()->GetComponents(); + if (!comps) + { + ErrorHandler(E_NO_COMPONENTS); + return E_NO_COMPONENTS; + } + + if (!sXPInstallEngine) return E_PARAM; + xpiengine = comps->GetCompByArchive(sXPInstallEngine); + + // 1> download + err = engine->Download(bCus, comps); + if (err == E_DL_DROP_CXN) + { + ShowCxnDroppedDlg(); + if (gCtx->opt->mMode != nsXIOptions::MODE_SILENT) + DLPause(NULL, NULL); + return err; + } + else if (err == E_CRC_FAILED) + { + ShowCRCFailedDlg(); + goto BAIL; + } + else if (err == E_DL_PAUSE || err == E_DL_CANCEL) + { + DUMP("Pause or Cancel pressed"); + goto BAIL; + } + else if (err != OK) + { + DUMP("dammit... hopped into the wrong hole!"); + ErrorHandler(err); + goto BAIL; + } + + // prepare install UI + if (gCtx->opt->mMode != nsXIOptions::MODE_SILENT) + { + InitInstallProgress(); + HideNavButtons(); + } + + // 2> extract engine + XI_ERR_BAIL(engine->Extract(xpiengine)); + + // 3> install .xpis + XI_ERR_BAIL(engine->Install(bCus, comps, gCtx->opt->mDestination)); + + // delete xpis if user didn't request saving them + if (bDownload && !gCtx->opt->mSaveModules) + { + engine->DeleteXPIs(bCus, comps); + } + + // run all specified applications after installation + if (sRunAppList) + { + if (gCtx->opt->mShouldRunApps) + RunApps(); + FreeRunAppList(); + } + +BAIL: + // destroy installer engine thread object + XI_IF_DELETE(engine); + + return err; +} + +void +nsInstallDlg::XPIProgressCB(const char *aMsg, int aVal, int aMax) +{ + if (gCtx->opt->mMode == nsXIOptions::MODE_SILENT) + return; + // DUMP("XPIProgressCB"); + + if (!aMsg) + return; + + static int updates = 0; + char msg[64]; + const char *colon = NULL, *lastSlash = NULL; + + if (aMax > 0) + { + // reset for next component + if (updates) + updates = 0; + + gfloat percent = (gfloat)((gfloat)aVal/(gfloat)aMax); +#if 0 + printf("progress percent: %f\taVal: %d\taMax: %d\n", percent, aVal, aMax); +#endif + gtk_progress_set_activity_mode(GTK_PROGRESS(sMinorProgBar), FALSE); + gtk_progress_bar_update(GTK_PROGRESS_BAR(sMinorProgBar), percent); + gtk_widget_show(sMinorProgBar); + + sprintf(msg, gCtx->Res("PROCESSING_FILE"), aVal, aMax); + } + else + { + updates++; + if (updates > 5) + updates = 0; + gfloat percent = (gfloat)((gfloat)updates/(gfloat)5); + + gtk_progress_set_activity_mode(GTK_PROGRESS(sMinorProgBar), TRUE); + gtk_progress_bar_update(GTK_PROGRESS_BAR(sMinorProgBar), percent); + gtk_widget_show(sMinorProgBar); + + /* tack on XPInstall action */ + memset(msg, 0, 64); + colon = strchr(aMsg, ':'); + if (colon) + strncpy(msg, aMsg, colon - aMsg); + + strncat(msg, " ", 1); + + /* tack on leaf name */ + lastSlash = strrchr(aMsg, '/'); + if (lastSlash) + strncat(msg, lastSlash + 1, strlen(lastSlash) - 1); + + strncat(msg, "\0", 1); + } + + gtk_label_set_text(GTK_LABEL(sMinorLabel), msg); + gtk_widget_draw(sMinorLabel, NULL); + + XI_GTK_UPDATE_UI(); +} + +void +nsInstallDlg::MajorProgressCB(char *aName, int aNum, int aTotal, int aActivity) +{ + // DUMP("MajorProgressCB"); + + char msg[256]; + + if (!aName) + return; + +#ifdef DEBUG + printf("%s %d: Name = %s\tNum = %d\tTotal = %d\tAct = %d\n", + __FILE__, __LINE__, aName, aNum, aTotal, aActivity); +#endif + + switch (aActivity) + { + case ACT_DOWNLOAD: + if (!bDownload) + sprintf(msg, gCtx->Res("PREPARING"), aName); + break; + + case ACT_EXTRACT: + sprintf(msg, gCtx->Res("EXTRACTING"), aName); + break; + + case ACT_INSTALL: + sprintf(msg, gCtx->Res("INSTALLING_XPI"), aName); + break; + + default: + break; + } + + gtk_label_set_text(GTK_LABEL(sMajorLabel), msg); + gtk_widget_show(sMajorLabel); + + if (aTotal <= 0) + { + XI_ASSERT(0, "aTotal was <= 0"); + XI_GTK_UPDATE_UI(); + return; + } + + gfloat percent = (gfloat)((gfloat)aNum/(gfloat)aTotal); + gtk_progress_bar_update(GTK_PROGRESS_BAR(sMajorProgBar), percent); + gtk_widget_show(sMajorProgBar); + + // reset minor progress ui + if (aActivity == ACT_INSTALL) + { + gtk_label_set_text(GTK_LABEL(sMinorLabel), ""); + gtk_progress_bar_update(GTK_PROGRESS_BAR(sMinorProgBar), (gfloat)0); + gtk_widget_show(sMinorLabel); + gtk_widget_show(sMinorProgBar); + } + + XI_GTK_UPDATE_UI(); +} + +const int kCharsInDLLabel = 50; + +void +nsInstallDlg::SetDownloadComp(nsComponent *aComp, int aURLIndex, + int aNum, int aTotal) +{ + static char xpiDir[MAXPATHLEN]; + static int bHaveXPIDir = FALSE; + char label[MAXPATHLEN]; + char localPath[MAXPATHLEN]; + + if (!aComp) + return; + + if (!bHaveXPIDir) + { + getcwd(xpiDir, MAXPATHLEN); + strcat(xpiDir, "/xpi"); + bHaveXPIDir = TRUE; + } + + // update comp name + sprintf(label, "%s [%d/%d]", aComp->GetDescShort(), aNum, aTotal); + gtk_label_set_text(GTK_LABEL(sDLProgress.compName), label); + + // update from URL + label[0] = 0; + CompressToFit(aComp->GetURL(aURLIndex), label, kCharsInDLLabel); + gtk_label_set_text(GTK_LABEL(sDLProgress.URL), label); + + // to local path + label[0] = 0; + sprintf(localPath, "%s/%s", xpiDir, aComp->GetArchive()); + CompressToFit(localPath, label, kCharsInDLLabel); + gtk_label_set_text(GTK_LABEL(sDLProgress.localPath), label); + + gettimeofday(&sDLStartTime, NULL); +} + +#define SHOW_EVERY_N_KB 16 +int +nsInstallDlg::DownloadCB(int aBytesRd, int aTotal) +{ + struct timeval now; + char label[64]; + int rate; + gfloat percent = 0; + static int timesCalled = 0; + static int activityCount = 0; + int dlKB; + static int lastTotal = 0; + static int lastBytesRd = 0; + + // new component being downloaded + if (lastTotal != aTotal) + { + lastBytesRd = 0; // reset + lastTotal = aTotal; + } + + if ((aBytesRd - lastBytesRd) > 0) + { + sDLProgress.downloadedBytes += aBytesRd - lastBytesRd; + lastBytesRd = aBytesRd; + } + + if (bDLPause || bDLCancel) + { + return nsHTTPConn::E_USER_CANCEL; + } + + if (++timesCalled < SHOW_EVERY_N_KB) + return 0; + else + timesCalled = 0; + + gettimeofday(&now, NULL); + rate = (int) nsSocket::CalcRate(&sDLStartTime, &now, aBytesRd); + + // update the status -- bytes thus far, rate, percent in prog bar + dlKB = sDLProgress.downloadedBytes/1024; + sprintf(label, gCtx->Res("DL_STATUS_STR"), dlKB, sDLProgress.totalKB, rate); + gtk_label_set_text(GTK_LABEL(sDLProgress.status), label); + +/* + // only update rate in major label line + XXX remove this: DLRATE no longer exists + sprintf(label, gCtx->Res("DLRATE"), rate); + gtk_label_set_text(GTK_LABEL(sRateLabel), label); +*/ + + if (sDLProgress.totalKB <= 0) + { + // show some activity + if (activityCount >= 5) activityCount = 0; + percent = (gfloat)( (gfloat)activityCount++/ (gfloat)5 ); + gtk_progress_set_activity_mode(GTK_PROGRESS(sDLProgress.progBar), TRUE); + gtk_progress_bar_update(GTK_PROGRESS_BAR(sDLProgress.progBar), percent); + } + else + { + percent = (gfloat)dlKB/(gfloat)sDLProgress.totalKB; +#ifdef DEBUG + printf("DLProgress: %d of %d (%f percent) at %d KB/sec\n", dlKB, + sDLProgress.totalKB, percent, rate); +#endif + gtk_progress_set_activity_mode(GTK_PROGRESS(sDLProgress.progBar), + FALSE); + gtk_progress_bar_update(GTK_PROGRESS_BAR(sDLProgress.progBar), percent); + } + + XI_GTK_UPDATE_UI(); + return 0; +} + +void +nsInstallDlg::ClearRateLabel() +{ + gtk_label_set_text(GTK_LABEL(sRateLabel), ""); + gtk_progress_set_activity_mode(GTK_PROGRESS(sMajorProgBar), FALSE); + XI_GTK_UPDATE_UI(); +} + +void +nsInstallDlg::SaveModulesToggled(GtkWidget *aWidget, gpointer aData) +{ + if (GTK_TOGGLE_BUTTON(aWidget)->active) + { + DUMP("Save modules toggled on"); + gCtx->opt->mSaveModules = TRUE; + } + else + { + DUMP("Save modules toggled off"); + gCtx->opt->mSaveModules = FALSE; + } +} + +void +nsInstallDlg::ShowProxySettings(GtkWidget *aWidget, gpointer aData) +{ + GtkWidget *psDlg, *psTable; + GtkWidget *okButton, *cancelButton; + GtkWidget *psLabel[NUM_PS_ENTRIES]; + int i; + char resName[16], *text = nsnull; + + psDlg = gtk_dialog_new(); + gtk_window_set_title(GTK_WINDOW(psDlg), gCtx->opt->mTitle); + gtk_window_set_position(GTK_WINDOW(psDlg), GTK_WIN_POS_CENTER); + + psTable = gtk_table_new(5, 2, FALSE); + gtk_container_add(GTK_CONTAINER(GTK_DIALOG(psDlg)->vbox), psTable); + gtk_widget_show(psTable); + + // create labels + for (i = 0; i < NUM_PS_ENTRIES; ++i) + { + sprintf(resName, "PS_LABEL%d", i); + psLabel[i] = gtk_label_new(gCtx->Res(resName)); + gtk_widget_show(psLabel[i]); + + gtk_table_attach_defaults(GTK_TABLE(psTable), psLabel[i], + 0, 1, i, i + 1); + } + + // create text entry fields + for (i = 0; i < NUM_PS_ENTRIES; ++i) + { + sPSTextEntry[i] = gtk_entry_new(); + gtk_entry_set_editable(GTK_ENTRY(sPSTextEntry[i]), TRUE); + + // reset text if we already opened this dlg before + if (i == 0) text = gCtx->opt->mProxyHost; + if (i == 1) text = gCtx->opt->mProxyPort; + if (i == 2) text = gCtx->opt->mProxyUser; + if (i == 3) text = gCtx->opt->mProxyPswd; + + if (text) + gtk_entry_set_text(GTK_ENTRY(sPSTextEntry[i]), text); + + // password field + if (i + 1 == NUM_PS_ENTRIES) + gtk_entry_set_visibility(GTK_ENTRY(sPSTextEntry[i]), FALSE); + + gtk_widget_show(sPSTextEntry[i]); + + gtk_table_attach(GTK_TABLE(psTable), sPSTextEntry[i], + 1, 2, i, i + 1, + static_cast(GTK_FILL | GTK_EXPAND), + static_cast(GTK_FILL | GTK_EXPAND), 5, 5); + } + + // pre-populate text entry fields if data already stored + okButton = gtk_button_new_with_label(gCtx->Res("OK_LABEL")); + gtk_container_add(GTK_CONTAINER(GTK_DIALOG(psDlg)->action_area), + okButton); + gtk_signal_connect(GTK_OBJECT(okButton), "clicked", + GTK_SIGNAL_FUNC(PSDlgOK), psDlg); + gtk_widget_show(okButton); + + cancelButton = gtk_button_new_with_label(gCtx->Res("CANCEL_LABEL")); + gtk_container_add(GTK_CONTAINER(GTK_DIALOG(psDlg)->action_area), + cancelButton); + gtk_signal_connect(GTK_OBJECT(cancelButton), "clicked", + GTK_SIGNAL_FUNC(PSDlgCancel), psDlg); + gtk_widget_show(cancelButton); + + gtk_widget_show(psDlg); +} + +void +nsInstallDlg::PSDlgOK(GtkWidget *aWidget, gpointer aData) +{ + GtkWidget *dlg = (GtkWidget *) aData; + char *text; + + // grab proxy host field + if (sPSTextEntry[0]) + { + text = gtk_editable_get_chars(GTK_EDITABLE(sPSTextEntry[0]), 0, -1); + if (text) + { + XI_IF_FREE(gCtx->opt->mProxyHost); + gCtx->opt->mProxyHost = text; + } + } + + // grab proxy port field + if (sPSTextEntry[1]) + { + text = gtk_editable_get_chars(GTK_EDITABLE(sPSTextEntry[1]), 0, -1); + if (text) + { + XI_IF_FREE(gCtx->opt->mProxyPort); + gCtx->opt->mProxyPort = text; + } + } + + // grab proxy user field + if (sPSTextEntry[2]) + { + text = gtk_editable_get_chars(GTK_EDITABLE(sPSTextEntry[2]), 0, -1); + if (text) + { + XI_IF_FREE(gCtx->opt->mProxyUser); + gCtx->opt->mProxyUser = text; + } + } + + // grab proxy pswd field + if (sPSTextEntry[3]) + { + text = gtk_editable_get_chars(GTK_EDITABLE(sPSTextEntry[3]), 0, -1); + if (text) + { + XI_IF_FREE(gCtx->opt->mProxyPswd); + gCtx->opt->mProxyPswd = text; + } + } + + if (dlg) + gtk_widget_destroy(dlg); +} + +void +nsInstallDlg::PSDlgCancel(GtkWidget *aWidget, gpointer aData) +{ + GtkWidget *dlg = (GtkWidget *) aData; + + if (dlg) + gtk_widget_destroy(dlg); +} + +void +nsInstallDlg::DLPause(GtkWidget *aWidget, gpointer aData) +{ + DUMP("DLPause"); + + // set pause for download callback to return to libxpnet + bDLPause = TRUE; + + // disbale pause button + gtk_widget_set_sensitive(gCtx->back, FALSE); + + // enable resume button + gtk_widget_set_sensitive(gCtx->next, TRUE); + + gtk_main(); +} + +void +nsInstallDlg::DLResume(GtkWidget *aWidget, gpointer aData) +{ + DUMP("DLResume"); + + if (!bDLPause) + { + DUMP("Not paused"); + return; + } + + DUMP("Unsetting bDLPause"); + bDLPause = FALSE; + + // disable resume button + gtk_widget_set_sensitive(gCtx->next, FALSE); + + // enable pause button + gtk_widget_set_sensitive(gCtx->back, TRUE); + + gtk_main_quit(); + + PerformInstall(); + + return; +} + +void +nsInstallDlg::DLCancel(GtkWidget *aWidget, gpointer aData) +{ + DUMP("DLCancel"); + + // show cancellation confirm dialog + // XXX TO DO + + // set cancel for download callback to return to libxpnet + bDLCancel = TRUE; + +#ifdef DEBUG + printf("%s %d: bDLPause: %d\tbDLCancel: %d\n", __FILE__, __LINE__, + bDLPause, bDLCancel); +#endif + + // already paused then take explicit action to quit + if (bDLPause) + { + gtk_main_quit(); + } +} + +int +nsInstallDlg::CancelOrPause() +{ + int err = OK; + + if (bDLPause) + { + err = E_DL_PAUSE; + } + else if (bDLCancel) + { + err = E_DL_CANCEL; + } + + return err; +} + +static GtkWidget *crcDlg = (GtkWidget *) NULL; + +void +nsInstallDlg::ShowCRCDlg() +{ + GtkWidget *label; + + if (gCtx->opt->mMode == nsXIOptions::MODE_SILENT) { + ErrorHandler(E_CRC_FAILED); + return; + } + + if ( crcDlg == (GtkWidget *) NULL ) { + // throw up dialog informing user to press resume + // or to cancel out + crcDlg = gtk_dialog_new_with_buttons(gCtx->opt->mTitle, NULL, + (GtkDialogFlags) 0, + GTK_STOCK_OK, + GTK_RESPONSE_NONE, + NULL); + + label = gtk_label_new(gCtx->Res("CRC_CHECK")); + + g_signal_connect_swapped(GTK_OBJECT(crcDlg), "response", + G_CALLBACK(CRCOKCb), GTK_OBJECT(crcDlg)); + + gtk_container_add(GTK_CONTAINER(GTK_DIALOG(crcDlg)->vbox), label); + gtk_widget_show_all(crcDlg); + } + XI_GTK_UPDATE_UI(); +} + +int +nsInstallDlg::ShowCRCFailedDlg() +{ + GtkWidget *crcFailedDlg, *label; + + // throw up dialog informing user to press resume + // or to cancel out + if (gCtx->opt->mMode == nsXIOptions::MODE_SILENT) { + ErrorHandler(E_CRC_FAILED); + return OK; + } + + crcFailedDlg = gtk_dialog_new_with_buttons(gCtx->opt->mTitle, NULL, + GTK_DIALOG_MODAL, + GTK_STOCK_OK, + GTK_RESPONSE_NONE, + NULL); + label = gtk_label_new(gCtx->Res("CRC_FAILED")); + + g_signal_connect_swapped(GTK_OBJECT(crcFailedDlg), "response", + G_CALLBACK(CRCFailedOK), GTK_OBJECT(crcFailedDlg)); + gtk_container_add(GTK_CONTAINER(GTK_DIALOG(crcFailedDlg)->vbox), label); + gtk_widget_show_all(crcFailedDlg); + XI_GTK_UPDATE_UI(); + + return OK; +} + +int +nsInstallDlg::ShowCxnDroppedDlg() +{ + GtkWidget *cxnDroppedDlg, *label; + + // throw up dialog informing user to press resume + // or to cancel out + if (gCtx->opt->mMode == nsXIOptions::MODE_SILENT) { + ErrorHandler(E_NO_DOWNLOAD); + return OK; + } + + cxnDroppedDlg = gtk_dialog_new_with_buttons(gCtx->opt->mTitle, NULL, + GTK_DIALOG_MODAL, + GTK_STOCK_OK, + GTK_RESPONSE_NONE, + NULL); + + label = gtk_label_new(gCtx->Res("CXN_DROPPED")); + g_signal_connect_swapped(GTK_OBJECT(cxnDroppedDlg), "response", + G_CALLBACK(CxnDroppedOK), GTK_OBJECT(cxnDroppedDlg)); + gtk_container_add(GTK_CONTAINER(GTK_DIALOG(cxnDroppedDlg)->vbox), label); + gtk_widget_show_all(cxnDroppedDlg); + XI_GTK_UPDATE_UI(); + + return OK; +} + +void +nsInstallDlg::CRCFailedOK(GtkWidget *aWidget, gpointer aData) +{ + gtk_main_quit(); + return; +} + +void +nsInstallDlg::DestroyCRCDlg() +{ + CRCOKCb( (GtkWidget *) NULL, (gpointer) NULL ); +} + +void +nsInstallDlg::CRCOKCb(GtkWidget *aWidget, gpointer aData) +{ + if (crcDlg != (GtkWidget *) NULL) + gtk_widget_destroy(crcDlg); + crcDlg = (GtkWidget *) NULL; + + return; +} + +void +nsInstallDlg::CxnDroppedOK(GtkWidget *aWidget, gpointer aData) +{ + GtkWidget *cxnDroppedDlg = (GtkWidget *) aData; + + if (cxnDroppedDlg) + gtk_widget_destroy(cxnDroppedDlg); + + return; +} + +void +nsInstallDlg::HideNavButtons() +{ + gtk_signal_disconnect(GTK_OBJECT(gCtx->back), gCtx->backID); + gtk_signal_disconnect(GTK_OBJECT(gCtx->next), gCtx->nextID); + gtk_signal_disconnect(GTK_OBJECT(gCtx->cancel), gCtx->cancelID); + + gtk_widget_set_sensitive(gCtx->back, FALSE); + gtk_widget_set_sensitive(gCtx->next, FALSE); + gtk_widget_set_sensitive(gCtx->cancel, FALSE); +} + +void +nsInstallDlg::InitDLProgress( int isFirst ) +{ + GtkWidget *titles[4]; + GtkWidget *hbox; + GtkWidget *table; + + gCtx->idlg->HideTable(); + + if ( isFirst == TRUE ) { + sDLProgress.vbox = gtk_vbox_new(FALSE, 10); + gtk_notebook_append_page(GTK_NOTEBOOK(gCtx->notebook), + sDLProgress.vbox, NULL); + gtk_widget_show(sDLProgress.vbox); + + table = gtk_table_new(5, 2, FALSE); + gtk_box_pack_start(GTK_BOX(sDLProgress.vbox), table, FALSE, + FALSE, 0); + gtk_widget_show(table); + + // setup static title progress labels in table left column + titles[0] = gtk_label_new(gCtx->Res("DOWNLOADING")); + titles[1] = gtk_label_new(gCtx->Res("FROM")); + titles[2] = gtk_label_new(gCtx->Res("TO")); + titles[3] = gtk_label_new(gCtx->Res("STATUS")); + + // setup dynamic progress labels in right column + sDLProgress.compName = gtk_label_new(gCtx->Res("UNKNOWN")); + sDLProgress.URL = gtk_label_new(gCtx->Res("UNKNOWN")); + sDLProgress.localPath = gtk_label_new(gCtx->Res("UNKNOWN")); + sDLProgress.status = gtk_label_new(gCtx->Res("UNKNOWN")); + + // pack and show titles + for (int i = 0; i < 4; ++i) + { + hbox = gtk_hbox_new(FALSE, 10); + gtk_box_pack_end(GTK_BOX(hbox), titles[i], FALSE, FALSE, 0); + gtk_table_attach(GTK_TABLE(table), hbox, + 0, 1, i, i + 1, GTK_FILL, GTK_FILL, 5, 5); + gtk_widget_show(titles[i]); + gtk_widget_show(hbox); + } + + // pack and show dynamic labels + hbox = gtk_hbox_new(FALSE, 10); + gtk_box_pack_start(GTK_BOX(hbox), sDLProgress.compName, FALSE, FALSE, 0); + gtk_table_attach(GTK_TABLE(table), hbox, 1, 2, 0, 1, + GTK_FILL, GTK_FILL, 5, 5); + gtk_widget_show(sDLProgress.compName); + gtk_widget_show(hbox); + + hbox = gtk_hbox_new(FALSE, 10); + gtk_box_pack_start(GTK_BOX(hbox), sDLProgress.URL, FALSE, FALSE, 0); + gtk_table_attach(GTK_TABLE(table), hbox, 1, 2, 1, 2, + GTK_FILL, GTK_FILL, 5, 5); + gtk_widget_show(sDLProgress.URL); + gtk_widget_show(hbox); + + hbox = gtk_hbox_new(FALSE, 10); + gtk_box_pack_start(GTK_BOX(hbox), sDLProgress.localPath, FALSE, + FALSE, 0); + gtk_table_attach(GTK_TABLE(table), hbox, 1, 2, 2, 3, + GTK_FILL, GTK_FILL, 5, 5); + gtk_widget_show(sDLProgress.localPath); + gtk_widget_show(hbox); + + hbox = gtk_hbox_new(FALSE, 10); + gtk_box_pack_start(GTK_BOX(hbox), sDLProgress.status, FALSE, + FALSE, 0); + gtk_table_attach(GTK_TABLE(table), hbox, 1, 2, 3, 4, + GTK_FILL, GTK_FILL, 5, 5); + gtk_widget_show(sDLProgress.status); + gtk_widget_show(hbox); + + // init and show prog bar + sDLProgress.progBar = gtk_progress_bar_new(); + + // show prog bar + hbox = gtk_hbox_new(TRUE, 10); + gtk_box_pack_start(GTK_BOX(hbox), sDLProgress.progBar, FALSE, + TRUE, 0); + gtk_box_pack_start(GTK_BOX(sDLProgress.vbox), hbox, FALSE, + FALSE, 0); + gtk_widget_show(sDLProgress.progBar); + gtk_widget_show(hbox); + } + + // set to non-activity mode and initialize + gtk_progress_set_activity_mode(GTK_PROGRESS(sDLProgress.progBar), FALSE); + gtk_progress_bar_update(GTK_PROGRESS_BAR(sDLProgress.progBar), (gfloat) 0); + + // compute total download size + sDLProgress.downloadedBytes = 0; + sDLProgress.totalKB = TotalDLSize(); + + XI_GTK_UPDATE_UI(); +} + +void +nsInstallDlg::InitInstallProgress() +{ + if ( sDLProgress.vbox ) + gtk_widget_hide(sDLProgress.vbox); + gCtx->idlg->ShowTable(); +} + +int +nsInstallDlg::TotalDLSize() +{ + int total = 0; // in KB + int bCustom; + nsComponentList *comps; + nsComponent *currComp; + int archiveSize, currentSize; + + bCustom = (gCtx->opt->mSetupType == (gCtx->sdlg->GetNumSetupTypes() - 1)); + comps = gCtx->sdlg->GetSelectedSetupType()->GetComponents(); + currComp = comps->GetHead(); + + // loop through all components + while (currComp) + { + if ((bCustom && currComp->IsSelected()) || (!bCustom)) + { + // if still have to download + if (!currComp->IsDownloaded()) + { + // find archive size - amount downloaded already + archiveSize = currComp->GetArchiveSize(); + currentSize = currComp->GetCurrentSize(); + +#ifdef DEBUG + printf("%s ar sz = %d cu sz = %d\n", currComp->GetArchive(), + archiveSize, currentSize); +#endif + + total += (archiveSize - currentSize); + } + } + currComp = currComp->GetNext(); + } + + return total; +} + +void +nsInstallDlg::CompressToFit(char *aOrigStr, char *aOutStr, int aOutStrLen) +{ + int origStrLen; + int halfOutStrLen; + char *lastPart; // last aOrigStr part start + + if (!aOrigStr || !aOutStr || aOutStrLen <= 0) + return; + + origStrLen = strlen(aOrigStr); + halfOutStrLen = (aOutStrLen/2) - 2; // minus 2 since ellipsis is 3 chars + lastPart = aOrigStr + origStrLen - halfOutStrLen; + + strncpy(aOutStr, aOrigStr, halfOutStrLen); + *(aOutStr + halfOutStrLen) = 0; + strcat(aOutStr, "..."); + strncat(aOutStr, lastPart, strlen(lastPart)); + *(aOutStr + aOutStrLen + 1) = 0; +} + +void +nsInstallDlg::ReInitUI( void ) +{ + InitDLProgress( FALSE ); +} diff --git a/mozilla/toolkit/mozapps/installer/unix/wizard/nsInstallDlg.h b/mozilla/toolkit/mozapps/installer/unix/wizard/nsInstallDlg.h new file mode 100644 index 00000000000..8cf9dbdffcb --- /dev/null +++ b/mozilla/toolkit/mozapps/installer/unix/wizard/nsInstallDlg.h @@ -0,0 +1,113 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* + * The contents of this file are subject to the Netscape Public + * License Version 1.1 (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.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is Mozilla Communicator client code, + * released March 31, 1998. + * + * The Initial Developer of the Original Code is Netscape Communications + * Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + * Samir Gehani + */ + +#ifndef _NS_INSTALLDLG_H_ +#define _NS_INSTALLDLG_H_ + +#include "nsXInstallerDlg.h" +#include "XIErrors.h" +#include "nsRunApp.h" + +class nsComponent; + +class nsInstallDlg : public nsXInstallerDlg +{ +public: + nsInstallDlg(); + ~nsInstallDlg(); + +/*------------------------------------------------------------------* + * Navigation + *------------------------------------------------------------------*/ + static void Back(GtkWidget *aWidget, gpointer aData); + static void Next(GtkWidget *aWidget, gpointer aData); + + int Parse(nsINIParser* aParser); + + int Show(int aDirection); + int Hide(int aDirection); + int ShowTable(); + int HideTable(); + + static void XPIProgressCB(const char *aMsg, int aVal, int aMax); + static void MajorProgressCB(char *aName, int aNum, int aTotal, + int aActivity); + static int DownloadCB(int aBytesRd, int aTotal); + static void SetDownloadComp(nsComponent *aComp, int aURLIndex, + int aNum, int aTotal); + static void ClearRateLabel(); + static int CancelOrPause(); + + void ReInitUI(); + void ShowCRCDlg(); + void DestroyCRCDlg(); + + enum + { + ACT_DOWNLOAD, + ACT_EXTRACT, + ACT_INSTALL + }; + + enum + { + E_DL_PAUSE = -1101, + E_DL_CANCEL = -1102, + E_DL_DROP_CXN = -1103 + }; + +/*------------------------------------------------------------------* + * INI Properties + *------------------------------------------------------------------*/ + int SetMsg0(char *aMsg); + char *GetMsg0(); + +private: + static int PerformInstall(void); // install start + static void SaveModulesToggled(GtkWidget *aWidget, gpointer aData); + static void ShowProxySettings(GtkWidget *aWidget, gpointer aData); + static void PSDlgOK (GtkWidget *aWidget, gpointer aData); + static void PSDlgCancel(GtkWidget *aWidget, gpointer aData); + static void RunApps(); + static void FreeRunAppList(); + int AppendRunApp(nsRunApp *aNewRunApp); + static void DLPause(GtkWidget *aWidget, gpointer aData); + static void DLResume(GtkWidget *aWidget, gpointer aData); + static void DLCancel(GtkWidget *aWidget, gpointer aData); + static int ShowCRCFailedDlg(); + static int ShowCxnDroppedDlg(); + static void CRCFailedOK(GtkWidget *aWidget, gpointer aData); + static void CxnDroppedOK(GtkWidget *aWidget, gpointer aData); + static void CRCOKCb(GtkWidget *aWidget, gpointer aData); + static void HideNavButtons(); + static void InitInstallProgress(); + static int TotalDLSize(); + static void CompressToFit(char *aOrigStr, char *aOutStr, + int aOutStrLen); + static void InitDLProgress(int IsFirst); + + char *mMsg0; +}; + +#endif /* _NS_INSTALLDLG_H_ */ diff --git a/mozilla/toolkit/mozapps/installer/unix/wizard/nsLicenseDlg.cpp b/mozilla/toolkit/mozapps/installer/unix/wizard/nsLicenseDlg.cpp new file mode 100644 index 00000000000..15517dbe66a --- /dev/null +++ b/mozilla/toolkit/mozapps/installer/unix/wizard/nsLicenseDlg.cpp @@ -0,0 +1,307 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* + * The contents of this file are subject to the Netscape Public + * License Version 1.1 (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.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is Mozilla Communicator client code, + * released March 31, 1998. + * + * The Initial Developer of the Original Code is Netscape Communications + * Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + * Samir Gehani + */ + +#include "nsLicenseDlg.h" +#include "nsXInstaller.h" +#include + +nsLicenseDlg::nsLicenseDlg() : + mLicenseFile(NULL), + mMsg0(NULL) +{ +} + +nsLicenseDlg::~nsLicenseDlg() +{ + XI_IF_FREE(mLicenseFile); +} + +void +nsLicenseDlg::Back(GtkWidget *aWidget, gpointer aData) +{ + DUMP("Back"); + if (aData != gCtx->ldlg) return; + +// XXX call gCtx->me->Shutdown() ? + gtk_main_quit(); + return; + +#if 0 + // hide this notebook page + gCtx->ldlg->Hide(nsXInstallerDlg::BACKWARD_MOVE); + + // disconnect this dlg's nav btn signal handlers + gtk_signal_disconnect(GTK_OBJECT(gCtx->back), gCtx->backID); + gtk_signal_disconnect(GTK_OBJECT(gCtx->next), gCtx->nextID); + + // show the prev dlg + gCtx->wdlg->Show(nsXInstallerDlg::BACKWARD_MOVE); +#endif +} + +void +nsLicenseDlg::Next(GtkWidget *aWidget, gpointer aData) +{ + DUMP("Next"); + if (aData != gCtx->ldlg) return; + + // hide this notebook page + gCtx->ldlg->Hide(nsXInstallerDlg::FORWARD_MOVE); + + // disconnect this dlg's nav btn signal handlers + gtk_signal_disconnect(GTK_OBJECT(gCtx->back), gCtx->backID); + gtk_signal_disconnect(GTK_OBJECT(gCtx->next), gCtx->nextID); + + // show the next dlg + gCtx->sdlg->Show(nsXInstallerDlg::FORWARD_MOVE); +} + +int +nsLicenseDlg::Parse(nsINIParser *aParser) +{ + int err = OK; + int bufsize = 0; + char *showDlg = NULL; + + /* compulsory keys*/ + XI_ERR_BAIL(aParser->GetStringAlloc(DLG_LICENSE, LICENSE, + &mLicenseFile, &bufsize)); + if (bufsize == 0 || !mLicenseFile) + return E_INVALID_KEY; + + bufsize = 5; + XI_ERR_BAIL(aParser->GetStringAlloc(DLG_LICENSE, SHOW_DLG, &showDlg, + &bufsize)); + if (bufsize != 0 && showDlg) + { + if (0 == strncmp(showDlg, "TRUE", 4)) + mShowDlg = nsXInstallerDlg::SHOW_DIALOG; + else if (0 == strncmp(showDlg, "FALSE", 5)) + mShowDlg = nsXInstallerDlg::SKIP_DIALOG; + } + + bufsize = 0; + XI_ERR_BAIL(aParser->GetStringAlloc(DLG_LICENSE, TITLE, &mTitle, + &bufsize)); + if (bufsize == 0) + XI_IF_FREE(mTitle); + + aParser->GetStringAlloc(DLG_LICENSE, SUBTITLE, &mSubTitle, &bufsize); + if (bufsize == 0) + XI_IF_FREE(mSubTitle); + + aParser->GetStringAlloc(DLG_LICENSE, MSG0, &mMsg0, &bufsize); + if (bufsize == 0) + XI_IF_FREE(mMsg0); + +BAIL: + return err; +} + +int +nsLicenseDlg::Show(int aDirection) +{ + int err = OK; + char *licenseContents = NULL; + char *titleBuf; + + XI_VERIFY(gCtx); + XI_VERIFY(gCtx->notebook); + + if (!mWidgetsInit) { + // static widget init + + // Create a vbox with the message and scrolled window, and append it + // as a page of the notebook. + + mBox = gtk_vbox_new(FALSE, 6); + gtk_container_set_border_width(GTK_CONTAINER(mBox), 12); + + gtk_notebook_append_page(GTK_NOTEBOOK(gCtx->notebook), mBox, NULL); + mPageNum = gtk_notebook_get_current_page(GTK_NOTEBOOK(gCtx->notebook)); + + // Change "\n" in the label to a space and a literal newline character. + char *newline = strstr(mMsg0, "\\n"); + if (newline) { + newline[0] = ' '; + newline[1] = '\n'; + } + + GtkWidget *msg0 = gtk_label_new(NULL); + gtk_label_set_markup(GTK_LABEL(msg0), mMsg0); + gtk_label_set_line_wrap(GTK_LABEL(msg0), TRUE); + gtk_misc_set_alignment(GTK_MISC(msg0), 0.0, 0.5); + gtk_box_pack_start(GTK_BOX(mBox), msg0, FALSE, FALSE, 0); + + GtkWidget *frame = gtk_frame_new(NULL); + // gtk_container_set_border_width(GTK_CONTAINER(frame), 10); + gtk_box_pack_start(GTK_BOX(mBox), frame, TRUE, TRUE, 0); + + GtkWidget *scrollWindow = gtk_scrolled_window_new(NULL, NULL); + gtk_container_add(GTK_CONTAINER(frame), scrollWindow); + + // read the license file contents into memory + licenseContents = GetLicenseContents(); + if (!licenseContents) { + err = ErrorHandler(E_EMPTY_LICENSE); + goto BAIL; + } + + GtkTextBuffer *buffer = gtk_text_buffer_new(NULL); + + GtkTextIter start_iter; + gtk_text_buffer_get_start_iter(buffer, &start_iter); + gtk_text_buffer_insert_with_tags(buffer, &start_iter, licenseContents, + -1, /* monoTag, */ NULL); + + GtkWidget *text = gtk_text_view_new_with_buffer(buffer); + gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(text), GTK_WRAP_WORD); + gtk_text_view_set_editable(GTK_TEXT_VIEW(text), FALSE); + gtk_text_view_set_left_margin(GTK_TEXT_VIEW(text), 2); + gtk_text_view_set_right_margin(GTK_TEXT_VIEW(text), 2); + // gtk_text_view_set_top_margin(GTK_TEXT_VIEW(text), 2); + // gtk_text_view_set_bottom_margin(GTK_TEXT_VIEW(text), 2); + + gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrollWindow), + GTK_POLICY_AUTOMATIC, + GTK_POLICY_AUTOMATIC); + + gtk_container_add(GTK_CONTAINER(scrollWindow), text); + + mWidgetsInit = TRUE; + } else { + gtk_notebook_set_page(GTK_NOTEBOOK(gCtx->notebook), mPageNum); + } + + gtk_widget_show_all(mBox); + + // title\0 + titleBuf = new char[strlen(mTitle) + 9]; + sprintf(titleBuf, "%s", mTitle); + + gtk_label_set_markup(GTK_LABEL(gCtx->header_title), titleBuf); + gtk_label_set_text(GTK_LABEL(gCtx->header_subtitle), mSubTitle); + + delete[] titleBuf; + + // Set up the header if we're moving forward. + if (aDirection == nsXInstallerDlg::FORWARD_MOVE) { + GtkStyle *style = gtk_widget_get_style(gCtx->header); + if (style->bg_pixmap[GTK_STATE_NORMAL]) { + gint width, height; + gdk_drawable_get_size(style->bg_pixmap[GTK_STATE_NORMAL], + &width, &height); + gtk_widget_set_size_request(gCtx->header, -1, height); + } + } + + // signal connect the buttons + gCtx->backID = gtk_signal_connect(GTK_OBJECT(gCtx->back), "clicked", + GTK_SIGNAL_FUNC(nsLicenseDlg::Back), gCtx->ldlg); + gCtx->nextID = gtk_signal_connect(GTK_OBJECT(gCtx->next), "clicked", + GTK_SIGNAL_FUNC(nsLicenseDlg::Next), gCtx->ldlg); + + // enable back button if we came from the welcome dlg + if (aDirection == nsXInstallerDlg::FORWARD_MOVE) + if (gCtx->back) + gtk_widget_set_sensitive(gCtx->back, TRUE); + + // always change the button titles to Accept/Decline + gtk_button_set_label(GTK_BUTTON(gCtx->next), gCtx->Res("ACCEPT")); + gtk_button_set_label(GTK_BUTTON(gCtx->back), gCtx->Res("DECLINE")); + +BAIL: + XI_IF_FREE(licenseContents); + return err; +} + +int +nsLicenseDlg::Hide(int aDirection) +{ + // hide all this dlg's widgets + gtk_widget_hide(mBox); + + return OK; +} + +int +nsLicenseDlg::SetLicenseFile(char *aLicenseFile) +{ + if (!aLicenseFile) + return E_PARAM; + + mLicenseFile = aLicenseFile; + + return OK; +} + +char * +nsLicenseDlg::GetLicenseFile() +{ + if (mLicenseFile) + return mLicenseFile; + + return NULL; +} + +char * +nsLicenseDlg::GetLicenseContents() +{ + char *buf = NULL; + FILE *fd = NULL; + struct stat attr; + int buflen; + + DUMP(mLicenseFile); + if (!mLicenseFile) + return NULL; + + // open file + fd = fopen(mLicenseFile, "r"); + if (!fd) return NULL; + DUMP("license fopen"); + + // get file length + if (0 != stat(mLicenseFile, &attr)) return NULL; + if (attr.st_size == 0) return NULL; + DUMP("license fstat"); + + // allocate buffer of file length + buflen = sizeof(char) * (attr.st_size + 1); + buf = (char *) malloc(buflen); + if (!buf) return NULL; + memset(buf, 0, buflen); + DUMP("license buf malloc"); + + // read entire file into buffer + if (attr.st_size != ((int) fread(buf, sizeof(char), attr.st_size, fd))) + XI_IF_FREE(buf); + DUMP("license fread"); + + // close file + fclose(fd); + DUMP("license close"); + + return buf; +} diff --git a/mozilla/toolkit/mozapps/installer/unix/wizard/nsLicenseDlg.h b/mozilla/toolkit/mozapps/installer/unix/wizard/nsLicenseDlg.h new file mode 100644 index 00000000000..f91f06f99b4 --- /dev/null +++ b/mozilla/toolkit/mozapps/installer/unix/wizard/nsLicenseDlg.h @@ -0,0 +1,62 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* + * The contents of this file are subject to the Netscape Public + * License Version 1.1 (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.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is Mozilla Communicator client code, + * released March 31, 1998. + * + * The Initial Developer of the Original Code is Netscape Communications + * Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + * Samir Gehani + */ + +#ifndef _NS_LICENSEDLG_H_ +#define _NS_LICENSEDLG_H_ + +#include "nsXInstallerDlg.h" +#include "XIErrors.h" + +class nsLicenseDlg : public nsXInstallerDlg +{ +public: + nsLicenseDlg(); + ~nsLicenseDlg(); + +/*-------------------------------------------------------------------* + * Navigation + *-------------------------------------------------------------------*/ + static void Back(GtkWidget *aWidget, gpointer aData); + static void Next(GtkWidget *aWidget, gpointer aData); + + int Parse(nsINIParser *aParser); + + int Show(int aDirection); + int Hide(int aDirection); + +/*-------------------------------------------------------------------* + * INI Properties + *-------------------------------------------------------------------*/ + int SetLicenseFile(char *aLicenseFile); + char *GetLicenseFile(); + char *GetLicenseContents(); + +private: + char *mLicenseFile; + char *mMsg0; + char *mMsg1; + GtkWidget *mBox; +}; + +#endif /* _NS_LICENSEDLG_H_ */ diff --git a/mozilla/toolkit/mozapps/installer/unix/wizard/nsRunApp.cpp b/mozilla/toolkit/mozapps/installer/unix/wizard/nsRunApp.cpp new file mode 100644 index 00000000000..d4f2ebe42ed --- /dev/null +++ b/mozilla/toolkit/mozapps/installer/unix/wizard/nsRunApp.cpp @@ -0,0 +1,63 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* + * The contents of this file are subject to the Netscape Public + * License Version 1.1 (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.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is Mozilla Communicator client code, + * released March 31, 1998. + * + * The Initial Developer of the Original Code is Netscape Communications + * Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + * Samir Gehani + */ + +#include "nsRunApp.h" + +nsRunApp::nsRunApp(char *aApp, char *aArgs) : + mApp(aApp), + mArgs(aArgs), + mNext(NULL) +{ +} + +nsRunApp::~nsRunApp() +{ + XI_IF_FREE(mApp); + XI_IF_FREE(mArgs); +} + +char * +nsRunApp::GetApp() +{ + return mApp; +} + +char * +nsRunApp::GetArgs() +{ + return mArgs; +} + +void +nsRunApp::SetNext(nsRunApp *aNext) +{ + mNext = aNext; +} + +nsRunApp * +nsRunApp::GetNext() +{ + return mNext; +} + diff --git a/mozilla/toolkit/mozapps/installer/unix/wizard/nsRunApp.h b/mozilla/toolkit/mozapps/installer/unix/wizard/nsRunApp.h new file mode 100644 index 00000000000..725979eaf7e --- /dev/null +++ b/mozilla/toolkit/mozapps/installer/unix/wizard/nsRunApp.h @@ -0,0 +1,47 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* + * The contents of this file are subject to the Netscape Public + * License Version 1.1 (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.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is Mozilla Communicator client code, + * released March 31, 1998. + * + * The Initial Developer of the Original Code is Netscape Communications + * Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + * Samir Gehani + */ + +#ifndef _NS_RUNAPP_H_ +#define _NS_RUNAPP_H_ + +#include "XIDefines.h" + +class nsRunApp +{ +public: + nsRunApp(char *aApp, char *aArgs); + ~nsRunApp(); + + char *GetApp(); + char *GetArgs(); + void SetNext(nsRunApp *aNext); + nsRunApp *GetNext(); + +private: + char *mApp; + char *mArgs; + nsRunApp *mNext; +}; + +#endif /* _NS_RUNAPP_H_ */ diff --git a/mozilla/toolkit/mozapps/installer/unix/wizard/nsSetupType.cpp b/mozilla/toolkit/mozapps/installer/unix/wizard/nsSetupType.cpp new file mode 100644 index 00000000000..ada217d1f70 --- /dev/null +++ b/mozilla/toolkit/mozapps/installer/unix/wizard/nsSetupType.cpp @@ -0,0 +1,139 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* + * The contents of this file are subject to the Netscape Public + * License Version 1.1 (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.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is Mozilla Communicator client code, + * released March 31, 1998. + * + * The Initial Developer of the Original Code is Netscape Communications + * Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + * Samir Gehani + */ + +#include "nsSetupType.h" + +nsSetupType::nsSetupType() : + mDescShort(NULL), + mDescLong(NULL), + mComponents(NULL), + mNext(NULL) +{ +} + +nsSetupType::~nsSetupType() +{ + if (mDescShort) + free (mDescShort); + if (mDescLong) + free (mDescLong); + if (mComponents) + delete mComponents; +} + +int +nsSetupType::SetDescShort(char *aDescShort) +{ + if (!aDescShort) + return E_PARAM; + + mDescShort = aDescShort; + + return OK; +} + +char * +nsSetupType::GetDescShort() +{ + if (mDescShort) + return mDescShort; + + return NULL; +} + +int +nsSetupType::SetDescLong(char *aDescLong) +{ + if (!aDescLong) + return E_PARAM; + + mDescLong = aDescLong; + + return OK; +} + +char * +nsSetupType::GetDescLong() +{ + if (mDescLong) + return mDescLong; + + return NULL; +} + +int +nsSetupType::SetComponent(nsComponent *aComponent) +{ + if (!aComponent) + return E_PARAM; + + if (!mComponents) + mComponents = new nsComponentList(); + + if (!mComponents) + return E_MEM; + + return mComponents->AddComponent(aComponent); +} + +int +nsSetupType::UnsetComponent(nsComponent *aComponent) +{ + if (!aComponent) + return E_PARAM; + + if (!mComponents) + return OK; + + return mComponents->RemoveComponent(aComponent); +} + +nsComponentList * +nsSetupType::GetComponents() +{ + if (mComponents) + return mComponents; + + return NULL; +} + +int +nsSetupType::SetNext(nsSetupType *aSetupType) +{ + if (!aSetupType) + return E_PARAM; + + mNext = aSetupType; + + return OK; +} + +nsSetupType * +nsSetupType::GetNext() +{ + if (mNext) + return mNext; + + return NULL; +} diff --git a/mozilla/toolkit/mozapps/installer/unix/wizard/nsSetupType.h b/mozilla/toolkit/mozapps/installer/unix/wizard/nsSetupType.h new file mode 100644 index 00000000000..c157931cc5c --- /dev/null +++ b/mozilla/toolkit/mozapps/installer/unix/wizard/nsSetupType.h @@ -0,0 +1,61 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* + * The contents of this file are subject to the Netscape Public + * License Version 1.1 (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.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is Mozilla Communicator client code, + * released March 31, 1998. + * + * The Initial Developer of the Original Code is Netscape Communications + * Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + * Samir Gehani + */ + +#ifndef _NS_SETUPTYPE_H_ +#define _NS_SETUPTYPE_H_ + +#include "XIDefines.h" +#include "XIErrors.h" + +#include "nsComponent.h" + +class nsComponentList; + +class nsSetupType +{ +public: + nsSetupType(); + ~nsSetupType(); + +/*--------------------------------------------------------------* + * Accessors/Mutators + *--------------------------------------------------------------*/ + int SetDescShort(char *aDescShort); + char * GetDescShort(); + int SetDescLong(char *aDescLong); + char * GetDescLong(); + int SetComponent(nsComponent *aComponent); + int UnsetComponent(nsComponent *aComponent); + nsComponentList *GetComponents(); + int SetNext(nsSetupType *aSetupType); + nsSetupType * GetNext(); + +private: + char *mDescShort; + char *mDescLong; + nsComponentList *mComponents; + nsSetupType *mNext; +}; + +#endif /* _NS_SETUPTYPE_H_ */ diff --git a/mozilla/toolkit/mozapps/installer/unix/wizard/nsSetupTypeDlg.cpp b/mozilla/toolkit/mozapps/installer/unix/wizard/nsSetupTypeDlg.cpp new file mode 100644 index 00000000000..6d6b350507c --- /dev/null +++ b/mozilla/toolkit/mozapps/installer/unix/wizard/nsSetupTypeDlg.cpp @@ -0,0 +1,936 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* + * The contents of this file are subject to the Netscape Public + * License Version 1.1 (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.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is Mozilla Communicator client code, + * released March 31, 1998. + * + * The Initial Developer of the Original Code is Netscape Communications + * Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + * Samir Gehani + */ + +#include "nscore.h" +#include "nsSetupTypeDlg.h" +#include "nsXInstaller.h" + + +// need these for statfs + +#ifdef HAVE_SYS_STATVFS_H +#include +#endif + +#ifdef HAVE_SYS_STATFS_H +#include +#endif + +#ifdef HAVE_STATVFS +#define STATFS statvfs +#else +#define STATFS statfs +#endif + + +static GtkWidget *sBrowseBtn; +static gint sBrowseBtnID; +static GtkWidget *sFolder; +static int sFilePickerUp = FALSE; + +nsSetupTypeDlg::nsSetupTypeDlg() : + mBox(NULL), + mExistingMsg(NULL), + mMsg0(NULL), + mSetupTypeList(NULL) +{ +} + +nsSetupTypeDlg::~nsSetupTypeDlg() +{ + FreeSetupTypeList(); + + XI_IF_FREE(mMsg0); + XI_IF_FREE(mExistingMsg); +} + +void +nsSetupTypeDlg::Back(GtkWidget *aWidget, gpointer aData) +{ + DUMP("Back"); + if (aData != gCtx->sdlg) return; + + // hide this notebook page + gCtx->sdlg->Hide(nsXInstallerDlg::BACKWARD_MOVE); + + // disconnect this dlg's nav btn signal handlers + gtk_signal_disconnect(GTK_OBJECT(gCtx->back), gCtx->backID); + gtk_signal_disconnect(GTK_OBJECT(gCtx->next), gCtx->nextID); + gtk_signal_disconnect(GTK_OBJECT(sBrowseBtn), sBrowseBtnID); + + // show the next dlg + gCtx->ldlg->Show(nsXInstallerDlg::BACKWARD_MOVE); +} + +void +nsSetupTypeDlg::Next(GtkWidget *aWidget, gpointer aData) +{ + DUMP("Next"); + if (aData != gCtx->sdlg) return; + + GSList *s = gCtx->sdlg->mRadioGroup; + while (s) { + if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(s->data))) + break; + + ++gCtx->opt->mSetupType; + s = s->next; + } + + // verify selected destination directory exists + if (OK != nsSetupTypeDlg::VerifyDestination()) + return; + + // old installation may exist: delete it + if (OK != nsSetupTypeDlg::DeleteOldInst()) + return; + + // if not custom setup type verify disk space + if (gCtx->opt->mSetupType != (gCtx->sdlg->GetNumSetupTypes() - 1)) + { + if (OK != nsSetupTypeDlg::VerifyDiskSpace()) + return; + } + + // hide this notebook page + gCtx->sdlg->Hide(nsXInstallerDlg::FORWARD_MOVE); + + // disconnect this dlg's nav btn signal handlers + gtk_signal_disconnect(GTK_OBJECT(gCtx->back), gCtx->backID); + gtk_signal_disconnect(GTK_OBJECT(gCtx->next), gCtx->nextID); + gtk_signal_disconnect(GTK_OBJECT(sBrowseBtn), sBrowseBtnID); + + // show the last dlg + if (gCtx->opt->mSetupType == (gCtx->sdlg->GetNumSetupTypes() - 1)) + gCtx->cdlg->Show(nsXInstallerDlg::FORWARD_MOVE); + else + gCtx->idlg->Show(nsXInstallerDlg::FORWARD_MOVE); +} + +nsComponent* +nsSetupTypeDlg::ParseComponent(nsINIParser *aParser, char *aCompName) +{ + char *descShort = NULL, *descLong = NULL, *archive = NULL, + *installSize = NULL, *archiveSize = NULL, *attr = NULL; + int bufsize = 0, err; + nsComponent *comp = NULL; + + err = aParser->GetStringAlloc(aCompName, DESC_SHORT, &descShort, &bufsize); + if (err != OK) + goto bail; + + err = aParser->GetStringAlloc(aCompName, DESC_LONG, &descLong, &bufsize); + if (err != OK) + goto bail; + + err = aParser->GetStringAlloc(aCompName, ARCHIVE, &archive, &bufsize); + if (err != OK) + goto bail; + + err = aParser->GetStringAlloc(aCompName, INSTALL_SIZE, + &installSize, &bufsize); + if (err != OK) + goto bail; + + err = aParser->GetStringAlloc(aCompName, ARCHIVE_SIZE, + &archiveSize, &bufsize); + if (err != OK) + goto bail; + + err = aParser->GetStringAlloc(aCompName, ATTRIBUTES, &attr, &bufsize); + if (err != OK && err != nsINIParser::E_NO_KEY) // this is optional + goto bail; + + comp = new nsComponent(); + if (!comp) + goto bail; + + comp->SetDescShort(descShort); + comp->SetDescLong(descLong); + comp->SetArchive(archive); + comp->SetInstallSize(atoi(installSize)); + comp->SetArchiveSize(atoi(archiveSize)); + + if (strstr(attr, SELECTED_ATTR)) { + comp->SetSelected(); + comp->DepAddRef(); + } + else { + comp->SetUnselected(); + } + + if (strstr(attr, INVISIBLE_ATTR)) + comp->SetInvisible(); + else + comp->SetVisible(); + + if (strstr(attr, LAUNCHAPP_ATTR)) + comp->SetLaunchApp(); + else + comp->SetDontLaunchApp(); + + if (strstr(attr, DOWNLOAD_ONLY_ATTR)) + comp->SetDownloadOnly(); + + if (strstr(attr, MAIN_COMPONENT_ATTR)) + comp->SetMainComponent(); + + for (int i = 0; i < MAX_URLS; ++i) { + char urlKey[MAX_URL_LEN], *currURL; + sprintf(urlKey, URLd, i); + err = aParser->GetStringAlloc(aCompName, urlKey, &currURL, &bufsize); + if (err != OK) + break; + + comp->SetURL(currURL, i); + } + + for (int j = 0; j < MAX_COMPONENTS; ++j) { + char *currDep = NULL; + char key[MAX_DEPENDEE_KEY_LEN]; + + sprintf(key, DEPENDEEd, j); + + err = aParser->GetStringAlloc(aCompName, key, &currDep, &bufsize); + if (bufsize == 0 || err != OK) + break; // no more dependees + + comp->AddDependee(currDep); // we will scan for invalid dependencies later + } + + return comp; + bail: + return NULL; +} + +int +nsSetupTypeDlg::Parse(nsINIParser *aParser) +{ + int err = OK; + int bufsize = 0; + char *showDlg = NULL; + int i, j; + char *currSec = (char *) malloc(strlen(SETUP_TYPE) + 3); // e.g. SetupType12 + if (!currSec) return E_MEM; + char *currKey = (char *) malloc(1 + 3); // e.g. C0, C1, C12 + if (!currKey) return E_MEM; + char *currVal = NULL; + nsComponent *currComp = NULL; + int currNumComps = 0; + nsSetupType *currST = NULL; + char *currDescShort = NULL; + char *currDescLong = NULL; + + XI_VERIFY(gCtx); + + XI_ERR_BAIL(aParser->GetStringAlloc(DLG_SETUP_TYPE, MSGEXISTING, + &mExistingMsg, &bufsize)); + if (bufsize == 0) + XI_IF_FREE(mExistingMsg); + + /* optional keys */ + err = aParser->GetStringAlloc(DLG_SETUP_TYPE, MSG0, &mMsg0, &bufsize); + if (err != OK && err != nsINIParser::E_NO_KEY) goto BAIL; else err = OK; + + bufsize = 5; + err = aParser->GetStringAlloc(DLG_SETUP_TYPE, SHOW_DLG, &showDlg, &bufsize); + if (err != OK && err != nsINIParser::E_NO_KEY) goto BAIL; else err = OK; + if (bufsize != 0 && showDlg) + { + if (0 == strncmp(showDlg, "TRUE", 4)) + mShowDlg = nsXInstallerDlg::SHOW_DIALOG; + else if (0 == strncmp(showDlg, "FALSE", 5)) + mShowDlg = nsXInstallerDlg::SKIP_DIALOG; + } + + bufsize = 0; + err = aParser->GetStringAlloc(DLG_SETUP_TYPE, TITLE, &mTitle, &bufsize); + if (err != OK && err != nsINIParser::E_NO_KEY) goto BAIL; else err = OK; + if (bufsize == 0) + XI_IF_FREE(mTitle); + + aParser->GetStringAlloc(DLG_SETUP_TYPE, SUBTITLE, &mSubTitle, &bufsize); + if (bufsize == 0) + XI_IF_FREE(mSubTitle); + + /* setup types */ + for (i=0; iGetStringAlloc(currSec, DESC_SHORT, &currDescShort, + &bufsize); + if (err != OK && err != nsINIParser::E_NO_SEC) goto fin_iter; + if (bufsize == 0 || err == nsINIParser::E_NO_SEC) // no more setup types + { + err = OK; + break; + } + + bufsize = 0; + err = aParser->GetStringAlloc(currSec, DESC_LONG, &currDescLong, + &bufsize); + if (err != OK || bufsize == 0) goto fin_iter; + + currST = new nsSetupType(); + if (!currST) goto fin_iter; + + // The short description may contain mnemonics by prefixing + // characters with "&". We need to change these to "_" for GTK. + for (char *c = currDescShort; *c != '\0'; ++c) { + if (*c == '&') // XXX this doesn't quite handle "&&" + *c = '_'; + } + + currST->SetDescShort(currDescShort); + currST->SetDescLong(currDescLong); + + currNumComps = 0; + for (j=0; jGetStringAlloc(currSec, currKey, &currVal, + &bufsize); + if (err != OK && err != nsINIParser::E_NO_KEY) continue; + if (bufsize == 0 || err == nsINIParser::E_NO_KEY) + { + err = OK; + break; + } + + currComp = ParseComponent(aParser, currVal); + if (currComp) { + currST->SetComponent(currComp); + ++currNumComps; + } + } + + if (currNumComps > 0) + { + AddSetupType(currST); + currST = NULL; + } + +fin_iter: + XI_IF_DELETE(currST); + } + + err = OK; + +BAIL: + XI_IF_FREE(currSec); + XI_IF_FREE(currKey); + + return err; +} + +int +nsSetupTypeDlg::Show(int aDirection) +{ + int err = OK; + int numSetupTypes = 0; + GtkWidget *radbtn; + nsSetupType *currST = NULL; + GtkWidget *frame = NULL; + + XI_VERIFY(gCtx); + XI_VERIFY(gCtx->notebook); + + if (mWidgetsInit == FALSE) + { + // add a vbox as a page of the notebook + mBox = gtk_vbox_new(FALSE, 0); + gtk_container_set_border_width(GTK_CONTAINER(mBox), 12); + gtk_notebook_append_page(GTK_NOTEBOOK(gCtx->notebook), mBox, NULL); + mPageNum = gtk_notebook_get_current_page(GTK_NOTEBOOK(gCtx->notebook)); + + // add the top text label + GtkWidget *msg0 = gtk_label_new(mMsg0); + gtk_misc_set_alignment(GTK_MISC(msg0), 0.0, 0.5); + gtk_box_pack_start(GTK_BOX(mBox), msg0, FALSE, FALSE, 12); + + // for each setup type, pack into the vbox: + // an hbox containing: (this is to pad the radio button on the right) + // the radio button with short description + // a label with the long description + + numSetupTypes = GetNumSetupTypes(); + currST = GetSetupTypeList(); + + for (int i = 0; i < numSetupTypes; ++i, currST = currST->GetNext()) { + if (i == 0) { + radbtn = gtk_radio_button_new_with_mnemonic(NULL, + currST->GetDescShort()); + mRadioGroup = gtk_radio_button_get_group(GTK_RADIO_BUTTON(radbtn)); + } else { + radbtn = gtk_radio_button_new_with_mnemonic(mRadioGroup, + currST->GetDescShort()); + } + + + GtkWidget *hbox = gtk_hbox_new(FALSE, 0); + gtk_box_pack_start(GTK_BOX(hbox), radbtn, FALSE, FALSE, 0); + gtk_box_pack_start(GTK_BOX(mBox), hbox, FALSE, FALSE, 6); + + GtkWidget *desc = gtk_label_new(currST->GetDescLong()); + gtk_label_set_line_wrap(GTK_LABEL(desc), TRUE); + gtk_misc_set_alignment(GTK_MISC(desc), 0.0, 0.5); + + // Pad the labels so that they line up with the radio button text + gint ind_size, ind_spacing; + gtk_widget_style_get(radbtn, + "indicator_size", &ind_size, + "indicator_spacing", &ind_spacing, + NULL); + + gtk_misc_set_padding(GTK_MISC(desc), ind_size + ind_spacing * 3, 0); + gtk_box_pack_start(GTK_BOX(mBox), desc, FALSE, FALSE, 6); + } + + + frame = gtk_frame_new(gCtx->Res("DEST_DIR")); + gtk_box_pack_start(GTK_BOX(mBox), frame, FALSE, FALSE, 12); + + GtkWidget *frame_hbox = gtk_hbox_new(FALSE, 6); + gtk_container_set_border_width(GTK_CONTAINER(frame_hbox), 6); + gtk_container_add(GTK_CONTAINER(frame), frame_hbox); + + if (!gCtx->opt->mDestination) { + gCtx->opt->mDestination = (char*)malloc(MAXPATHLEN * sizeof(char)); + getcwd(gCtx->opt->mDestination, MAXPATHLEN); + } + + sFolder = gtk_label_new(gCtx->opt->mDestination); + gtk_label_set_line_wrap(GTK_LABEL(sFolder), TRUE); + gtk_misc_set_alignment(GTK_MISC(sFolder), 0.0, 0.5); + gtk_box_pack_start(GTK_BOX(frame_hbox), sFolder, TRUE, TRUE, 0); + + sBrowseBtn = gtk_button_new_with_label(gCtx->Res("BROWSE")); + gtk_box_pack_start(GTK_BOX(frame_hbox), sBrowseBtn, FALSE, FALSE, 0); + + mWidgetsInit = TRUE; + } else { + gtk_notebook_set_page(GTK_NOTEBOOK(gCtx->notebook), mPageNum); + } + + // title\0 + char *titleBuf = new char[strlen(mTitle) + 9]; + sprintf(titleBuf, "%s", mTitle); + + gtk_label_set_markup(GTK_LABEL(gCtx->header_title), titleBuf); + gtk_label_set_text(GTK_LABEL(gCtx->header_subtitle), mSubTitle); + + delete[] titleBuf; + + gtk_widget_show_all(mBox); + + // signal connect the buttons + // NOTE: back button disfunctional in this dlg since user accepted license + gCtx->backID = gtk_signal_connect(GTK_OBJECT(gCtx->back), "clicked", + GTK_SIGNAL_FUNC(nsSetupTypeDlg::Back), gCtx->sdlg); + gCtx->nextID = gtk_signal_connect(GTK_OBJECT(gCtx->next), "clicked", + GTK_SIGNAL_FUNC(nsSetupTypeDlg::Next), gCtx->sdlg); + sBrowseBtnID = gtk_signal_connect(GTK_OBJECT(sBrowseBtn), "clicked", + GTK_SIGNAL_FUNC(nsSetupTypeDlg::SelectFolder), NULL); + + if (aDirection == nsXInstallerDlg::FORWARD_MOVE) + { + // change the button titles back to Back/Next + gtk_button_set_label(GTK_BUTTON(gCtx->next), GTK_STOCK_GO_FORWARD); + gtk_button_set_label(GTK_BUTTON(gCtx->back), GTK_STOCK_GO_BACK); + } + // from install dlg + if (aDirection == nsXInstallerDlg::BACKWARD_MOVE && + // not custom setup type + gCtx->opt->mSetupType != (gCtx->sdlg->GetNumSetupTypes() - 1)) + { + DUMP("Back from Install to Setup Type"); + gtk_button_set_label(GTK_BUTTON(gCtx->next), GTK_STOCK_GO_FORWARD); + } + + gtk_widget_set_sensitive(gCtx->back, FALSE); + + return err; +} + +int +nsSetupTypeDlg::Hide(int aDirection) +{ + // gtk_widget_hide(mTable); + gtk_widget_hide(mBox); + + return OK; +} + +int +nsSetupTypeDlg::SetMsg0(char *aMsg) +{ + if (!aMsg) + return E_PARAM; + + mMsg0 = aMsg; + + return OK; +} + +char * +nsSetupTypeDlg::GetMsg0() +{ + if (mMsg0) + return mMsg0; + + return NULL; +} + +int +nsSetupTypeDlg::AddSetupType(nsSetupType *aSetupType) +{ + if (!aSetupType) + return E_PARAM; + + if (!mSetupTypeList) + { + mSetupTypeList = aSetupType; + return OK; + } + + nsSetupType *curr = mSetupTypeList; + nsSetupType *next; + while (curr) + { + next = NULL; + next = curr->GetNext(); + + if (!next) + { + return curr->SetNext(aSetupType); + } + + curr = next; + } + + return OK; +} + +nsSetupType * +nsSetupTypeDlg::GetSetupTypeList() +{ + if (mSetupTypeList) + return mSetupTypeList; + + return NULL; +} + +int +nsSetupTypeDlg::GetNumSetupTypes() +{ + int num = 0; + nsSetupType *curr = NULL; + + if (!mSetupTypeList) + return 0; + + curr = mSetupTypeList; + while(curr) + { + num++; + curr = curr->GetNext(); + } + + return num; +} + +nsSetupType * +nsSetupTypeDlg::GetSelectedSetupType() +{ + nsSetupType *curr = NULL; + int numSetupTypes = GetNumSetupTypes(); + int setupTypeCount = 0; + + curr = GetSetupTypeList(); + while (curr && setupTypeCount < numSetupTypes) // paranoia! + { + if (setupTypeCount == gCtx->opt->mSetupType) + return curr; + + setupTypeCount++; + curr = curr->GetNext(); + } + + return NULL; +} + +void +nsSetupTypeDlg::FreeSetupTypeList() +{ + nsSetupType *curr = mSetupTypeList; + nsSetupType *prev; + + while (curr) + { + prev = curr; + curr = curr->GetNext(); + + XI_IF_DELETE(prev); + } +} + +void +nsSetupTypeDlg::SelectFolder(GtkWidget *aWidget, gpointer aData) +{ + DUMP("SelectFolder"); + + if (sFilePickerUp) + return; + + GtkWidget *fileSel = NULL; + char *selDir = gCtx->opt->mDestination; + + fileSel = gtk_file_selection_new(gCtx->Res("SELECT_DIR")); + gtk_file_selection_set_filename(GTK_FILE_SELECTION(fileSel), selDir); + gtk_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(fileSel)->ok_button), + "clicked", (GtkSignalFunc) SelectFolderOK, fileSel); + gtk_signal_connect_object(GTK_OBJECT( + GTK_FILE_SELECTION(fileSel)->cancel_button), + "clicked", (GtkSignalFunc) SelectFolderCancel, + GTK_OBJECT(fileSel)); + gtk_widget_show(fileSel); + sFilePickerUp = TRUE; +} + +void +nsSetupTypeDlg::SelectFolderOK(GtkWidget *aWidget, GtkFileSelection *aFileSel) +{ + DUMP("SelectFolderOK"); + + struct stat destStat; + const gchar *selDir = + gtk_file_selection_get_filename(GTK_FILE_SELECTION(aFileSel)); + + // put the candidate file name in the global variable, then verify it + + strcpy(gCtx->opt->mDestination, selDir); + + if (0 == stat(selDir, &destStat)) + if (!S_ISDIR(destStat.st_mode) || VerifyDestination() != OK ) /* not a directory, or we don't have access permissions, so don't tear down */ + return; + + // update folder path displayed + gtk_label_set_text(GTK_LABEL(sFolder), gCtx->opt->mDestination); + gtk_widget_show(sFolder); + + // tear down file sel dlg + gtk_object_destroy(GTK_OBJECT(aFileSel)); + sFilePickerUp = FALSE; +} + +void +nsSetupTypeDlg::SelectFolderCancel(GtkWidget *aWidget, + GtkFileSelection *aFileSel) +{ + // tear down file sel dlg + gtk_object_destroy(GTK_OBJECT(aWidget)); + gtk_object_destroy(GTK_OBJECT(aFileSel)); + sFilePickerUp = FALSE; +} + +int +nsSetupTypeDlg::VerifyDestination() +{ + int stat_err = 0; + struct stat stbuf; + + stat_err = stat(gCtx->opt->mDestination, &stbuf); + if (stat_err == 0) + { + if (access(gCtx->opt->mDestination, R_OK | W_OK | X_OK ) != 0) + { + GtkWidget *noPermsDlg = + gtk_message_dialog_new(GTK_WINDOW(gCtx->window), + GtkDialogFlags(GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT), + GTK_MESSAGE_ERROR, + GTK_BUTTONS_OK, + gCtx->Res("NO_PERMS"), + gCtx->opt->mDestination); + + gtk_dialog_run(GTK_DIALOG(noPermsDlg)); + + return E_NO_PERMS; + } + else + { + // perms OK, we can proceed + return OK; + } + } + + // destination doesn't exist so ask user if we should create it + GtkWidget *createDestDlg = + gtk_message_dialog_new(GTK_WINDOW(gCtx->window), + GtkDialogFlags(GTK_DIALOG_MODAL|GTK_DIALOG_DESTROY_WITH_PARENT), + GTK_MESSAGE_QUESTION, + GTK_BUTTONS_YES_NO, + gCtx->Res("DOESNT_EXIST"), + gCtx->opt->mDestination); + + gint result = gtk_dialog_run(GTK_DIALOG(createDestDlg)); + gtk_widget_destroy(createDestDlg); + + if (result == GTK_RESPONSE_YES) { + // Create the destination directory. + char path[PATH_MAX + 1]; + int pathLen = strlen(gCtx->opt->mDestination); + int dirErr = 0; + + if (pathLen > PATH_MAX) + pathLen = PATH_MAX; + memcpy(path, gCtx->opt->mDestination, pathLen); + path[pathLen] = '/'; // for uniform handling + + struct stat buf; + mode_t oldPerms = umask(022); + + for (int i = 1; !dirErr && i <= pathLen; i++) { + if (path[i] == '/') { + path[i] = '\0'; + if (stat(path, &buf) != 0) { + dirErr = mkdir(path, (0777 & ~oldPerms)); + } + path[i] = '/'; + } + } + + umask(oldPerms); // restore original umask + if (dirErr != 0) + ErrorHandler(E_MKDIR_FAIL); + else + return OK; + } + + return E_NO_DEST; +} + +int +nsSetupTypeDlg::DeleteOldInst() +{ + DUMP("DeleteOldInst"); + + int err = OK; + struct stat dummy; + char path[MAXPATHLEN]; + + memset(path, 0, MAXPATHLEN); + ConstructPath(path, gCtx->opt->mDestination, gCtx->opt->mProgramName); + + DUMP(path); + + // check if old installation exists + if (0 == stat(path, &dummy)) { + // throw up delete dialog + GtkWidget *delInstDlg = + gtk_message_dialog_new(GTK_WINDOW(gCtx->window), + GtkDialogFlags(GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT), + GTK_MESSAGE_QUESTION, + GTK_BUTTONS_NONE, + gCtx->sdlg->mExistingMsg, + gCtx->opt->mDestination); + + gtk_dialog_add_buttons(GTK_DIALOG(delInstDlg), + GTK_STOCK_DELETE, GTK_RESPONSE_ACCEPT, + GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, NULL); + + gint result = gtk_dialog_run(GTK_DIALOG(delInstDlg)); + if (result == GTK_RESPONSE_ACCEPT) { + // Delete the old installation + char cwd[MAXPATHLEN]; + getcwd(cwd, MAXPATHLEN); + chdir(gCtx->opt->mDestination); + system("rm -rf *"); + chdir(cwd); + err = OK; + } else { + err = E_OLD_INST; + } + + gtk_widget_destroy(delInstDlg); + } + + return err; +} + +int +nsSetupTypeDlg::ConstructPath(char *aDest, char *aTrunk, char *aLeaf) +{ + int err = OK; + int trunkLen; + char *lastSlash = NULL; + + if (!aDest || !aTrunk || !aLeaf) + return E_PARAM; + + trunkLen = strlen(aTrunk); + lastSlash = strrchr(aTrunk, '/'); + + strcpy(aDest, aTrunk); + if (lastSlash != aTrunk + (trunkLen - 1)) + { + // need to tack on a slash + strcat(aDest, "/"); + } + strcat(aDest, aLeaf); + + return err; +} + +int +nsSetupTypeDlg::VerifyDiskSpace(void) +{ + int err = OK; + int dsAvail, dsReqd; + char dsAvailStr[128], dsReqdStr[128]; + char message[512]; + GtkWidget *noDSDlg, *label; + + // find disk space available at destination + dsAvail = DSAvailable(); + if (dsAvail < 0) + return OK; // optimistic when statfs failed + // or we don't have statfs + + // get disk space required + dsReqd = DSRequired(); + + if (dsReqd > dsAvail) + { + // throw up not enough ds dlg + sprintf(dsAvailStr, gCtx->Res("DS_AVAIL"), dsAvail); + sprintf(dsReqdStr, gCtx->Res("DS_REQD"), dsReqd); + sprintf(message, "%s\n%s\n\n%s", dsAvailStr, dsReqdStr, + gCtx->Res("NO_DISK_SPACE")); + + noDSDlg = gtk_dialog_new_with_buttons(gCtx->opt->mTitle, + NULL, (GtkDialogFlags) 0, + GTK_STOCK_OK, + GTK_RESPONSE_NONE, + NULL); + label = gtk_label_new(message); + + g_signal_connect_swapped(GTK_OBJECT(noDSDlg), "response", + G_CALLBACK(NoDiskSpaceOK), + GTK_OBJECT(noDSDlg)); + + gtk_container_add(GTK_CONTAINER(GTK_DIALOG(noDSDlg)->vbox), label); + gtk_widget_show_all(noDSDlg); + err = E_NO_DISK_SPACE; + } + + return err; +} + +int +nsSetupTypeDlg::DSAvailable(void) +{ + // returns disk space available in kilobytes + + int dsAvail = -1; + +#if defined(HAVE_SYS_STATVFS_H) || defined(HAVE_SYS_STATFS_H) + struct STATFS buf; + int rv; + + if (gCtx->opt->mDestination) + { + rv = STATFS(gCtx->opt->mDestination, &buf); + if (rv == 0) + { + if (buf.f_bsize > 1024 && (buf.f_bsize%1024 == 0)) + { + // normally the block size is >= 1024 and a multiple + // so we can shave off the last three digits before + // finding the product of the block size and num blocks + // which is important for large disks + + dsAvail = (buf.f_bsize/1024) * (buf.f_bavail); + } + else + { + // attempt to stuff into a 32 bit int even though + // we convert from bytes -> kilobytes later + // (may fail to compute on very large disks whose + // block size is not a multiple of 1024 -- highly + // improbable) + + dsAvail = (buf.f_bsize * buf.f_bavail)/1024; + } + } + } +#endif // HAVE_SYS_STATVFS_H -or- HAVE_SYS_STATFS_H + + return dsAvail; +} + +int +nsSetupTypeDlg::DSRequired(void) +{ + // returns disk space required in kilobytes + + int dsReqd = 0; + nsComponentList *comps; + int bCus; + + // find setup type's component list + bCus = (gCtx->opt->mSetupType == (gCtx->sdlg->GetNumSetupTypes() - 1)); + comps = gCtx->sdlg->GetSelectedSetupType()->GetComponents(); + + // loop through all components + nsComponent *currComp = comps->GetHead(); + while (currComp) + { + if ( (bCus == TRUE && currComp->IsSelected()) || (bCus == FALSE) ) + { + // add to disk space required + dsReqd += currComp->GetInstallSize(); + dsReqd += currComp->GetArchiveSize(); + } + + currComp = currComp->GetNext(); + } + + return dsReqd; +} + +void +nsSetupTypeDlg::NoDiskSpaceOK(GtkWidget *aWidget, gpointer aData) +{ + GtkWidget *noDSDlg = (GtkWidget *) aData; + + if (!noDSDlg) + return; + + gtk_widget_destroy(noDSDlg); +} + diff --git a/mozilla/toolkit/mozapps/installer/unix/wizard/nsSetupTypeDlg.h b/mozilla/toolkit/mozapps/installer/unix/wizard/nsSetupTypeDlg.h new file mode 100644 index 00000000000..05d451636e2 --- /dev/null +++ b/mozilla/toolkit/mozapps/installer/unix/wizard/nsSetupTypeDlg.h @@ -0,0 +1,86 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* + * The contents of this file are subject to the Netscape Public + * License Version 1.1 (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.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is Mozilla Communicator client code, + * released March 31, 1998. + * + * The Initial Developer of the Original Code is Netscape Communications + * Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + * Samir Gehani + */ + +#ifndef _NS_SETUPTYPEDLG_H_ +#define _NS_SETUPTYPEDLG_H_ + +#include +#include "nsXInstallerDlg.h" +#include "nsSetupType.h" + +class nsComponent; + +class nsSetupTypeDlg : public nsXInstallerDlg +{ +public: + nsSetupTypeDlg(); + ~nsSetupTypeDlg(); + +/*---------------------------------------------------------------------* + * Navigation + *---------------------------------------------------------------------*/ + static void Back(GtkWidget *aWidget, gpointer aData); + static void Next(GtkWidget *aWidget, gpointer aData); + + int Parse(nsINIParser *aParser); + + int Show(int aDirection); + int Hide(int aDirection); + + static void SelectFolder(GtkWidget *aWidget, gpointer aData); + static void SelectFolderOK(GtkWidget *aWidget, + GtkFileSelection *aFileSel); + static void SelectFolderCancel(GtkWidget *aWidget, + GtkFileSelection *aFileSel); + static int VerifyDestination(); + static int DeleteOldInst(); + static int ConstructPath(char *aDest, char *aTrunk, char *aLeaf); + static int VerifyDiskSpace(); + static int DSAvailable(); + static int DSRequired(); + static void NoDiskSpaceOK(GtkWidget *aWidget, gpointer aData); + +/*---------------------------------------------------------------------* + * INI Properties + *---------------------------------------------------------------------*/ + int SetMsg0(char *aMsg); + char *GetMsg0(); + + int AddSetupType(nsSetupType *aSetupType); + nsSetupType *GetSetupTypeList(); + int GetNumSetupTypes(); + nsSetupType *GetSelectedSetupType(); + +private: + void FreeSetupTypeList(); + nsComponent* ParseComponent(nsINIParser *aParser, char *aCompName); + + GtkWidget *mBox; + char *mExistingMsg; + char *mMsg0; + nsSetupType *mSetupTypeList; + GSList *mRadioGroup; +}; + +#endif /* _NS_SETUPTYPEDLG_H_ */ diff --git a/mozilla/toolkit/mozapps/installer/unix/wizard/nsWelcomeDlg.cpp b/mozilla/toolkit/mozapps/installer/unix/wizard/nsWelcomeDlg.cpp new file mode 100644 index 00000000000..d9ec7d4771f --- /dev/null +++ b/mozilla/toolkit/mozapps/installer/unix/wizard/nsWelcomeDlg.cpp @@ -0,0 +1,259 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* + * The contents of this file are subject to the Netscape Public + * License Version 1.1 (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.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is Mozilla Communicator client code, + * released March 31, 1998. + * + * The Initial Developer of the Original Code is Netscape Communications + * Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + * Samir Gehani + * Brian Ryner + */ + +#include "nsWelcomeDlg.h" +#include "nsXInstaller.h" +#include + +nsWelcomeDlg::nsWelcomeDlg() + : mTitle(NULL), mWelcomeMsg(NULL), mPixmap(NULL), mBox(NULL) +{ + memset(mMsgs, 0, sizeof(mMsgs)); +} + +nsWelcomeDlg::~nsWelcomeDlg() +{ + XI_IF_FREE(mPixmap); + for (int i = 0; i < kMsgCount; ++i) + XI_IF_FREE(mMsgs[i]); + + XI_IF_FREE(mWelcomeMsg); + XI_IF_FREE(mTitle); +} + +void +nsWelcomeDlg::Back(GtkWidget *aWidget, gpointer aData) +{ + DUMP("Back"); + if (aData != gCtx->wdlg) return; +} + +void +nsWelcomeDlg::Next(GtkWidget *aWidget, gpointer aData) +{ + DUMP("Next"); + if (aData != gCtx->wdlg) return; + + // hide this notebook page + gCtx->wdlg->Hide(nsXInstallerDlg::FORWARD_MOVE); + + // disconnect this dlg's nav btn signal handlers + gtk_signal_disconnect(GTK_OBJECT(gCtx->back), gCtx->backID); + gtk_signal_disconnect(GTK_OBJECT(gCtx->next), gCtx->nextID); + + // show the next dlg + gCtx->ldlg->Show(nsXInstallerDlg::FORWARD_MOVE); +} + +int +nsWelcomeDlg::Parse(nsINIParser *aParser) +{ + int bufsize = 0; + char *showDlg = NULL; + char msgName[] = "Message0"; + char *tmp; + + /* optional keys */ + bufsize = 5; + aParser->GetStringAlloc(DLG_WELCOME, SHOW_DLG, &showDlg, &bufsize); + if (bufsize != 0 && showDlg) { + if (strncmp(showDlg, "TRUE", 4) == 0) + mShowDlg = nsXInstallerDlg::SHOW_DIALOG; + else if (strncmp(showDlg, "FALSE", 5) == 0) + mShowDlg = nsXInstallerDlg::SKIP_DIALOG; + } + + bufsize = 0; + aParser->GetStringAlloc(DLG_WELCOME, TITLE, &mTitle, &bufsize); + if (bufsize == 0) + XI_IF_FREE(mTitle); + + bufsize = 0; + aParser->GetStringAlloc(DLG_WELCOME, WATERMARK, &mPixmap, &bufsize); + if (bufsize == 0) + XI_IF_FREE(mPixmap); + + bufsize = 0; + aParser->GetStringAlloc(DLG_WELCOME, MSGWELCOME, &tmp, &bufsize); + if (bufsize == 0) { + XI_IF_FREE(tmp); + } else { + mWelcomeMsg = g_strdup_printf(tmp, gCtx->opt->mProductName); + } + + for (int i = 0; i < kMsgCount; ++i) { + bufsize = 0; + msgName[7] = (char)(i + 48); // ASCII 48 == 0 + aParser->GetStringAlloc(DLG_WELCOME, msgName, &tmp, &bufsize); + if (bufsize == 0) { + XI_IF_FREE(tmp); + } else { + mMsgs[i] = g_strdup_printf(tmp, gCtx->opt->mProductName); + } + } + + return OK; +} + +int +nsWelcomeDlg::Show(int aDirection) +{ + int err = 0; + int msgLength = 0; + char *msgText, *textPos; + + XI_VERIFY(gCtx); + XI_VERIFY(gCtx->notebook); + + if (mWidgetsInit == FALSE) { + // static widget init + + // Note our page number in the wizard. + mPageNum = gtk_notebook_get_current_page(GTK_NOTEBOOK(gCtx->notebook)); + + // Set up the window title + gtk_window_set_title(GTK_WINDOW(gCtx->window), mTitle); + + mBox = gtk_hbox_new(FALSE, 0); + gtk_notebook_append_page(GTK_NOTEBOOK(gCtx->notebook), mBox, NULL); + + GtkWidget *wmbox = gtk_event_box_new(); + if (mPixmap) { + GdkPixmap *pm = gdk_pixmap_create_from_xpm(GDK_ROOT_PARENT(), + NULL, NULL, mPixmap); + + if (pm) { + GtkStyle *newStyle = gtk_style_copy(gtk_widget_get_style(wmbox)); + newStyle->bg_pixmap[GTK_STATE_NORMAL] = pm; + gtk_widget_set_style(wmbox, newStyle); + + // newStyle now owns the pixmap, so we don't unref it. + g_object_unref(newStyle); + + // Make the watermark box the width of the pixmap. + gint width, height; + gdk_drawable_get_size(pm, &width, &height); + gtk_widget_set_size_request(wmbox, width, -1); + } + } + + gtk_box_pack_start(GTK_BOX(mBox), wmbox, FALSE, FALSE, 0); + + wmbox = gtk_event_box_new(); + gtk_box_pack_start_defaults(GTK_BOX(mBox), wmbox); + + GtkWidget *inner_hbox = gtk_hbox_new(FALSE, 0); + gtk_container_add(GTK_CONTAINER(wmbox), inner_hbox); + + GtkWidget *spacer = gtk_alignment_new(0, 0, 0, 0); + gtk_widget_set_size_request(spacer, 5, -1); + gtk_box_pack_start(GTK_BOX(inner_hbox), spacer, FALSE, FALSE, 0); + + GtkWidget *vbox = gtk_vbox_new(FALSE, 8); + gtk_box_pack_start(GTK_BOX(inner_hbox), vbox, FALSE, FALSE, 0); + + for (int i = 0; i < kMsgCount - 1; ++i) + msgLength += strlen(mMsgs[i]); + +#define kSpanBegin "" +#define kSpanEnd "\n\n" + + msgLength += strlen(kSpanBegin) + strlen(mWelcomeMsg) + strlen(kSpanEnd); + msgText = (char*) malloc(msgLength + (kMsgCount - 1) * 2 + 1); + + textPos = msgText; + + textPos += sprintf(textPos, kSpanBegin "%s" kSpanEnd, mWelcomeMsg); + + for (int i = 0; i < kMsgCount - 1; ++i) + textPos += sprintf(textPos, "%s\n\n", mMsgs[i]); + + GtkWidget *msg = gtk_label_new(NULL); + gtk_label_set_markup(GTK_LABEL(msg), msgText); + gtk_label_set_line_wrap(GTK_LABEL(msg), TRUE); + gtk_misc_set_alignment(GTK_MISC(msg), 0.0, 0.5); + + GdkColor black_col = { 0, 0, 0, 0 }; + GdkColor white_col = { 0, 65535, 65535, 65535 }; + + gtk_widget_modify_text(msg, GTK_STATE_NORMAL, &black_col); + gtk_widget_modify_bg(wmbox, GTK_STATE_NORMAL, &white_col); + + gtk_box_pack_start(GTK_BOX(vbox), msg, FALSE, FALSE, 0); + gtk_container_child_set(GTK_CONTAINER(vbox), msg, "padding", 5, NULL); + + free(msgText); + + // Now add 100px of padding, and then the last mesage. + spacer = gtk_alignment_new(0.0, 0.0, 0.0, 0.0); + gtk_widget_set_size_request(spacer, -1, 110); + gtk_box_pack_start(GTK_BOX(vbox), spacer, FALSE, FALSE, 0); + + msgText = (char*) malloc(strlen(mMsgs[kMsgCount - 1]) + 2); + sprintf(msgText, "%s\n", mMsgs[kMsgCount - 1]); + + msg = gtk_label_new(msgText); + gtk_widget_modify_text(msg, GTK_STATE_NORMAL, &black_col); + gtk_misc_set_alignment(GTK_MISC(msg), 0.0, 0.5); + gtk_box_pack_start(GTK_BOX(vbox), msg, FALSE, FALSE, 0); + gtk_container_child_set(GTK_CONTAINER(vbox), msg, "padding", 5, NULL); + + free(msgText); + + mWidgetsInit = TRUE; + } else { + gtk_notebook_set_page(GTK_NOTEBOOK(gCtx->notebook), mPageNum); + } + + // No header image for the welcome dialog + gtk_widget_set_usize(gCtx->header, 0, 0); + + gtk_widget_show_all(mBox); + + // signal connect the buttons + gCtx->backID = gtk_signal_connect(GTK_OBJECT(gCtx->back), "clicked", + GTK_SIGNAL_FUNC(nsWelcomeDlg::Back), + gCtx->wdlg); + gCtx->nextID = gtk_signal_connect(GTK_OBJECT(gCtx->next), "clicked", + GTK_SIGNAL_FUNC(nsWelcomeDlg::Next), + gCtx->wdlg); + + gtk_widget_set_sensitive(gCtx->back, FALSE); + + GTK_WIDGET_SET_FLAGS(gCtx->next, GTK_CAN_DEFAULT); + gtk_widget_grab_default(gCtx->next); + gtk_widget_grab_focus(gCtx->next); + + return err; +} + +int +nsWelcomeDlg::Hide(int aDirection) +{ + // hide all this dlg's widgets + gtk_widget_hide(mBox); + + return OK; +} diff --git a/mozilla/toolkit/mozapps/installer/unix/wizard/nsWelcomeDlg.h b/mozilla/toolkit/mozapps/installer/unix/wizard/nsWelcomeDlg.h new file mode 100644 index 00000000000..d9353e13e3c --- /dev/null +++ b/mozilla/toolkit/mozapps/installer/unix/wizard/nsWelcomeDlg.h @@ -0,0 +1,63 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* + * The contents of this file are subject to the Netscape Public + * License Version 1.1 (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.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is Mozilla Communicator client code, + * released March 31, 1998. + * + * The Initial Developer of the Original Code is Netscape Communications + * Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + * Samir Gehani + */ + +#ifndef _NS_WELCOMEDLG_H_ +#define _NS_WELCOMEDLG_H_ + +#include "nsXInstallerDlg.h" +#include "XIErrors.h" + +class nsWelcomeDlg : public nsXInstallerDlg +{ +public: + nsWelcomeDlg(); + ~nsWelcomeDlg(); + +/*--------------------------------------------------------------------* + * Navigation + *--------------------------------------------------------------------*/ + static void Back(GtkWidget *aWidget, gpointer aData); + static void Next(GtkWidget *aWidget, gpointer aData); + + int Parse(nsINIParser *aParser); + + int Show(int aDirection); + int Hide(int aDirection); + +private: + // Number of text messages in the dialog, which must be <= 10. + // The last message is displayed at the bottom of the dialog, + // next to the navigation buttons. + + static const int kMsgCount = 4; + + char *mTitle; + char *mMsgs[kMsgCount]; + char *mWelcomeMsg; + char *mPixmap; + + GtkWidget *mBox; +}; + +#endif /* _NS_WELCOMEDLG_H_ */ diff --git a/mozilla/toolkit/mozapps/installer/unix/wizard/nsXIContext.cpp b/mozilla/toolkit/mozapps/installer/unix/wizard/nsXIContext.cpp new file mode 100644 index 00000000000..1e8aa4a603c --- /dev/null +++ b/mozilla/toolkit/mozapps/installer/unix/wizard/nsXIContext.cpp @@ -0,0 +1,290 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* + * The contents of this file are subject to the Netscape Public + * License Version 1.1 (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.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is Mozilla Communicator client code, + * released March 31, 1998. + * + * The Initial Developer of the Original Code is Netscape Communications + * Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + * Samir Gehani + */ + +#include "nsXIContext.h" + +#define __EOT__ "EndOfTable" + +nsXIContext::nsXIContext() +{ + me = NULL; + + ldlg = NULL; + wdlg = NULL; + sdlg = NULL; + cdlg = NULL; + idlg = NULL; + + opt = new nsXIOptions(); + + window = NULL; + back = NULL; + next = NULL; + cancel = NULL; + nextLabel = NULL; + backLabel = NULL; + acceptLabel = NULL; + declineLabel = NULL; + installLabel = NULL; + logo = NULL; + notebook = NULL; + header = NULL; + + backID = 0; + nextID = 0; + cancelID = 0; + bDone = FALSE; + + reslist = NULL; +} + +nsXIContext::~nsXIContext() +{ + // NOTE: don't try to delete "me" cause I control thee + + ReleaseResources(); + + XI_IF_DELETE(ldlg); + XI_IF_DELETE(wdlg); + XI_IF_DELETE(sdlg); + XI_IF_DELETE(cdlg); + XI_IF_DELETE(idlg); + + XI_IF_DELETE(opt); +} + +char * +nsXIContext::itoa(int n) +{ + char *s; + int i, j, sign, tmp; + + /* check sign and convert to positive to stringify numbers */ + if ( (sign = n) < 0) + n = -n; + i = 0; + s = (char*) malloc(sizeof(char)); + + /* grow string as needed to add numbers from powers of 10 + * down till none left + */ + do + { + s = (char*) realloc(s, (i+1)*sizeof(char)); + s[i++] = n % 10 + '0'; /* '0' or 30 is where ASCII numbers start */ + s[i] = '\0'; + } + while( (n /= 10) > 0); + + /* tack on minus sign if we found earlier that this was negative */ + if (sign < 0) + { + s = (char*) realloc(s, (i+1)*sizeof(char)); + s[i++] = '-'; + } + s[i] = '\0'; + + /* pop numbers (and sign) off of string to push back into right direction */ + for (i = 0, j = strlen(s) - 1; i < j; i++, j--) + { + tmp = s[i]; + s[i] = s[j]; + s[j] = tmp; + } + + return s; +} + +#define MAX_KEY_SIZE 64 +#define FIRST_ERR -601 +#define LAST_ERR -625 +int +nsXIContext::LoadResources() +{ + int err = OK; + nsINIParser *parser = NULL; + char *resfile = NULL; + kvpair *currkv = NULL; + char currkey[MAX_KEY_SIZE]; + int len, i; + + resfile = nsINIParser::ResolveName(RES_FILE); + if (!resfile) + return E_INVALID_PTR; + + parser = new nsINIParser(resfile); + if (!parser) + { + XI_IF_FREE(resfile); + return E_MEM; + } + + char *strkeys[] = + { + "NEXT", + "BACK", + "CANCEL", + "ACCEPT", + "DECLINE", + "INSTALL", + "PAUSE", + "RESUME", + "DEFAULT_TITLE", + "DEST_DIR", + "BROWSE", + "SELECT_DIR", + "DOESNT_EXIST", + "YES_LABEL", + "NO_LABEL", + "OK_LABEL", + "DELETE_LABEL", + "CANCEL_LABEL", + "ERROR", + "FATAL_ERROR", + "DESCRIPTION", + "WILL_INSTALL", + "TO_LOCATION", + "PREPARING", + "EXTRACTING", + "INSTALLING_XPI", + "PROCESSING_FILE", + "NO_PERMS", + "DL_SETTINGS", + "SAVE_MODULES", + "PROXY_SETTINGS", + "PS_LABEL0", + "PS_LABEL1", + "PS_LABEL2", + "PS_LABEL3", + "ERROR_TITLE", + "DS_AVAIL", + "DS_REQD", + "NO_DISK_SPACE", + "CXN_DROPPED", + "DOWNLOADING", + "FROM", + "TO", + "STATUS", + "DL_STATUS_STR", + "CRC_FAILED", + "CRC_CHECK", + "USAGE_MSG", + "UNKNOWN", + + __EOT__ + }; + + /* read in UI strings */ + currkv = (kvpair *) malloc(sizeof(kvpair)); + reslist = currkv; + for (i = 0; strcmp(strkeys[i], __EOT__) != 0; i++) + { + err = parser->GetStringAlloc(RES_SECT, strkeys[i], + &(currkv->val), &len); + if (err != OK) + goto BAIL; + + currkv->key = strdup(strkeys[i]); + currkv->next = (kvpair *) malloc(sizeof(kvpair)); + currkv = currkv->next; + + if (i > 1024) /* inf loop prevention paranoia */ + break; + } + currkv->next = NULL; /* seal off list */ + + /* read in err strings */ + for (i = FIRST_ERR; i >= LAST_ERR; i--) + { + sprintf(currkey, "%d", i); + err = parser->GetStringAlloc(RES_SECT, currkey, &(currkv->val), &len); + if (err != OK) + goto BAIL; + + currkv->key = strdup(currkey); + if (i == LAST_ERR) + break; + currkv->next = (kvpair *) malloc(sizeof(kvpair)); + currkv = currkv->next; + } + currkv->next = NULL; /* seal off list */ + +BAIL: + if (err != OK) + { + fprintf(stderr, "FATAL ERROR: Failed to load resources!\n"); + } + XI_IF_FREE(resfile); + XI_IF_DELETE(parser); + return err; +} + +int +nsXIContext::ReleaseResources() +{ + int err = OK; + kvpair *currkv = NULL, *delkv = NULL; + + /* empty list -- should never really happen */ + if (!reslist) + return E_PARAM; + + currkv = reslist; + while (currkv) + { + XI_IF_FREE(currkv->key); + XI_IF_FREE(currkv->val); + delkv = currkv; + currkv = currkv->next; + XI_IF_FREE(delkv); + } + + return err; +} + +char * +nsXIContext::Res(char *aKey) +{ + char *val = NULL; + kvpair *currkv = NULL; + + /* param check */ + if (!aKey || !reslist) + return NULL; + + /* search through linked list */ + currkv = reslist; + while (currkv) + { + if (strcmp(aKey, currkv->key) == 0) + { + val = currkv->val; + break; + } + currkv = currkv->next; + } + + return val; +} + diff --git a/mozilla/toolkit/mozapps/installer/unix/wizard/nsXIContext.h b/mozilla/toolkit/mozapps/installer/unix/wizard/nsXIContext.h new file mode 100644 index 00000000000..10a98f24ece --- /dev/null +++ b/mozilla/toolkit/mozapps/installer/unix/wizard/nsXIContext.h @@ -0,0 +1,105 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* + * The contents of this file are subject to the Netscape Public + * License Version 1.1 (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.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is Mozilla Communicator client code, + * released March 31, 1998. + * + * The Initial Developer of the Original Code is Netscape Communications + * Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + * Samir Gehani + */ + +#ifndef _NS_XICONTEXT_H_ +#define _NS_XICONTEXT_H_ + +#include "nsLicenseDlg.h" +#include "nsWelcomeDlg.h" +#include "nsSetupTypeDlg.h" +#include "nsComponentsDlg.h" +#include "nsInstallDlg.h" +#include "nsXIOptions.h" +#include "nsINIParser.h" + +#define RES_FILE "installer" +#define RES_SECT "String Resources" + +class nsXInstaller; + +typedef struct _kvpair +{ + char *key; + char *val; + + struct _kvpair *next; +} kvpair; + +class nsXIContext +{ +public: + nsXIContext(); + ~nsXIContext(); + + nsXInstaller *me; + +/*-------------------------------------------------------------------* + * Dialog Contexts + *-------------------------------------------------------------------*/ + nsLicenseDlg *ldlg; + nsWelcomeDlg *wdlg; + nsSetupTypeDlg *sdlg; + nsComponentsDlg *cdlg; + nsInstallDlg *idlg; + + nsXIOptions *opt; + +/*-------------------------------------------------------------------* + * Global Widgets + *-------------------------------------------------------------------*/ + GtkWidget *window; /* unique canvas for dialogs */ + GtkWidget *back; /* back button */ + GtkWidget *next; /* next button */ + GtkWidget *cancel; /* cancel button */ + GtkWidget *nextLabel; /* "Next" label */ + GtkWidget *backLabel; /* "Back" label */ + GtkWidget *acceptLabel; /* "Accept" label */ + GtkWidget *declineLabel; /* "Decline" label */ + GtkWidget *installLabel; /* "Install" label */ + GtkWidget *logo; /* branding icon: an xpm image */ + GtkWidget *mainbox; /* vbox holding all except logo */ + GtkWidget *notebook; /* notebook whose pages are dlgs */ + GtkWidget *header; /* header area (with bg image) */ + GtkWidget *header_title; /* title label in header */ + GtkWidget *header_subtitle; /* subtitle label in header */ + + int backID; /* signal handler id for back btn */ + int nextID; /* signal handler id for next btn */ + int cancelID; /* signal handler id for cancel btn */ + int bDone; /* engine thread sets boolean when done + so that ui/main thread can exit */ + +/*-------------------------------------------------------------------* + * Utilities + *-------------------------------------------------------------------*/ + char *itoa(int n); + int LoadResources(); /* load string resources */ + int ReleaseResources(); /* release alloc'd resource strings */ + char *Res(char *aKey); /* get string resource for key; NULL==err */ + +private: + kvpair *reslist; /* string resource linked list */ +}; + +#endif /* _NS_XICONTEXT_H_ */ diff --git a/mozilla/toolkit/mozapps/installer/unix/wizard/nsXIEngine.cpp b/mozilla/toolkit/mozapps/installer/unix/wizard/nsXIEngine.cpp new file mode 100644 index 00000000000..208c21b7433 --- /dev/null +++ b/mozilla/toolkit/mozapps/installer/unix/wizard/nsXIEngine.cpp @@ -0,0 +1,1178 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* + * The contents of this file are subject to the Netscape Public + * License Version 1.1 (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.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is Mozilla Communicator client code, + * released March 31, 1998. + * + * The Initial Developer of the Original Code is Netscape Communications + * Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + * Samir Gehani + * Syd Logan syd@netscape.com + */ + +#include "nsFTPConn.h" +#include "nsHTTPConn.h" +#include "nsXIEngine.h" + +#include +#include + +#define CORE_LIB_COUNT 11 + +const char kHTTPProto[] = "http://"; +const char kFTPProto[] = "ftp://"; +const char kDLMarkerPath[] = "./xpi/.current_download"; + +nsXIEngine::nsXIEngine() : + mTmp(NULL), + mTotalComps(0), + mOriginalDir(NULL) +{ +} + +#define RM_PREFIX "rm -rf " + +nsXIEngine::~nsXIEngine() +{ + DUMP("~nsXIEngine"); + + // reset back to original directory + chdir(mOriginalDir); + + if ( mTmp != (char *) NULL ) { + + // blow away the temp dir + + char *buf; + buf = (char *) malloc( strlen(RM_PREFIX) + strlen( mTmp ) + 1 ); + if ( buf != (char *) NULL ) { + strcpy( buf, RM_PREFIX ); + strcat( buf, mTmp ); + system( buf ); + XI_IF_FREE(mTmp); + free( buf ); + } + } + XI_IF_FREE(mOriginalDir); +} + +int +EventPumpCB(void) +{ + return 0; +} + +#define MAXCRC 4 + +int +nsXIEngine::Download(int aCustom, nsComponentList *aComps) +{ + DUMP("Download"); + + if (!aComps) + return E_PARAM; + + int err = OK; + nsComponent *currComp = aComps->GetHead(), *markedComp = NULL; + nsComponent *currCompSave; + char *currURL = NULL; + char *currHost = NULL; + char *currPath = NULL; + char localPath[MAXPATHLEN]; + char *srvPath = NULL; + char *proxyURL = NULL; + char *qualURL = NULL; + int i, crcPass, bDone; + int currPort; + struct stat stbuf; + int resPos = 0; + int fileSize = 0; + int currCompNum = 1, markedCompNum = 0; + int numToDL = 0; // num xpis to download + int passCount; + CONN myConn; + + err = GetDLMarkedComp(aComps, aCustom, &markedComp, &markedCompNum); + if (err == OK && markedComp) + { + currComp = markedComp; + currCompNum = markedCompNum; + sprintf(localPath, "%s/%s", XPI_DIR, currComp->GetArchive()); + currComp->SetResumePos(GetFileSize(localPath)); + } + else + { + // if all .xpis exist in the ./xpi dir (blob/CD) + // we don't need to download + if (ExistAllXPIs(aCustom, aComps, &mTotalComps)) + return OK; + } + + // check if ./xpi dir exists else create it + if (0 != stat(XPI_DIR, &stbuf)) + { + if (0 != mkdir(XPI_DIR, 0755)) + return E_MKDIR_FAIL; + } + + numToDL = TotalToDownload(aCustom, aComps); + + myConn.URL = (char *) NULL; + myConn.type = TYPE_UNDEF; + + crcPass = 0; + currCompSave = currComp; + bDone = 0; + while ( bDone == 0 && crcPass < MAXCRC ) { + passCount = 0; + while (currComp) + { + if ( (aCustom == TRUE && currComp->IsSelected()) || (aCustom == FALSE) ) + { + // in case we are resuming inter- or intra-installer session + if (currComp->IsDownloaded()) + { + currComp = currComp->GetNext(); + continue; + } + + SetDLMarker(currComp->GetArchive()); + + for (i = 0; i < MAX_URLS; i++) + { + currURL = currComp->GetURL(i); + if (!currURL) break; + + if (gCtx->opt->mMode != nsXIOptions::MODE_SILENT) + nsInstallDlg::SetDownloadComp(currComp, i, + currCompNum, numToDL); + + // restore resume position + resPos = currComp->GetResumePos(); + + // has a proxy server been specified? + if (gCtx->opt->mProxyHost && gCtx->opt->mProxyPort) + { + // URL of the proxy server + proxyURL = (char *) malloc(strlen(kHTTPProto) + + strlen(gCtx->opt->mProxyHost) + 1 + + strlen(gCtx->opt->mProxyPort) + 1); + if (!proxyURL) + { + err = E_MEM; + break; + } + + sprintf(proxyURL, "%s%s:%s", kHTTPProto, + gCtx->opt->mProxyHost, gCtx->opt->mProxyPort); + + nsHTTPConn *conn = new nsHTTPConn(proxyURL, EventPumpCB); + if (!conn) + { + err = E_MEM; + break; + } + + // URL of the actual file to download + qualURL = (char *) malloc(strlen(currURL) + + strlen(currComp->GetArchive()) + 1); + if (!qualURL) + { + err = E_MEM; + break; + } + sprintf(qualURL, "%s%s", currURL, currComp->GetArchive()); + + if (*gCtx->opt->mProxyUser || *gCtx->opt->mProxyPswd) + { + conn->SetProxyInfo(qualURL, gCtx->opt->mProxyUser, + gCtx->opt->mProxyPswd); + } + else + { + conn->SetProxyInfo(qualURL, NULL, NULL); + } + + err = conn->Open(); + if (err == nsHTTPConn::OK) + { + sprintf(localPath, "%s/%s", XPI_DIR, + currComp->GetArchive()); + if (gCtx->opt->mMode == nsXIOptions::MODE_SILENT) + err = conn->Get(NULL, localPath, resPos); + else + err = conn->Get(nsInstallDlg::DownloadCB, localPath, + resPos); + conn->Close(); + } + + XI_IF_FREE(proxyURL); + XI_IF_FREE(qualURL); + XI_IF_DELETE(conn); + } + + // is this an HTTP URL? + else if (strncmp(currURL, kHTTPProto, strlen(kHTTPProto)) == 0) + { + // URL of the actual file to download + qualURL = (char *) malloc(strlen(currURL) + + strlen(currComp->GetArchive()) + 1); + if (!qualURL) + { + err = E_MEM; + break; + } + sprintf(qualURL, "%s%s", currURL, currComp->GetArchive()); + + nsHTTPConn *conn = new nsHTTPConn(qualURL, EventPumpCB); + if (!conn) + { + err = E_MEM; + break; + } + + err = conn->Open(); + if (err == nsHTTPConn::OK) + { + sprintf(localPath, "%s/%s", XPI_DIR, + currComp->GetArchive()); + if (gCtx->opt->mMode == nsXIOptions::MODE_SILENT) + err = conn->Get(NULL, localPath, resPos); + else + err = conn->Get(nsInstallDlg::DownloadCB, localPath, + resPos); + conn->Close(); + } + + XI_IF_FREE(qualURL); + XI_IF_DELETE(conn); + } + + // or is this an FTP URL? + else if (strncmp(currURL, kFTPProto, strlen(kFTPProto)) == 0) + { + PRBool isNewConn; + + err = nsHTTPConn::ParseURL(kFTPProto, currURL, &currHost, + &currPort, &currPath); + if (err != nsHTTPConn::OK) + break; + + // path on the remote server + srvPath = (char *) malloc(strlen(currPath) + + strlen(currComp->GetArchive()) + 1); + if (!srvPath) + { + err = E_MEM; + break; + } + sprintf(srvPath, "%s%s", currPath, currComp->GetArchive()); + + // closes the old connection if any + + isNewConn = CheckConn( currHost, TYPE_FTP, &myConn, PR_FALSE ); + err = nsFTPConn::OK; + + nsFTPConn *conn; + if ( isNewConn == PR_TRUE ) { + conn = new nsFTPConn(currHost, EventPumpCB); + if (!conn) { + err = E_MEM; + break; + } + err = conn->Open(); + myConn.conn = (void *) conn; + myConn.type = TYPE_FTP; + myConn.URL = (char *) calloc(strlen(currHost) + 1, sizeof(char)); + if ( myConn.URL != (char *) NULL ) + strcpy( myConn.URL, currHost ); + } else + conn = (nsFTPConn *) myConn.conn; + + if (isNewConn == PR_FALSE || err == nsFTPConn::OK) + { + sprintf(localPath, "%s/%s", XPI_DIR, + currComp->GetArchive()); + if (gCtx->opt->mMode == nsXIOptions::MODE_SILENT) + err = conn->Get(srvPath, localPath, nsFTPConn::BINARY, + resPos, 1, NULL); + else + err = conn->Get(srvPath, localPath, nsFTPConn::BINARY, + resPos, 1, nsInstallDlg::DownloadCB); + passCount++; + } + + XI_IF_FREE(currHost); + XI_IF_FREE(currPath); + XI_IF_FREE(srvPath); + } + + // else error: malformed URL + else + { + err = nsHTTPConn::E_MALFORMED_URL; + } + + if (err == nsHTTPConn::E_USER_CANCEL) + err = nsInstallDlg::CancelOrPause(); + + // user hit pause and subsequently resumed + if (err == nsInstallDlg::E_DL_PAUSE) + { + currComp->SetResumePos(GetFileSize(localPath)); + return err; + } + + // user cancelled during download + else if (err == nsInstallDlg::E_DL_CANCEL) + return err; + + // user didn't cancel or pause: some other dl error occured + else if (err != OK) + { + fileSize = GetFileSize(localPath); + + if (fileSize > 0) + { + // assume dropped connection if file size > 0 + currComp->SetResumePos(fileSize); + return nsInstallDlg::E_DL_DROP_CXN; + } + else + { + // failover + continue; + } + } + + if (gCtx->opt->mMode != nsXIOptions::MODE_SILENT) + nsInstallDlg::ClearRateLabel(); // clean after ourselves + + if (err == OK) + { + currComp->SetDownloaded(TRUE); + currCompNum++; + break; // no need to failover + } + } + } + + currComp = currComp->GetNext(); + } + + CheckConn( "", TYPE_UNDEF, &myConn, true ); + + bDone = CRCCheckDownloadedArchives(XPI_DIR, strlen(XPI_DIR), + currCompSave, passCount, aCustom); + crcPass++; + if ( bDone == 0 && crcPass < MAXCRC ) { + // reset ourselves + if (markedComp) { + currComp = markedComp; + currCompNum = markedCompNum; + } else { + currComp = aComps->GetHead(); + currCompNum = 1; + } + currCompSave = currComp; + if (gCtx->opt->mMode != nsXIOptions::MODE_SILENT) + gCtx->idlg->ReInitUI(); + gCtx->idlg->ShowCRCDlg(); + numToDL = TotalToDownload(aCustom, aComps); + } + } + gCtx->idlg->DestroyCRCDlg(); // destroy the CRC dialog if showing + if ( crcPass < MAXCRC ) { + // download complete: remove marker + DelDLMarker(); + return OK; + } else { + return E_CRC_FAILED; + } +} + +/* + * Name: CheckConn + * + * Arguments: + * + * char *URL; -- URL of connection we need to have established + * int type; -- connection type (TYPE_HTTP, etc.) + * CONN *myConn; -- connection state (info about currently established + * connection) + * PRBool force; -- force closing of connection + * + * Description: + * + * This function determines if the caller should open a connection based upon + * the current connection that is open (if any), and the type of connection + * desired. If no previous connection was established, the function returns + * true. If the connection is for a different protocol, then true is also + * returned (and the previous connection is closed). If the connection is for + * the same protocol and the URL is different, the previous connection is + * closed and true is returned. Otherwise, the connection has already been + * established, and false is returned. + * + * Return Value: If a new connection needs to be opened, true. Otherwise, + * false is returned. + * + * Original Code: Syd Logan (syd@netscape.com) 6/24/2001 + * +*/ + +PRBool +nsXIEngine::CheckConn( char *URL, int type, CONN *myConn, PRBool force ) +{ + nsFTPConn *fconn; + nsHTTPConn *hconn; + PRBool retval = false; + + if ( myConn->type == TYPE_UNDEF ) + retval = PR_TRUE; // first time + else if ( ( myConn->type != type || myConn->URL == (char *) NULL || strcmp( URL, myConn->URL ) || force == PR_TRUE ) /* && gControls->state != ePaused */) { + retval = PR_TRUE; + switch ( myConn->type ) { + case TYPE_HTTP: + case TYPE_PROXY: + hconn = (nsHTTPConn *) myConn->conn; + hconn->Close(); + break; + case TYPE_FTP: + fconn = (nsFTPConn *) myConn->conn; + if ( fconn != (nsFTPConn *) NULL ) { + fconn->Close(); + XI_IF_DELETE(fconn); + myConn->conn = NULL; + } + break; + } + } + + if ( retval == PR_TRUE && myConn->URL != (char *) NULL ) { + free( myConn->URL ); + myConn->URL = (char *) NULL; + } + + return retval; +} + +int +nsXIEngine::Extract(nsComponent *aXPIEngine) +{ + int rv; + + if (!aXPIEngine) + return E_PARAM; + + mTmp = NULL; + rv = MakeUniqueTmpDir(); + if (!mTmp || rv != OK) + return E_DIR_CREATE; + + nsZipExtractor *unzip = new nsZipExtractor(XPI_DIR, mTmp); + rv = unzip->Extract(aXPIEngine, CORE_LIB_COUNT); + XI_IF_DELETE(unzip); + + return rv; +} + +int +nsXIEngine::Install(int aCustom, nsComponentList *aComps, char *aDestination) +{ + DUMP("Install"); + + int err = OK; + xpistub_t stub; + char *old_LD_LIBRARY_PATH = NULL; + char new_LD_LIBRARY_PATH[MAXPATHLEN]; + int i; + int compNum = 1; + nsComponent *currComp = NULL; + + if (!aComps || !aDestination) + return E_PARAM; + + // handle LD_LIBRARY_PATH settings +#if defined (SOLARIS) || defined (IRIX) + sprintf(new_LD_LIBRARY_PATH, "LD_LIBRARY_PATH=%s/bin:.", mTmp); +#else + sprintf(new_LD_LIBRARY_PATH, "%s/bin:.", mTmp); +#endif + DUMP(new_LD_LIBRARY_PATH); + old_LD_LIBRARY_PATH = getenv("LD_LIBRARY_PATH"); +#if defined (SOLARIS) || defined (IRIX) + putenv(new_LD_LIBRARY_PATH); +#else + setenv("LD_LIBRARY_PATH", new_LD_LIBRARY_PATH, 1); +#endif + currComp = aComps->GetHead(); + err = LoadXPIStub(&stub, aDestination); + if (err == OK) + { + for (i = 0; i < MAX_COMPONENTS; i++) + { + if (!currComp) + break; + + if ( (aCustom && currComp->IsSelected()) || + (!aCustom) ) + { +#ifdef DEBUG + printf("%s %d: DOWNLOAD_ONLY for %s is %d\n", __FILE__, __LINE__, + currComp->GetArchive(), currComp->IsDownloadOnly()); +#endif + if (!currComp->IsDownloadOnly()) + { + if (gCtx->opt->mMode != nsXIOptions::MODE_SILENT) + nsInstallDlg::MajorProgressCB(currComp->GetDescShort(), + compNum, mTotalComps, nsInstallDlg::ACT_INSTALL); + err = InstallXPI(currComp, &stub); + if (err != OK) + if (err == E_INSTALL) + ErrorHandler(err, currComp->GetArchive()); //handle E_INSTALL separately + else + ErrorHandler(err); //handle and continue + compNum++; + } + } + + currComp = currComp->GetNext(); + } + UnloadXPIStub(&stub); + } + + // restore LD_LIBRARY_PATH settings +#if defined (SOLARIS) || defined (IRIX) + char old_LD_env[MAXPATHLEN]; + + sprintf(old_LD_env, "LD_LIBRARY_PATH=%s", old_LD_LIBRARY_PATH); + putenv(old_LD_env); +#else + setenv("LD_LIBRARY_PATH", old_LD_LIBRARY_PATH, 1); +#endif + + return err; +} + +int +nsXIEngine::MakeUniqueTmpDir() +{ + int err = E_DIR_CREATE; + char tmpnam[MAXPATHLEN]; + char *tmpdir = getenv("TMPDIR"); + if (!tmpdir) tmpdir = getenv("TMP"); + if (!tmpdir) tmpdir = getenv("TEMP"); + if (!tmpdir) tmpdir = P_tmpdir; + snprintf(tmpnam, sizeof(tmpnam), "%s/xpi.XXXXXX", tmpdir); +#ifdef HAVE_MKDTEMP + if (mkdtemp(tmpnam)) { + mTmp = strdup(tmpnam); + if (mTmp) err = OK; + } +#else + int fd = mkstemp(tmpnam); + if (fd < 0) return err; + close(fd); + if (unlink(tmpnam) < 0) return err; + mTmp = strdup(tmpnam); + if (!mTmp) return err; + if (mkdir(mTmp, 0755) < 0) return err; + err = OK; +#endif + return err; +} + +int +nsXIEngine::ParseURL(char *aURL, char **aHost, char **aDir) +{ + int err = OK; + char *host = NULL; + char *hostTerminator = NULL; + char *dirTerminator = NULL; + + if (!aURL || !aHost || !aDir) + return E_PARAM; + + if (0 != strncmp(aURL, "ftp://", 6)) return E_BAD_FTP_URL; + + host = aURL + 6; + if (!host) return E_BAD_FTP_URL; + hostTerminator = strchr(host, '/'); + if (!hostTerminator) return E_BAD_FTP_URL; + + *aHost = (char *) calloc(hostTerminator - host + 1, 1); + strncpy(*aHost, host, hostTerminator - host); + + dirTerminator = strrchr(hostTerminator + 1, '/'); + if (!dirTerminator) + { + // no dir == root dir + *aDir = (char *) malloc(2); + sprintf(*aDir, "/"); + } + else + { + *aDir = (char *) malloc(sizeof(char) * + (dirTerminator - hostTerminator + 2)); + memset(*aDir, 0, (dirTerminator - hostTerminator + 2)); + strncpy(*aDir, hostTerminator, dirTerminator - hostTerminator + 1); + } + + return err; +} + +int +nsXIEngine::LoadXPIStub(xpistub_t *aStub, char *aDestination) +{ + int err = OK; + + char libpath[MAXPATHLEN]; + char libloc[MAXPATHLEN]; + char *dlerr; + nsresult rv = 0; + + DUMP("LoadXPIStub"); + + /* param check */ + if (!aStub || !aDestination) + return E_PARAM; + + /* save original directory to reset it after installing */ + mOriginalDir = (char *) malloc(MAXPATHLEN * sizeof(char)); + getcwd(mOriginalDir, MAXPATHLEN); + + /* chdir to library location for dll deps resolution */ + sprintf(libloc, "%s/bin", mTmp); + chdir(libloc); + + /* open the library */ + getcwd(libpath, MAXPATHLEN); + sprintf(libpath, "%s/%s", libpath, XPISTUB); + +#ifdef DEBUG +printf("DEBUG: libpath = >>%s<<\n", libpath); +#endif + + aStub->handle = NULL; + aStub->handle = dlopen(libpath, RTLD_LAZY); + if (!aStub->handle) + { + dlerr = dlerror(); + DUMP(dlerr); + return E_LIB_OPEN; + } + DUMP("xpistub opened"); + + /* read and store symbol addresses */ + aStub->fn_init = (pfnXPI_Init) dlsym(aStub->handle, FN_INIT); + aStub->fn_install = (pfnXPI_Install) dlsym(aStub->handle, FN_INSTALL); + aStub->fn_exit = (pfnXPI_Exit) dlsym(aStub->handle, FN_EXIT); + if (!aStub->fn_init || !aStub->fn_install || !aStub->fn_exit) + { + dlerr = dlerror(); + DUMP(dlerr); + err = E_LIB_SYM; + goto BAIL; + } + DUMP("xpistub symbols loaded"); + + rv = aStub->fn_init(aDestination, NULL, ProgressCallback); + +#ifdef DEBUG +printf("DEBUG: XPI_Init returned 0x%.8X\n", rv); +#endif + + DUMP("XPI_Init called"); + if (NS_FAILED(rv)) + { + err = E_XPI_FAIL; + goto BAIL; + } + + return err; + +BAIL: + return err; +} + +int +nsXIEngine::InstallXPI(nsComponent *aXPI, xpistub_t *aStub) +{ + int err = OK; + char xpipath[MAXPATHLEN]; + nsresult rv = 0; + + if (!aStub || !aXPI || !mOriginalDir) + return E_PARAM; + + sprintf(xpipath, "%s/%s/%s", mOriginalDir, XPI_DIR, aXPI->GetArchive()); + DUMP(xpipath); + +#define XPI_NO_NEW_THREAD 0x1000 + + rv = aStub->fn_install(xpipath, "", XPI_NO_NEW_THREAD); + +#ifdef DEBUG +printf("DEBUG: XPI_Install %s returned %d\n", aXPI->GetArchive(), rv); +#endif + + if (NS_FAILED(rv)) + err = E_INSTALL; + + return err; +} + +int +nsXIEngine::UnloadXPIStub(xpistub_t *aStub) +{ + int err = OK; + + /* param check */ + if (!aStub) + return E_PARAM; + + /* release XPCOM and XPInstall */ + XI_ASSERT(aStub->fn_exit, "XPI_Exit is NULL and wasn't called!"); + if (aStub->fn_exit) + { + aStub->fn_exit(); + DUMP("XPI_Exit called"); + } + +#if 0 + /* NOTE: + * ---- + * Don't close the stub: it'll be released on exit. + * This fixes the seg fault on exit bug, + * Apparently, the global destructors are no longer + * around when the app exits (since xpcom etc. was + * unloaded when the stub was unloaded). To get + * around this we don't close the stub (which is + * apparently safe on Linux/Unix). + */ + + /* close xpistub library */ + if (aStub->handle) + { + dlclose(aStub->handle); + DUMP("xpistub closed"); + } +#endif + + return err; +} + +void +nsXIEngine::ProgressCallback(const char* aMsg, PRInt32 aVal, PRInt32 aMax) +{ + // DUMP("ProgressCallback"); + + nsInstallDlg::XPIProgressCB(aMsg, (int)aVal, (int)aMax); +} + +int +nsXIEngine::ExistAllXPIs(int aCustom, nsComponentList *aComps, int *aTotal) +{ + // param check + if (!aComps || !aTotal) + return E_PARAM; + + int bAllExist = TRUE; + nsComponent *currComp = aComps->GetHead(); + char currArchivePath[256]; + struct stat dummy; + + while (currComp) + { + if (currComp->IsSelected()) + { + sprintf(currArchivePath, "%s/%s", XPI_DIR, currComp->GetArchive()); + DUMP(currArchivePath); + + if (0 != stat(currArchivePath, &dummy)) + bAllExist = FALSE; + else + currComp->SetDownloaded(TRUE); + + (*aTotal)++; + } + + currComp = currComp->GetNext(); + } + + return bAllExist; +} + +int +nsXIEngine::DeleteXPIs(int aCustom, nsComponentList *aComps) +{ + int err = OK; + nsComponent *currComp = aComps->GetHead(); + char currXPIPath[MAXPATHLEN]; + + if (!aComps || !mOriginalDir) + return E_PARAM; + + while (currComp) + { + if ( (aCustom == TRUE && currComp->IsSelected()) || (aCustom == FALSE) ) + { + sprintf(currXPIPath, "%s/%s/%s", mOriginalDir, XPI_DIR, + currComp->GetArchive()); + + // delete the xpi + err = unlink(currXPIPath); + +#ifdef DEBUG + printf("%s %d: unlink %s returned: %d\n", __FILE__, __LINE__, + currXPIPath, err); +#endif + } + + currComp = currComp->GetNext(); + } + + // all xpi should be deleted so delete the ./xpi dir + sprintf(currXPIPath, "%s/xpi", mOriginalDir); + err = rmdir(currXPIPath); + +#ifdef DEBUG + printf("%s %d: rmdir %s returned: %d\n", __FILE__, __LINE__, + currXPIPath, err); +#endif + + return err; +} + +int +nsXIEngine::GetFileSize(char *aPath) +{ + struct stat stbuf; + + if (!aPath) + return 0; + + if (0 == stat(aPath, &stbuf)) + { + return stbuf.st_size; + } + + return 0; +} + +int +nsXIEngine::SetDLMarker(char *aCompName) +{ + int rv = OK; + FILE *dlMarkerFD; + int compNameLen; + + if (!aCompName) + return E_PARAM; + + // open the marker file + dlMarkerFD = fopen(kDLMarkerPath, "w"); + if (!dlMarkerFD) + return E_OPEN_MKR; + + // write out the current comp name + compNameLen = strlen(aCompName); + if (compNameLen > 0) + { + rv = fwrite((void *) aCompName, sizeof(char), compNameLen, dlMarkerFD); + if (rv != compNameLen) + rv = E_WRITE_MKR; + else + rv = OK; + } + + // close the marker file + fclose(dlMarkerFD); + +#ifdef DEBUG + printf("%s %d: SetDLMarker rv = %d\n", __FILE__, __LINE__, rv); +#endif + return rv; +} + +int +nsXIEngine::GetDLMarkedComp(nsComponentList *aComps, int aCustom, + nsComponent **aOutComp, int *aOutCompNum) +{ + int rv = OK; + FILE *dlMarkerFD = NULL; + struct stat stbuf; + char *compNameInFile = NULL; + int compNum = 1; + nsComponent *currComp = NULL; + + if (!aComps || !aOutComp || !aOutCompNum) + return E_PARAM; + + *aOutComp = NULL; + currComp = aComps->GetHead(); + + // open the marker file + dlMarkerFD = fopen(kDLMarkerPath, "r"); + if (!dlMarkerFD) + return E_OPEN_MKR; + + // find it's length + if (0 != stat(kDLMarkerPath, &stbuf)) + { + rv = E_STAT; + goto BAIL; + } + if (stbuf.st_size <= 0) + { + rv = E_FIND_COMP; + goto BAIL; + } + + // allocate a buffer the length of the file + compNameInFile = (char *) malloc(sizeof(char) * (stbuf.st_size + 1)); + if (!compNameInFile) + { + rv = E_MEM; + goto BAIL; + } + memset(compNameInFile, 0 , (stbuf.st_size + 1)); + + // read in the file contents + rv = fread((void *) compNameInFile, sizeof(char), + stbuf.st_size, dlMarkerFD); + if (rv != stbuf.st_size) + rv = E_READ_MKR; + else + rv = OK; + + if (rv == OK) + { + // compare the comp name read in with all those in the components list + while (currComp) + { + if ( (aCustom == TRUE && currComp->IsSelected()) || + (aCustom == FALSE) ) + { + if (strcmp(currComp->GetArchive(), compNameInFile) == 0) + { + *aOutComp = currComp; + break; + } + + compNum++; + } + + currComp = currComp->GetNext(); + } + } + + *aOutCompNum = compNum; + +BAIL: + if (dlMarkerFD) + fclose(dlMarkerFD); + + XI_IF_FREE(compNameInFile); + + return rv; +} + +int +nsXIEngine::DelDLMarker() +{ + return unlink(kDLMarkerPath); +} + +int +nsXIEngine::TotalToDownload(int aCustom, nsComponentList *aComps) +{ + int total = 0; + nsComponent *currComp; + + if (!aComps) + return 0; + + currComp = aComps->GetHead(); + while (currComp) + { + if ( (aCustom == TRUE && currComp->IsSelected()) || (aCustom == FALSE) ) + { + if (!currComp->IsDownloaded()) + total++; + } + currComp = currComp->GetNext(); + } + + return total; +} + +/* + * Name: CRCCheckDownloadedArchives + * + * Arguments: + * + * Handle dlPath; -- a handle to the location of the XPI files on disk + * short dlPathlen; -- length, in bytes, of dlPath + * + * Description: + * + * This function iterates the XPI files and calls VerifyArchive() on each to + * determine which archives pass checksum checks. + * + * Return Value: if all archives pass, true. Otherwise, false. + * + * Original Code: Syd Logan (syd@netscape.com) 6/24/2001 + * +*/ + +PRBool +nsXIEngine::CRCCheckDownloadedArchives(char *dlPath, short dlPathlen, + nsComponent *currComp, int count, int aCustom) +{ + int i; + PRBool isClean; + char buf[ 1024 ]; + + isClean = PR_TRUE; + + for(i = 0; currComp != (nsComponent *) NULL && i < MAX_COMPONENTS; i++) { + strncpy( buf, (const char *) dlPath, dlPathlen ); + buf[ dlPathlen ] = '\0'; + strcat( buf, "/" ); + strcat( buf, currComp->GetArchive() ); + if (gCtx->opt->mMode != nsXIOptions::MODE_SILENT) + nsInstallDlg::MajorProgressCB(buf, i, count, nsInstallDlg::ACT_INSTALL); + if (((aCustom == TRUE && currComp->IsSelected()) || + (aCustom == FALSE)) && IsArchiveFile(buf) == PR_TRUE && + VerifyArchive( buf ) != ZIP_OK) { + currComp->SetDownloaded(FALSE); // VerifyArchive has unlinked it + isClean = false; + } + currComp = currComp->GetNext(); + } + return isClean; +} + +/* + * Name: IsArchiveFile( char *path ) + * + * Arguments: + * + * char *path -- NULL terminated pathname + * + * Description: + * + * This function extracts the file extension of filename pointed to by path + * and then checks it against a table of extensions. If a match occurs, the + * file is considered to be an archive file that has a checksum we can + * validate, and we return PR_TRUE. + * Otherwise, PR_FALSE is returned. + * + * Return Value: true if the file extension matches one of those we are + * looking for, and false otherwise. + * + * Original Code: Syd Logan 7/28/2001 + * +*/ + +static char *extensions[] = { "ZIP", "XPI", "JAR" }; // must be uppercase + +PRBool +nsXIEngine::IsArchiveFile( char *buf ) +{ + PRBool ret = false; + char lbuf[1024]; + char *p; + int i, max; + + // if we have a string and it contains a '.' + + if ( buf != (char *) NULL && ( p = strrchr( buf, '.' ) ) != (char *) NULL ) { + p++; + + // if there are characters after the '.' then see if there is a match + + if ( *p != '\0' ) { + + // make a copy of the extension, and fold to uppercase, since mac has no strcasecmp + // and we need to ensure we are comparing strings of chars that have the same case. + + strcpy( lbuf, p ); + for ( i = 0; i < (int) strlen( lbuf ); i++ ) + lbuf[i] = toupper(lbuf[i]); + + // search + + max = sizeof( extensions ) / sizeof ( char * ); + for ( i = 0; i < max; i++ ) + if ( !strcmp( lbuf, extensions[i] ) ) { + ret = true; + break; + } + } + } + return ( ret ); +} + +/* + * Name: VerifyArchive + * + * Arguments: + * + * char *szArchive; -- path of archive to verify + * + * Description: + * + * This function verifies that the specified path exists, that it is a XPI + * file, and that it has a valid checksum. + * + * Return Value: If all tests pass, ZIP_OK. Otherwise, !ZIP_OK + * + * Original Code: Syd Logan (syd@netscape.com) 6/25/2001 + * +*/ + +int +nsXIEngine::VerifyArchive(char *szArchive) +{ + void *vZip; + int iTestRv; + char *penv; + + if((iTestRv = ZIP_OpenArchive(szArchive, &vZip)) == ZIP_OK) + { + /* 1st parameter should be NULL or it will fail */ + /* It indicates extract the entire archive */ + iTestRv = ZIP_TestArchive(vZip); + ZIP_CloseArchive(&vZip); + } + + // for testing, this will cause about half of the CRCs to fail. Since + // randomly selecting which fail, likely next pass the same file will + // end up a success. + + penv = getenv("MOZ_INSTALL_TEST_CRC"); + if ( penv != (char *) NULL ) { + if ( random() < RAND_MAX / 2 ) + iTestRv = !ZIP_OK; + } + + if ( iTestRv != ZIP_OK ) + unlink( szArchive ); + return(iTestRv); +} + diff --git a/mozilla/toolkit/mozapps/installer/unix/wizard/nsXIEngine.h b/mozilla/toolkit/mozapps/installer/unix/wizard/nsXIEngine.h new file mode 100644 index 00000000000..9b52c2a1870 --- /dev/null +++ b/mozilla/toolkit/mozapps/installer/unix/wizard/nsXIEngine.h @@ -0,0 +1,131 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* + * The contents of this file are subject to the Netscape Public + * License Version 1.1 (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.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is Mozilla Communicator client code, + * released March 31, 1998. + * + * The Initial Developer of the Original Code is Netscape Communications + * Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + * Samir Gehani + */ + +#ifndef _NS_XIENGINE_H_ +#define _NS_XIENGINE_H_ + +#include "XIDefines.h" +#include "nsXInstaller.h" +#include "nsComponent.h" +#include "nsComponentList.h" +#include "nsInstallDlg.h" +#include "nsZipExtractor.h" + +#include "xpistub.h" + +#define STANDALONE 1 +#include "zipfile.h" +#include + +#include +#include +#include +#include +#include +#include +#include + +/*------------------------------------------------------------------------* + * XPI Stub Glue + *------------------------------------------------------------------------*/ +typedef nsresult (*pfnXPI_Init) + (const char *aProgramDir, const char *aLogName, + pfnXPIProgress progressCB); +typedef nsresult (*pfnXPI_Install) + (const char *file, const char *args, long flags); +typedef void (*pfnXPI_Exit)(); + +typedef struct _xpistub_t +{ + const char *name; + void *handle; + pfnXPI_Init fn_init; + pfnXPI_Install fn_install; + pfnXPI_Exit fn_exit; +} xpistub_t; + +#define TYPE_UNDEF 0 +#define TYPE_PROXY 1 +#define TYPE_HTTP 2 +#define TYPE_FTP 3 + +typedef struct _conn +{ + unsigned char type; // TYPE_UNDEF, etc. + char *URL; // URL this connection is for + void *conn; // pointer to open connection +} CONN; + +/*------------------------------------------------------------------------* + * nsXIEngine + *------------------------------------------------------------------------*/ +class nsXIEngine +{ +public: + nsXIEngine(); + ~nsXIEngine(); + + int Download(int aCustom, nsComponentList *aComps); + int Extract(nsComponent *aXPIEngine); + int Install(int aCustom, nsComponentList *aComps, char *aDestination); + int DeleteXPIs(int aCustom, nsComponentList *aComps); + + static void ProgressCallback(const char* aMsg, PRInt32 aVal, PRInt32 aMax); + static int ExistAllXPIs(int aCustom, nsComponentList *aComps, int *aTotal); + + enum + { + OK = 0, + E_PARAM = -1201, + E_MEM = -1202, + E_OPEN_MKR = -1203, + E_WRITE_MKR = -1204, + E_READ_MKR = -1205, + E_FIND_COMP = -1206, + E_STAT = -1207 + }; + +private: + int MakeUniqueTmpDir(); + int ParseURL(char *aURL, char **aHost, char **aDir); + int LoadXPIStub(xpistub_t *aStub, char *aDestionation); + int InstallXPI(nsComponent *aComp, xpistub_t *aStub); + int UnloadXPIStub(xpistub_t *aStub); + int GetFileSize(char *aPath); + int SetDLMarker(char *aCompName); + int GetDLMarkedComp(nsComponentList *aComps, int aCustom, + nsComponent **aOutComp, int *aOutCompNum); + int DelDLMarker(); + int TotalToDownload(int aCustom, nsComponentList *aComps); + PRBool CRCCheckDownloadedArchives(char *dlPath, short dlPathLen, + nsComponent *currComp, int count, int aCustom); + PRBool IsArchiveFile(char *path); + int VerifyArchive(char *szArchive); + PRBool CheckConn( char *URL, int type, CONN *myConn, PRBool force ); + char *mTmp; + int mTotalComps; + char *mOriginalDir; +}; + +#endif /* _NS_XIENGINE_H_ */ diff --git a/mozilla/toolkit/mozapps/installer/unix/wizard/nsXIOptions.cpp b/mozilla/toolkit/mozapps/installer/unix/wizard/nsXIOptions.cpp new file mode 100644 index 00000000000..9cc6a49b5c3 --- /dev/null +++ b/mozilla/toolkit/mozapps/installer/unix/wizard/nsXIOptions.cpp @@ -0,0 +1,52 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* + * The contents of this file are subject to the Netscape Public + * License Version 1.1 (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.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is Mozilla Communicator client code, + * released March 31, 1998. + * + * The Initial Developer of the Original Code is Netscape Communications + * Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + * Samir Gehani + */ + +#include "nsXIOptions.h" + +nsXIOptions::nsXIOptions() : + mTitle(NULL), + mDestination(NULL), + mProductName(NULL), + mHeaderPixmap(NULL), + mProgramName(NULL), + mSetupType(0), + mMode(MODE_DEFAULT), + mShouldRunApps(TRUE), + mProxyHost(NULL), + mProxyPort(NULL), + mProxyUser(NULL), + mProxyPswd(NULL), + mSaveModules(FALSE) +{ +} + +nsXIOptions::~nsXIOptions() +{ + XI_IF_FREE(mTitle); + XI_IF_FREE(mDestination); + XI_IF_FREE(mProxyHost); + XI_IF_FREE(mProxyPort); + XI_IF_FREE(mProxyUser); + XI_IF_FREE(mProxyPswd); +} diff --git a/mozilla/toolkit/mozapps/installer/unix/wizard/nsXIOptions.h b/mozilla/toolkit/mozapps/installer/unix/wizard/nsXIOptions.h new file mode 100644 index 00000000000..cd469b3a0cc --- /dev/null +++ b/mozilla/toolkit/mozapps/installer/unix/wizard/nsXIOptions.h @@ -0,0 +1,60 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* + * The contents of this file are subject to the Netscape Public + * License Version 1.1 (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.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is Mozilla Communicator client code, + * released March 31, 1998. + * + * The Initial Developer of the Original Code is Netscape Communications + * Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + * Samir Gehani + */ + +#ifndef _NS_XIOPTIONS_H_ +#define _NS_XIOPTIONS_H_ + +#include "XIDefines.h" + +class nsXIOptions +{ +public: + nsXIOptions(); + ~nsXIOptions(); + + char *mTitle; + char *mDestination; + char *mProductName; + char *mHeaderPixmap; + char *mProgramName; + int mSetupType; + int mMode; + int mShouldRunApps; + + enum + { + MODE_DEFAULT = 0, + MODE_AUTO, + MODE_SILENT + }; + + char *mProxyHost; + char *mProxyPort; + char *mProxyUser; + char *mProxyPswd; + + int mSaveModules; +}; + +#endif /* _NS_XIOPTIONS_H_ */ diff --git a/mozilla/toolkit/mozapps/installer/unix/wizard/nsXInstaller.cpp b/mozilla/toolkit/mozapps/installer/unix/wizard/nsXInstaller.cpp new file mode 100644 index 00000000000..9077acfa02a --- /dev/null +++ b/mozilla/toolkit/mozapps/installer/unix/wizard/nsXInstaller.cpp @@ -0,0 +1,509 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* + * The contents of this file are subject to the Netscape Public + * License Version 1.1 (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.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is Mozilla Communicator client code, + * released March 31, 1998. + * + * The Initial Developer of the Original Code is Netscape Communications + * Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + * Samir Gehani + * Brian Ryner + */ + +#include "nscore.h" +#include "nsXInstaller.h" +#include + +nsXIContext *gCtx = NULL; +static GtkWidget *sErrDlg = NULL; + +nsXInstaller::nsXInstaller() +{ +} + +nsXInstaller::~nsXInstaller() +{ + XI_IF_DELETE(gCtx); +} + +int +nsXInstaller::ParseArgs(int aArgc, char **aArgv) +{ + if (aArgc <= 0 || !aArgv) + return E_PARAM; + + for (int argNum = 1; argNum < aArgc; ++argNum) { + /* Print usage */ + if (strcmp(aArgv[argNum], "-h") == 0 || + strcmp(aArgv[argNum], "--help") == 0) { + + if (gCtx->Res("USAGE_MSG")) + fprintf (stderr, gCtx->Res("USAGE_MSG"), aArgv[0], "\n", + "\n", "\n", "\n", "\n", "\n", "\n", "\n"); + return E_USAGE_SHOWN; + } + + /* + * mode: auto (show progress UI but assume defaults + * without user intervention) + */ + else if (strcmp(aArgv[argNum], "-ma") == 0) { + gCtx->opt->mMode = nsXIOptions::MODE_AUTO; + } + + /* + * mode: silent (show no UI and have no user intervention) + */ + else if (strcmp(aArgv[argNum], "-ms") == 0) { + gCtx->opt->mMode = nsXIOptions::MODE_SILENT; + } + + /* + * ignore [RunAppX] sections + */ + else if (strcmp(aArgv[argNum], "-ira") == 0) { + gCtx->opt->mShouldRunApps = FALSE; + } + } + + return OK; +} + +int +nsXInstaller::ParseConfig() +{ + int err = OK; + nsINIParser *parser = NULL; + char *cfg = NULL; + + XI_ERR_BAIL(InitContext()); + err = gCtx->LoadResources(); + if (err != OK) + return err; + + cfg = nsINIParser::ResolveName(CONFIG); + if (!cfg) + return E_INVALID_PTR; + + parser = new nsINIParser(cfg); + if (!parser) { + err = E_MEM; + goto BAIL; + } + + err = parser->GetError(); + if (err != nsINIParser::OK) + return err; + + XI_ERR_BAIL(ParseGeneral(parser)); + XI_ERR_BAIL(gCtx->ldlg->Parse(parser)); + XI_ERR_BAIL(gCtx->wdlg->Parse(parser)); + //XI_ERR_BAIL(gCtx->cdlg->Parse(parser)); // components before setup type + XI_ERR_BAIL(gCtx->sdlg->Parse(parser)); + XI_ERR_BAIL(gCtx->idlg->Parse(parser)); + +BAIL: + XI_IF_FREE(cfg); + return err; +} + +int +nsXInstaller::InitContext() +{ + int err = OK; + + gCtx = new nsXIContext(); + if (!gCtx) + return E_MEM; + + gCtx->me = this; + + gCtx->ldlg = new nsLicenseDlg(); + gCtx->wdlg = new nsWelcomeDlg(); + gCtx->sdlg = new nsSetupTypeDlg(); + gCtx->cdlg = new nsComponentsDlg(); + gCtx->idlg = new nsInstallDlg(); + + if (!(gCtx->ldlg && gCtx->wdlg && gCtx->sdlg && gCtx->cdlg && gCtx->idlg)) { + err = E_MEM; + goto BAIL; + } + + return OK; + +BAIL: + XI_IF_DELETE(gCtx->ldlg); + XI_IF_DELETE(gCtx->wdlg); + XI_IF_DELETE(gCtx->sdlg); + XI_IF_DELETE(gCtx->cdlg); + XI_IF_DELETE(gCtx->idlg); + XI_IF_DELETE(gCtx); + + return err; +} + +int +nsXInstaller::RunWizard() +{ + int err = OK; + + XI_VERIFY(gCtx); + + // create the dialog window + if (gCtx->opt->mMode != nsXIOptions::MODE_SILENT) { + gCtx->window = gtk_window_new(GTK_WINDOW_TOPLEVEL); + XI_VERIFY(gCtx->window); + + gtk_window_set_position(GTK_WINDOW(gCtx->window), GTK_WIN_POS_CENTER); + gtk_signal_connect(GTK_OBJECT(gCtx->window), "delete_event", + GTK_SIGNAL_FUNC(Kill), NULL); + + gtk_signal_connect(GTK_OBJECT(gCtx->window), "key_press_event", + GTK_SIGNAL_FUNC(HandleKeyPress), NULL); + + gtk_window_set_title(GTK_WINDOW(gCtx->window), gCtx->opt->mTitle); + + SetupBoxes(); + + // create an area for the header image. + // this will remain 0-height until the user advances past + // the welcome dialog. + + gCtx->header = gtk_event_box_new(); + if (gCtx->opt->mHeaderPixmap) { + GdkPixmap *pm = gdk_pixmap_create_from_xpm(GDK_ROOT_PARENT(), + NULL, NULL, + gCtx->opt->mHeaderPixmap); + + if (pm) { + GtkStyle *newStyle = + gtk_style_copy(gtk_widget_get_style(gCtx->header)); + + newStyle->bg_pixmap[GTK_STATE_NORMAL] = pm; + gtk_widget_set_style(gCtx->header, newStyle); + + // newStyle now owns the pixmap, so we don't unref it. + g_object_unref(newStyle); + } + } + + // The header contains a vbox with two labels + GtkWidget *header_vbox = gtk_vbox_new(FALSE, 6); + gtk_container_set_border_width(GTK_CONTAINER(header_vbox), 6); + + gCtx->header_title = gtk_label_new(NULL); + gtk_misc_set_alignment(GTK_MISC(gCtx->header_title), 0.0, 0.5); + gtk_box_pack_start(GTK_BOX(header_vbox), gCtx->header_title, + FALSE, FALSE, 0); + + gCtx->header_subtitle = gtk_label_new(NULL); + gtk_misc_set_alignment(GTK_MISC(gCtx->header_subtitle), 0.0, 0.5); + gtk_misc_set_padding(GTK_MISC(gCtx->header_subtitle), 24, 0); + gtk_box_pack_start(GTK_BOX(header_vbox), gCtx->header_subtitle, + FALSE, FALSE, 0); + + gtk_container_add(GTK_CONTAINER(gCtx->header), header_vbox); + + gtk_widget_set_size_request(header_vbox, 0, 0); + gtk_box_pack_start(GTK_BOX(gCtx->mainbox), gCtx->header, FALSE, FALSE, 0); + + // create the notebook whose pages are dlgs + gCtx->notebook = gtk_notebook_new(); + XI_VERIFY(gCtx->notebook); + gtk_notebook_set_show_tabs(GTK_NOTEBOOK(gCtx->notebook), FALSE); + gtk_notebook_set_show_border(GTK_NOTEBOOK(gCtx->notebook), FALSE); + gtk_notebook_set_scrollable(GTK_NOTEBOOK(gCtx->notebook), FALSE); + gtk_widget_show(gCtx->notebook); + gtk_box_pack_start(GTK_BOX(gCtx->mainbox), gCtx->notebook, TRUE, TRUE, 0); + + // create and display the nav buttons + XI_ERR_BAIL(DrawNavButtons()); + } + + if (gCtx->opt->mMode == nsXIOptions::MODE_DEFAULT) { + // show welcome dlg + gCtx->wdlg->Show(nsXInstallerDlg::FORWARD_MOVE); + gtk_widget_show(gCtx->window); + + // pop over to main event loop + gtk_main(); + } else { + // show install dlg + if (gCtx->opt->mMode == nsXIOptions::MODE_AUTO) + gCtx->idlg->Show(nsXInstallerDlg::FORWARD_MOVE); + + gCtx->idlg->Next((GtkWidget *)NULL, (gpointer) gCtx->idlg); + } + + return OK; + +BAIL: + return err; +} + +gboolean +nsXInstaller::HandleKeyPress(GtkWidget *widget, GdkEventKey *event, + gpointer data) +{ + if (event->keyval == GDK_Escape) { + gtk_main_quit(); + return TRUE; + } + + return FALSE; +} + +gint +nsXInstaller::Kill(GtkWidget *widget, GdkEvent *event, gpointer data) +{ + gtk_main_quit(); + return FALSE; +} + +void +nsXInstaller::SetupBoxes() +{ + GtkWidget *mainbox = gtk_vbox_new(FALSE, 0); + gtk_container_add(GTK_CONTAINER(gCtx->window), mainbox); + + gtk_widget_show(mainbox); + gCtx->mainbox = mainbox; /* mainbox = canvas + nav btns' box */ +} + +int +nsXInstaller::DrawNavButtons() +{ + int err = OK; + + GtkWidget *navbtnhbox; + GtkWidget *navbtntable; + + XI_VERIFY(gCtx->mainbox); + + gCtx->next = gtk_button_new_from_stock(GTK_STOCK_GO_FORWARD); + gCtx->back = gtk_button_new_from_stock(GTK_STOCK_GO_BACK); + gCtx->cancel = gtk_button_new_from_stock(GTK_STOCK_CANCEL); + + gCtx->nextLabel = gtk_label_new(gCtx->Res("NEXT")); + gCtx->backLabel = gtk_label_new(gCtx->Res("BACK")); + XI_VERIFY(gCtx->next); + XI_VERIFY(gCtx->back); + XI_VERIFY(gCtx->cancel); + + gCtx->cancelID = gtk_signal_connect(GTK_OBJECT(gCtx->cancel), "clicked", + GTK_SIGNAL_FUNC(Kill), NULL); + + GTK_WIDGET_SET_FLAGS(gCtx->next, GTK_CAN_DEFAULT); + + navbtnhbox = gtk_hbox_new(TRUE, 10); + GtkWidget *separator = gtk_hseparator_new(); + + gtk_box_pack_start(GTK_BOX(gCtx->mainbox), separator, FALSE, FALSE, 0); + gtk_box_pack_start(GTK_BOX(gCtx->mainbox), navbtnhbox, FALSE, FALSE, 0); + + // put a table in the nav btn box + navbtntable = gtk_table_new(1, 5, TRUE); + gtk_box_pack_start(GTK_BOX(navbtnhbox), navbtntable, TRUE, TRUE, 0); + + gtk_table_attach(GTK_TABLE(navbtntable), gCtx->cancel, 2, 3, 0, 1, + static_cast(GTK_FILL | GTK_EXPAND), + static_cast(GTK_SHRINK), + 5, 5); + + gtk_table_attach(GTK_TABLE(navbtntable), gCtx->back, 3, 4, 0, 1, + static_cast(GTK_FILL | GTK_EXPAND), + static_cast(GTK_SHRINK), + 5, 5); + gtk_table_attach(GTK_TABLE(navbtntable), gCtx->next, 4, 5, 0, 1, + static_cast(GTK_FILL | GTK_EXPAND), + static_cast(GTK_SHRINK), + 5, 5); + + gtk_widget_show_all(gCtx->mainbox); + + return err; +} + +int +nsXInstaller::ParseGeneral(nsINIParser *aParser) +{ + int err = OK, size = 0; + char *buf = NULL; + + /* optional: main program name. if this file exists in the destination + directory, the user will be prompted to remove the directory or choose + a different directory. */ + + err = aParser->GetStringAlloc(GENERAL, PROGRAM_NAME, &buf, &size); + if (err == OK && size > 0) { + gCtx->opt->mProgramName = buf; + } + + /* optional: destination directory can be specified in config.ini */ + err = aParser->GetStringAlloc(GENERAL, DEFAULT_LOCATION, &buf, &size); + if (err == OK && size > 0) { + /* malloc MAXPATHLEN for consistency in behavior if destination + * directory is not specified in the config.ini + */ + gCtx->opt->mDestination = (char *)malloc(MAXPATHLEN * sizeof(char)); + strncpy(gCtx->opt->mDestination, buf, size); + XI_IF_FREE(buf); + } else { + err = OK; /* optional so no error if we didn't find it */ + } + + /* optional: installer app window title */ + size = 0; + buf = NULL; + err = aParser->GetStringAlloc(GENERAL, TITLE, &buf, &size); + if (err == OK && size > 0) { + gCtx->opt->mTitle = buf; + } else { + err = OK; /* optional so no error if we didn't find it */ + gCtx->opt->mTitle = strdup(gCtx->Res("DEFAULT_TITLE")); + } + + /* optional: product name (substituted for %s elsewhere) */ + size = 0; + buf = NULL; + err = aParser->GetStringAlloc(GENERAL, PRODUCT_NAME, &buf, &size); + if (err == OK && size > 0) + gCtx->opt->mProductName = buf; + else + err = OK; + + /* optional: header image */ + size = 0; + buf = NULL; + err = aParser->GetStringAlloc(GENERAL, HEADER_IMAGE, &buf, &size); + if (err == OK && size > 0) + gCtx->opt->mHeaderPixmap = buf; + else + err = OK; + + return err; +} + +int +main(int argc, char **argv) +{ + int err = OK; + nsXInstaller *installer = new nsXInstaller(); + if (!installer) { + err = E_MEM; + goto out; + } + + if ((err = installer->ParseArgs(argc, argv)) != OK) + goto out; + + gtk_init(&argc, &argv); + + if ((err = installer->ParseConfig()) != OK) + goto out; + + err = installer->RunWizard(); + + out: + XI_IF_DELETE(installer); + _exit(err); +} + +/*------------------------------------------------------------------* + * Default Error Handler + *------------------------------------------------------------------*/ +int +ErrorHandler(int aErr, const char* aErrMsg) +{ + GtkWidget *okButton, *label; + char msg[256]; + char newmsg[256]; + char errStr[16]; + + sprintf(errStr, "%d", aErr); + if (!IsErrFatal(aErr)) { + if (aErr == E_INSTALL) { + if (aErrMsg) { + sprintf(newmsg, gCtx->Res(errStr), aErrMsg); + sprintf(msg, gCtx->Res("ERROR"), aErr, newmsg); + } + } else { + sprintf(msg, gCtx->Res("ERROR"), aErr, gCtx->Res(errStr)); + } + } else { + sprintf(msg, gCtx->Res("FATAL_ERROR"), aErr, gCtx->Res(errStr)); + } + + if (gCtx->opt->mMode == nsXIOptions::MODE_SILENT) { + fprintf (stderr, "%s\n", msg); + return aErr; + } + + sErrDlg = gtk_dialog_new(); + gtk_window_set_title(GTK_WINDOW(sErrDlg), gCtx->Res("ERROR_TITLE")); + okButton = gtk_button_new_with_label(gCtx->Res("OK_LABEL")); + label = gtk_label_new(msg); + + gtk_window_set_position(GTK_WINDOW(sErrDlg), GTK_WIN_POS_CENTER); + gtk_container_add(GTK_CONTAINER(GTK_DIALOG(sErrDlg)->action_area), okButton); + gtk_signal_connect(GTK_OBJECT(okButton), "clicked", + GTK_SIGNAL_FUNC(ErrDlgOK), (void*)aErr); + + gtk_container_add(GTK_CONTAINER(GTK_DIALOG(sErrDlg)->vbox), label); + + GTK_WIDGET_SET_FLAGS(okButton, GTK_CAN_DEFAULT); + gtk_widget_grab_default(okButton); + gtk_widget_show_all(sErrDlg); + + gtk_main(); + + return aErr; +} + +void +ErrDlgOK(GtkWidget *aWidget, gpointer aData) +{ + int err = NS_PTR_TO_INT32(aData); + + if (sErrDlg) { + gtk_widget_destroy(sErrDlg); + sErrDlg = NULL; + } + + gtk_main_quit(); + + if (IsErrFatal(err)) + exit(err); +} + +int +IsErrFatal(int aErr) +{ + int bFatal = TRUE; + + /* non-fatal errors */ + switch (aErr) { + case -620: + case -621: + case -624: + case -625: + bFatal = FALSE; + default: + break; + } + + return bFatal; +} diff --git a/mozilla/toolkit/mozapps/installer/unix/wizard/nsXInstaller.h b/mozilla/toolkit/mozapps/installer/unix/wizard/nsXInstaller.h new file mode 100644 index 00000000000..c7621418560 --- /dev/null +++ b/mozilla/toolkit/mozapps/installer/unix/wizard/nsXInstaller.h @@ -0,0 +1,76 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* + * The contents of this file are subject to the Netscape Public + * License Version 1.1 (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.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is Mozilla Communicator client code, + * released March 31, 1998. + * + * The Initial Developer of the Original Code is Netscape Communications + * Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + * Samir Gehani + */ + +#ifndef _NS_XINSTALLER_H_ +#define _NS_XINSTALLER_H_ + +#include "XIDefines.h" +#include "XIErrors.h" + +#include "nsINIParser.h" +#include "nsLicenseDlg.h" +#include "nsXIContext.h" + +extern nsXIContext *gCtx; + +class nsXInstaller +{ +public: + nsXInstaller(); + ~nsXInstaller(); + + int ParseArgs(int aArgc, char **aArgv); + int ParseConfig(); + int RunWizard(); + int ParseGeneral(nsINIParser *aParser); + + static gint Kill(GtkWidget *widget, GdkEvent *event, gpointer data); + +private: + static gboolean HandleKeyPress(GtkWidget *widget, GdkEventKey *event, + gpointer data); + + int InitContext(); + void SetupBoxes(); + int DrawNavButtons(); +}; + +int main(int argc, char **argv); +int ErrorHandler(int aErr, const char *aErrMsg=NULL); +void ErrDlgOK(GtkWidget *aWidget, gpointer aData); +int IsErrFatal(int aErr); + +#define CONFIG "config" + +#if defined(DUMP) +#undef DUMP +#endif +#if defined(DEBUG_sgehani) || defined(DEBUG_druidd) || defined(DEBUG_root) +#define DUMP(_msg) printf("%s %d: %s \n", __FILE__, __LINE__, _msg); +#else +#define DUMP(_msg) +#endif + + +#endif /*_NS_XINSTALLER_H_ */ diff --git a/mozilla/toolkit/mozapps/installer/unix/wizard/nsXInstallerDlg.cpp b/mozilla/toolkit/mozapps/installer/unix/wizard/nsXInstallerDlg.cpp new file mode 100644 index 00000000000..b9c04f4de5e --- /dev/null +++ b/mozilla/toolkit/mozapps/installer/unix/wizard/nsXInstallerDlg.cpp @@ -0,0 +1,78 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* + * The contents of this file are subject to the Netscape Public + * License Version 1.1 (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.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is Mozilla Communicator client code, + * released March 31, 1998. + * + * The Initial Developer of the Original Code is Netscape Communications + * Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + * Samir Gehani + */ + +#include "nsXInstallerDlg.h" + +nsXInstallerDlg::nsXInstallerDlg() : + mShowDlg(nsXInstallerDlg::SHOW_DIALOG), + mTitle(NULL), + mSubTitle(NULL), + mWidgetsInit((int)FALSE), + mTable(NULL) +{ +} + +nsXInstallerDlg::~nsXInstallerDlg() +{ + if (mTitle) + free (mTitle); +} + +int +nsXInstallerDlg::SetShowDlg(int aShowDlg) +{ + if ( aShowDlg != nsXInstallerDlg::SHOW_DIALOG && + aShowDlg != nsXInstallerDlg::SKIP_DIALOG ) + return E_PARAM; + + mShowDlg = aShowDlg; + + return OK; +} + +int +nsXInstallerDlg::GetShowDlg() +{ + return mShowDlg; +} + +int +nsXInstallerDlg::SetTitle(char *aTitle) +{ + if (!aTitle) + return E_PARAM; + + mTitle = aTitle; + + return OK; +} + +char * +nsXInstallerDlg::GetTitle() +{ + if (mTitle) + return mTitle; + + return NULL; +} diff --git a/mozilla/toolkit/mozapps/installer/unix/wizard/nsXInstallerDlg.h b/mozilla/toolkit/mozapps/installer/unix/wizard/nsXInstallerDlg.h new file mode 100644 index 00000000000..993bc5709d6 --- /dev/null +++ b/mozilla/toolkit/mozapps/installer/unix/wizard/nsXInstallerDlg.h @@ -0,0 +1,88 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* + * The contents of this file are subject to the Netscape Public + * License Version 1.1 (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.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is Mozilla Communicator client code, + * released March 31, 1998. + * + * The Initial Developer of the Original Code is Netscape Communications + * Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + * Samir Gehani + */ + +#ifndef _NS_XINSTALLERDLG_H_ +#define _NS_XINSTALLERDLG_H_ + +#include +#include "XIErrors.h" +#include "XIDefines.h" + +#include "nsINIParser.h" + +/** + * nsXInstallerDlg + * + * The interface for all installer dialogs. Helps maintain + * uniform navigation mechanism, startup init, and UI widgets. + */ +class nsXInstallerDlg +{ +public: + nsXInstallerDlg(); + virtual ~nsXInstallerDlg(); + +/*-------------------------------------------------------------------* + * Navigation + *-------------------------------------------------------------------*/ + // NOTE: Please define these static methods too + // (static methods can't be virtual) + // static void Back(GtkWidget *aWidget, gpointer aData); + // static void Next(GtkWidget *aWidget, gpointer aData); + + virtual int Parse(nsINIParser *aParser) = 0; + + virtual int Show(int aDirection) = 0; + virtual int Hide(int aDirection) = 0; + +/*-------------------------------------------------------------------* + * INI Properties + *-------------------------------------------------------------------*/ + int SetShowDlg(int aShowDlg); + int GetShowDlg(); + int SetTitle(char *aTitle); + char *GetTitle(); + + void SetPageNum(int aPageNum); + int GetPageNum(); + + enum + { + SKIP_DIALOG = 0, + SHOW_DIALOG = 1, + + FORWARD_MOVE = 555, + BACKWARD_MOVE = -555 + }; + +protected: + int mShowDlg; + char *mTitle; + char *mSubTitle; + int mPageNum; // GtkNotebook page number for this dlg + int mWidgetsInit; // FALSE until widgets are created (first Show()) + GtkWidget *mTable; +}; + +#endif /* _NS_XINSTALLERDLG_H_ */ diff --git a/mozilla/toolkit/mozapps/installer/unix/wizard/nsZipExtractor.cpp b/mozilla/toolkit/mozapps/installer/unix/wizard/nsZipExtractor.cpp new file mode 100644 index 00000000000..689e36be5da --- /dev/null +++ b/mozilla/toolkit/mozapps/installer/unix/wizard/nsZipExtractor.cpp @@ -0,0 +1,173 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* + * The contents of this file are subject to the Netscape Public + * License Version 1.1 (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.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is Mozilla Communicator client code, + * released March 31, 1998. + * + * The Initial Developer of the Original Code is Netscape Communications + * Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + * Samir Gehani + */ + +#include "nsZipExtractor.h" + +#define STANDALONE 1 +#include "zipstub.h" +#include "zipfile.h" + +nsZipExtractor::nsZipExtractor(char *aSrc, char *aDest) : + mSrc(NULL), + mDest(NULL) +{ + if (aSrc) + mSrc = strdup(aSrc); + if (aDest) + mDest = strdup(aDest); +} + +nsZipExtractor::~nsZipExtractor() +{ + XI_IF_FREE(mSrc); + XI_IF_FREE(mDest); +} + +int +nsZipExtractor::Extract(nsComponent *aXPIEngine, int aTotal) +{ + DUMP("Extract"); + + char apath[MAXPATHLEN]; /* archive path */ + char bindir[512]; + char zpath[MAXPATHLEN]; /* path of file in zip archive */ + char epath[MAXPATHLEN]; /* path of file after being extracted */ + char *leaf = NULL, *lslash = NULL; + struct stat dummy; + int i, bFoundAll = FALSE, err = OK; + PRInt32 zerr = ZIP_OK; + void *hZip = NULL, *hFind = NULL; + + if (!aXPIEngine || !(aXPIEngine->GetArchive())) + return E_PARAM; + + sprintf(apath, "%s/%s", mSrc, aXPIEngine->GetArchive()); + if (-1 == stat(apath, &dummy)) + return E_NO_DOWNLOAD; + + /* initialize archive etc. + */ + zerr = ZIP_OpenArchive(apath, &hZip); + if (zerr != ZIP_OK) return E_EXTRACTION; + hFind = ZIP_FindInit(hZip, (const char *) NULL); + if (!hFind) + { + err = E_EXTRACTION; + goto au_revoir; + } + + /* extract files + */ + i = 0; + while (!bFoundAll) + { + memset(zpath, 0, MAXPATHLEN); + zerr = ZIP_FindNext(hFind, zpath, MAXPATHLEN); + if (zerr == ZIP_ERR_FNF) + { + bFoundAll = true; + break; + } + if (zerr != ZIP_OK) + { + err = E_EXTRACTION; + goto au_revoir; + } + + /* directory encountered: ignore entry + */ + lslash = strrchr(zpath, '/'); + if (lslash == (zpath + strlen(zpath) - 1)) + continue; + + if (!lslash) + leaf = zpath; + else + leaf = lslash + 1; + if (!leaf) + continue; + + /* update UI + */ + if (gCtx->opt->mMode != nsXIOptions::MODE_SILENT) + nsInstallDlg::MajorProgressCB(leaf, i, + aTotal, nsInstallDlg::ACT_EXTRACT); + + sprintf(epath, "%s/%s", mDest, zpath); + err = DirCreateRecursive(epath); + if (err != OK) goto au_revoir; + + zerr = ZIP_ExtractFile(hZip, zpath, epath); + if (zerr != ZIP_OK) + { + err = E_EXTRACTION; + goto au_revoir; + } + + i++; + } + + sprintf(bindir, "%s/%s", mDest, TMP_EXTRACT_SUBDIR); + if (-1 == stat(bindir, &dummy)) + err = E_EXTRACTION; + +au_revoir: + /* close archive etc. + */ + if (hFind) + ZIP_FindFree(hFind); + if (hZip) + ZIP_CloseArchive(&hZip); + return err; +} + +int +nsZipExtractor::DirCreateRecursive(char *aPath) +{ + int err = OK; + char *slash = NULL, *pathpos = NULL; + char currdir[MAXPATHLEN]; + struct stat dummy; + + if (!aPath || !mDest) + return E_PARAM; + + slash = aPath + strlen(mDest); + if (*slash != '/') + return E_INVALID_PTR; + + while (slash) + { + memset(currdir, 0, MAXPATHLEN); + strncpy(currdir, aPath, slash - aPath); + + if (-1 == stat(currdir, &dummy)) + mkdir(currdir, 0755); + + pathpos = slash; + slash = strchr(pathpos+1, '/'); + } + + return err; +} diff --git a/mozilla/toolkit/mozapps/installer/unix/wizard/nsZipExtractor.h b/mozilla/toolkit/mozapps/installer/unix/wizard/nsZipExtractor.h new file mode 100644 index 00000000000..ec87eebb246 --- /dev/null +++ b/mozilla/toolkit/mozapps/installer/unix/wizard/nsZipExtractor.h @@ -0,0 +1,49 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* + * The contents of this file are subject to the Netscape Public + * License Version 1.1 (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.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is Mozilla Communicator client code, + * released March 31, 1998. + * + * The Initial Developer of the Original Code is Netscape Communications + * Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + * Samir Gehani + */ + +#ifndef _NS_ZIPEXTRACTOR_H_ +#define _NS_ZIPEXTRACTOR_H_ + +#include "XIDefines.h" +#include "nsComponent.h" +#include "nsXInstaller.h" + +#include + +class nsZipExtractor +{ +public: + nsZipExtractor(char *aSrc, char *aDest); + ~nsZipExtractor(); + + int Extract(nsComponent *aXPIEngine, int aTotal); + +private: + int DirCreateRecursive(char *aPath); + + char *mSrc; + char *mDest; +}; + +#endif /* _NS_ZIPEXTRACTOR_H_ */ diff --git a/mozilla/toolkit/mozapps/installer/unix/wizard/watermark.xpm b/mozilla/toolkit/mozapps/installer/unix/wizard/watermark.xpm new file mode 100644 index 00000000000..f358c25b288 --- /dev/null +++ b/mozilla/toolkit/mozapps/installer/unix/wizard/watermark.xpm @@ -0,0 +1,542 @@ +/* XPM */ +static char * welcome_bg2_xpm[] = { +"181 500 39 1", +" c None", +". c #FFFFFF", +"+ c #B4B4B4", +"@ c #F8F8F8", +"# c #F0F0F0", +"$ c #FEFEFE", +"% c #0F0F0F", +"& c #171717", +"* c #000000", +"= c #0A0A0A", +"- c #E3E3E3", +"; c #D3D3D3", +"> c #9B9B9B", +", c #4A4A4A", +"' c #080303", +") c #A9A9A9", +"! c #2E2E2E", +"~ c #646464", +"{ c #828282", +"] c #1D0000", +"^ c #6F0E01", +"/ c #A51F0D", +"( c #C92B15", +"_ c #420100", +": c #CACACA", +"< c #F73A1F", +"[ c #FF3E23", +"} c #EC361D", +"| c #BBBBBB", +"1 c #FBFBFB", +"2 c #F4F4F4", +"3 c #E6E0D7", +"4 c #E8E2DA", +"5 c #EAE5DE", +"6 c #ECE7E0", +"7 c #EDE8E2", +"8 c #EDEAE4", +"9 c #EDE9E3", +"0 c #EEEAE4", +"..................................................................................................................................................................................+.+", +"...................................................................................................................................................................................++", +"..................................................................................................................................................................................++.", +"..................................................................................................................................................................................+.+", +"...................................................................................................................................................................................++", +"..................................................................................................................................................................................++.", +"..................................................................................................................................................................................+.+", +"...................................................................................................................................................................................++", +"..................................................................................................................................................................................++.", +"..................................................................................................................................................................................+.+", +"...................................................................................................................................................................................++", +"..................................................................................................................................................................................++.", +"...@####################################################################$.........................................................................................................+.+", +"...%%&%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%&#..........................................................................................................++", +"...**=*****************************************************************=#.........................................................................................................++.", +"...**%=%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%**%#.........................................................................................................+.+", +"...%*%..############################################################-%*%#..........................................................................................................++", +"...%*%...............................................................%*%#.........................................................................................................++.", +"...%*%...............................................................%*%#.........................................................................................................+.+", +"...%*%...............................................................%*%#..........................................................................................................++", +"...%*%......................;>,'=&)#.................................%*%#.........................................................................................................++.", +"...%*%...................#>!*******%~)#.....@@$......................%*%#.........................................................................................................+.+", +"...%*%.................#{&************&,>>~!%=!~;....................%*%#..........................................................................................................++", +"...%*%................>&****]^/(((^_************=:...................%*%#.........................................................................................................++.", +"...%*%..............-~****]/<[[[[[[<}/****_^//(]*&-..................%*%#.........................................................................................................+.+", +"...%*%.............|%****^[[<[}(//(<<_'_/[}^]*]_**~..................%*%#..........................................................................................................++", +"...%*%...........1{*****([}<}^'***/<}/<[(_********%@.................%*%#.........................................................................................................++.", +"...%*%..........#!****]}[}}<]***^}<}/^_****^/]****&..................%*%#.........................................................................................................+.+", +"...%*%.........|&*****([<}[^***][<}}^*****/(]*****%:.................%*%#..........................................................................................................++", +"...%*%........)******_}^/<}'/_*^[}<^/[}}*'[*~!*****=>................%*%#.........................................................................................................++.", +"...%*%.......{*********]}<(([/*^[[[(*_}[^*}^**,,]^***,:..............%*%#.........................................................................................................+.+", +"...%*%.....$~*********'<<}}<}[_^[^_]**]}[_^}^****^('***,|............%*%#..........................................................................................................++", +"...%*%.....,***'%*****/[}}}}}}}}[/***^(}<[(^_/^_]*/<^****!{-.........%*%#.........................................................................................................++.", +"...%*%...-!*%,>>!****'<}}}}}}}[(_]***_[(_/[<_']_/}}<[}/]***=,>@......%*%#.........................................................................................................+.+", +"...%*%..@~~|@.;&*****_[}}}}}<.....%*%#..........................................................................................................++", +"...%*%..1@...{*******^[}}}}[/^}}<<<<}((<<^*]([<<}}}}}}}}<[}/^***!;...%*%#.........................................................................................................++.", +"...%*%.....1~********^[}}}<}'(<}}}}}}<}.........................+.+", +"...%*%..~~-.;%****'}}<}}}}[_*^[}}}}}}}<(***********/[<}}}}}}[/*^*=...%*%#.........................................................)**=)...|***!@....,***>..........................++", +"...%*%..#..)**!!***(<}}}}}[_**([}}}}}}}}'***********_([<}}}}}<^/_=...%*%#........................................................1!***!1..|***!@....,***>.........................++.", +"...%*%....)*&)-&***^[}}}}}}'**'}<}}}}}}[^*********!&**_(<[[<<<}(_=...%*%#........................................................1!***!1..|***!@....,***>.........................+.+", +"...%*%...|&{$2!****'}<}}}<(*]]*]}<}}}}}<}'**_^****!'*=**]^/(}}[[]=...%*%#.........................................................>***>...|***!@....,***>..........................++", +"...%*%...|-..!******^[}}}}}*][/_/(<}}}}}<}_**//******=!%******_^*=...%*%#.........................................................${,>....|***!@....,***>.........................++.", +"...%*%......~**&,****(<}}}<(*^[[<]^[}}}}}<<^_](}^]****%*,*&*=****,...%*%#.................................................................|***!@....,***>.........................+.+", +"...%*%.....>*%{2,****]<}}}}[(*/<[/*^<[}}}}}[[}}[[[(^'*****!*,*~**)...%*%#.........2#$......##1...........@#2..............................|***!@....,***>.........1##2.............++", +"...%*%....#&~-.{******^<}}}}[(^}}[_*_([[<<[[<}(/__}[[(^_********&1...%*%#.;~~~>.-~&%,|...:,&%!{@.......|~!%&~)....1{~~~~~~~~~~~>..;~~~|...|***!@....,***>.......;~!&%&,>#.........++.", +"...%*%....::..|*==****]<}}}}}<}}}<}]**_/((^_]******^([[[[/******{....%*%#.|***~#!****'|.)=*****,1.....{*******~@..@&***********{..|***>...|***!@....,***>......>=*******!-........+.+", +"...%*%.......;',>=****^[}}}}}}}}}}<(*****************]^//_**&{{{1....%*%#.|***~~******,;&*******)....>*********{..@!**********%-..|***>...|***!@....,***>.....|**********,$........++", +"...%*%......$,{.&*****}<}}}}}}}}}}}[(_*******&{||>~&*******~-........%*%#.|***!==!%***=,*=!%****,...-&***,{,***=;.@,%%%%%&=***~...|***>...|***!@....,***>.....,***!{{!****:.......++.", +"...%*%......#:.~=~!**_[<<}}}}}}}}}}}[(]****%~#.....1:{~,!,|..........%*%#.|****!;@;!****!;@;!***!1..{***!@..,***~..2######!***|...|***>...|***!@....,***>....-***&-..@,***>.......+.+", +"...%*%........2{-~***_}(/(}}}}}}}}}[^*****,-.........................%*%#.|****|...{****|...{***!@.$,***)...|***!@.......;'**!1...|***>...|***!@....,***>....-{,=~....>***{........++", +"...%*%........$.-,'*****_}}}}}}}}}[/*****~...........................%*%#.|***&#...|***&#...|***!@.#%**=-...@&**';.......~***{....|***>...|***!@....,***>.......--....>***{.......++.", +"...%*%.........#>!****]/<<}}}}}}}[}]^(]*!............................%*%#.|***!@...|***!@...|***!@.:***!@....,***)......#&**=-....|***>...|***!@....,***>.............>***{.......+.+", +"...%*%.........;****_/}((}}}}}}<(^}([(**>............................%*%#.|***!@...|***!@...|***!@.)***!1....,***{......>***,.....|***>...|***!@....,***>.........1###>***{........++", +"...%*%..........:=*]^__/}}}}}}}}<_'/[/*=#............................%*%#.|***!@...|***!@...|***!@.>***,.....~***{......,***).....|***>...|***!@....,***>.......|~!&===***{.......)).", +"...%*%...........)***_[[}}}}}}}}<}**]_*,.............................%*%#.|***!@...|***!@...|***!@.{***,.....~***~.....;'**!2.....|***>...|***!@....,***>.....@~**********{.......).)", +"...%*%............|&*]([}}}}}}}}}[(****{.............................%*%#.|***!@...|***!@...|***!@.{***,.....~***~.....{***{......|***>...|***!@....,***>.....~*****=='***{........))", +"...%*%.............;!**^}[<}}}}}/([(***|.............................%*%#.|***!@...|***!@...|***!@.{***,.....~***~....2!**';......|***>...|***!@....,***>....;'***!>:-{***{.......)).", +"...%*%..............2~**'^}[<}}***!1....,***~....)***,.......|***>...|***!@....,***>....{***!-...>***{.......).)", +"...%*%................|!***^(}<[[^****,..............................%*%#.|***!@...|***!@...|***!@.>***!@....,***{....,***).......|***>...|***!@....,***>....,***{....>***{........))", +"...%*%.................1),****_^//****>..............................%*%#.|***!@...|***!@...|***!@.|***%#...@!***>...-=**&#.......|***>...|***!@....,***>...$,***|....>***{.......)).", +"...%*%....................:~&*********{..............................%*%#.|***!@...|***!@...|***!@.-=**':...-=***:...{***~........|***>...|***!@....,***>...@!***|....{***{.......).)", +"...%*%......................1:{~,!!!!!{..............................%*%#.|***!@...|***!@...|***!@.1!***>...)***&#..@!**';........|***>...|***&1....,***>...@!***|....,***{........))", +"...%*%.............................$.................................%*%#.|***!@...|***!@...|***!@..~***!$..,***,...|***!222222@..|***>...|****)....,***,#...,***{...>****{...$...)).", +"...%*%...............................................................%*%#.|***!@...|***!@...|***!@..:'***~:{****)...~***&!!!!!!~..|***>...-=***=~>1.~****!~:.~***&>;{==***{.1;@...).)", +"...**%'============================'*'***''''''''''**']'*'***========**%#.|***!@...|***!@...|***!@...~****'****,$..-&**********,..|***>....,*****&@.|******>.|*****'*&~***!~!>$....))", +"...**=*****************************************************************=#.|***!@...|***!@...|***!@...#!*******!-...{***********,..|***>....:=****!@.$~*****>.1,******>:=****,@....)).", +"...&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&#.|&&&,@...|&&&,@...|&&&,@....#~&***%~-....~&&&&&&&&&&&~..|&&&).....|,=**!@..#{&***>..#~=**&{..>!&&~#.....).)", +"...122222222222222222222222222222222222222222222222222222222222222222222$.1222@....1222@....1222@.......#|)|-......@22222222222@..12221......$;)>|$....#|)>-....;))-....@2@........))", +"..................................................................................................................................................................................)).", +"..................................................................................................................................................................................).)", +"...................................................................................................................................................................................))", +"..................................................................................................................................................................................)).", +"..................................................................................................................................................................................).)", +"...................................................................................................................................................................................))", +"..................................................................................................................................................................................)).", +"..................................................................................................................................................................................).)", +"...................................................................................................................................................................................))", +"..................................................................................................................................................................................)).", +"3333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333).)", +"4444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444.))", +"5555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555)).", +"6666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666).)", +"7777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777.))", +"8888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888)).", +"9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999).)", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.))", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000)).", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000).)", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.))", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000++.", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000+.+", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.++", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000++.", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000+.+", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.++", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000++.", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000+.+", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.++", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000++.", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000+.+", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.++", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000++.", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000+.+", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.++", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000++.", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000+.+", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.++", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000++.", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000+.+", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.++", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000++.", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000+.+", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.++", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000++.", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000+.+", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.++", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000++.", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000+.+", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.++", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000++.", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000+.+", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.++", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000++.", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000+.+", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.++", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000++.", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000+.+", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.++", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000++.", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000+.+", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.++", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000++.", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000+.+", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.++", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000++.", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000+.+", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.++", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000++.", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000+.+", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.++", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000++.", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000+.+", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.++", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000++.", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000+.+", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.++", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000)).", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000).)", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.))", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000)).", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000).)", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.))", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000)).", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000).)", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.))", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000)).", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000).)", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.))", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000)).", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000).)", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.))", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000)).", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000).)", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.))", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000)).", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000).)", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.))", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000)).", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000).)", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.))", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000)).", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000).)", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.))", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000)).", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000).)", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.))", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000)).", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000).)", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.))", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000)).", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000).)", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.))", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000++.", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000+.+", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.++", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000++.", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000+.+", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.++", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000++.", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000+.+", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.++", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000++.", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000+.+", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.++", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000++.", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000+.+", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.++", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000++.", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000+.+", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.++", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000++.", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000+.+", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.++", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000++.", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000+.+", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.++", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000++.", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000+.+", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.++", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000++.", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000+.+", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.++", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000++.", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000+.+", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.++", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000++.", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000+.+", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.++", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000++.", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000+.+", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.++", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000++.", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000+.+", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.++", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000++.", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000+.+", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.++", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000++.", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000+.+", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.++", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000++.", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000+.+", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.++", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000++.", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000+.+", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.++", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000++.", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000+.+", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.++", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000)).", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000).)", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.))", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000)).", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000).)", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.))", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000)).", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000).)", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.))", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000)).", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000).)", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.))", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000)).", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000).)", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.))", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000)).", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000).)", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.))", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000)).", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000).)", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.))", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000)).", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000).)", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.))", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000)).", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000).)", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.))", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000)).", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000).)", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.))", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000)).", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000).)", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.))", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000)).", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000).)", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.))", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000++.", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000+.+", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.++", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000++.", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000+.+", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.++", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000++.", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000+.+", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.++", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000++.", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000+.+", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.++", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000++.", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000+.+", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.++", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000++.", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000+.+", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.++", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000++.", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000+.+", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.++", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000++.", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000+.+", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.++", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000++.", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000+.+", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.++", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000++.", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000+.+", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.++", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000++.", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000+.+", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.++", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000++.", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000+.+", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.++", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000++.", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000+.+", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.++", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000++.", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000+.+", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.++", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000++.", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000+.+", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.++", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000++.", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000+.+", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.++", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000++.", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000+.+", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.++", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000++.", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000+.+", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.++", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000++.", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000+.+", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.++", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000)).", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000).)", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.))", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000)).", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000).)", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.))", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000)).", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000).)", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.))", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000)).", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000).)", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.))", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000)).", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000).)", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.))", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000)).", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000).)", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.))", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000)).", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000).)", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.))", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000)).", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000).)", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.))", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000)).", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000).)", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.))", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000)).", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000).)", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.))", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000)).", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000).)", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.))", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000)).", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000).)", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.))", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000++.", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000+.+", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.++", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000++.", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000+.+", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.++", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000++.", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000+.+", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.++", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000++.", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000+.+", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.++", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000++.", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000+.+", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.++", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000++.", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000+.+", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.++", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000++.", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000+.+", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.++", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000++.", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000+.+", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.++", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000++.", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000+.+", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.++", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000++.", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000+.+", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.++", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000++.", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000+.+", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.++", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000++.", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000+.+", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.++", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000++.", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000+.+", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.++", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000++.", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000+.+", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.++", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000++.", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000+.+", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.++", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000++.", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000+.+", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.++", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000++.", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000+.+", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.++", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000++.", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000+.+", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.++", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000++.", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000+.+", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.++", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000)).", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000).)", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.))", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000)).", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000).)", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.))", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000)).", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000).)", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.))", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000)).", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000).)", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.))", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000)).", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000).)", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.))", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000)).", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000).)", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.))", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000)).", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000).)", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.))", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000)).", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000).)", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.))", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000)).", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000).)", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.))", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000)).", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000).)", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.))", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000)).", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000).)", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.))", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000)).", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000).)", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.))", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000++.", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000+.+", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.++", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000++.", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000+.+", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.++", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000++.", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000+.+", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.++", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000++.", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000+.+", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.++", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000++.", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000+.+", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.++", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000++.", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000+.+", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.++", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000++.", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000+.+", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.++", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000++.", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000+.+", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.++", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000++.", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000+.+", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.++", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000++.", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000+.+", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.++", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000++.", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000+.+", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.++", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000++.", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000+.+", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.++"};