diff --git a/xpinstall/src/nsInstall.cpp b/xpinstall/src/nsInstall.cpp index f93eb9924e2a..23aac5c50867 100644 --- a/xpinstall/src/nsInstall.cpp +++ b/xpinstall/src/nsInstall.cpp @@ -1756,8 +1756,42 @@ nsInstall::FileOpFileWindowsShortcut(nsFileSpec& aTarget, nsFileSpec& aShortcutP } PRInt32 -nsInstall::FileOpFileMacAlias(nsFileSpec& aTarget, PRInt32 aFlags, PRInt32* aReturn) +nsInstall::FileOpFileMacAlias(nsString& aSourcePath, nsString& aAliasPath, PRInt32* aReturn) { + *aReturn = nsInstall::SUCCESS; + +#ifdef XP_MAC + nsFileSpec nsfsSource(aSourcePath, PR_FALSE); + nsFileSpec nsfsAlias(aAliasPath, PR_TRUE); + + nsInstallFileOpItem* ifop = new nsInstallFileOpItem(this, NS_FOP_MAC_ALIAS, nsfsSource, nsfsAlias, aReturn); + + PRInt32 result = SanityCheck(); + if (result != nsInstall::SUCCESS) + { + *aReturn = SaveError( result ); + return NS_OK; + } + + if (ifop == nsnull) + { + *aReturn = SaveError(nsInstall::OUT_OF_MEMORY); + return NS_OK; + } + + if (*aReturn == nsInstall::SUCCESS) + { + *aReturn = ScheduleForInstall( ifop ); + } + + if (*aReturn == nsInstall::FILE_DOES_NOT_EXIST) + { + *aReturn = nsInstall::SUCCESS; + } + + SaveError(*aReturn); +#endif + return NS_OK; } diff --git a/xpinstall/src/nsInstall.h b/xpinstall/src/nsInstall.h index 1da6214938a4..b5fece185604 100644 --- a/xpinstall/src/nsInstall.h +++ b/xpinstall/src/nsInstall.h @@ -220,7 +220,7 @@ class nsInstall PRInt32 FileOpFileMove(nsFileSpec& aSrc, nsFileSpec& aTarget, PRInt32* aReturn); PRInt32 FileOpFileRename(nsFileSpec& aSrc, nsString& aTarget, PRInt32* aReturn); PRInt32 FileOpFileWindowsShortcut(nsFileSpec& aTarget, nsFileSpec& aShortcutPath, nsString& aDescription, nsFileSpec& aWorkingPath, nsString& aParams, nsFileSpec& aIcon, PRInt32 aIconId, PRInt32* aReturn); - PRInt32 FileOpFileMacAlias(nsFileSpec& aTarget, PRInt32 aFlags, PRInt32* aReturn); + PRInt32 FileOpFileMacAlias(nsString& aSourcePath, nsString& aAliasPath, PRInt32* aReturn); PRInt32 FileOpFileUnixLink(nsFileSpec& aTarget, PRInt32 aFlags, PRInt32* aReturn); void LogComment(nsString& aComment); diff --git a/xpinstall/src/nsInstallFileOpItem.cpp b/xpinstall/src/nsInstallFileOpItem.cpp index 89a3847568c1..3b82370d6d59 100644 --- a/xpinstall/src/nsInstallFileOpItem.cpp +++ b/xpinstall/src/nsInstallFileOpItem.cpp @@ -25,6 +25,13 @@ #include "nsWinShortcut.h" #endif +#ifdef XP_MAC +#include "Aliases.h" +#include "Gestalt.h" +#include "Resources.h" +#include "script.h" +#endif + /* Public Methods */ nsInstallFileOpItem::nsInstallFileOpItem(nsInstall* aInstallObj, @@ -199,45 +206,49 @@ nsInstallFileOpItem::~nsInstallFileOpItem() PRInt32 nsInstallFileOpItem::Complete() { - PRInt32 aReturn = NS_OK; + PRInt32 aReturn = nsInstall::SUCCESS; switch(mCommand) { case NS_FOP_DIR_CREATE: - NativeFileOpDirCreate(mTarget); + aReturn = NativeFileOpDirCreate(mTarget); break; case NS_FOP_DIR_REMOVE: - NativeFileOpDirRemove(mTarget, mFlags); + aReturn = NativeFileOpDirRemove(mTarget, mFlags); break; case NS_FOP_DIR_RENAME: - NativeFileOpDirRename(mSrc, mStrTarget); + aReturn = NativeFileOpDirRename(mSrc, mStrTarget); break; case NS_FOP_FILE_COPY: - NativeFileOpFileCopy(mSrc, mTarget); + aReturn = NativeFileOpFileCopy(mSrc, mTarget); break; case NS_FOP_FILE_DELETE: - NativeFileOpFileDelete(mTarget, mFlags); + aReturn = NativeFileOpFileDelete(mTarget, mFlags); break; case NS_FOP_FILE_EXECUTE: - NativeFileOpFileExecute(mTarget, mParams); + aReturn = NativeFileOpFileExecute(mTarget, mParams); break; case NS_FOP_FILE_MOVE: - NativeFileOpFileMove(mSrc, mTarget); + aReturn = NativeFileOpFileMove(mSrc, mTarget); break; case NS_FOP_FILE_RENAME: - NativeFileOpFileRename(mSrc, mStrTarget); + aReturn = NativeFileOpFileRename(mSrc, mStrTarget); break; case NS_FOP_WIN_SHORTCUT: - NativeFileOpWindowsShortcut(mTarget, mShortcutPath, mDescription, mWorkingPath, mParams, mIcon, mIconId); + aReturn = NativeFileOpWindowsShortcut(mTarget, mShortcutPath, mDescription, mWorkingPath, mParams, mIcon, mIconId); break; case NS_FOP_MAC_ALIAS: - NativeFileOpMacAlias(); + aReturn = NativeFileOpMacAlias(mSrc, mTarget); break; case NS_FOP_UNIX_LINK: - NativeFileOpUnixLink(); + aReturn = NativeFileOpUnixLink(); break; } - return aReturn; + + if ( (aReturn!=NS_OK) && (aReturn < nsInstall::GESTALT_INVALID_ARGUMENT || aReturn > nsInstall::REBOOT_NEEDED) ) + aReturn = nsInstall::UNEXPECTED_ERROR; /* translate to XPInstall error */ + + return aReturn; } char* nsInstallFileOpItem::toString() @@ -245,6 +256,8 @@ char* nsInstallFileOpItem::toString() nsString result; char* resultCString; + // XXX these hardcoded strings should be replaced by nsInstall::GetResourcedString(id) + switch(mCommand) { case NS_FOP_FILE_COPY: @@ -294,6 +307,9 @@ char* nsInstallFileOpItem::toString() resultCString = result.ToNewCString(); break; case NS_FOP_MAC_ALIAS: + result = "Mac Alias: "; + result.Append(mSrc->GetCString()); + resultCString = result.ToNewCString(); break; case NS_FOP_UNIX_LINK: break; @@ -337,6 +353,10 @@ nsInstallFileOpItem::RegisterPackageNode() return PR_FALSE; } +#ifdef XP_MAC +#pragma mark - +#endif + // // File operation functions begin here // @@ -357,21 +377,21 @@ nsInstallFileOpItem::NativeFileOpDirRemove(nsFileSpec* aTarget, PRInt32 aFlags) PRInt32 nsInstallFileOpItem::NativeFileOpDirRename(nsFileSpec* aSrc, nsString* aTarget) { + PRInt32 retval = NS_OK; char* szTarget = aTarget->ToNewCString(); - aSrc->Rename(szTarget); + retval = aSrc->Rename(szTarget); if (szTarget) Recycle(szTarget); - return NS_OK; + return retval; } PRInt32 nsInstallFileOpItem::NativeFileOpFileCopy(nsFileSpec* aSrc, nsFileSpec* aTarget) { - aSrc->Copy(*aTarget); - return NS_OK; + return aSrc->Copy(*aTarget); } PRInt32 @@ -384,28 +404,27 @@ nsInstallFileOpItem::NativeFileOpFileDelete(nsFileSpec* aTarget, PRInt32 aFlags) PRInt32 nsInstallFileOpItem::NativeFileOpFileExecute(nsFileSpec* aTarget, nsString* aParams) { - aTarget->Execute(*aParams); - return NS_OK; + return aTarget->Execute(*aParams); } PRInt32 nsInstallFileOpItem::NativeFileOpFileMove(nsFileSpec* aSrc, nsFileSpec* aTarget) { - aSrc->Move(*aTarget); - return NS_OK; + return aSrc->Move(*aTarget); } PRInt32 nsInstallFileOpItem::NativeFileOpFileRename(nsFileSpec* aSrc, nsString* aTarget) { + PRInt32 retval = NS_OK; char* szTarget = aTarget->ToNewCString(); - aSrc->Rename(szTarget); + retval = aSrc->Rename(szTarget); if (szTarget) Recycle(szTarget); - return NS_OK; + return retval; } PRInt32 @@ -436,8 +455,42 @@ nsInstallFileOpItem::NativeFileOpWindowsShortcut(nsFileSpec* mTarget, nsFileSpec } PRInt32 -nsInstallFileOpItem::NativeFileOpMacAlias() +nsInstallFileOpItem::NativeFileOpMacAlias(nsFileSpec* aSrc, nsFileSpec* aTarget) { + +#ifdef XP_MAC + // XXX gestalt to see if alias manager is around + + FSSpec *fsPtrAlias = aTarget->GetFSSpecPtr(); + AliasHandle aliasH; + FInfo info; + OSErr err = noErr; + + err = NewAliasMinimal( aSrc->GetFSSpecPtr(), &aliasH ); + if (err != noErr) // bubble up Alias Manager error + return err; + + // create the alias file + FSpGetFInfo(aSrc->GetFSSpecPtr(), &info); + FSpCreateResFile(fsPtrAlias, info.fdCreator, info.fdType, smRoman); + short refNum = FSpOpenResFile(fsPtrAlias, fsRdWrPerm); + if (refNum != -1) + { + UseResFile(refNum); + AddResource((Handle)aliasH, rAliasType, 0, fsPtrAlias->name); + ReleaseResource((Handle)aliasH); + UpdateResFile(refNum); + CloseResFile(refNum); + } + else + return nsInstall::UNEXPECTED_ERROR; + + // mark newly created file as an alias file + FSpGetFInfo(fsPtrAlias, &info); + info.fdFlags |= kIsAlias; + FSpSetFInfo(fsPtrAlias, &info); +#endif + return NS_OK; } diff --git a/xpinstall/src/nsInstallFileOpItem.h b/xpinstall/src/nsInstallFileOpItem.h index 7a5228e9414b..c35fd82f8ce7 100644 --- a/xpinstall/src/nsInstallFileOpItem.h +++ b/xpinstall/src/nsInstallFileOpItem.h @@ -44,6 +44,7 @@ class nsInstallFileOpItem : public nsInstallObject // FileOpDirRemove() // FileOpFileCopy() // FileOpFileMove() + // FileMacAlias() nsInstallFileOpItem(nsInstall* installObj, PRInt32 aCommand, nsFileSpec& aSrc, @@ -120,7 +121,7 @@ class nsInstallFileOpItem : public nsInstallObject PRInt32 NativeFileOpFileMove(nsFileSpec* aSrc, nsFileSpec* aTarget); PRInt32 NativeFileOpFileRename(nsFileSpec* aSrc, nsString* aTarget); PRInt32 NativeFileOpWindowsShortcut(nsFileSpec* mTarget, nsFileSpec* mShortcutPath, nsString* mDescription, nsFileSpec* mWorkingPath, nsString* mParams, nsFileSpec* mIcon, PRInt32 mIconId); - PRInt32 NativeFileOpMacAlias(); + PRInt32 NativeFileOpMacAlias(nsFileSpec* aSrc, nsFileSpec* aTarget); PRInt32 NativeFileOpUnixLink(); }; diff --git a/xpinstall/src/nsJSInstall.cpp b/xpinstall/src/nsJSInstall.cpp index 3b6bf16d8bcc..77adf769ce69 100644 --- a/xpinstall/src/nsJSInstall.cpp +++ b/xpinstall/src/nsJSInstall.cpp @@ -2183,7 +2183,7 @@ InstallFileOpFileWindowsShortcut(JSContext *cx, JSObject *obj, uintN argc, jsval } // -// Native method FileMacAliasCreate +// Native method FileMacAlias // PR_STATIC_CALLBACK(JSBool) InstallFileOpFileMacAlias(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) @@ -2191,7 +2191,9 @@ InstallFileOpFileMacAlias(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, nsInstall *nativeThis = (nsInstall*)JS_GetPrivate(cx, obj); PRInt32 nativeRet; nsAutoString b0; - PRInt32 b1; + nsAutoString b1; + nsAutoString b2; + nsAutoString b3; *rval = JSVAL_NULL; @@ -2201,16 +2203,82 @@ InstallFileOpFileMacAlias(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, return JS_TRUE; } - if(argc >= 2) + if(argc >= 4) { - // public int FileMacAliasCreate (String aSourceFolder, - // Number aFlags); - + // public int FileMacAlias( String aSourceFolder, + // String aSourceFileName, + // String aAliasFolder, + // String aAliasName ); + // where + // aSourceFolder -- the folder of the installed file from Get*Folder() APIs + // aSourceName -- the installed file's name + // aAliasFolder -- the folder of the new alias from Get*Folder() APIs + // aAliasName -- the actual name of the new alias + // + // returns SUCCESS for successful scheduling of operation + // UNEXPECTED_ERROR for failure + ConvertJSValToStr(b0, cx, argv[0]); - b1 = JSVAL_TO_INT(argv[1]); - nsFileSpec fsB0(b0); + ConvertJSValToStr(b1, cx, argv[1]); + ConvertJSValToStr(b2, cx, argv[2]); + ConvertJSValToStr(b3, cx, argv[3]); - if(NS_OK != nativeThis->FileOpFileMacAlias(fsB0, b1, &nativeRet)) + b0 += b1; + b2 += b3; + + if(NS_OK != nativeThis->FileOpFileMacAlias(b0, b2, &nativeRet)) + { + return JS_FALSE; + } + + *rval = INT_TO_JSVAL(nativeRet); + } + else if (argc >= 3) + { + // public int FileMacAlias( String aSourceFolder, + // String aSourceName, + // String aAliasFolder ); + // where + // aSourceFolder -- the folder of the installed file from Get*Folder() APIs + // aSourceName -- the installed file's name + // aAliasFolder -- the folder of the new alias from Get*Folder() APIs + // + // NOTE: + // The destination alias name is aSourceName + " alias" (Mac-like behavior). + // + // returns SUCCESS for successful scheduling of operation + // UNEXPECTED_ERROR for failure + + ConvertJSValToStr(b0, cx, argv[0]); + ConvertJSValToStr(b1, cx, argv[1]); + ConvertJSValToStr(b2, cx, argv[2]); + + b0 += b1; + b2 += b1; + b2 += " alias"; // XXX use GetResourcedString(id) + + if(NS_OK != nativeThis->FileOpFileMacAlias(b0, b2, &nativeRet)) + { + return JS_FALSE; + } + + *rval = INT_TO_JSVAL(nativeRet); + } + else if (argc >= 2) + { + // public int FileMacAlias( String aSourcePath, + // String aAliasPath ); + // where + // aSourcePath -- the full path to the installed file + // aAliasPath -- the full path to the new alias + // + // returns SUCCESS for successful scheduling of operation + // UNEXPECTED_ERROR for failure + + ConvertJSValToStr(b0, cx, argv[0]); + ConvertJSValToStr(b1, cx, argv[1]); + + if(NS_OK != nativeThis->FileOpFileMacAlias(b0, b1, &nativeRet)) { return JS_FALSE; } @@ -2219,7 +2287,7 @@ InstallFileOpFileMacAlias(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, } else { - JS_ReportError(cx, "Function FileMacAlias requires 2 parameters"); + JS_ReportError(cx, "Function FileMacAlias requires 2 to 4 parameters"); return JS_FALSE; }