Fix for 65672. Add CRC checking and single connection ftp to install.
r=dveditz, sr=mscott git-svn-id: svn://10.0.0.236/trunk@101388 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
@@ -64,7 +64,8 @@
|
||||
E_MKDIR_FAIL = -624, /* can't make destination dir */
|
||||
E_OLD_INST = -625, /* old instllation exists */
|
||||
E_NO_PERMS = -626, /* don't have rwx perms on selected dir */
|
||||
E_NO_DISK_SPACE = -627 /* not eough disk space to install */
|
||||
E_NO_DISK_SPACE = -627, /* not eough disk space to install */
|
||||
E_CRC_FAILED = -628 /* CRC failed */
|
||||
};
|
||||
|
||||
#endif /* _XI_ERRORS_H_ */
|
||||
|
||||
@@ -44,6 +44,8 @@ DS_AVAIL=Disk Space Available = %ld KB
|
||||
DS_REQD=Disk Space Required = %ld KB
|
||||
NO_DISK_SPACE=Please select a directory on a disk with enough space to install or free some disk space on the selected disk.
|
||||
CXN_DROPPED=A network connection failure occured. Please check your network connection and press the 'Resume' button. Alternatively, press the 'Cancel' button to quit the installer.
|
||||
CRC_CHECK=Some files failed to download correctly. Retrying.
|
||||
CRC_FAILED=Installation has failed due to multiple CRC failures.
|
||||
DOWNLOADING=Downloading:
|
||||
FROM=From:
|
||||
TO=To:
|
||||
|
||||
@@ -470,9 +470,9 @@ nsComponent::GetResumePos()
|
||||
}
|
||||
|
||||
int
|
||||
nsComponent::SetDownloaded()
|
||||
nsComponent::SetDownloaded( int which )
|
||||
{
|
||||
mDownloaded = TRUE;
|
||||
mDownloaded = which;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
@@ -84,7 +84,7 @@ public:
|
||||
int DepGetRefCount();
|
||||
int SetResumePos(int aResPos);
|
||||
int GetResumePos();
|
||||
int SetDownloaded();
|
||||
int SetDownloaded(int which);
|
||||
int IsDownloaded();
|
||||
|
||||
/*---------------------------------------------------------------*
|
||||
|
||||
@@ -136,7 +136,7 @@ nsInstallDlg::Next(GtkWidget *aWidget, gpointer aData)
|
||||
|
||||
if (bDownload)
|
||||
{
|
||||
InitDLProgress();
|
||||
InitDLProgress( TRUE );
|
||||
|
||||
pauseLabel = gtk_label_new(gCtx->Res("PAUSE"));
|
||||
resumeLabel = gtk_label_new(gCtx->Res("RESUME"));
|
||||
@@ -180,7 +180,7 @@ nsInstallDlg::Next(GtkWidget *aWidget, gpointer aData)
|
||||
XI_GTK_UPDATE_UI();
|
||||
|
||||
bInstallClicked = TRUE;
|
||||
WorkDammitWork();
|
||||
PerformInstall();
|
||||
if (bDLCancel) // set only when download was cancelled
|
||||
{
|
||||
// mode auto has no call to gtk_main()
|
||||
@@ -523,9 +523,9 @@ nsInstallDlg::GetMsg0()
|
||||
}
|
||||
|
||||
int
|
||||
nsInstallDlg::WorkDammitWork()
|
||||
nsInstallDlg::PerformInstall()
|
||||
{
|
||||
DUMP("WorkDammitWork");
|
||||
DUMP("PerformInstall");
|
||||
|
||||
int err = OK;
|
||||
|
||||
@@ -558,6 +558,11 @@ nsInstallDlg::WorkDammitWork()
|
||||
ShowCxnDroppedDlg();
|
||||
return err;
|
||||
}
|
||||
else if (err == E_CRC_FAILED)
|
||||
{
|
||||
ShowCRCFailedDlg();
|
||||
goto BAIL;
|
||||
}
|
||||
else if (err == E_DL_PAUSE || err == E_DL_CANCEL)
|
||||
{
|
||||
DUMP("Pause or Cancel pressed");
|
||||
@@ -1090,7 +1095,7 @@ nsInstallDlg::DLResume(GtkWidget *aWidget, gpointer aData)
|
||||
// enable pause button
|
||||
gtk_widget_set_sensitive(gCtx->back, TRUE);
|
||||
|
||||
WorkDammitWork();
|
||||
PerformInstall();
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -1137,6 +1142,73 @@ nsInstallDlg::CancelOrPause()
|
||||
return err;
|
||||
}
|
||||
|
||||
static GtkWidget *crcDlg = (GtkWidget *) NULL;
|
||||
|
||||
void
|
||||
nsInstallDlg::ShowCRCDlg()
|
||||
{
|
||||
GtkWidget *label, *okButton, *packer;
|
||||
|
||||
if ( crcDlg == (GtkWidget *) NULL ) {
|
||||
// throw up dialog informing user to press resume
|
||||
// or to cancel out
|
||||
crcDlg = gtk_dialog_new();
|
||||
label = gtk_label_new(gCtx->Res("CRC_CHECK"));
|
||||
okButton = gtk_button_new_with_label(gCtx->Res("OK_LABEL"));
|
||||
packer = gtk_packer_new();
|
||||
|
||||
if (crcDlg && 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_title(GTK_WINDOW(crcDlg), gCtx->opt->mTitle);
|
||||
gtk_window_set_position(GTK_WINDOW(crcDlg), GTK_WIN_POS_CENTER);
|
||||
gtk_container_add(GTK_CONTAINER(GTK_DIALOG(crcDlg)->vbox),
|
||||
packer);
|
||||
gtk_container_add(GTK_CONTAINER(GTK_DIALOG(crcDlg)->action_area),
|
||||
okButton);
|
||||
gtk_signal_connect(GTK_OBJECT(okButton), "clicked",
|
||||
GTK_SIGNAL_FUNC(CRCOKCb), crcDlg);
|
||||
gtk_widget_show_all(crcDlg);
|
||||
}
|
||||
}
|
||||
XI_GTK_UPDATE_UI();
|
||||
}
|
||||
|
||||
int
|
||||
nsInstallDlg::ShowCRCFailedDlg()
|
||||
{
|
||||
GtkWidget *crcFailedDlg, *label, *okButton, *packer;
|
||||
|
||||
// throw up dialog informing user to press resume
|
||||
// or to cancel out
|
||||
crcFailedDlg = gtk_dialog_new();
|
||||
label = gtk_label_new(gCtx->Res("CRC_FAILED"));
|
||||
okButton = gtk_button_new_with_label(gCtx->Res("OK_LABEL"));
|
||||
packer = gtk_packer_new();
|
||||
|
||||
if (crcFailedDlg && 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(crcFailedDlg), TRUE);
|
||||
gtk_window_set_title(GTK_WINDOW(crcFailedDlg), gCtx->opt->mTitle);
|
||||
gtk_window_set_position(GTK_WINDOW(crcFailedDlg), GTK_WIN_POS_CENTER);
|
||||
gtk_container_add(GTK_CONTAINER(GTK_DIALOG(crcFailedDlg)->vbox),
|
||||
packer);
|
||||
gtk_container_add(GTK_CONTAINER(GTK_DIALOG(crcFailedDlg)->action_area),
|
||||
okButton);
|
||||
gtk_signal_connect(GTK_OBJECT(okButton), "clicked",
|
||||
GTK_SIGNAL_FUNC(CRCFailedOK), crcFailedDlg);
|
||||
gtk_widget_show_all(crcFailedDlg);
|
||||
}
|
||||
XI_GTK_UPDATE_UI();
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
int
|
||||
nsInstallDlg::ShowCxnDroppedDlg()
|
||||
{
|
||||
@@ -1170,6 +1242,29 @@ nsInstallDlg::ShowCxnDroppedDlg()
|
||||
return OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsInstallDlg::CRCFailedOK(GtkWidget *aWidget, gpointer aData)
|
||||
{
|
||||
gtk_main_quit();
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
nsInstallDlg::DestroyCRCDlg()
|
||||
{
|
||||
CRCOKCb( (GtkWidget *) NULL, (gpointer) NULL );
|
||||
}
|
||||
|
||||
void
|
||||
nsInstallDlg::CRCOKCb(GtkWidget *aWidget, gpointer aData)
|
||||
{
|
||||
if (crcDlg != (GtkWidget *) NULL)
|
||||
gtk_widget_destroy(crcDlg);
|
||||
crcDlg = (GtkWidget *) NULL;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
nsInstallDlg::CxnDroppedOK(GtkWidget *aWidget, gpointer aData)
|
||||
{
|
||||
@@ -1194,7 +1289,7 @@ nsInstallDlg::HideNavButtons()
|
||||
}
|
||||
|
||||
void
|
||||
nsInstallDlg::InitDLProgress()
|
||||
nsInstallDlg::InitDLProgress( int isFirst )
|
||||
{
|
||||
GtkWidget *titles[4];
|
||||
GtkWidget *hbox;
|
||||
@@ -1202,73 +1297,84 @@ nsInstallDlg::InitDLProgress()
|
||||
|
||||
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);
|
||||
if ( isFirst == TRUE ) {
|
||||
sDLProgress.vbox = gtk_vbox_new(FALSE, 10);
|
||||
gtk_notebook_append_page(GTK_NOTEBOOK(gCtx->notebook),
|
||||
sDLProgress.vbox, NULL);
|
||||
gtk_widget_show(sDLProgress.vbox);
|
||||
|
||||
table = gtk_table_new(5, 2, FALSE);
|
||||
gtk_box_pack_start(GTK_BOX(sDLProgress.vbox), table, FALSE,
|
||||
FALSE, 0);
|
||||
gtk_widget_show(table);
|
||||
|
||||
// setup static title progress labels in table left column
|
||||
titles[0] = gtk_label_new(gCtx->Res("DOWNLOADING"));
|
||||
titles[1] = gtk_label_new(gCtx->Res("FROM"));
|
||||
titles[2] = gtk_label_new(gCtx->Res("TO"));
|
||||
titles[3] = gtk_label_new(gCtx->Res("STATUS"));
|
||||
// setup 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"));
|
||||
// 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 titles
|
||||
for (int i = 0; i < 4; ++i)
|
||||
{
|
||||
hbox = gtk_hbox_new(FALSE, 10);
|
||||
gtk_box_pack_end(GTK_BOX(hbox), titles[i], FALSE, FALSE, 0);
|
||||
gtk_table_attach(GTK_TABLE(table), hbox,
|
||||
0, 1, i, i + 1, GTK_FILL, GTK_FILL, 5, 5);
|
||||
gtk_widget_show(titles[i]);
|
||||
gtk_widget_show(hbox);
|
||||
}
|
||||
|
||||
// pack and show dynamic labels
|
||||
hbox = gtk_hbox_new(FALSE, 10);
|
||||
gtk_box_pack_start(GTK_BOX(hbox), sDLProgress.compName, FALSE, FALSE, 0);
|
||||
gtk_table_attach(GTK_TABLE(table), hbox, 1, 2, 0, 1,
|
||||
GTK_FILL, GTK_FILL, 5, 5);
|
||||
gtk_widget_show(sDLProgress.compName);
|
||||
gtk_widget_show(hbox);
|
||||
|
||||
hbox = gtk_hbox_new(FALSE, 10);
|
||||
gtk_box_pack_start(GTK_BOX(hbox), sDLProgress.URL, FALSE, FALSE, 0);
|
||||
gtk_table_attach(GTK_TABLE(table), hbox, 1, 2, 1, 2,
|
||||
GTK_FILL, GTK_FILL, 5, 5);
|
||||
gtk_widget_show(sDLProgress.URL);
|
||||
gtk_widget_show(hbox);
|
||||
|
||||
hbox = gtk_hbox_new(FALSE, 10);
|
||||
gtk_box_pack_start(GTK_BOX(hbox), sDLProgress.localPath, FALSE,
|
||||
FALSE, 0);
|
||||
gtk_table_attach(GTK_TABLE(table), hbox, 1, 2, 2, 3,
|
||||
GTK_FILL, GTK_FILL, 5, 5);
|
||||
gtk_widget_show(sDLProgress.localPath);
|
||||
gtk_widget_show(hbox);
|
||||
|
||||
hbox = gtk_hbox_new(FALSE, 10);
|
||||
gtk_box_pack_start(GTK_BOX(hbox), sDLProgress.status, FALSE,
|
||||
FALSE, 0);
|
||||
gtk_table_attach(GTK_TABLE(table), hbox, 1, 2, 3, 4,
|
||||
GTK_FILL, GTK_FILL, 5, 5);
|
||||
gtk_widget_show(sDLProgress.status);
|
||||
gtk_widget_show(hbox);
|
||||
|
||||
// init and show prog bar
|
||||
sDLProgress.progBar = gtk_progress_bar_new();
|
||||
|
||||
// show prog bar
|
||||
hbox = gtk_hbox_new(TRUE, 10);
|
||||
gtk_box_pack_start(GTK_BOX(hbox), sDLProgress.progBar, FALSE,
|
||||
TRUE, 0);
|
||||
gtk_box_pack_start(GTK_BOX(sDLProgress.vbox), hbox, FALSE,
|
||||
FALSE, 0);
|
||||
gtk_widget_show(sDLProgress.progBar);
|
||||
gtk_widget_show(hbox);
|
||||
}
|
||||
|
||||
// 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);
|
||||
@@ -1277,13 +1383,6 @@ nsInstallDlg::InitDLProgress()
|
||||
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();
|
||||
}
|
||||
|
||||
@@ -1354,3 +1453,8 @@ nsInstallDlg::CompressToFit(char *aOrigStr, char *aOutStr, int aOutStrLen)
|
||||
*(aOutStr + aOutStrLen + 1) = 0;
|
||||
}
|
||||
|
||||
void
|
||||
nsInstallDlg::ReInitUI( void )
|
||||
{
|
||||
InitDLProgress( FALSE );
|
||||
}
|
||||
|
||||
@@ -59,6 +59,10 @@ public:
|
||||
static void ClearRateLabel();
|
||||
static int CancelOrPause();
|
||||
|
||||
void ReInitUI();
|
||||
void ShowCRCDlg();
|
||||
void DestroyCRCDlg();
|
||||
|
||||
enum
|
||||
{
|
||||
ACT_DOWNLOAD,
|
||||
@@ -80,7 +84,7 @@ public:
|
||||
char *GetMsg0();
|
||||
|
||||
private:
|
||||
static int WorkDammitWork(void); // install start
|
||||
static int PerformInstall(void); // install start
|
||||
static void SaveModulesToggled(GtkWidget *aWidget, gpointer aData);
|
||||
static void ShowProxySettings(GtkWidget *aWidget, gpointer aData);
|
||||
static void PSDlgOK (GtkWidget *aWidget, gpointer aData);
|
||||
@@ -93,14 +97,17 @@ private:
|
||||
static void DLPause(GtkWidget *aWidget, gpointer aData);
|
||||
static void DLResume(GtkWidget *aWidget, gpointer aData);
|
||||
static void DLCancel(GtkWidget *aWidget, gpointer aData);
|
||||
static int ShowCRCFailedDlg();
|
||||
static int ShowCxnDroppedDlg();
|
||||
static void CRCFailedOK(GtkWidget *aWidget, gpointer aData);
|
||||
static void CxnDroppedOK(GtkWidget *aWidget, gpointer aData);
|
||||
static void CRCOKCb(GtkWidget *aWidget, gpointer aData);
|
||||
static void HideNavButtons();
|
||||
static void InitDLProgress();
|
||||
static void InitInstallProgress();
|
||||
static int TotalDLSize();
|
||||
static void CompressToFit(char *aOrigStr, char *aOutStr,
|
||||
int aOutStrLen);
|
||||
static void InitDLProgress(int IsFirst);
|
||||
|
||||
char *mMsg0;
|
||||
};
|
||||
|
||||
@@ -187,6 +187,8 @@ nsXIContext::LoadResources()
|
||||
"TO",
|
||||
"STATUS",
|
||||
"DL_STATUS_STR",
|
||||
"CRC_FAILED",
|
||||
"CRC_CHECK",
|
||||
"UNKNOWN",
|
||||
|
||||
__EOT__
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
*
|
||||
* Contributor(s):
|
||||
* Samir Gehani <sgehani@netscape.com>
|
||||
* Syd Logan syd@netscape.com
|
||||
*/
|
||||
|
||||
#include "nsFTPConn.h"
|
||||
@@ -27,6 +28,7 @@
|
||||
#include "nsXIEngine.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define CORE_LIB_COUNT 11
|
||||
|
||||
@@ -58,6 +60,8 @@ EventPumpCB(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define MAXCRC 4
|
||||
|
||||
int
|
||||
nsXIEngine::Download(int aCustom, nsComponentList *aComps)
|
||||
{
|
||||
@@ -68,6 +72,7 @@ nsXIEngine::Download(int aCustom, nsComponentList *aComps)
|
||||
|
||||
int err = OK;
|
||||
nsComponent *currComp = aComps->GetHead(), *markedComp = NULL;
|
||||
nsComponent *currCompSave;
|
||||
char *currURL = NULL;
|
||||
char *currHost = NULL;
|
||||
char *currPath = NULL;
|
||||
@@ -75,13 +80,14 @@ nsXIEngine::Download(int aCustom, nsComponentList *aComps)
|
||||
char *srvPath = NULL;
|
||||
char *proxyURL = NULL;
|
||||
char *qualURL = NULL;
|
||||
int i;
|
||||
int i, crcPass, bDone;
|
||||
int currPort;
|
||||
struct stat stbuf;
|
||||
int resPos = 0;
|
||||
int fileSize = 0;
|
||||
int currCompNum = 1, markedCompNum = 0;
|
||||
int numToDL = 0; // num xpis to download
|
||||
CONN myConn;
|
||||
|
||||
err = GetDLMarkedComp(aComps, aCustom, &markedComp, &markedCompNum);
|
||||
if (err == OK && markedComp)
|
||||
@@ -108,8 +114,15 @@ nsXIEngine::Download(int aCustom, nsComponentList *aComps)
|
||||
|
||||
numToDL = TotalToDownload(aCustom, aComps);
|
||||
|
||||
while (currComp)
|
||||
{
|
||||
myConn.URL = (char *) NULL;
|
||||
myConn.type = TYPE_UNDEF;
|
||||
|
||||
crcPass = 0;
|
||||
currCompSave = currComp;
|
||||
bDone = 0;
|
||||
while ( bDone == 0 && crcPass < MAXCRC ) {
|
||||
while (currComp)
|
||||
{
|
||||
if ( (aCustom == TRUE && currComp->IsSelected()) || (aCustom == FALSE) )
|
||||
{
|
||||
// in case we are resuming inter- or intra-installer session
|
||||
@@ -219,6 +232,8 @@ nsXIEngine::Download(int aCustom, nsComponentList *aComps)
|
||||
// or is this an FTP URL?
|
||||
else if (strncmp(currURL, kFTPProto, strlen(kFTPProto)) == 0)
|
||||
{
|
||||
PRBool isNewConn;
|
||||
|
||||
err = nsHTTPConn::ParseURL(kFTPProto, currURL, &currHost,
|
||||
&currPort, &currPath);
|
||||
if (err != nsHTTPConn::OK)
|
||||
@@ -234,27 +249,40 @@ nsXIEngine::Download(int aCustom, nsComponentList *aComps)
|
||||
}
|
||||
sprintf(srvPath, "%s%s", currPath, currComp->GetArchive());
|
||||
|
||||
nsFTPConn *conn = new nsFTPConn(currHost, EventPumpCB);
|
||||
if (!conn)
|
||||
{
|
||||
// closes the old connection if any
|
||||
|
||||
isNewConn = CheckConn( currHost, TYPE_FTP, &myConn, PR_FALSE );
|
||||
|
||||
err = nsFTPConn::OK;
|
||||
|
||||
nsFTPConn *conn;
|
||||
if ( isNewConn == PR_TRUE ) {
|
||||
conn = new nsFTPConn(currHost, EventPumpCB);
|
||||
if (!conn) {
|
||||
err = E_MEM;
|
||||
break;
|
||||
}
|
||||
|
||||
err = conn->Open();
|
||||
if (err == nsFTPConn::OK)
|
||||
}
|
||||
err = conn->Open();
|
||||
myConn.conn = (void *) conn;
|
||||
myConn.type = TYPE_FTP;
|
||||
myConn.URL = (char *) calloc(strlen(currHost) + 1, sizeof(char));
|
||||
if ( myConn.URL != (char *) NULL )
|
||||
strcpy( myConn.URL, currHost );
|
||||
} else
|
||||
conn = (nsFTPConn *) myConn.conn;
|
||||
|
||||
if (isNewConn == PR_FALSE || err == nsFTPConn::OK)
|
||||
{
|
||||
sprintf(localPath, "%s/%s", XPI_DIR,
|
||||
currComp->GetArchive());
|
||||
err = conn->Get(srvPath, localPath, nsFTPConn::BINARY,
|
||||
resPos, 1, nsInstallDlg::DownloadCB);
|
||||
conn->Close();
|
||||
// conn->Close();
|
||||
}
|
||||
|
||||
XI_IF_FREE(currHost);
|
||||
XI_IF_FREE(currPath);
|
||||
XI_IF_FREE(srvPath);
|
||||
XI_IF_DELETE(conn);
|
||||
}
|
||||
|
||||
// else error: malformed URL
|
||||
@@ -299,7 +327,7 @@ nsXIEngine::Download(int aCustom, nsComponentList *aComps)
|
||||
|
||||
if (err == OK)
|
||||
{
|
||||
currComp->SetDownloaded();
|
||||
currComp->SetDownloaded(TRUE);
|
||||
currCompNum++;
|
||||
break; // no need to failover
|
||||
}
|
||||
@@ -307,11 +335,95 @@ nsXIEngine::Download(int aCustom, nsComponentList *aComps)
|
||||
}
|
||||
|
||||
currComp = currComp->GetNext();
|
||||
}
|
||||
|
||||
CheckConn( "", TYPE_UNDEF, &myConn, true );
|
||||
|
||||
bDone = CRCCheckDownloadedArchives(XPI_DIR, strlen(XPI_DIR), currCompSave, currCompNum);
|
||||
crcPass++;
|
||||
if ( bDone == 0 && crcPass < MAXCRC ) {
|
||||
// reset ourselves
|
||||
if (markedComp) {
|
||||
currComp = markedComp;
|
||||
currCompNum = markedCompNum;
|
||||
} else {
|
||||
currComp = aComps->GetHead();
|
||||
currCompNum = 1;
|
||||
}
|
||||
currCompSave = currComp;
|
||||
gCtx->idlg->ReInitUI();
|
||||
gCtx->idlg->ShowCRCDlg();
|
||||
numToDL = TotalToDownload(aCustom, aComps);
|
||||
}
|
||||
}
|
||||
|
||||
// download complete: remove marker
|
||||
DelDLMarker();
|
||||
return OK;
|
||||
gCtx->idlg->DestroyCRCDlg(); // destroy the CRC dialog if showing
|
||||
if ( crcPass < MAXCRC ) {
|
||||
// download complete: remove marker
|
||||
DelDLMarker();
|
||||
return OK;
|
||||
} else {
|
||||
return E_CRC_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Name: CheckConn
|
||||
*
|
||||
* Arguments:
|
||||
*
|
||||
* char *URL; -- URL of connection we need to have established
|
||||
* int type; -- connection type (TYPE_HTTP, etc.)
|
||||
* CONN *myConn; -- connection state (info about currently established
|
||||
* connection)
|
||||
* PRBool force; -- force closing of connection
|
||||
*
|
||||
* Description:
|
||||
*
|
||||
* This function determines if the caller should open a connection based upon
|
||||
* the current connection that is open (if any), and the type of connection
|
||||
* desired. If no previous connection was established, the function returns
|
||||
* true. If the connection is for a different protocol, then true is also
|
||||
* returned (and the previous connection is closed). If the connection is for
|
||||
* the same protocol and the URL is different, the previous connection is
|
||||
* closed and true is returned. Otherwise, the connection has already been
|
||||
* established, and false is returned.
|
||||
*
|
||||
* Return Value: If a new connection needs to be opened, true. Otherwise,
|
||||
* false is returned.
|
||||
*
|
||||
* Original Code: Syd Logan (syd@netscape.com) 6/24/2001
|
||||
*
|
||||
*/
|
||||
|
||||
PRBool
|
||||
nsXIEngine::CheckConn( char *URL, int type, CONN *myConn, PRBool force )
|
||||
{
|
||||
nsFTPConn *fconn;
|
||||
nsHTTPConn *hconn;
|
||||
PRBool retval = false;
|
||||
|
||||
if ( myConn->type == TYPE_UNDEF )
|
||||
retval = PR_TRUE; // first time
|
||||
else if ( ( myConn->type != type || strcmp( URL, myConn->URL ) || force == PR_TRUE ) /* && gControls->state != ePaused */) {
|
||||
retval = PR_TRUE;
|
||||
switch ( myConn->type ) {
|
||||
case TYPE_HTTP:
|
||||
case TYPE_PROXY:
|
||||
hconn = (nsHTTPConn *) myConn->conn;
|
||||
hconn->Close();
|
||||
break;
|
||||
case TYPE_FTP:
|
||||
fconn = (nsFTPConn *) myConn->conn;
|
||||
fconn->Close();
|
||||
XI_IF_DELETE(fconn);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( retval == PR_TRUE && myConn->URL != (char *) NULL )
|
||||
free( myConn->URL );
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
int
|
||||
@@ -395,10 +507,9 @@ nsXIEngine::Install(int aCustom, nsComponentList *aComps, char *aDestination)
|
||||
|
||||
currComp = currComp->GetNext();
|
||||
}
|
||||
UnloadXPIStub(&stub);
|
||||
}
|
||||
|
||||
UnloadXPIStub(&stub);
|
||||
|
||||
// restore LD_LIBRARY_PATH settings
|
||||
#ifdef SOLARIS
|
||||
char old_LD_env[MAXPATHLEN];
|
||||
@@ -860,3 +971,157 @@ nsXIEngine::TotalToDownload(int aCustom, nsComponentList *aComps)
|
||||
|
||||
return total;
|
||||
}
|
||||
|
||||
/*
|
||||
* Name: CRCCheckDownloadedArchives
|
||||
*
|
||||
* Arguments:
|
||||
*
|
||||
* Handle dlPath; -- a handle to the location of the XPI files on disk
|
||||
* short dlPathlen; -- length, in bytes, of dlPath
|
||||
*
|
||||
* Description:
|
||||
*
|
||||
* This function iterates the XPI files and calls VerifyArchive() on each to
|
||||
* determine which archives pass checksum checks.
|
||||
*
|
||||
* Return Value: if all archives pass, true. Otherwise, false.
|
||||
*
|
||||
* Original Code: Syd Logan (syd@netscape.com) 6/24/2001
|
||||
*
|
||||
*/
|
||||
|
||||
PRBool
|
||||
nsXIEngine::CRCCheckDownloadedArchives(char *dlPath, short dlPathlen,
|
||||
nsComponent *currComp, int count)
|
||||
{
|
||||
int i;
|
||||
PRBool isClean;
|
||||
char buf[ 1024 ];
|
||||
|
||||
isClean = PR_TRUE;
|
||||
|
||||
for(i = 0; currComp != (nsComponent *) NULL && i < MAX_COMPONENTS; i++) {
|
||||
strncpy( buf, (const char *) dlPath, dlPathlen );
|
||||
buf[ dlPathlen ] = '\0';
|
||||
strcat( buf, "/" );
|
||||
strcat( buf, currComp->GetArchive() );
|
||||
nsInstallDlg::MajorProgressCB(buf, i, count, nsInstallDlg::ACT_INSTALL);
|
||||
if (IsArchiveFile(buf) == PR_TRUE && VerifyArchive( buf ) != ZIP_OK) {
|
||||
currComp->SetDownloaded(FALSE); // VerifyArchive has unlinked it
|
||||
isClean = false;
|
||||
}
|
||||
currComp = currComp->GetNext();
|
||||
}
|
||||
return isClean;
|
||||
}
|
||||
|
||||
/*
|
||||
* Name: IsArchiveFile( char *path )
|
||||
*
|
||||
* Arguments:
|
||||
*
|
||||
* char *path -- NULL terminated pathname
|
||||
*
|
||||
* Description:
|
||||
*
|
||||
* This function extracts the file extension of filename pointed to by path
|
||||
* and then checks it against a table of extensions. If a match occurs, the
|
||||
* file is considered to be an archive file that has a checksum we can
|
||||
* validate, and we return PR_TRUE.
|
||||
* Otherwise, PR_FALSE is returned.
|
||||
*
|
||||
* Return Value: true if the file extension matches one of those we are
|
||||
* looking for, and false otherwise.
|
||||
*
|
||||
* Original Code: Syd Logan 7/28/2001
|
||||
*
|
||||
*/
|
||||
|
||||
static char *extensions[] = { "ZIP", "XPI", "JAR" }; // must be uppercase
|
||||
|
||||
PRBool
|
||||
nsXIEngine::IsArchiveFile( char *buf )
|
||||
{
|
||||
PRBool ret = false;
|
||||
char lbuf[1024];
|
||||
char *p;
|
||||
int i, max;
|
||||
|
||||
// if we have a string and it contains a '.'
|
||||
|
||||
if ( buf != (char *) NULL && ( p = strrchr( buf, '.' ) ) != (char *) NULL ) {
|
||||
p++;
|
||||
|
||||
// if there are characters after the '.' then see if there is a match
|
||||
|
||||
if ( *p != '\0' ) {
|
||||
|
||||
// make a copy of the extension, and fold to uppercase, since mac has no strcasecmp
|
||||
// and we need to ensure we are comparing strings of chars that have the same case.
|
||||
|
||||
strcpy( lbuf, p );
|
||||
for ( i = 0; i < (int) strlen( lbuf ); i++ )
|
||||
lbuf[i] = toupper(lbuf[i]);
|
||||
|
||||
// search
|
||||
|
||||
max = sizeof( extensions ) / sizeof ( char * );
|
||||
for ( i = 0; i < max; i++ )
|
||||
if ( !strcmp( lbuf, extensions[i] ) ) {
|
||||
ret = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return ( ret );
|
||||
}
|
||||
|
||||
/*
|
||||
* Name: VerifyArchive
|
||||
*
|
||||
* Arguments:
|
||||
*
|
||||
* char *szArchive; -- path of archive to verify
|
||||
*
|
||||
* Description:
|
||||
*
|
||||
* This function verifies that the specified path exists, that it is a XPI
|
||||
* file, and that it has a valid checksum.
|
||||
*
|
||||
* Return Value: If all tests pass, ZIP_OK. Otherwise, !ZIP_OK
|
||||
*
|
||||
* Original Code: Syd Logan (syd@netscape.com) 6/25/2001
|
||||
*
|
||||
*/
|
||||
|
||||
int
|
||||
nsXIEngine::VerifyArchive(char *szArchive)
|
||||
{
|
||||
void *vZip;
|
||||
int iTestRv;
|
||||
char *penv;
|
||||
|
||||
if((iTestRv = ZIP_OpenArchive(szArchive, &vZip)) == ZIP_OK)
|
||||
{
|
||||
/* 1st parameter should be NULL or it will fail */
|
||||
/* It indicates extract the entire archive */
|
||||
iTestRv = ZIP_TestArchive(vZip);
|
||||
ZIP_CloseArchive(&vZip);
|
||||
}
|
||||
|
||||
// for testing, this will cause about half of the CRCs to fail. Since
|
||||
// randomly selecting which fail, likely next pass the same file will
|
||||
// end up a success.
|
||||
|
||||
penv = getenv("MOZ_INSTALL_TEST_CRC");
|
||||
if ( penv != (char *) NULL ) {
|
||||
if ( random() < RAND_MAX / 2 )
|
||||
iTestRv = !ZIP_OK;
|
||||
}
|
||||
|
||||
if ( iTestRv != ZIP_OK )
|
||||
unlink( szArchive );
|
||||
return(iTestRv);
|
||||
}
|
||||
|
||||
|
||||
@@ -34,6 +34,10 @@
|
||||
|
||||
#include "xpistub.h"
|
||||
|
||||
#define STANDALONE 1
|
||||
#include "zipfile.h"
|
||||
#include <ctype.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <malloc.h>
|
||||
@@ -61,6 +65,17 @@ typedef struct _xpistub_t
|
||||
pfnXPI_Exit fn_exit;
|
||||
} xpistub_t;
|
||||
|
||||
#define TYPE_UNDEF 0
|
||||
#define TYPE_PROXY 1
|
||||
#define TYPE_HTTP 2
|
||||
#define TYPE_FTP 3
|
||||
|
||||
typedef struct _conn
|
||||
{
|
||||
unsigned char type; // TYPE_UNDEF, etc.
|
||||
char *URL; // URL this connection is for
|
||||
void *conn; // pointer to open connection
|
||||
} CONN;
|
||||
|
||||
/*------------------------------------------------------------------------*
|
||||
* nsXIEngine
|
||||
@@ -103,7 +118,11 @@ private:
|
||||
nsComponent **aOutComp, int *aOutCompNum);
|
||||
int DelDLMarker();
|
||||
int TotalToDownload(int aCustom, nsComponentList *aComps);
|
||||
|
||||
PRBool CRCCheckDownloadedArchives(char *dlPath, short dlPathLen,
|
||||
nsComponent *currComp, int count);
|
||||
PRBool IsArchiveFile(char *path);
|
||||
int VerifyArchive(char *szArchive);
|
||||
PRBool CheckConn( char *URL, int type, CONN *myConn, PRBool force );
|
||||
char *mTmp;
|
||||
int mTotalComps;
|
||||
char *mOriginalDir;
|
||||
|
||||
Reference in New Issue
Block a user