Files
Mozilla/mozilla/xpinstall/src/nsInstallPatch.cpp
dougt%netscape.com 2eb050c4c0 Removed InstallFolder Object - just using nsStrings now.
Now creating tempfiles for ZIP calls
hooked up to nsSpecialSystemDirectory
cleaned up Install() api


git-svn-id: svn://10.0.0.236/trunk@23231 18797224-902f-48f8-a5cc-f745e15eee43
1999-03-09 00:50:23 +00:00

347 lines
8.3 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.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "nsFileSpec.h"
#include "prmem.h"
#include "nsInstall.h"
#include "nsInstallPatch.h"
#include "nsIDOMInstallVersion.h"
#include "VerReg.h"
nsInstallPatch::nsInstallPatch( nsInstall* inInstall,
const nsString& inVRName,
nsIDOMInstallVersion* inVInfo,
const nsString& inJarLocation,
PRInt32 *error)
: nsInstallObject(inInstall)
{
char* tempTargetFile = new char[MAXREGPATHLEN];
char* tempVersionString = inVRName.ToNewCString();
PRInt32 err = VR_GetPath(tempVersionString, MAXREGPATHLEN, tempTargetFile );
delete [] tempVersionString;
if (err != REGERR_OK)
{
if(tempTargetFile)
delete [] tempTargetFile;
*error = nsInstall::NO_SUCH_COMPONENT;
return;
}
nsInstallPatch( inInstall, inVRName, inVInfo, inJarLocation, nsString(tempTargetFile), "null", error);
delete tempTargetFile;
}
nsInstallPatch::nsInstallPatch( nsInstall* inInstall,
const nsString& inVRName,
nsIDOMInstallVersion* inVInfo,
const nsString& inJarLocation,
const nsString& folderSpec,
const nsString& inPartialPath,
PRInt32 *error)
: nsInstallObject(inInstall)
{
if ((inInstall == nsnull) || (inVRName == "null") || (inJarLocation == "null"))
{
*error = nsInstall::INVALID_ARGUMENTS;
return;
}
mPatchFile = nsnull;
mTargetFile = nsnull;
mPatchedFile = nsnull;
mRegistryName = new nsString(inVRName);
mJarLocation = new nsString(inJarLocation);
nsString tempString;
inVInfo->ToString(tempString);
mVersionInfo = new nsInstallVersion();
mVersionInfo->Init(tempString);
mTargetFile = new nsFileSpec(folderSpec);
if(inPartialPath != "null")
*mTargetFile += inPartialPath;
}
nsInstallPatch::~nsInstallPatch()
{
if (mVersionInfo)
delete mVersionInfo;
if (mTargetFile)
delete mTargetFile;
if (mJarLocation)
delete mJarLocation;
if (mRegistryName)
delete mRegistryName;
if (mPatchedFile)
delete mPatchedFile;
if (mPatchFile)
delete mPatchFile;
}
PRInt32 nsInstallPatch::Prepare()
{
PRInt32 err;
PRBool deleteOldSrc;
if (mTargetFile == nsnull)
return nsInstall::INVALID_ARGUMENTS;
if (mTargetFile->Exists())
{
if (mTargetFile->IsFile())
{
err = nsInstall::SUCCESS;
}
else
{
err = nsInstall::FILE_IS_DIRECTORY;
}
}
else
{
err = nsInstall::FILE_DOES_NOT_EXIST;
}
if (err != nsInstall::SUCCESS)
{
return err;
}
err = mInstall->ExtractFileFromJar(*mJarLocation, mTargetFile, &mPatchFile);
nsFileSpec *fileName = nsnull;
nsVoidKey ikey( HashFilePath( nsFilePath(*mTargetFile) ) );
mInstall->GetPatch(&ikey, fileName);
if (fileName != nsnull)
{
deleteOldSrc = PR_TRUE;
}
else
{
fileName = mTargetFile;
deleteOldSrc = PR_FALSE;
}
err = NativePatch( *fileName, // the file to patch
*mPatchFile, // the patch that was extracted from the jarfile
&mPatchedFile); // the new patched file
if (err != nsInstall::SUCCESS)
{
return err;
}
if ( mPatchedFile != nsnull )
{
mInstall->AddPatch(&ikey, mPatchedFile );
}
else
{
// This is a wierd state. NativePatch should have generated an error here. Is there any
// reason why we return a Invalid_Arg error here?
err = nsInstall::INVALID_ARGUMENTS;
}
if ( deleteOldSrc )
{
NativeDeleteFile( fileName );
}
return err;
}
PRInt32 nsInstallPatch::Complete()
{
if ((mInstall == nsnull) || (mVersionInfo == nsnull) || (mPatchedFile == nsnull) || (mTargetFile == nsnull))
{
return nsInstall::INVALID_ARGUMENTS;
}
PRInt32 err = nsInstall::SUCCESS;
nsFileSpec *fileName = nsnull;
nsVoidKey ikey( HashFilePath( nsFilePath(*mTargetFile) ) );
mInstall->GetPatch(&ikey, fileName);
if (fileName != nsnull && fileName->Equals(*mPatchedFile) )
{
// the patch has not been superceded--do final replacement
err = NativeReplace( *mTargetFile, *mPatchedFile );
if ( 0 == err || nsInstall::REBOOT_NEEDED == err )
{
nsString tempVersionString;
mVersionInfo->ToString(tempVersionString);
char* tempRegName = mRegistryName->ToNewCString();
char* tempVersion = tempVersionString.ToNewCString();
err = VR_Install( tempRegName,
nsFilePath(*mTargetFile),
tempVersion,
PR_FALSE );
delete [] tempRegName;
delete [] tempVersion;
}
else
{
err = nsInstall::UNEXPECTED_ERROR;
}
}
else
{
// nothing -- old intermediate patched file was
// deleted by a superceding patch
}
return err;
}
void nsInstallPatch::Abort()
{
nsFileSpec *fileName = nsnull;
nsVoidKey ikey( HashFilePath( nsFilePath(*mTargetFile) ) );
mInstall->GetPatch(&ikey, fileName);
if (fileName != nsnull && fileName->Equals(*mPatchedFile) )
{
NativeDeleteFile( mPatchedFile );
}
}
char* nsInstallPatch::toString()
{
//return GetString1(DETAILS_PATCH, targetfile);
return nsnull;
}
PRBool
nsInstallPatch::CanUninstall()
{
return PR_FALSE;
}
PRBool
nsInstallPatch::RegisterPackageNode()
{
return PR_FALSE;
}
PRInt32
nsInstallPatch::NativePatch(const nsFileSpec &sourceFile, const nsFileSpec &patchfile, nsFileSpec **newFile)
{
return -1;
}
PRInt32
nsInstallPatch::NativeDeleteFile(nsFileSpec* doomedFile)
{
if (doomedFile->Exists())
{
if (doomedFile->IsFile())
{
doomedFile->Delete(false);
if (doomedFile->Exists())
{
// If file still exists, we need to delete it later!
// FIX DeleteOldFileLater( (char*)finalFile );
return nsInstall::REBOOT_NEEDED;
}
}
else
{
return nsInstall::FILE_IS_DIRECTORY;
}
}
return nsInstall::FILE_DOES_NOT_EXIST;
}
PRInt32
nsInstallPatch::NativeReplace(const nsFileSpec& oldfile, const nsFileSpec& newFile)
{
oldfile.Delete(PR_FALSE);
if (oldfile.Exists())
{
//FIX: FE_ReplaceExistingFile
}
nsFileSpec parentDirectory;
oldfile.GetParent(parentDirectory);
if (parentDirectory.Exists() && parentDirectory.IsDirectory())
{
if (newFile.Move(parentDirectory) != 0)
{
return nsInstall::UNEXPECTED_ERROR;
}
}
return nsInstall::SUCCESS;
}
void*
nsInstallPatch::HashFilePath(const nsFilePath& aPath)
{
PRUint32 rv = 0;
if(aPath)
{
char ch;
char* filePath = nsnull;
strcpy(filePath, aPath);
while ((ch = *filePath++) != 0)
{
// FYI: rv = rv*37 + ch
rv = ((rv << 5) + (rv << 2) + rv) + ch;
}
PR_Free(filePath);
}
return (void*)rv;
}