1
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
3
* The contents of this file are subject to the Netscape Public
4
* License Version 1.1 (the "License"); you may not use this file
5
* except in compliance with the License. You may obtain a copy of
6
* the License at http://www.mozilla.org/NPL/
8
* Software distributed under the License is distributed on an "AS
9
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
10
* implied. See the License for the specific language governing
11
* rights and limitations under the License.
13
* The Original Code is Mozilla Communicator client code,
14
* released March 31, 1998.
16
* The Initial Developer of the Original Code is Netscape Communications
17
* Corporation. Portions created by Netscape are
18
* Copyright (C) 1998 Netscape Communications Corporation. All
22
* Samir Gehani <sgehani@netscape.com>
23
* Syd Logan syd@netscape.com
26
#include "nsFTPConn.h"
27
#include "nsHTTPConn.h"
28
#include "nsXIEngine.h"
33
#define CORE_LIB_COUNT 11
35
const char kHTTPProto[] = "http://";
36
const char kFTPProto[] = "ftp://";
37
const char kDLMarkerPath[] = "./xpi/.current_download";
39
nsXIEngine::nsXIEngine() :
46
#define RM_PREFIX "rm -rf "
48
nsXIEngine::~nsXIEngine()
52
// reset back to original directory
55
if ( mTmp != (char *) NULL ) {
57
// blow away the temp dir
60
buf = (char *) malloc( strlen(RM_PREFIX) + strlen( mTmp ) + 1 );
61
if ( buf != (char *) NULL ) {
62
strcpy( buf, RM_PREFIX );
69
XI_IF_FREE(mOriginalDir);
81
nsXIEngine::Download(int aCustom, nsComponentList *aComps)
89
nsComponent *currComp = aComps->GetHead(), *markedComp = NULL;
90
nsComponent *currCompSave;
92
char *currHost = NULL;
93
char *currPath = NULL;
94
char localPath[MAXPATHLEN];
96
char *proxyURL = NULL;
98
int i, crcPass, bDone;
103
int currCompNum = 1, markedCompNum = 0;
104
int numToDL = 0; // num xpis to download
108
err = GetDLMarkedComp(aComps, aCustom, &markedComp, &markedCompNum);
109
if (err == OK && markedComp)
111
currComp = markedComp;
112
currCompNum = markedCompNum;
113
sprintf(localPath, "%s/%s", XPI_DIR, currComp->GetArchive());
114
currComp->SetResumePos(GetFileSize(localPath));
118
// if all .xpis exist in the ./xpi dir (blob/CD)
119
// we don't need to download
120
if (ExistAllXPIs(aCustom, aComps, &mTotalComps))
124
// check if ./xpi dir exists else create it
125
if (0 != stat(XPI_DIR, &stbuf))
127
if (0 != mkdir(XPI_DIR, 0755))
131
numToDL = TotalToDownload(aCustom, aComps);
133
myConn.URL = (char *) NULL;
134
myConn.type = TYPE_UNDEF;
137
currCompSave = currComp;
139
while ( bDone == 0 && crcPass < MAXCRC ) {
143
if ( (aCustom == TRUE && currComp->IsSelected()) || (aCustom == FALSE) )
145
// in case we are resuming inter- or intra-installer session
146
if (currComp->IsDownloaded())
148
currComp = currComp->GetNext();
152
SetDLMarker(currComp->GetArchive());
154
for (i = 0; i < MAX_URLS; i++)
156
currURL = currComp->GetURL(i);
159
if (gCtx->opt->mMode != nsXIOptions::MODE_SILENT)
160
nsInstallDlg::SetDownloadComp(currComp, i,
161
currCompNum, numToDL);
163
// restore resume position
164
resPos = currComp->GetResumePos();
166
// has a proxy server been specified?
167
if (gCtx->opt->mProxyHost && gCtx->opt->mProxyPort)
169
// URL of the proxy server
170
proxyURL = (char *) malloc(strlen(kHTTPProto) +
171
strlen(gCtx->opt->mProxyHost) + 1 +
172
strlen(gCtx->opt->mProxyPort) + 1);
179
sprintf(proxyURL, "%s%s:%s", kHTTPProto,
180
gCtx->opt->mProxyHost, gCtx->opt->mProxyPort);
182
nsHTTPConn *conn = new nsHTTPConn(proxyURL, EventPumpCB);
189
// URL of the actual file to download
190
qualURL = (char *) malloc(strlen(currURL) +
191
strlen(currComp->GetArchive()) + 1);
197
sprintf(qualURL, "%s%s", currURL, currComp->GetArchive());
199
if (*gCtx->opt->mProxyUser || *gCtx->opt->mProxyPswd)
201
conn->SetProxyInfo(qualURL, gCtx->opt->mProxyUser,
202
gCtx->opt->mProxyPswd);
206
conn->SetProxyInfo(qualURL, NULL, NULL);
210
if (err == nsHTTPConn::OK)
212
sprintf(localPath, "%s/%s", XPI_DIR,
213
currComp->GetArchive());
214
if (gCtx->opt->mMode == nsXIOptions::MODE_SILENT)
215
err = conn->Get(NULL, localPath, resPos);
217
err = conn->Get(nsInstallDlg::DownloadCB, localPath,
222
XI_IF_FREE(proxyURL);
227
// is this an HTTP URL?
228
else if (strncmp(currURL, kHTTPProto, strlen(kHTTPProto)) == 0)
230
// URL of the actual file to download
231
qualURL = (char *) malloc(strlen(currURL) +
232
strlen(currComp->GetArchive()) + 1);
238
sprintf(qualURL, "%s%s", currURL, currComp->GetArchive());
240
nsHTTPConn *conn = new nsHTTPConn(qualURL, EventPumpCB);
248
if (err == nsHTTPConn::OK)
250
sprintf(localPath, "%s/%s", XPI_DIR,
251
currComp->GetArchive());
252
if (gCtx->opt->mMode == nsXIOptions::MODE_SILENT)
253
err = conn->Get(NULL, localPath, resPos);
255
err = conn->Get(nsInstallDlg::DownloadCB, localPath,
264
// or is this an FTP URL?
265
else if (strncmp(currURL, kFTPProto, strlen(kFTPProto)) == 0)
269
err = nsHTTPConn::ParseURL(kFTPProto, currURL, &currHost,
270
&currPort, &currPath);
271
if (err != nsHTTPConn::OK)
274
// path on the remote server
275
srvPath = (char *) malloc(strlen(currPath) +
276
strlen(currComp->GetArchive()) + 1);
282
sprintf(srvPath, "%s%s", currPath, currComp->GetArchive());
284
// closes the old connection if any
286
isNewConn = CheckConn( currHost, TYPE_FTP, &myConn, PR_FALSE );
290
if ( isNewConn == PR_TRUE ) {
291
conn = new nsFTPConn(currHost, EventPumpCB);
297
myConn.conn = (void *) conn;
298
myConn.type = TYPE_FTP;
299
myConn.URL = (char *) calloc(strlen(currHost) + 1, sizeof(char));
300
if ( myConn.URL != (char *) NULL )
301
strcpy( myConn.URL, currHost );
303
conn = (nsFTPConn *) myConn.conn;
305
if (isNewConn == PR_FALSE || err == nsFTPConn::OK)
307
sprintf(localPath, "%s/%s", XPI_DIR,
308
currComp->GetArchive());
309
if (gCtx->opt->mMode == nsXIOptions::MODE_SILENT)
310
err = conn->Get(srvPath, localPath, nsFTPConn::BINARY,
313
err = conn->Get(srvPath, localPath, nsFTPConn::BINARY,
314
resPos, 1, nsInstallDlg::DownloadCB);
318
XI_IF_FREE(currHost);
319
XI_IF_FREE(currPath);
323
// else error: malformed URL
326
err = nsHTTPConn::E_MALFORMED_URL;
329
if (err == nsHTTPConn::E_USER_CANCEL)
330
err = nsInstallDlg::CancelOrPause();
332
// user hit pause and subsequently resumed
333
if (err == nsInstallDlg::E_DL_PAUSE)
335
currComp->SetResumePos(GetFileSize(localPath));
339
// user cancelled during download
340
else if (err == nsInstallDlg::E_DL_CANCEL)
343
// user didn't cancel or pause: some other dl error occured
346
fileSize = GetFileSize(localPath);
350
// assume dropped connection if file size > 0
351
currComp->SetResumePos(fileSize);
352
return nsInstallDlg::E_DL_DROP_CXN;
361
if (gCtx->opt->mMode != nsXIOptions::MODE_SILENT)
362
nsInstallDlg::ClearRateLabel(); // clean after ourselves
366
currComp->SetDownloaded(TRUE);
368
break; // no need to failover
373
currComp = currComp->GetNext();
376
CheckConn( "", TYPE_UNDEF, &myConn, true );
378
bDone = CRCCheckDownloadedArchives(XPI_DIR, strlen(XPI_DIR),
379
currCompSave, passCount, aCustom);
381
if ( bDone == 0 && crcPass < MAXCRC ) {
384
currComp = markedComp;
385
currCompNum = markedCompNum;
387
currComp = aComps->GetHead();
390
currCompSave = currComp;
391
if (gCtx->opt->mMode != nsXIOptions::MODE_SILENT)
392
gCtx->idlg->ReInitUI();
393
gCtx->idlg->ShowCRCDlg();
394
numToDL = TotalToDownload(aCustom, aComps);
397
gCtx->idlg->DestroyCRCDlg(); // destroy the CRC dialog if showing
398
if ( crcPass < MAXCRC ) {
399
// download complete: remove marker
412
* char *URL; -- URL of connection we need to have established
413
* int type; -- connection type (TYPE_HTTP, etc.)
414
* CONN *myConn; -- connection state (info about currently established
416
* PRBool force; -- force closing of connection
420
* This function determines if the caller should open a connection based upon
421
* the current connection that is open (if any), and the type of connection
422
* desired. If no previous connection was established, the function returns
423
* true. If the connection is for a different protocol, then true is also
424
* returned (and the previous connection is closed). If the connection is for
425
* the same protocol and the URL is different, the previous connection is
426
* closed and true is returned. Otherwise, the connection has already been
427
* established, and false is returned.
429
* Return Value: If a new connection needs to be opened, true. Otherwise,
432
* Original Code: Syd Logan (syd@netscape.com) 6/24/2001
437
nsXIEngine::CheckConn( char *URL, int type, CONN *myConn, PRBool force )
441
PRBool retval = false;
443
if ( myConn->type == TYPE_UNDEF )
444
retval = PR_TRUE; // first time
445
else if ( ( myConn->type != type || myConn->URL == (char *) NULL || strcmp( URL, myConn->URL ) || force == PR_TRUE ) /* && gControls->state != ePaused */) {
447
switch ( myConn->type ) {
450
hconn = (nsHTTPConn *) myConn->conn;
454
fconn = (nsFTPConn *) myConn->conn;
455
if ( fconn != (nsFTPConn *) NULL ) {
464
if ( retval == PR_TRUE && myConn->URL != (char *) NULL ) {
466
myConn->URL = (char *) NULL;
473
nsXIEngine::Extract(nsComponent *aXPIEngine)
481
rv = MakeUniqueTmpDir();
482
if (!mTmp || rv != OK)
485
nsZipExtractor *unzip = new nsZipExtractor(XPI_DIR, mTmp);
486
rv = unzip->Extract(aXPIEngine, CORE_LIB_COUNT);
493
nsXIEngine::Install(int aCustom, nsComponentList *aComps, char *aDestination)
499
char *old_LD_LIBRARY_PATH = NULL;
500
char new_LD_LIBRARY_PATH[MAXPATHLEN];
503
nsComponent *currComp = NULL;
505
if (!aComps || !aDestination)
508
// handle LD_LIBRARY_PATH settings
509
#if defined (SOLARIS) || defined (IRIX)
510
sprintf(new_LD_LIBRARY_PATH, "LD_LIBRARY_PATH=%s/bin:.", mTmp);
512
sprintf(new_LD_LIBRARY_PATH, "%s/bin:.", mTmp);
514
DUMP(new_LD_LIBRARY_PATH);
515
old_LD_LIBRARY_PATH = getenv("LD_LIBRARY_PATH");
516
#if defined (SOLARIS) || defined (IRIX)
517
putenv(new_LD_LIBRARY_PATH);
519
setenv("LD_LIBRARY_PATH", new_LD_LIBRARY_PATH, 1);
521
currComp = aComps->GetHead();
522
err = LoadXPIStub(&stub, aDestination);
525
for (i = 0; i < MAX_COMPONENTS; i++)
530
if ( (aCustom && currComp->IsSelected()) ||
534
printf("%s %d: DOWNLOAD_ONLY for %s is %d\n", __FILE__, __LINE__,
535
currComp->GetArchive(), currComp->IsDownloadOnly());
537
if (!currComp->IsDownloadOnly())
539
if (gCtx->opt->mMode != nsXIOptions::MODE_SILENT)
540
nsInstallDlg::MajorProgressCB(currComp->GetDescShort(),
541
compNum, mTotalComps, nsInstallDlg::ACT_INSTALL);
542
err = InstallXPI(currComp, &stub);
544
if (err == E_INSTALL)
545
ErrorHandler(err, currComp->GetArchive()); //handle E_INSTALL separately
547
ErrorHandler(err); //handle and continue
552
currComp = currComp->GetNext();
554
UnloadXPIStub(&stub);
557
// restore LD_LIBRARY_PATH settings
558
#if defined (SOLARIS) || defined (IRIX)
559
char old_LD_env[MAXPATHLEN];
561
sprintf(old_LD_env, "LD_LIBRARY_PATH=%s", old_LD_LIBRARY_PATH);
564
setenv("LD_LIBRARY_PATH", old_LD_LIBRARY_PATH, 1);
571
nsXIEngine::MakeUniqueTmpDir()
573
int err = E_DIR_CREATE;
574
char tmpnam[MAXPATHLEN];
575
char *tmpdir = getenv("TMPDIR");
576
if (!tmpdir) tmpdir = getenv("TMP");
577
if (!tmpdir) tmpdir = getenv("TEMP");
578
if (!tmpdir) tmpdir = P_tmpdir;
579
snprintf(tmpnam, sizeof(tmpnam), "%s/xpi.XXXXXX", tmpdir);
581
if (mkdtemp(tmpnam)) {
582
mTmp = strdup(tmpnam);
586
int fd = mkstemp(tmpnam);
587
if (fd < 0) return err;
589
if (unlink(tmpnam) < 0) return err;
590
mTmp = strdup(tmpnam);
591
if (!mTmp) return err;
592
if (mkdir(mTmp, 0755) < 0) return err;
599
nsXIEngine::ParseURL(char *aURL, char **aHost, char **aDir)
603
char *hostTerminator = NULL;
604
char *dirTerminator = NULL;
606
if (!aURL || !aHost || !aDir)
609
if (0 != strncmp(aURL, "ftp://", 6)) return E_BAD_FTP_URL;
612
if (!host) return E_BAD_FTP_URL;
613
hostTerminator = strchr(host, '/');
614
if (!hostTerminator) return E_BAD_FTP_URL;
616
*aHost = (char *) calloc(hostTerminator - host + 1, 1);
617
strncpy(*aHost, host, hostTerminator - host);
619
dirTerminator = strrchr(hostTerminator + 1, '/');
622
// no dir == root dir
623
*aDir = (char *) malloc(2);
628
*aDir = (char *) malloc(sizeof(char) *
629
(dirTerminator - hostTerminator + 2));
630
memset(*aDir, 0, (dirTerminator - hostTerminator + 2));
631
strncpy(*aDir, hostTerminator, dirTerminator - hostTerminator + 1);
638
nsXIEngine::LoadXPIStub(xpistub_t *aStub, char *aDestination)
642
char libpath[MAXPATHLEN];
643
char libloc[MAXPATHLEN];
650
if (!aStub || !aDestination)
653
/* save original directory to reset it after installing */
654
mOriginalDir = (char *) malloc(MAXPATHLEN * sizeof(char));
655
getcwd(mOriginalDir, MAXPATHLEN);
657
/* chdir to library location for dll deps resolution */
658
sprintf(libloc, "%s/bin", mTmp);
661
/* open the library */
662
getcwd(libpath, MAXPATHLEN);
663
sprintf(libpath, "%s/%s", libpath, XPISTUB);
666
printf("DEBUG: libpath = >>%s<<\n", libpath);
669
aStub->handle = NULL;
670
aStub->handle = dlopen(libpath, RTLD_LAZY);
677
DUMP("xpistub opened");
679
/* read and store symbol addresses */
680
aStub->fn_init = (pfnXPI_Init) dlsym(aStub->handle, FN_INIT);
681
aStub->fn_install = (pfnXPI_Install) dlsym(aStub->handle, FN_INSTALL);
682
aStub->fn_exit = (pfnXPI_Exit) dlsym(aStub->handle, FN_EXIT);
683
if (!aStub->fn_init || !aStub->fn_install || !aStub->fn_exit)
690
DUMP("xpistub symbols loaded");
692
rv = aStub->fn_init(aDestination, NULL, ProgressCallback);
695
printf("DEBUG: XPI_Init returned 0x%.8X\n", rv);
698
DUMP("XPI_Init called");
712
nsXIEngine::InstallXPI(nsComponent *aXPI, xpistub_t *aStub)
715
char xpipath[MAXPATHLEN];
718
if (!aStub || !aXPI || !mOriginalDir)
721
sprintf(xpipath, "%s/%s/%s", mOriginalDir, XPI_DIR, aXPI->GetArchive());
724
#define XPI_NO_NEW_THREAD 0x1000
726
rv = aStub->fn_install(xpipath, "", XPI_NO_NEW_THREAD);
729
printf("DEBUG: XPI_Install %s returned %d\n", aXPI->GetArchive(), rv);
739
nsXIEngine::UnloadXPIStub(xpistub_t *aStub)
747
/* release XPCOM and XPInstall */
748
XI_ASSERT(aStub->fn_exit, "XPI_Exit is NULL and wasn't called!");
752
DUMP("XPI_Exit called");
758
* Don't close the stub: it'll be released on exit.
759
* This fixes the seg fault on exit bug,
760
* Apparently, the global destructors are no longer
761
* around when the app exits (since xpcom etc. was
762
* unloaded when the stub was unloaded). To get
763
* around this we don't close the stub (which is
764
* apparently safe on Linux/Unix).
767
/* close xpistub library */
770
dlclose(aStub->handle);
771
DUMP("xpistub closed");
779
nsXIEngine::ProgressCallback(const char* aMsg, PRInt32 aVal, PRInt32 aMax)
781
// DUMP("ProgressCallback");
783
nsInstallDlg::XPIProgressCB(aMsg, (int)aVal, (int)aMax);
787
nsXIEngine::ExistAllXPIs(int aCustom, nsComponentList *aComps, int *aTotal)
790
if (!aComps || !aTotal)
793
int bAllExist = TRUE;
794
nsComponent *currComp = aComps->GetHead();
795
char currArchivePath[256];
800
if ( (aCustom == TRUE && currComp->IsSelected()) || (aCustom == FALSE) )
802
sprintf(currArchivePath, "%s/%s", XPI_DIR, currComp->GetArchive());
803
DUMP(currArchivePath);
805
if (0 != stat(currArchivePath, &dummy))
808
currComp->SetDownloaded(TRUE);
813
currComp = currComp->GetNext();
820
nsXIEngine::DeleteXPIs(int aCustom, nsComponentList *aComps)
823
nsComponent *currComp = aComps->GetHead();
824
char currXPIPath[MAXPATHLEN];
826
if (!aComps || !mOriginalDir)
831
if ( (aCustom == TRUE && currComp->IsSelected()) || (aCustom == FALSE) )
833
sprintf(currXPIPath, "%s/%s/%s", mOriginalDir, XPI_DIR,
834
currComp->GetArchive());
837
err = unlink(currXPIPath);
840
printf("%s %d: unlink %s returned: %d\n", __FILE__, __LINE__,
845
currComp = currComp->GetNext();
848
// all xpi should be deleted so delete the ./xpi dir
849
sprintf(currXPIPath, "%s/xpi", mOriginalDir);
850
err = rmdir(currXPIPath);
853
printf("%s %d: rmdir %s returned: %d\n", __FILE__, __LINE__,
861
nsXIEngine::GetFileSize(char *aPath)
868
if (0 == stat(aPath, &stbuf))
870
return stbuf.st_size;
877
nsXIEngine::SetDLMarker(char *aCompName)
886
// open the marker file
887
dlMarkerFD = fopen(kDLMarkerPath, "w");
891
// write out the current comp name
892
compNameLen = strlen(aCompName);
895
rv = fwrite((void *) aCompName, sizeof(char), compNameLen, dlMarkerFD);
896
if (rv != compNameLen)
902
// close the marker file
906
printf("%s %d: SetDLMarker rv = %d\n", __FILE__, __LINE__, rv);
912
nsXIEngine::GetDLMarkedComp(nsComponentList *aComps, int aCustom,
913
nsComponent **aOutComp, int *aOutCompNum)
916
FILE *dlMarkerFD = NULL;
918
char *compNameInFile = NULL;
920
nsComponent *currComp = NULL;
922
if (!aComps || !aOutComp || !aOutCompNum)
926
currComp = aComps->GetHead();
928
// open the marker file
929
dlMarkerFD = fopen(kDLMarkerPath, "r");
934
if (0 != stat(kDLMarkerPath, &stbuf))
939
if (stbuf.st_size <= 0)
945
// allocate a buffer the length of the file
946
compNameInFile = (char *) malloc(sizeof(char) * (stbuf.st_size + 1));
952
memset(compNameInFile, 0 , (stbuf.st_size + 1));
954
// read in the file contents
955
rv = fread((void *) compNameInFile, sizeof(char),
956
stbuf.st_size, dlMarkerFD);
957
if (rv != stbuf.st_size)
964
// compare the comp name read in with all those in the components list
967
if ( (aCustom == TRUE && currComp->IsSelected()) ||
970
if (strcmp(currComp->GetArchive(), compNameInFile) == 0)
972
*aOutComp = currComp;
979
currComp = currComp->GetNext();
983
*aOutCompNum = compNum;
989
XI_IF_FREE(compNameInFile);
995
nsXIEngine::DelDLMarker()
997
return unlink(kDLMarkerPath);
1001
nsXIEngine::TotalToDownload(int aCustom, nsComponentList *aComps)
1004
nsComponent *currComp;
1009
currComp = aComps->GetHead();
1012
if ( (aCustom == TRUE && currComp->IsSelected()) || (aCustom == FALSE) )
1014
if (!currComp->IsDownloaded())
1017
currComp = currComp->GetNext();
1024
* Name: CRCCheckDownloadedArchives
1028
* Handle dlPath; -- a handle to the location of the XPI files on disk
1029
* short dlPathlen; -- length, in bytes, of dlPath
1033
* This function iterates the XPI files and calls VerifyArchive() on each to
1034
* determine which archives pass checksum checks.
1036
* Return Value: if all archives pass, true. Otherwise, false.
1038
* Original Code: Syd Logan (syd@netscape.com) 6/24/2001
1043
nsXIEngine::CRCCheckDownloadedArchives(char *dlPath, short dlPathlen,
1044
nsComponent *currComp, int count, int aCustom)
1052
for(i = 0; currComp != (nsComponent *) NULL && i < MAX_COMPONENTS; i++) {
1053
strncpy( buf, (const char *) dlPath, dlPathlen );
1054
buf[ dlPathlen ] = '\0';
1056
strcat( buf, currComp->GetArchive() );
1057
if (gCtx->opt->mMode != nsXIOptions::MODE_SILENT)
1058
nsInstallDlg::MajorProgressCB(buf, i, count, nsInstallDlg::ACT_INSTALL);
1059
if (((aCustom == TRUE && currComp->IsSelected()) ||
1060
(aCustom == FALSE)) && IsArchiveFile(buf) == PR_TRUE &&
1061
VerifyArchive( buf ) != ZIP_OK) {
1062
currComp->SetDownloaded(FALSE); // VerifyArchive has unlinked it
1065
currComp = currComp->GetNext();
1071
* Name: IsArchiveFile( char *path )
1075
* char *path -- NULL terminated pathname
1079
* This function extracts the file extension of filename pointed to by path
1080
* and then checks it against a table of extensions. If a match occurs, the
1081
* file is considered to be an archive file that has a checksum we can
1082
* validate, and we return PR_TRUE.
1083
* Otherwise, PR_FALSE is returned.
1085
* Return Value: true if the file extension matches one of those we are
1086
* looking for, and false otherwise.
1088
* Original Code: Syd Logan 7/28/2001
1092
static char *extensions[] = { "ZIP", "XPI", "JAR" }; // must be uppercase
1095
nsXIEngine::IsArchiveFile( char *buf )
1102
// if we have a string and it contains a '.'
1104
if ( buf != (char *) NULL && ( p = strrchr( buf, '.' ) ) != (char *) NULL ) {
1107
// if there are characters after the '.' then see if there is a match
1111
// make a copy of the extension, and fold to uppercase, since mac has no strcasecmp
1112
// and we need to ensure we are comparing strings of chars that have the same case.
1115
for ( i = 0; i < (int) strlen( lbuf ); i++ )
1116
lbuf[i] = toupper(lbuf[i]);
1120
max = sizeof( extensions ) / sizeof ( char * );
1121
for ( i = 0; i < max; i++ )
1122
if ( !strcmp( lbuf, extensions[i] ) ) {
1132
* Name: VerifyArchive
1136
* char *szArchive; -- path of archive to verify
1140
* This function verifies that the specified path exists, that it is a XPI
1141
* file, and that it has a valid checksum.
1143
* Return Value: If all tests pass, ZIP_OK. Otherwise, !ZIP_OK
1145
* Original Code: Syd Logan (syd@netscape.com) 6/25/2001
1150
nsXIEngine::VerifyArchive(char *szArchive)
1156
if((iTestRv = ZIP_OpenArchive(szArchive, &vZip)) == ZIP_OK)
1158
/* 1st parameter should be NULL or it will fail */
1159
/* It indicates extract the entire archive */
1160
iTestRv = ZIP_TestArchive(vZip);
1161
ZIP_CloseArchive(&vZip);
1164
// for testing, this will cause about half of the CRCs to fail. Since
1165
// randomly selecting which fail, likely next pass the same file will
1166
// end up a success.
1168
penv = getenv("MOZ_INSTALL_TEST_CRC");
1169
if ( penv != (char *) NULL ) {
1170
if ( random() < RAND_MAX / 2 )
1174
if ( iTestRv != ZIP_OK )
1175
unlink( szArchive );