(*) 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
This commit is contained in:
sgehani%netscape.com 2001-05-03 02:17:27 +00:00
Родитель 882fe0046f
Коммит f67be14c0f
22 изменённых файлов: 1241 добавлений и 175 удалений

Просмотреть файл

@ -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"

Просмотреть файл

@ -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_ */

Просмотреть файл

@ -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.

Просмотреть файл

@ -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

Просмотреть файл

@ -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.*

Просмотреть файл

@ -23,18 +23,22 @@
*/
#include "nsComponent.h"
#include <sys/stat.h>
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;
}

Просмотреть файл

@ -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_ */

Просмотреть файл

@ -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();

Просмотреть файл

@ -23,15 +23,34 @@
*/
#include "nsSocket.h"
#include "nsHTTPConn.h"
#include "nsInstallDlg.h"
#include "nsXInstaller.h"
#include "nsXIEngine.h"
#include <signal.h>
#include <gtk/gtk.h>
#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;
}

Просмотреть файл

@ -29,7 +29,7 @@
#include "XIErrors.h"
#include "nsRunApp.h"
#include <sys/time.h>
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;
};

Просмотреть файл

@ -25,6 +25,24 @@
#include "nsSetupTypeDlg.h"
#include "nsXInstaller.h"
// need these for statfs
#ifdef HAVE_SYS_STATVFS_H
#include <sys/statvfs.h>
#endif
#ifdef HAVE_SYS_STATFS_H
#include <sys/statfs.h>
#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<GtkAttachOptions>(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<GtkAttachOptions>(GTK_EXPAND | GTK_FILL),
static_cast<GtkAttachOptions>(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<GtkAttachOptions>(GTK_FILL | GTK_EXPAND),
static_cast<GtkAttachOptions>(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<GtkAttachOptions>(GTK_FILL | GTK_EXPAND), 0, 0);
gtk_signal_connect(GTK_OBJECT(radbtns[i]), "toggled",
GTK_SIGNAL_FUNC(RadBtnToggled),
reinterpret_cast<void *>(i));
reinterpret_cast<void *>(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<GtkAttachOptions>(GTK_EXPAND | GTK_FILL),
static_cast<GtkAttachOptions>(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<GtkAttachOptions>(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);
}

Просмотреть файл

@ -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

Просмотреть файл

@ -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__
};

Просмотреть файл

@ -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

Просмотреть файл

@ -26,10 +26,13 @@
#include "nsHTTPConn.h"
#include "nsXIEngine.h"
#include <errno.h>
#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;
}

Просмотреть файл

@ -42,8 +42,6 @@
#include <dlfcn.h>
#include <sys/stat.h>
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;

Просмотреть файл

@ -27,7 +27,8 @@
nsXIOptions::nsXIOptions() :
mTitle(NULL),
mDestination(NULL),
mSetupType(-1),
mSetupType(0),
mMode(MODE_DEFAULT),
mProxyHost(NULL),
mProxyPort(NULL),
mProxyUser(NULL),

Просмотреть файл

@ -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;

Просмотреть файл

@ -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;

Просмотреть файл

@ -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);

Просмотреть файл

@ -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;

Просмотреть файл

@ -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_ */