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:
syd%netscape.com
2001-08-18 01:15:59 +00:00
parent 4e410a3ede
commit 255b5688c7
9 changed files with 501 additions and 101 deletions

View File

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

View File

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

View File

@@ -470,9 +470,9 @@ nsComponent::GetResumePos()
}
int
nsComponent::SetDownloaded()
nsComponent::SetDownloaded( int which )
{
mDownloaded = TRUE;
mDownloaded = which;
return OK;
}

View File

@@ -84,7 +84,7 @@ public:
int DepGetRefCount();
int SetResumePos(int aResPos);
int GetResumePos();
int SetDownloaded();
int SetDownloaded(int which);
int IsDownloaded();
/*---------------------------------------------------------------*

View File

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

View File

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

View File

@@ -187,6 +187,8 @@ nsXIContext::LoadResources()
"TO",
"STATUS",
"DL_STATUS_STR",
"CRC_FAILED",
"CRC_CHECK",
"UNKNOWN",
__EOT__

View File

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

View File

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