зеркало из https://github.com/mozilla/gecko-dev.git
510 строки
12 KiB
C++
510 строки
12 KiB
C++
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
/*
|
|
* The contents of this file are subject to the Netscape Public
|
|
* License Version 1.1 (the "License"); you may not use this file
|
|
* except in compliance with the License. You may obtain a copy of
|
|
* the License at http://www.mozilla.org/NPL/
|
|
*
|
|
* Software distributed under the License is distributed on an "AS
|
|
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
|
* implied. See the License for the specific language governing
|
|
* rights and limitations under the License.
|
|
*
|
|
* The Original Code is Mozilla Communicator client code,
|
|
* released March 31, 1998.
|
|
*
|
|
* The Initial Developer of the Original Code is Netscape Communications
|
|
* Corporation. Portions created by Netscape are
|
|
* Copyright (C) 1998 Netscape Communications Corporation. All
|
|
* Rights Reserved.
|
|
*
|
|
* Contributor(s):
|
|
* Samir Gehani <sgehani@netscape.com>
|
|
*/
|
|
|
|
#include "nsXIEngine.h"
|
|
|
|
#define CORE_LIB_COUNT 9
|
|
static char sCoreLibs[ CORE_LIB_COUNT * 2 ][ 32 ] =
|
|
{
|
|
/* Archive Subdir File */
|
|
/* -------------- ---- */
|
|
"bin/", "libjsdom.so",
|
|
"bin/", "libmozjs.so",
|
|
"bin/", "libnspr4.so",
|
|
"bin/", "libplc4.so",
|
|
"bin/", "libplds4.so",
|
|
"bin/", "libxpcom.so",
|
|
"bin/", "libxpistub.so",
|
|
"bin/components/", "libxpinstall.so",
|
|
"bin/components/", "libjar50.so"
|
|
};
|
|
|
|
nsXIEngine::nsXIEngine() :
|
|
mTmp(NULL)
|
|
{
|
|
}
|
|
|
|
nsXIEngine::~nsXIEngine()
|
|
{
|
|
DUMP("~nsXIEngine");
|
|
|
|
// rm tmp dir
|
|
char cmd[1024];
|
|
|
|
sprintf(cmd, "rm -rf %s", mTmp);
|
|
system(cmd);
|
|
|
|
XI_IF_FREE(mTmp);
|
|
}
|
|
|
|
int
|
|
nsXIEngine::Download(int aCustom, nsComponentList *aComps)
|
|
{
|
|
DUMP("Download");
|
|
|
|
if (!aComps)
|
|
return E_PARAM;
|
|
|
|
int err = OK;
|
|
nsComponent *currComp = aComps->GetHead();
|
|
char *currURL = NULL;
|
|
char *currHost = NULL;
|
|
char *currDir = NULL;
|
|
int i;
|
|
|
|
mTmp = NULL;
|
|
err = MakeUniqueTmpDir();
|
|
if (!mTmp || err != OK)
|
|
return E_DIR_CREATE;
|
|
|
|
// if all .xpis exist in the ./xpi dir (blob/CD) we don't need to download
|
|
if (ExistAllXPIs(aCustom, aComps))
|
|
return CopyToTmp(aCustom, aComps);
|
|
|
|
while (currComp)
|
|
{
|
|
if ( (aCustom == TRUE && currComp->IsSelected()) || (aCustom == FALSE) )
|
|
{
|
|
for (i = 0; i < MAX_URLS; i++)
|
|
{
|
|
currURL = currComp->GetURL(i);
|
|
if (!currURL) break;
|
|
|
|
currHost = NULL;
|
|
currDir = NULL;
|
|
err = ParseURL(currURL, &currHost, &currDir);
|
|
if (err == OK)
|
|
{
|
|
err = FTPAnonGet(currHost, currDir, currComp->GetArchive());
|
|
if (err == OK) break; // no need to failover
|
|
}
|
|
}
|
|
}
|
|
|
|
currComp = currComp->GetNext();
|
|
}
|
|
|
|
return OK;
|
|
}
|
|
|
|
int
|
|
nsXIEngine::Extract(nsComponent *aXPIEngine)
|
|
{
|
|
DUMP("Extract");
|
|
|
|
char path[1024];
|
|
char bindir[512];
|
|
char unzipcmd[512];
|
|
struct stat dummy;
|
|
int i;
|
|
|
|
if (!aXPIEngine || !(aXPIEngine->GetArchive()))
|
|
return E_PARAM;
|
|
|
|
sprintf(path, "%s/%s", mTmp, aXPIEngine->GetArchive());
|
|
if (-1 == stat(path, &dummy))
|
|
return E_NO_DOWNLOAD;
|
|
|
|
for (i = 0; i < CORE_LIB_COUNT*2; i++)
|
|
{
|
|
sprintf(unzipcmd, "unzip %s -d %s %s%s > /dev/null",
|
|
path, mTmp, sCoreLibs[i], sCoreLibs[i+1]);
|
|
i++;
|
|
system(unzipcmd);
|
|
}
|
|
|
|
sprintf(bindir, "%s/%s", mTmp, TMP_EXTRACT_SUBDIR);
|
|
if (-1 == stat(bindir, &dummy))
|
|
return E_EXTRACTION;
|
|
|
|
return OK;
|
|
}
|
|
|
|
int
|
|
nsXIEngine::Install(int aCustom, nsComponentList *aComps, char *aDestination)
|
|
{
|
|
DUMP("Install");
|
|
|
|
int err = OK;
|
|
xpistub_t stub;
|
|
char cmd[1024];
|
|
char *old_LD_LIBRARY_PATH = NULL;
|
|
char new_LD_LIBRARY_PATH[256];
|
|
int i;
|
|
int compNum = 1;
|
|
int totalComps;
|
|
nsComponent *currComp = NULL;
|
|
|
|
if (!aComps || !aDestination)
|
|
return E_PARAM;
|
|
|
|
// handle LD_LIBRARY_PATH settings
|
|
memset(new_LD_LIBRARY_PATH, 0, 256);
|
|
sprintf(new_LD_LIBRARY_PATH, "%s/bin:.", mTmp);
|
|
DUMP(new_LD_LIBRARY_PATH);
|
|
old_LD_LIBRARY_PATH = getenv("LD_LIBRARY_PATH");
|
|
setenv("LD_LIBRARY_PATH", new_LD_LIBRARY_PATH, 1);
|
|
|
|
if (aCustom)
|
|
totalComps = aComps->GetLengthSelected();
|
|
else
|
|
totalComps = aComps->GetLength();
|
|
|
|
currComp = aComps->GetHead();
|
|
err = LoadXPIStub(&stub, aDestination);
|
|
if (err == OK)
|
|
{
|
|
for (i = 0; i < MAX_COMPONENTS; i++)
|
|
{
|
|
if (!currComp)
|
|
break;
|
|
|
|
if ( (aCustom && currComp->IsSelected()) ||
|
|
(!aCustom) )
|
|
{
|
|
nsInstallDlg::MajorProgressCB(currComp->GetDescShort(),
|
|
compNum, totalComps);
|
|
err = InstallXPI(currComp, &stub);
|
|
if (err != OK)
|
|
ErrorHandler(err); // handle and continue
|
|
compNum++;
|
|
}
|
|
|
|
currComp = currComp->GetNext();
|
|
}
|
|
}
|
|
|
|
UnloadXPIStub(&stub);
|
|
|
|
// restore LD_LIBRARY_PATH settings
|
|
setenv("LD_LIBRARY_PATH", old_LD_LIBRARY_PATH, 1);
|
|
|
|
// rm tmp dir --> now in {ROOT}/
|
|
chdir("../..");
|
|
sprintf(cmd, "rm -rf %s", mTmp);
|
|
DUMP(cmd);
|
|
system(cmd);
|
|
|
|
// XXX call gCtx->me->Shutdown();
|
|
gtk_main_quit();
|
|
exit(err);
|
|
|
|
return err;
|
|
}
|
|
|
|
int
|
|
nsXIEngine::MakeUniqueTmpDir()
|
|
{
|
|
int err = OK;
|
|
int i;
|
|
char buf[1024];
|
|
char cwd[1024];
|
|
char cmd[1030];
|
|
struct stat dummy;
|
|
mTmp = NULL;
|
|
|
|
memset(cwd, 0, 1024);
|
|
if (!getcwd(cwd, 1024))
|
|
return E_MEM;
|
|
|
|
for (i = 0; i < MAX_TMP_DIRS; i++)
|
|
{
|
|
memset(buf, 0, 1024);
|
|
sprintf(buf, TMP_DIR_TEMPLATE, cwd, i);
|
|
if (-1 == stat(buf, &dummy))
|
|
break;
|
|
}
|
|
|
|
mTmp = (char *) malloc( (strlen(buf) * sizeof(char)) + 1 );
|
|
if (!mTmp) return E_MEM;
|
|
|
|
sprintf(mTmp, "%s", buf);
|
|
sprintf(cmd, "mkdir %s", mTmp);
|
|
system(cmd);
|
|
|
|
return err;
|
|
}
|
|
|
|
int
|
|
nsXIEngine::ParseURL(char *aURL, char **aHost, char **aDir)
|
|
{
|
|
int err = OK;
|
|
char *host = NULL;
|
|
char *hostTerminator = NULL;
|
|
char *dirTerminator = NULL;
|
|
|
|
if (!aURL || !aHost || !aDir)
|
|
return E_PARAM;
|
|
|
|
if (0 != strncmp(aURL, "ftp://", 6)) return E_BAD_FTP_URL;
|
|
|
|
host = aURL + 6;
|
|
if (!host) return E_BAD_FTP_URL;
|
|
hostTerminator = strchr(host, '/');
|
|
if (!hostTerminator) return E_BAD_FTP_URL;
|
|
|
|
*aHost = (char *) malloc(sizeof(char) * (hostTerminator - host + 1));
|
|
memset(*aHost, 0, (hostTerminator - host + 1));
|
|
strncpy(*aHost, host, hostTerminator - host);
|
|
|
|
dirTerminator = strrchr(hostTerminator + 1, '/');
|
|
if (!dirTerminator)
|
|
{
|
|
// no dir == root dir
|
|
*aDir = (char *) malloc(2);
|
|
sprintf(*aDir, "/");
|
|
}
|
|
else
|
|
{
|
|
*aDir = (char *) malloc(sizeof(char) *
|
|
(dirTerminator - hostTerminator + 2));
|
|
memset(*aDir, 0, (dirTerminator - hostTerminator + 2));
|
|
strncpy(*aDir, hostTerminator, dirTerminator - hostTerminator + 1);
|
|
}
|
|
|
|
return err;
|
|
}
|
|
|
|
int
|
|
nsXIEngine::FTPAnonGet(char *aHost, char *aDir, char *aArchive)
|
|
{
|
|
int err = OK;
|
|
char qualifiedPath[1024];
|
|
char basename[256];
|
|
char ftpcmds[1024];
|
|
struct stat dummy;
|
|
|
|
if (!aHost || !aDir || !aArchive)
|
|
return E_PARAM;
|
|
|
|
sprintf(qualifiedPath, "%s%s", aDir, aArchive);
|
|
sprintf(basename, "%s/%s", mTmp, aArchive);
|
|
sprintf(ftpcmds, "\
|
|
\
|
|
ftp -n %s <<EndFTP\n\
|
|
user anonymous dev@null.edu\n\
|
|
binary\n\
|
|
get %s %s\n\
|
|
EndFTP\n\
|
|
\
|
|
", aHost, qualifiedPath, basename);
|
|
|
|
system(ftpcmds);
|
|
|
|
if (-1 == stat(basename, &dummy))
|
|
err = E_NO_DOWNLOAD;
|
|
|
|
return err;
|
|
}
|
|
|
|
int
|
|
nsXIEngine::LoadXPIStub(xpistub_t *aStub, char *aDestination)
|
|
{
|
|
int err = OK;
|
|
|
|
char libpath[1024];
|
|
char libloc[1024];
|
|
char *dlerr;
|
|
nsresult rv = 0;
|
|
|
|
DUMP("LoadXPIStub");
|
|
|
|
/* param check */
|
|
if (!aStub || !aDestination)
|
|
return E_PARAM;
|
|
|
|
/* chdir to library location for dll deps resolution */
|
|
memset(libloc, 0, 1024);
|
|
sprintf(libloc, "%s/bin", mTmp);
|
|
chdir(libloc);
|
|
|
|
/* open the library */
|
|
memset(libpath, 0, 1024);
|
|
getcwd(libpath, 1024);
|
|
sprintf(libpath, "%s/%s", libpath, XPISTUB);
|
|
|
|
#ifdef DEBUG
|
|
printf("DEBUG: libpath = >>%s<<\n", libpath);
|
|
#endif
|
|
|
|
aStub->handle = NULL;
|
|
aStub->handle = dlopen(libpath, RTLD_LAZY);
|
|
if (!aStub->handle)
|
|
{
|
|
dlerr = dlerror();
|
|
DUMP(dlerr);
|
|
return E_LIB_OPEN;
|
|
}
|
|
DUMP("xpistub opened");
|
|
|
|
/* read and store symbol addresses */
|
|
aStub->fn_init = (pfnXPI_Init) dlsym(aStub->handle, FN_INIT);
|
|
aStub->fn_install = (pfnXPI_Install) dlsym(aStub->handle, FN_INSTALL);
|
|
aStub->fn_exit = (pfnXPI_Exit) dlsym(aStub->handle, FN_EXIT);
|
|
if (!aStub->fn_init || !aStub->fn_install || !aStub->fn_exit)
|
|
{
|
|
dlerr = dlerror();
|
|
DUMP(dlerr);
|
|
err = E_LIB_SYM;
|
|
goto BAIL;
|
|
}
|
|
DUMP("xpistub symbols loaded");
|
|
|
|
rv = aStub->fn_init(aDestination, ProgressCallback);
|
|
|
|
#ifdef DEBUG
|
|
printf("DEBUG: XPI_Init returned 0x%.8X\n", rv);
|
|
#endif
|
|
|
|
DUMP("XPI_Init called");
|
|
if (NS_FAILED(rv))
|
|
{
|
|
err = E_XPI_FAIL;
|
|
goto BAIL;
|
|
}
|
|
|
|
return err;
|
|
|
|
BAIL:
|
|
return err;
|
|
}
|
|
|
|
int
|
|
nsXIEngine::InstallXPI(nsComponent *aXPI, xpistub_t *aStub)
|
|
{
|
|
int err = OK;
|
|
char xpipath[1024];
|
|
nsresult rv = 0;
|
|
|
|
if (!aStub || !aXPI)
|
|
return E_PARAM;
|
|
|
|
memset(xpipath, 0, 1024);
|
|
sprintf(xpipath, "../%s", aXPI->GetArchive());
|
|
DUMP(xpipath);
|
|
|
|
#define XPI_NO_NEW_THREAD 0x1000
|
|
|
|
rv = aStub->fn_install(xpipath, "", XPI_NO_NEW_THREAD);
|
|
|
|
#ifdef DEBUG
|
|
printf("DEBUG: XPI_Install %s returned %d\n", aXPI->GetArchive(), rv);
|
|
#endif
|
|
|
|
if (!NS_SUCCEEDED(rv))
|
|
err = E_INSTALL;
|
|
|
|
return err;
|
|
}
|
|
|
|
int
|
|
nsXIEngine::UnloadXPIStub(xpistub_t *aStub)
|
|
{
|
|
int err = OK;
|
|
|
|
/* param check */
|
|
if (!aStub)
|
|
return E_PARAM;
|
|
|
|
/* release XPCOM and XPInstall */
|
|
if (aStub->fn_exit)
|
|
{
|
|
aStub->fn_exit();
|
|
DUMP("XPI_Exit called");
|
|
}
|
|
|
|
/* close xpistub library */
|
|
if (aStub->handle)
|
|
{
|
|
dlclose(aStub->handle);
|
|
DUMP("xpistub closed");
|
|
}
|
|
|
|
return err;
|
|
}
|
|
|
|
void
|
|
nsXIEngine::ProgressCallback(const char* aMsg, PRInt32 aVal, PRInt32 aMax)
|
|
{
|
|
// DUMP("ProgressCallback");
|
|
|
|
pthread_mutex_lock(&gCtx->prog_mutex);
|
|
|
|
nsInstallDlg::XPIProgressCB(aMsg, (int)aVal, (int)aMax);
|
|
|
|
gCtx->threadTurn = nsXIContext::UI_THREAD;
|
|
|
|
pthread_cond_signal(&gCtx->prog_cv);
|
|
pthread_mutex_unlock(&gCtx->prog_mutex);
|
|
}
|
|
|
|
int
|
|
nsXIEngine::ExistAllXPIs(int aCustom, nsComponentList *aComps)
|
|
{
|
|
int bAllExist = TRUE;
|
|
nsComponent *currComp = aComps->GetHead();
|
|
char currArchivePath[256];
|
|
struct stat dummy;
|
|
|
|
while (currComp)
|
|
{
|
|
if ( (aCustom == TRUE && currComp->IsSelected()) || (aCustom == FALSE) )
|
|
{
|
|
memset(currArchivePath, 0, 256);
|
|
sprintf(currArchivePath, "%s/%s", XPI_DIR, currComp->GetArchive());
|
|
DUMP(currArchivePath);
|
|
|
|
if (0 != stat(currArchivePath, &dummy))
|
|
return FALSE;
|
|
}
|
|
|
|
currComp = currComp->GetNext();
|
|
}
|
|
|
|
return bAllExist;
|
|
}
|
|
|
|
int
|
|
nsXIEngine::CopyToTmp(int aCustom, nsComponentList *aComps)
|
|
{
|
|
int err = OK;
|
|
nsComponent *currComp = aComps->GetHead();
|
|
char cmd[256];
|
|
|
|
while (currComp)
|
|
{
|
|
if ( (aCustom == TRUE && currComp->IsSelected()) || (aCustom == FALSE) )
|
|
{
|
|
memset(cmd, 0, 256);
|
|
sprintf(cmd, "cp %s/%s %s", XPI_DIR, currComp->GetArchive(), mTmp);
|
|
DUMP(cmd);
|
|
system(cmd);
|
|
}
|
|
|
|
currComp = currComp->GetNext();
|
|
}
|
|
|
|
return err;
|
|
}
|