From f67be14c0fce1ed637691077ff160cd54cb7438d Mon Sep 17 00:00:00 2001 From: "sgehani%netscape.com" Date: Thu, 3 May 2001 02:17:27 +0000 Subject: [PATCH] (*) Hook in libxpnet's pause/resume support and add a disk space warning. (*) Also, fix the download location for resumption. (*) Implement a new and improved download UI with a unified prog bar. b = 77980 r = suu sr = mscott --- xpinstall/wizard/unix/src2/XIDefines.h | 3 +- xpinstall/wizard/unix/src2/XIErrors.h | 3 +- xpinstall/wizard/unix/src2/config.ini | 7 +- xpinstall/wizard/unix/src2/installer.ini | 14 +- xpinstall/wizard/unix/src2/mozilla-installer | 2 +- xpinstall/wizard/unix/src2/nsComponent.cpp | 84 ++- xpinstall/wizard/unix/src2/nsComponent.h | 16 +- .../wizard/unix/src2/nsComponentsDlg.cpp | 18 +- xpinstall/wizard/unix/src2/nsInstallDlg.cpp | 556 ++++++++++++++++-- xpinstall/wizard/unix/src2/nsInstallDlg.h | 28 +- xpinstall/wizard/unix/src2/nsSetupTypeDlg.cpp | 178 +++++- xpinstall/wizard/unix/src2/nsSetupTypeDlg.h | 4 + xpinstall/wizard/unix/src2/nsXIContext.cpp | 15 +- xpinstall/wizard/unix/src2/nsXIContext.h | 1 + xpinstall/wizard/unix/src2/nsXIEngine.cpp | 371 +++++++++--- xpinstall/wizard/unix/src2/nsXIEngine.h | 24 +- xpinstall/wizard/unix/src2/nsXIOptions.cpp | 3 +- xpinstall/wizard/unix/src2/nsXIOptions.h | 8 + xpinstall/wizard/unix/src2/nsXInstaller.cpp | 53 +- xpinstall/wizard/unix/src2/nsXInstaller.h | 1 + xpinstall/wizard/unix/src2/nsZipExtractor.cpp | 22 +- xpinstall/wizard/unix/src2/nsZipExtractor.h | 5 +- 22 files changed, 1241 insertions(+), 175 deletions(-) diff --git a/xpinstall/wizard/unix/src2/XIDefines.h b/xpinstall/wizard/unix/src2/XIDefines.h index 66b7d0ab68e4..8be9baf71305 100644 --- a/xpinstall/wizard/unix/src2/XIDefines.h +++ b/xpinstall/wizard/unix/src2/XIDefines.h @@ -83,7 +83,8 @@ #define Cd "C%d" #define ARCHIVE "Archive" #define URLd "URL%d" -#define SIZE "Install Size" +#define INSTALL_SIZE "Install Size" +#define ARCHIVE_SIZE "Archive Size" #define DEPENDENCYd "Dependency%d" #define DEPENDEEd "Dependee%d" #define ATTRIBUTES "Attributes" diff --git a/xpinstall/wizard/unix/src2/XIErrors.h b/xpinstall/wizard/unix/src2/XIErrors.h index b6179087d745..b5cad0cd53e7 100644 --- a/xpinstall/wizard/unix/src2/XIErrors.h +++ b/xpinstall/wizard/unix/src2/XIErrors.h @@ -63,7 +63,8 @@ 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_PERMS = -626, /* don't have rwx perms on selected dir */ + E_NO_DISK_SPACE = -627 /* not eough disk space to install */ }; #endif /* _XI_ERRORS_H_ */ diff --git a/xpinstall/wizard/unix/src2/config.ini b/xpinstall/wizard/unix/src2/config.ini index 0047a9ff4f64..9a1655329257 100644 --- a/xpinstall/wizard/unix/src2/config.ini +++ b/xpinstall/wizard/unix/src2/config.ini @@ -71,6 +71,7 @@ Description Short=XPInstall Engine Description Long=Installer technology Archive=xpcom.xpi Install Size=1000 +Archive Size=837900 Attributes=SELECTED|INVISIBLE URL0=ftp://127.0.0.1/pub/xpi/ URL1=ftp://orb.mcom.com/pub/xpi/ @@ -80,6 +81,7 @@ Description Short=Navigator Description Long=Web browser software Archive=browser.xpi Install Size=2000 +Archive Size=200 Attributes=SELECTED URL0=ftp://127.0.0.1/pub/xpi/ URL1=ftp://orb.mcom.com/pub/xpi/ @@ -91,6 +93,7 @@ Description Short=Mail & News Description Long=Email and Newsgroup software Archive=mail.xpi Install Size=1500 +Archive Size=150 Attributes=SELECTED URL0=ftp://127.0.0.1/pub/xpi/ URL1=ftp://orb.mcom.com/pub/xpi/ @@ -100,6 +103,7 @@ Description Short=Java Description Long=Java runtime environment Archive=java.xpi Install Size=1500 +Archive Size=150 Attributes= URL0=ftp://127.0.0.1/pub/xpi/ URL1=ftp://orb.mcom.com/pub/xpi/ @@ -109,6 +113,7 @@ Description Short=Browser-UI Description Long=Browser User Interface Archive=browser-ui.xpi Install Size=2000 +Archive Size=200 Attributes= URL0=ftp://127.0.0.1/pub/xpi/ URL1=ftp://orb.mcom.com/pub/xpi/ @@ -127,4 +132,4 @@ XPInstall Engine=xpcom.xpi [LegacyCheck0] ;------------------------------------------------------------------------- Filename=mozilla-bin -Message=An older installation of Mozilla was detected. Please choose to delete the directory contents of your current Mozilla installation by hitting the 'Delete' button. Alternatively, please hit the 'Cancel' button and choose a different destination directory. +Message=An older installation of Mozilla was detected. Please choose to delete the directory contents of your current Mozilla installation by pressing the 'Delete' button. Alternatively, please press the 'Cancel' button and choose a different destination directory. diff --git a/xpinstall/wizard/unix/src2/installer.ini b/xpinstall/wizard/unix/src2/installer.ini index 773538796624..fa1192bded02 100644 --- a/xpinstall/wizard/unix/src2/installer.ini +++ b/xpinstall/wizard/unix/src2/installer.ini @@ -11,6 +11,8 @@ CANCEL=Cancel ACCEPT=Accept DECLINE=Decline INSTALL=Install +PAUSE=Pause +RESUME=Resume DEFAULT_TITLE=Mozilla Installer DEST_DIR=Destination Directory BROWSE=Change... @@ -24,8 +26,6 @@ CANCEL_LABEL=Cancel ERROR=Error [%d]: %s FATAL_ERROR=Fatal error [%d]: %s DESCRIPTION=Description -DOWNLOADING=Downloading %s [%d/%d] -DLRATE= at %d K/sec... PREPARING=Preparing %s... EXTRACTING=Extracting %s... INSTALLING_XPI=Installing %s... @@ -40,6 +40,16 @@ 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. +DOWNLOADING=Downloading: +FROM=From: +TO=To: +STATUS=Status: +DL_STATUS_STR=%d KB of %d KB (at %d KB/sec) +UNKNOWN=Unknown ;------------------------------------------------------------------------------ ; Error strings diff --git a/xpinstall/wizard/unix/src2/mozilla-installer b/xpinstall/wizard/unix/src2/mozilla-installer index 0b044d45890c..225573982158 100755 --- a/xpinstall/wizard/unix/src2/mozilla-installer +++ b/xpinstall/wizard/unix/src2/mozilla-installer @@ -45,6 +45,6 @@ export PATH MOZILLA_FIVE_HOME=. export MOZILLA_FIVE_HOME -./mozilla-installer-bin --sync +./mozilla-installer-bin --sync $@ rm -rf /tmp/.tmp.xi.* diff --git a/xpinstall/wizard/unix/src2/nsComponent.cpp b/xpinstall/wizard/unix/src2/nsComponent.cpp index 90a98cbf4787..1bebead88f6c 100644 --- a/xpinstall/wizard/unix/src2/nsComponent.cpp +++ b/xpinstall/wizard/unix/src2/nsComponent.cpp @@ -23,18 +23,22 @@ */ #include "nsComponent.h" +#include nsComponent::nsComponent() : mDescShort(NULL), mDescLong(NULL), mArchive(NULL), - mSize(0), + mInstallSize(0), + mArchiveSize(0), + mNextDependeeIdx(0), mAttributes(NO_ATTR), mNext(NULL), mIndex(-1), mRefCount(0), mDepRefCount(0), - mNextDependeeIdx(0) + mResPos(0), + mDownloaded(FALSE) { int i; @@ -129,22 +133,57 @@ nsComponent::GetArchive() } int -nsComponent::SetSize(int aSize) +nsComponent::SetInstallSize(int aInstallSize) { - mSize = aSize; + mInstallSize = aInstallSize; return OK; } int -nsComponent::GetSize() +nsComponent::GetInstallSize() { - if (mSize >= 0) - return mSize; + 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) { @@ -395,3 +434,34 @@ 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() +{ + mDownloaded = TRUE; + + return OK; +} + +int +nsComponent::IsDownloaded() +{ + return mDownloaded; +} diff --git a/xpinstall/wizard/unix/src2/nsComponent.h b/xpinstall/wizard/unix/src2/nsComponent.h index a57ef47a8c4a..e06af635c3bd 100644 --- a/xpinstall/wizard/unix/src2/nsComponent.h +++ b/xpinstall/wizard/unix/src2/nsComponent.h @@ -48,8 +48,11 @@ public: char * GetDescLong(); int SetArchive(char *aAcrhive); char * GetArchive(); - int SetSize(int aSize); - int GetSize(); + 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); @@ -77,6 +80,10 @@ public: int DepAddRef(); int DepRelease(); int DepGetRefCount(); + int SetResumePos(int aResPos); + int GetResumePos(); + int SetDownloaded(); + int IsDownloaded(); /*---------------------------------------------------------------* * Attributes @@ -93,7 +100,8 @@ private: char *mDescShort; char *mDescLong; char *mArchive; - int mSize; + int mInstallSize; + int mArchiveSize; char *mURL[MAX_URLS]; char *mDependees[MAX_COMPONENTS]; int mNextDependeeIdx; @@ -102,6 +110,8 @@ private: int mIndex; int mRefCount; int mDepRefCount; + int mResPos; + int mDownloaded; }; #endif /* _NS_COMPONENT_H_ */ diff --git a/xpinstall/wizard/unix/src2/nsComponentsDlg.cpp b/xpinstall/wizard/unix/src2/nsComponentsDlg.cpp index b8dcf25d6d8c..09958003473a 100644 --- a/xpinstall/wizard/unix/src2/nsComponentsDlg.cpp +++ b/xpinstall/wizard/unix/src2/nsComponentsDlg.cpp @@ -75,6 +75,9 @@ nsComponentsDlg::Next(GtkWidget *aWidget, gpointer aData) return; } + if (OK != nsSetupTypeDlg::VerifyDiskSpace()) + return; + // hide this notebook page gCtx->cdlg->Hide(nsXInstallerDlg::FORWARD_MOVE); @@ -100,7 +103,8 @@ nsComponentsDlg::Parse(nsINIParser *aParser) char *currDescShort = NULL; char *currDescLong = NULL; char *currArchive = NULL; - char *currSizeStr = NULL; + char *currInstallSizeStr = NULL; + char *currArchiveSizeStr = NULL; char *currAttrStr = NULL; char *currURL = NULL; char *currDepName = NULL; @@ -139,7 +143,8 @@ nsComponentsDlg::Parse(nsINIParser *aParser) currDescShort = NULL; currDescLong = NULL; currArchive = NULL; - currSizeStr = NULL; + currInstallSizeStr = NULL; + currArchiveSizeStr = NULL; currAttrStr = NULL; sprintf(currSec, COMPONENTd, i); @@ -157,8 +162,10 @@ nsComponentsDlg::Parse(nsINIParser *aParser) &currDescLong, &bufsize)); XI_ERR_BAIL(aParser->GetStringAlloc(currSec, ARCHIVE, &currArchive, &bufsize)); - XI_ERR_BAIL(aParser->GetStringAlloc(currSec, SIZE, - &currSizeStr, &bufsize)); + XI_ERR_BAIL(aParser->GetStringAlloc(currSec, INSTALL_SIZE, + &currInstallSizeStr, &bufsize)); + XI_ERR_BAIL(aParser->GetStringAlloc(currSec, ARCHIVE_SIZE, + &currArchiveSizeStr, &bufsize)); err = aParser->GetStringAlloc(currSec, ATTRIBUTES, &currAttrStr, &bufsize); if (err != OK && err != nsINIParser::E_NO_KEY) goto BAIL; else err = OK; @@ -169,7 +176,8 @@ nsComponentsDlg::Parse(nsINIParser *aParser) currComp->SetDescShort(currDescShort); currComp->SetDescLong(currDescLong); currComp->SetArchive(currArchive); - currComp->SetSize(atoi(currSizeStr)); + currComp->SetInstallSize(atoi(currInstallSizeStr)); + currComp->SetArchiveSize(atoi(currArchiveSizeStr)); if (NULL != strstr(currAttrStr, SELECTED_ATTR)) { currComp->SetSelected(); diff --git a/xpinstall/wizard/unix/src2/nsInstallDlg.cpp b/xpinstall/wizard/unix/src2/nsInstallDlg.cpp index 2dd21ca2b33c..4e96ee1ac0ce 100644 --- a/xpinstall/wizard/unix/src2/nsInstallDlg.cpp +++ b/xpinstall/wizard/unix/src2/nsInstallDlg.cpp @@ -23,15 +23,34 @@ */ #include "nsSocket.h" +#include "nsHTTPConn.h" #include "nsInstallDlg.h" #include "nsXInstaller.h" #include "nsXIEngine.h" #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; @@ -44,6 +63,10 @@ static GtkWidget *sPSTextEntry[NUM_PS_ENTRIES]; static int bDownload = FALSE; static struct timeval sDLStartTime; +static int bDLPause = FALSE; +static int bDLCancel = FALSE; +static int bComplete = FALSE; +static int bInstallClicked = FALSE; nsInstallDlg::nsInstallDlg() : mMsg0(NULL) @@ -87,21 +110,19 @@ nsInstallDlg::Next(GtkWidget *aWidget, gpointer aData) DUMP("Next"); int bCus; nsComponentList *comps = NULL; + GtkWidget *pauseLabel, *resumeLabel; if (aData != gCtx->idlg) return; if (gCtx->bMoving) { gCtx->bMoving = FALSE; + DUMP("Moving done!"); return; } bCus = (gCtx->opt->mSetupType == (gCtx->sdlg->GetNumSetupTypes() - 1)); comps = gCtx->sdlg->GetSelectedSetupType()->GetComponents(); - // hide the cancel button - if (gCtx->cancel) - gtk_widget_hide(gCtx->cancel); - // initialize progress bar cleanly int totalComps = 0; if (nsXIEngine::ExistAllXPIs(bCus, comps, &totalComps)) @@ -112,25 +133,61 @@ nsInstallDlg::Next(GtkWidget *aWidget, gpointer aData) 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), ""); - gtk_widget_show(sMajorLabel); - gtk_widget_show(sMajorProgBar); - gtk_widget_hide(gCtx->back); - gtk_widget_hide(gCtx->next); + if (bDownload) + { + InitDLProgress(); + + pauseLabel = gtk_label_new(gCtx->Res("PAUSE")); + resumeLabel = gtk_label_new(gCtx->Res("RESUME")); + gtk_container_remove(GTK_CONTAINER(gCtx->back), gCtx->backLabel); + gtk_container_remove(GTK_CONTAINER(gCtx->next), gCtx->installLabel); + gtk_container_add(GTK_CONTAINER(gCtx->back), pauseLabel); + gtk_container_add(GTK_CONTAINER(gCtx->next), resumeLabel); + gtk_widget_show(pauseLabel); + gtk_widget_show(resumeLabel); + + 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_hide(gCtx->back); + gtk_widget_hide(gCtx->next); + gtk_widget_hide(gCtx->cancel); + } + gtk_widget_hide(sMsg0Label); if (bDownload && sDLTable) gtk_widget_hide(sDLTable); XI_GTK_UPDATE_UI(); - WorkDammitWork((void*) NULL); - - // run all specified applications after installation - if (sRunAppList) + bInstallClicked = TRUE; + WorkDammitWork(); + if (bDLCancel) // set only when download was cancelled { - RunApps(); - FreeRunAppList(); + // mode auto has no call to gtk_main() + if (gCtx->opt->mMode != nsXIOptions::MODE_AUTO) + gtk_main_quit(); } - + gCtx->bMoving = TRUE; return; } @@ -423,6 +480,28 @@ nsInstallDlg::Hide(int aDirection) 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) { @@ -443,8 +522,8 @@ nsInstallDlg::GetMsg0() return NULL; } -void * -nsInstallDlg::WorkDammitWork(void *arg) +int +nsInstallDlg::WorkDammitWork() { DUMP("WorkDammitWork"); @@ -455,7 +534,7 @@ nsInstallDlg::WorkDammitWork(void *arg) if (!engine) { ErrorHandler(E_MEM); - return NULL; + return E_MEM; } // get the component list for the current setup type @@ -466,14 +545,34 @@ nsInstallDlg::WorkDammitWork(void *arg) if (!comps) { ErrorHandler(E_NO_COMPONENTS); - return NULL; + return E_NO_COMPONENTS; } - if (!sXPInstallEngine) return NULL; + if (!sXPInstallEngine) return E_PARAM; xpiengine = comps->GetCompByArchive(sXPInstallEngine); // 1> download - XI_ERR_BAIL(engine->Download(bCus, comps)); + err = engine->Download(bCus, comps); + if (err == E_DL_DROP_CXN) + { + ShowCxnDroppedDlg(); + return err; + } + 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 + InitInstallProgress(); + HideNavButtons(); // 2> extract engine XI_ERR_BAIL(engine->Extract(xpiengine)); @@ -481,19 +580,26 @@ nsInstallDlg::WorkDammitWork(void *arg) // 3> install .xpis XI_ERR_BAIL(engine->Install(bCus, comps, gCtx->opt->mDestination)); - // save xpis if user requested so - if (bDownload && gCtx->opt->mSaveModules) + // delete xpis if user didn't request saving them + if (bDownload && !gCtx->opt->mSaveModules) { - engine->SaveXPIs(); + engine->DeleteXPIs(bCus, comps); } ShowCompleteDlg(); + // run all specified applications after installation + if (sRunAppList) + { + RunApps(); + FreeRunAppList(); + } + BAIL: // destroy installer engine thread object XI_IF_DELETE(engine); - return NULL; + return err; } void @@ -617,15 +723,42 @@ nsInstallDlg::MajorProgressCB(char *aName, int aNum, int aTotal, int aActivity) XI_GTK_UPDATE_UI(); } +const int kCharsInDLLabel = 50; + void -nsInstallDlg::SetDownloadComp(char *aName, int aNum, int aTotal) +nsInstallDlg::SetDownloadComp(nsComponent *aComp, int aURLIndex, + int aNum, int aTotal) { - char label[64]; + static char xpiDir[MAXPATHLEN]; + static int bHaveXPIDir = FALSE; + char label[MAXPATHLEN]; + char localPath[MAXPATHLEN]; + + if (!aComp) + return; - // major label format e.g., "Downloading Navigator [4/12] at 635 K/sec..." - sprintf(label, gCtx->Res("DOWNLOADING"), aName, aNum, aTotal); - gtk_label_set_text(GTK_LABEL(sMajorLabel), label); + 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); } @@ -639,6 +772,27 @@ nsInstallDlg::DownloadCB(int aBytesRd, int aTotal) 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; @@ -648,23 +802,36 @@ nsInstallDlg::DownloadCB(int aBytesRd, int aTotal) 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 (aTotal <= 0) + 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(sMajorProgBar), TRUE); - gtk_progress_bar_update(GTK_PROGRESS_BAR(sMajorProgBar), percent); + gtk_progress_set_activity_mode(GTK_PROGRESS(sDLProgress.progBar), TRUE); + gtk_progress_bar_update(GTK_PROGRESS_BAR(sDLProgress.progBar), percent); } else { - percent = (gfloat)aBytesRd/(gfloat)aTotal; - gtk_progress_set_activity_mode(GTK_PROGRESS(sMajorProgBar), FALSE); - gtk_progress_bar_update(GTK_PROGRESS_BAR(sMajorProgBar), percent); + 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(); @@ -704,7 +871,13 @@ nsInstallDlg::ShowCompleteDlg() gtk_signal_connect(GTK_OBJECT(okButton), "clicked", GTK_SIGNAL_FUNC(CompleteOK), completeDlg); gtk_widget_show_all(completeDlg); - XI_GTK_UPDATE_UI(); + + while (!bComplete) + { + XI_GTK_UPDATE_UI(); + } + + gtk_main_quit(); } void @@ -715,7 +888,7 @@ nsInstallDlg::CompleteOK(GtkWidget *aWidget, gpointer aData) if (dlg) gtk_widget_destroy(dlg); - gtk_main_quit(); + bComplete = TRUE; } void @@ -874,3 +1047,310 @@ nsInstallDlg::PSDlgCancel(GtkWidget *aWidget, gpointer 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); +} + +void +nsInstallDlg::DLResume(GtkWidget *aWidget, gpointer aData) +{ + DUMP("DLResume"); + + if (!bDLPause) + { + DUMP("Not paused"); + return; + } + + if (bInstallClicked) + { + DUMP("Lingering signal from when Install clicked"); + bInstallClicked = FALSE; + 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); + + WorkDammitWork(); + + 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) + { + // mode auto has no call to gtk_main() + if (gCtx->opt->mMode != nsXIOptions::MODE_AUTO) + gtk_main_quit(); + } +} + +int +nsInstallDlg::CancelOrPause() +{ + int err; + + if (bDLPause) + { + err = E_DL_PAUSE; + } + else if (bDLCancel) + { + err = E_DL_CANCEL; + } + + return err; +} + +int +nsInstallDlg::ShowCxnDroppedDlg() +{ + GtkWidget *cxnDroppedDlg, *label, *okButton, *packer; + + // throw up dialog informing user to press resume + // or to cancel out + cxnDroppedDlg = gtk_dialog_new(); + label = gtk_label_new(gCtx->Res("CXN_DROPPED")); + okButton = gtk_button_new_with_label(gCtx->Res("OK_LABEL")); + packer = gtk_packer_new(); + + if (cxnDroppedDlg && label && okButton && packer) + { + gtk_packer_set_default_border_width(GTK_PACKER(packer), 20); + gtk_packer_add_defaults(GTK_PACKER(packer), label, GTK_SIDE_BOTTOM, + GTK_ANCHOR_CENTER, GTK_FILL_X); + gtk_window_set_modal(GTK_WINDOW(cxnDroppedDlg), TRUE); + gtk_window_set_title(GTK_WINDOW(cxnDroppedDlg), gCtx->opt->mTitle); + gtk_window_set_position(GTK_WINDOW(cxnDroppedDlg), GTK_WIN_POS_CENTER); + gtk_container_add(GTK_CONTAINER(GTK_DIALOG(cxnDroppedDlg)->vbox), + packer); + gtk_container_add(GTK_CONTAINER(GTK_DIALOG(cxnDroppedDlg)->action_area), + okButton); + gtk_signal_connect(GTK_OBJECT(okButton), "clicked", + GTK_SIGNAL_FUNC(CxnDroppedOK), cxnDroppedDlg); + gtk_widget_show_all(cxnDroppedDlg); + } + XI_GTK_UPDATE_UI(); + + return OK; +} + +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_hide(gCtx->back); + gtk_widget_hide(gCtx->next); + gtk_widget_hide(gCtx->cancel); +} + +void +nsInstallDlg::InitDLProgress() +{ + GtkWidget *titles[4]; + GtkWidget *hbox; + GtkWidget *table; + + gCtx->idlg->HideTable(); + + 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(); + + // 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(); + + // 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); + + XI_GTK_UPDATE_UI(); +} + +void +nsInstallDlg::InitInstallProgress() +{ + 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; +} + diff --git a/xpinstall/wizard/unix/src2/nsInstallDlg.h b/xpinstall/wizard/unix/src2/nsInstallDlg.h index 61c702363b03..6a38839050cf 100644 --- a/xpinstall/wizard/unix/src2/nsInstallDlg.h +++ b/xpinstall/wizard/unix/src2/nsInstallDlg.h @@ -29,7 +29,7 @@ #include "XIErrors.h" #include "nsRunApp.h" -#include +class nsComponent; class nsInstallDlg : public nsXInstallerDlg { @@ -47,13 +47,17 @@ public: 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(char *aName, int aNum, int aTotal); + static void SetDownloadComp(nsComponent *aComp, int aURLIndex, + int aNum, int aTotal); static void ClearRateLabel(); + static int CancelOrPause(); enum { @@ -62,6 +66,13 @@ public: ACT_INSTALL }; + enum + { + E_DL_PAUSE = -1101, + E_DL_CANCEL = -1102, + E_DL_DROP_CXN = -1103 + }; + /*------------------------------------------------------------------* * INI Properties *------------------------------------------------------------------*/ @@ -69,7 +80,7 @@ public: char *GetMsg0(); private: - static void *WorkDammitWork(void *arg); // install start + static int WorkDammitWork(void); // install start static void SaveModulesToggled(GtkWidget *aWidget, gpointer aData); static void ShowProxySettings(GtkWidget *aWidget, gpointer aData); static void PSDlgOK (GtkWidget *aWidget, gpointer aData); @@ -79,6 +90,17 @@ private: 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 ShowCxnDroppedDlg(); + static void CxnDroppedOK(GtkWidget *aWidget, gpointer aData); + static void HideNavButtons(); + static void InitDLProgress(); + static void InitInstallProgress(); + static int TotalDLSize(); + static void CompressToFit(char *aOrigStr, char *aOutStr, + int aOutStrLen); char *mMsg0; }; diff --git a/xpinstall/wizard/unix/src2/nsSetupTypeDlg.cpp b/xpinstall/wizard/unix/src2/nsSetupTypeDlg.cpp index ab3dc05f71c2..4dc098479377 100644 --- a/xpinstall/wizard/unix/src2/nsSetupTypeDlg.cpp +++ b/xpinstall/wizard/unix/src2/nsSetupTypeDlg.cpp @@ -25,6 +25,24 @@ #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; @@ -97,6 +115,13 @@ nsSetupTypeDlg::Next(GtkWidget *aWidget, gpointer aData) 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); @@ -321,7 +346,7 @@ nsSetupTypeDlg::Show(int aDirection) 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_FILL, 20, 20); gtk_widget_show(msg0); // insert a [n x 2] heterogeneous table in the second row @@ -332,7 +357,7 @@ nsSetupTypeDlg::Show(int aDirection) gtk_table_attach(GTK_TABLE(mTable), stTable, 0, 1, 2, 3, static_cast(GTK_EXPAND | GTK_FILL), static_cast(GTK_EXPAND | GTK_FILL), - 20, 0); + 20, 0); currST = GetSetupTypeList(); if (!currST) return E_NO_SETUPTYPES; @@ -345,7 +370,7 @@ nsSetupTypeDlg::Show(int aDirection) gtk_table_attach(GTK_TABLE(stTable), radbtns[0], 0, 1, 0, 1, static_cast(GTK_FILL | GTK_EXPAND), static_cast(GTK_FILL | GTK_EXPAND), - 0, 0); + 0, 0); gtk_signal_connect(GTK_OBJECT(radbtns[0]), "toggled", GTK_SIGNAL_FUNC(RadBtnToggled), 0); gtk_widget_show(radbtns[0]); @@ -373,7 +398,7 @@ nsSetupTypeDlg::Show(int aDirection) static_cast(GTK_FILL | GTK_EXPAND), 0, 0); gtk_signal_connect(GTK_OBJECT(radbtns[i]), "toggled", GTK_SIGNAL_FUNC(RadBtnToggled), - reinterpret_cast(i)); + reinterpret_cast(i)); gtk_widget_show(radbtns[i]); desc[i] = gtk_label_new(currST->GetDescLong()); @@ -393,7 +418,7 @@ nsSetupTypeDlg::Show(int aDirection) gtk_table_attach(GTK_TABLE(mTable), destTable, 0, 1, 3, 4, static_cast(GTK_EXPAND | GTK_FILL), static_cast(GTK_EXPAND | GTK_FILL), - 20, 5); + 20, 5); frame = gtk_frame_new(gCtx->Res("DEST_DIR")); gtk_table_attach_defaults(GTK_TABLE(destTable), frame, 0, 2, 0, 1); gtk_widget_show(frame); @@ -412,7 +437,7 @@ nsSetupTypeDlg::Show(int aDirection) gtk_widget_show(sBrowseBtn); gtk_table_attach(GTK_TABLE(destTable), sBrowseBtn, 1, 2, 0, 1, static_cast(GTK_EXPAND | GTK_FILL), - GTK_SHRINK, 10, 10); + GTK_SHRINK, 10, 10); mWidgetsInit = TRUE; } @@ -936,3 +961,144 @@ nsSetupTypeDlg::ConstructPath(char *aDest, char *aTrunk, char *aLeaf) return err; } + +int +nsSetupTypeDlg::VerifyDiskSpace(void) +{ + int err = OK; + int dsAvail, dsReqd; + char dsAvailStr[128], dsReqdStr[128]; + char message[512]; + GtkWidget *noDSDlg, *label, *okButton, *packer; + + // 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(); + label = gtk_label_new(message); + okButton = gtk_button_new_with_label(gCtx->Res("OK_LABEL")); + packer = gtk_packer_new(); + + if (noDSDlg && label && okButton && packer) + { + gtk_window_set_title(GTK_WINDOW(noDSDlg), gCtx->opt->mTitle); + gtk_window_set_position(GTK_WINDOW(noDSDlg), + GTK_WIN_POS_CENTER); + gtk_label_set_line_wrap(GTK_LABEL(label), TRUE); + gtk_packer_set_default_border_width(GTK_PACKER(packer), 20); + gtk_packer_add_defaults(GTK_PACKER(packer), label, GTK_SIDE_BOTTOM, + GTK_ANCHOR_CENTER, GTK_FILL_X); + gtk_box_pack_start(GTK_BOX( + GTK_DIALOG(noDSDlg)->action_area), okButton, + FALSE, FALSE, 10); + gtk_signal_connect(GTK_OBJECT(okButton), "clicked", + GTK_SIGNAL_FUNC(NoDiskSpaceOK), noDSDlg); + gtk_box_pack_start(GTK_BOX( + GTK_DIALOG(noDSDlg)->vbox), packer, FALSE, FALSE, 10); + + 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/xpinstall/wizard/unix/src2/nsSetupTypeDlg.h b/xpinstall/wizard/unix/src2/nsSetupTypeDlg.h index bef226af2f0c..3a5482dfb867 100644 --- a/xpinstall/wizard/unix/src2/nsSetupTypeDlg.h +++ b/xpinstall/wizard/unix/src2/nsSetupTypeDlg.h @@ -61,6 +61,10 @@ public: static void DeleteInstDelete(GtkWidget *aWidget, gpointer aData); static void DeleteInstCancel(GtkWidget *aWidget, gpointer aData); 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 diff --git a/xpinstall/wizard/unix/src2/nsXIContext.cpp b/xpinstall/wizard/unix/src2/nsXIContext.cpp index 185468a1ef24..8f38a959ec11 100644 --- a/xpinstall/wizard/unix/src2/nsXIContext.cpp +++ b/xpinstall/wizard/unix/src2/nsXIContext.cpp @@ -53,6 +53,7 @@ nsXIContext::nsXIContext() backID = 0; nextID = 0; + cancelID = 0; bMoving = FALSE; bDone = FALSE; @@ -148,6 +149,8 @@ nsXIContext::LoadResources() "ACCEPT", "DECLINE", "INSTALL", + "PAUSE", + "RESUME", "DEFAULT_TITLE", "DEST_DIR", "BROWSE", @@ -161,8 +164,6 @@ nsXIContext::LoadResources() "ERROR", "FATAL_ERROR", "DESCRIPTION", - "DOWNLOADING", - "DLRATE", "PREPARING", "EXTRACTING", "INSTALLING_XPI", @@ -177,6 +178,16 @@ nsXIContext::LoadResources() "PS_LABEL2", "PS_LABEL3", "ERROR_TITLE", + "DS_AVAIL", + "DS_REQD", + "NO_DISK_SPACE", + "CXN_DROPPED", + "DOWNLOADING", + "FROM", + "TO", + "STATUS", + "DL_STATUS_STR", + "UNKNOWN", __EOT__ }; diff --git a/xpinstall/wizard/unix/src2/nsXIContext.h b/xpinstall/wizard/unix/src2/nsXIContext.h index 224af1da7303..0101a01b9d87 100644 --- a/xpinstall/wizard/unix/src2/nsXIContext.h +++ b/xpinstall/wizard/unix/src2/nsXIContext.h @@ -84,6 +84,7 @@ public: 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 bMoving; /* when moving between dlgs signals are emitted twice; this notes the state */ int bDone; /* engine thread sets boolean when done diff --git a/xpinstall/wizard/unix/src2/nsXIEngine.cpp b/xpinstall/wizard/unix/src2/nsXIEngine.cpp index 90b705ba2f33..edbcf72c28ee 100644 --- a/xpinstall/wizard/unix/src2/nsXIEngine.cpp +++ b/xpinstall/wizard/unix/src2/nsXIEngine.cpp @@ -26,10 +26,13 @@ #include "nsHTTPConn.h" #include "nsXIEngine.h" +#include + #define CORE_LIB_COUNT 11 -const char kHTTPProto[8] = "http://"; -const char kFTPProto[7] = "ftp://"; +const char kHTTPProto[] = "http://"; +const char kFTPProto[] = "ftp://"; +const char kDLMarkerPath[] = "./xpi/.current_download"; nsXIEngine::nsXIEngine() : mTmp(NULL), @@ -58,7 +61,7 @@ nsXIEngine::Download(int aCustom, nsComponentList *aComps) return E_PARAM; int err = OK; - nsComponent *currComp = aComps->GetHead(); + nsComponent *currComp = aComps->GetHead(), *markedComp = NULL; char *currURL = NULL; char *currHost = NULL; char *currPath = NULL; @@ -68,28 +71,60 @@ nsXIEngine::Download(int aCustom, nsComponentList *aComps) char *qualURL = NULL; int i; int currPort; + struct stat stbuf; + int resPos = 0; + int fileSize = 0; + int currCompNum = 1, markedCompNum = 0; + int numToDL = 0; // num xpis to download - mTmp = NULL; - err = MakeUniqueTmpDir(); - if (!mTmp || err != OK) - return E_DIR_CREATE; + 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; + } - // if all .xpis exist in the ./xpi dir (blob/CD) we don't need to download - if (ExistAllXPIs(aCustom, aComps, &mTotalComps)) - return CopyToTmp(aCustom, aComps); + // 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); - int currCompNum = 1; 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; - nsInstallDlg::SetDownloadComp(currComp->GetDescShort(), - currCompNum, mTotalComps); + 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) @@ -129,18 +164,16 @@ nsXIEngine::Download(int aCustom, nsComponentList *aComps) err = conn->Open(); if (err == nsHTTPConn::OK) { - sprintf(localPath, "%s/%s", mTmp, + sprintf(localPath, "%s/%s", XPI_DIR, currComp->GetArchive()); - err = conn->Get(nsInstallDlg::DownloadCB, localPath); + err = conn->Get(nsInstallDlg::DownloadCB, localPath, + resPos); conn->Close(); } XI_IF_FREE(proxyURL); XI_IF_FREE(qualURL); XI_IF_DELETE(conn); - - if (err != nsHTTPConn::OK) - continue; // failover } // is this an HTTP URL? @@ -166,17 +199,15 @@ nsXIEngine::Download(int aCustom, nsComponentList *aComps) err = conn->Open(); if (err == nsHTTPConn::OK) { - sprintf(localPath, "%s/%s", mTmp, + sprintf(localPath, "%s/%s", XPI_DIR, currComp->GetArchive()); - err = conn->Get(nsInstallDlg::DownloadCB, localPath); + err = conn->Get(nsInstallDlg::DownloadCB, localPath, + resPos); conn->Close(); } XI_IF_FREE(qualURL); XI_IF_DELETE(conn); - - if (err != nsHTTPConn::OK) - continue; // failover } // or is this an FTP URL? @@ -207,10 +238,10 @@ nsXIEngine::Download(int aCustom, nsComponentList *aComps) err = conn->Open(); if (err == nsFTPConn::OK) { - sprintf(localPath, "%s/%s", mTmp, + sprintf(localPath, "%s/%s", XPI_DIR, currComp->GetArchive()); err = conn->Get(srvPath, localPath, nsFTPConn::BINARY, - 1, nsInstallDlg::DownloadCB); + resPos, 1, nsInstallDlg::DownloadCB); conn->Close(); } @@ -218,9 +249,6 @@ nsXIEngine::Download(int aCustom, nsComponentList *aComps) XI_IF_FREE(currPath); XI_IF_FREE(srvPath); XI_IF_DELETE(conn); - - if (err != nsFTPConn::OK) - continue; // failover } // else error: malformed URL @@ -229,10 +257,43 @@ nsXIEngine::Download(int aCustom, nsComponentList *aComps) 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; + } + } + nsInstallDlg::ClearRateLabel(); // clean after ourselves if (err == OK) { + currComp->SetDownloaded(); currCompNum++; break; // no need to failover } @@ -242,17 +303,29 @@ nsXIEngine::Download(int aCustom, nsComponentList *aComps) currComp = currComp->GetNext(); } + // download complete: remove marker + DelDLMarker(); return OK; } int nsXIEngine::Extract(nsComponent *aXPIEngine) { + int rv; + if (!aXPIEngine) return E_PARAM; - nsZipExtractor *unzip = new nsZipExtractor(mTmp); - return unzip->Extract(aXPIEngine, CORE_LIB_COUNT); + 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 @@ -388,31 +461,6 @@ nsXIEngine::ParseURL(char *aURL, char **aHost, char **aDir) return err; } -int -nsXIEngine::FTPAnonGet(nsFTPConn *aConn, char *aDir, char *aArchive) -{ - int err = OK; - char srvrPath[MAXPATHLEN]; - char loclPath[MAXPATHLEN]; - struct stat dummy; - - if (!aConn || !aDir || !aArchive) - return E_PARAM; - - sprintf(srvrPath, "%s%s", aDir, aArchive); - sprintf(loclPath, "%s/%s", mTmp, aArchive); - - err = aConn->Get(srvrPath, loclPath, nsFTPConn::BINARY, TRUE, - nsInstallDlg::DownloadCB); - if (err != nsFTPConn::OK) - return E_NO_DOWNLOAD; - - if (-1 == stat(loclPath, &dummy)) - err = E_NO_DOWNLOAD; - - return err; -} - int nsXIEngine::LoadXPIStub(xpistub_t *aStub, char *aDestination) { @@ -494,10 +542,10 @@ nsXIEngine::InstallXPI(nsComponent *aXPI, xpistub_t *aStub) char xpipath[MAXPATHLEN]; nsresult rv = 0; - if (!aStub || !aXPI) + if (!aStub || !aXPI || !mOriginalDir) return E_PARAM; - sprintf(xpipath, "../%s", aXPI->GetArchive()); + sprintf(xpipath, "%s/%s/%s", mOriginalDir, XPI_DIR, aXPI->GetArchive()); DUMP(xpipath); #define XPI_NO_NEW_THREAD 0x1000 @@ -540,7 +588,7 @@ nsXIEngine::UnloadXPIStub(xpistub_t *aStub) * 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. + * apparently safe on Linux/Unix). */ /* close xpistub library */ @@ -593,49 +641,206 @@ nsXIEngine::ExistAllXPIs(int aCustom, nsComponentList *aComps, int *aTotal) return bAllExist; } -int -nsXIEngine::CopyToTmp(int aCustom, nsComponentList *aComps) +int +nsXIEngine::DeleteXPIs(int aCustom, nsComponentList *aComps) { int err = OK; nsComponent *currComp = aComps->GetHead(); - char cmd[256]; + char currXPIPath[MAXPATHLEN]; + + if (!aComps || !mOriginalDir) + return E_PARAM; - int currCompNum = 1; while (currComp) { if ( (aCustom == TRUE && currComp->IsSelected()) || (aCustom == FALSE) ) { - sprintf(cmd, "cp %s/%s %s", XPI_DIR, currComp->GetArchive(), mTmp); - DUMP(cmd); + sprintf(currXPIPath, "%s/%s/%s", mOriginalDir, XPI_DIR, + currComp->GetArchive()); + + // delete the xpi + err = unlink(currXPIPath); - // update UI - nsInstallDlg::MajorProgressCB(currComp->GetDescShort(), - currCompNum, mTotalComps, nsInstallDlg::ACT_DOWNLOAD); - - system(cmd); - currCompNum++; +#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; } -void -nsXIEngine::SaveXPIs(void) +int +nsXIEngine::GetFileSize(char *aPath) { - char xpidir[MAXPATHLEN]; - char cpcmd[3 + MAXPATHLEN + 1 + MAXPATHLEN + 1]; + struct stat stbuf; - // make local "xpi" directory next to installer binary - sprintf(xpidir, "%s/xpi", mOriginalDir); - if (0 != mkdir(xpidir, 0755)) - return; + if (!aPath) + return 0; - // cp all xpis from tmp to "xpi" dir - sprintf(cpcmd, "cp %s/*.xpi %s", mTmp, xpidir); - DUMP(cpcmd); + if (0 == stat(aPath, &stbuf)) + { + return stbuf.st_size; + } - system(cpcmd); + 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; } diff --git a/xpinstall/wizard/unix/src2/nsXIEngine.h b/xpinstall/wizard/unix/src2/nsXIEngine.h index 83e64f109173..aae38daa55c9 100644 --- a/xpinstall/wizard/unix/src2/nsXIEngine.h +++ b/xpinstall/wizard/unix/src2/nsXIEngine.h @@ -42,8 +42,6 @@ #include #include -class nsFTPConn; - /*------------------------------------------------------------------------* * XPI Stub Glue *------------------------------------------------------------------------*/ @@ -76,19 +74,35 @@ public: int Download(int aCustom, nsComponentList *aComps); int Extract(nsComponent *aXPIEngine); int Install(int aCustom, nsComponentList *aComps, char *aDestination); - void SaveXPIs(void); + 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 FTPAnonGet(nsFTPConn *aConn, char *aDir, char *aAcrhive); int LoadXPIStub(xpistub_t *aStub, char *aDestionation); int InstallXPI(nsComponent *aComp, xpistub_t *aStub); int UnloadXPIStub(xpistub_t *aStub); - int CopyToTmp(int aCustom, nsComponentList *aComps); + 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); char *mTmp; int mTotalComps; diff --git a/xpinstall/wizard/unix/src2/nsXIOptions.cpp b/xpinstall/wizard/unix/src2/nsXIOptions.cpp index 5a5cda3bcea9..04e75c0d945a 100644 --- a/xpinstall/wizard/unix/src2/nsXIOptions.cpp +++ b/xpinstall/wizard/unix/src2/nsXIOptions.cpp @@ -27,7 +27,8 @@ nsXIOptions::nsXIOptions() : mTitle(NULL), mDestination(NULL), - mSetupType(-1), + mSetupType(0), + mMode(MODE_DEFAULT), mProxyHost(NULL), mProxyPort(NULL), mProxyUser(NULL), diff --git a/xpinstall/wizard/unix/src2/nsXIOptions.h b/xpinstall/wizard/unix/src2/nsXIOptions.h index 10f2512cf419..54e2d7d83aba 100644 --- a/xpinstall/wizard/unix/src2/nsXIOptions.h +++ b/xpinstall/wizard/unix/src2/nsXIOptions.h @@ -36,6 +36,14 @@ public: char *mTitle; char *mDestination; int mSetupType; + int mMode; + + enum + { + MODE_DEFAULT = 0, + MODE_AUTO, + MODE_SILENT + }; char *mProxyHost; char *mProxyPort; diff --git a/xpinstall/wizard/unix/src2/nsXInstaller.cpp b/xpinstall/wizard/unix/src2/nsXInstaller.cpp index 890e1eb53ddb..f6fee2af2bb5 100644 --- a/xpinstall/wizard/unix/src2/nsXInstaller.cpp +++ b/xpinstall/wizard/unix/src2/nsXInstaller.cpp @@ -38,6 +38,34 @@ 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) + { + /* mode: auto (show progress UI but assume defaults + * without user intervention) + */ + 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; + } + } + + return OK; +} + int nsXInstaller::ParseConfig() { @@ -155,11 +183,21 @@ nsXInstaller::RunWizard(int argc, char **argv) gtk_widget_show(gCtx->notebook); gtk_container_add(GTK_CONTAINER(gCtx->canvas), gCtx->notebook); - // show welcome dlg - gCtx->wdlg->Show(nsXInstallerDlg::FORWARD_MOVE); + if (gCtx->opt->mMode == nsXIOptions::MODE_AUTO) + { + // show install dlg + gCtx->idlg->Show(nsXInstallerDlg::FORWARD_MOVE); + gCtx->idlg->Next((GtkWidget *)NULL, (gpointer) gCtx->idlg); + } + else + { + // show welcome dlg + gCtx->wdlg->Show(nsXInstallerDlg::FORWARD_MOVE); - // pop over to main event loop - gtk_main(); + // pop over to main event loop + gtk_main(); + + } return OK; @@ -222,8 +260,8 @@ nsXInstaller::DrawCancelButton(GtkWidget *aLogoVBox) hbox = gtk_hbox_new(FALSE, 10); gtk_box_pack_start(GTK_BOX(hbox), gCtx->cancel, TRUE, TRUE, 15); gtk_box_pack_end(GTK_BOX(aLogoVBox), hbox, FALSE, TRUE, 10); - gtk_signal_connect(GTK_OBJECT(gCtx->cancel), "clicked", - GTK_SIGNAL_FUNC(Kill), NULL); + gCtx->cancelID = gtk_signal_connect(GTK_OBJECT(gCtx->cancel), "clicked", + GTK_SIGNAL_FUNC(Kill), NULL); gtk_widget_show(hbox); gtk_widget_show(gCtx->cancel); @@ -328,7 +366,10 @@ main(int argc, char **argv) if (installer) { if ( (err = installer->ParseConfig()) == OK) + { + installer->ParseArgs(argc, argv); err = installer->RunWizard(argc, argv); + } } else err = E_MEM; diff --git a/xpinstall/wizard/unix/src2/nsXInstaller.h b/xpinstall/wizard/unix/src2/nsXInstaller.h index c07aab1aeb2c..9a44075bb890 100644 --- a/xpinstall/wizard/unix/src2/nsXInstaller.h +++ b/xpinstall/wizard/unix/src2/nsXInstaller.h @@ -40,6 +40,7 @@ public: nsXInstaller(); ~nsXInstaller(); + int ParseArgs(int aArgc, char **aArgv); int ParseConfig(); int RunWizard(int argc, char **argv); int ParseGeneral(nsINIParser *aParser); diff --git a/xpinstall/wizard/unix/src2/nsZipExtractor.cpp b/xpinstall/wizard/unix/src2/nsZipExtractor.cpp index b94d14a78cf5..363d48511a81 100644 --- a/xpinstall/wizard/unix/src2/nsZipExtractor.cpp +++ b/xpinstall/wizard/unix/src2/nsZipExtractor.cpp @@ -28,14 +28,20 @@ #include "zipstub.h" #include "zipfile.h" -nsZipExtractor::nsZipExtractor(char *aTmp) : - mTmp(aTmp) +nsZipExtractor::nsZipExtractor(char *aSrc, char *aDest) : + mSrc(NULL), + mDest(NULL) { + if (aSrc) + mSrc = strdup(aSrc); + if (aDest) + mDest = strdup(aDest); } nsZipExtractor::~nsZipExtractor() { - // don't free mTmp: we don't own it + XI_IF_FREE(mSrc); + XI_IF_FREE(mDest); } int @@ -56,7 +62,7 @@ nsZipExtractor::Extract(nsComponent *aXPIEngine, int aTotal) if (!aXPIEngine || !(aXPIEngine->GetArchive())) return E_PARAM; - sprintf(apath, "%s/%s", mTmp, aXPIEngine->GetArchive()); + sprintf(apath, "%s/%s", mSrc, aXPIEngine->GetArchive()); if (-1 == stat(apath, &dummy)) return E_NO_DOWNLOAD; @@ -107,7 +113,7 @@ nsZipExtractor::Extract(nsComponent *aXPIEngine, int aTotal) nsInstallDlg::MajorProgressCB(leaf, i, aTotal, nsInstallDlg::ACT_EXTRACT); - sprintf(epath, "%s/%s", mTmp, zpath); + sprintf(epath, "%s/%s", mDest, zpath); err = DirCreateRecursive(epath); if (err != OK) goto au_revoir; @@ -121,7 +127,7 @@ nsZipExtractor::Extract(nsComponent *aXPIEngine, int aTotal) i++; } - sprintf(bindir, "%s/%s", mTmp, TMP_EXTRACT_SUBDIR); + sprintf(bindir, "%s/%s", mDest, TMP_EXTRACT_SUBDIR); if (-1 == stat(bindir, &dummy)) err = E_EXTRACTION; @@ -143,10 +149,10 @@ nsZipExtractor::DirCreateRecursive(char *aPath) char currdir[MAXPATHLEN]; struct stat dummy; - if (!aPath || !mTmp) + if (!aPath || !mDest) return E_PARAM; - slash = aPath + strlen(mTmp); + slash = aPath + strlen(mDest); if (*slash != '/') return E_INVALID_PTR; diff --git a/xpinstall/wizard/unix/src2/nsZipExtractor.h b/xpinstall/wizard/unix/src2/nsZipExtractor.h index 5238debcbe0c..ec87eebb2464 100644 --- a/xpinstall/wizard/unix/src2/nsZipExtractor.h +++ b/xpinstall/wizard/unix/src2/nsZipExtractor.h @@ -34,7 +34,7 @@ class nsZipExtractor { public: - nsZipExtractor(char *aTmp); + nsZipExtractor(char *aSrc, char *aDest); ~nsZipExtractor(); int Extract(nsComponent *aXPIEngine, int aTotal); @@ -42,7 +42,8 @@ public: private: int DirCreateRecursive(char *aPath); - char *mTmp; + char *mSrc; + char *mDest; }; #endif /* _NS_ZIPEXTRACTOR_H_ */