/* -*- 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.org code. * * 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): */ #include "prmem.h" #include "prmon.h" #include "prlog.h" #include "prthread.h" #include "fe_proto.h" #include "xp.h" #include "xp_str.h" #include "xpgetstr.h" #include "prefapi.h" #include "proto.h" #include "prprf.h" #include "prthread.h" #include "nsFolderSpec.h" #include "nsSUError.h" extern "C" { #include "su_folderspec.h" } #ifndef MAX_PATH #if defined(XP_WIN) || defined(XP_OS2) #define MAX_PATH _MAX_PATH #endif #ifdef XP_UNIX #if defined(HPUX) || defined(SCO) /* ** HPUX: PATH_MAX is defined in to be 1023, but they ** recommend that it not be used, and that pathconf() be ** used to determine the maximum at runtime. ** SCO: This is what MAXPATHLEN is set to in and ** NL_MAXPATHLEN in . PATH_MAX is defined in ** to be 256, but the comments in that file ** claim the setting is wrong. */ #define MAX_PATH 1024 #else #define MAX_PATH PATH_MAX #endif #endif #endif extern int SU_INSTALL_ASK_FOR_DIRECTORY; PR_BEGIN_EXTERN_C /* Public Methods */ /* Constructor */ nsFolderSpec::nsFolderSpec(char* inFolderID , char* inVRPath, char* inPackageName) { char *errorMsg = NULL; urlPath = folderID = versionRegistryPath = userPackageName = NULL; /* Since urlPath is set to NULL, this FolderSpec is essentially the error message */ if ((inFolderID == NULL) || (inVRPath == NULL) || (inPackageName == NULL)) { return; } folderID = XP_STRDUP(inFolderID); versionRegistryPath = XP_STRDUP(inVRPath); userPackageName = XP_STRDUP(inPackageName); /* Setting the urlPath to a real file patch. */ *errorMsg = NULL; urlPath = SetDirectoryPath(&errorMsg); if (errorMsg != NULL) { urlPath = NULL; return; } } nsFolderSpec::~nsFolderSpec(void) { if (folderID) XP_FREE(folderID); if (versionRegistryPath) XP_FREE(versionRegistryPath); if (userPackageName) XP_FREE(userPackageName); if (urlPath) XP_FREE(urlPath); } /* * GetDirectoryPath * Returns urlPath * * Caller should not dispose of the return value */ char* nsFolderSpec::GetDirectoryPath(void) { return urlPath; } /* * SetDirectoryPath * sets full path to the directory in the standard URL form */ char* nsFolderSpec::SetDirectoryPath(char* *errorMsg) { if ((folderID == NULL) || (versionRegistryPath == NULL)) { *errorMsg = SU_GetErrorMsg3("Invalid arguments to the constructor", SUERR_INVALID_ARGUMENTS); return NULL; } if (urlPath == NULL) { if (XP_STRCMP(folderID, "User Pick") == 0) { // Default package folder // Try the version registry default path first // urlPath = VersionRegistry.getDefaultDirectory( versionRegistryPath ); // if (urlPath == NULL) urlPath = PickDefaultDirectory(errorMsg); } else if (XP_STRCMP(folderID, "Installed") == 0) { // Then use the Version Registry path urlPath = XP_STRDUP(versionRegistryPath); } else { // Built-in folder /* NativeGetDirectoryPath updates urlPath */ int err = NativeGetDirectoryPath(); if (err != 0) *errorMsg = SU_GetErrorMsg3(folderID, err); } } return urlPath; } /** * Returns full path to a file. Makes sure that the full path is bellow * this directory (security measure) * * Caller should free the returned string * * @param relativePath relative path * @return full path to a file */ char* nsFolderSpec::MakeFullPath(char* relativePath, char* *errorMsg) { // Security check. Make sure that we do not have '.. in the name // if ( (GetSecurityTargetID() == SoftwareUpdate.LIMITED_INSTALL) && // ( relativePath.regionMatches(0, "..", 0, 2))) // throw new SoftUpdateException(Strings.error_IllegalPath(), SoftwareUpdate.ILLEGAL_RELATIVE_PATH ); char *fullPath=NULL; char *dir_path; *errorMsg = NULL; dir_path = GetDirectoryPath(); if (dir_path == NULL) { return NULL; } fullPath = XP_Cat(dir_path, GetNativePath(relativePath)); return fullPath; } /* * The caller is supposed to free the memory. */ char* nsFolderSpec::toString() { char* path = GetDirectoryPath(); char* copyPath = NULL; if (path != NULL) { copyPath = XP_STRDUP(path); } return copyPath; } /* Private Methods */ /* PickDefaultDirectory * asks the user for the default directory for the package * stores the choice */ char* nsFolderSpec::PickDefaultDirectory(char* *errorMsg) { urlPath = NativePickDefaultDirectory(); if (urlPath == NULL) *errorMsg = SU_GetErrorMsg3(folderID, SUERR_INVALID_PATH_ERR); return urlPath; } /* Private Native Methods */ /* NativeGetDirectoryPath * gets a platform-specific directory path * stores it in urlPath */ int nsFolderSpec::NativeGetDirectoryPath() { su_DirSpecID folderDirSpecID; char* folderPath = NULL; /* Get the name of the package to prompt for */ folderDirSpecID = MapNameToEnum(folderID); switch (folderDirSpecID) { case eBadFolder: return SUERR_INVALID_PATH_ERR; case eCurrentUserFolder: { char dir[MAX_PATH]; int len = MAX_PATH; if ( PREF_GetCharPref("profile.directory", dir, &len) == PREF_NOERROR) { char * platformDir = WH_FileName(dir, xpURL); if (platformDir) folderPath = AppendSlashToDirPath(platformDir); XP_FREEIF(platformDir); } } break; default: /* Get the FE path */ folderPath = FE_GetDirectoryPath(folderDirSpecID); break; } /* Store it in the object */ if (folderPath != NULL) { urlPath = NULL; urlPath = XP_STRDUP(folderPath); XP_FREE(folderPath); return 0; } return SUERR_INVALID_PATH_ERR; } /* GetNativePath * returns a native equivalent of a XP directory path */ char* nsFolderSpec::GetNativePath(char* path) { char *xpPath, *p; char pathSeparator; #define XP_PATH_SEPARATOR '/' #ifdef XP_WIN pathSeparator = '\\'; #elif defined(XP_MAC) pathSeparator = ':'; #else /* XP_UNIX */ pathSeparator = '/'; #endif p = xpPath = path; /* * Traverse XP path and replace XP_PATH_SEPARATOR with * the platform native equivalent */ if ( p == NULL ) { xpPath = ""; } else { while ( *p ) { if ( *p == XP_PATH_SEPARATOR ) *p = pathSeparator; ++p; } } return xpPath; } /* * NativePickDefaultDirectory * Platform-specific implementation of GetDirectoryPath */ char* nsFolderSpec::NativePickDefaultDirectory(void) { su_PickDirTimer callback; char * packageName; char prompt[200]; callback.context = XP_FindSomeContext(); callback.fileName = NULL; callback.done = FALSE; /* Get the name of the package to prompt for */ packageName = userPackageName; if (packageName) { /* In Java thread now, and need to call FE_PromptForFileName * from the main thread * post an event on a timer, and busy-wait until it completes. */ PR_snprintf(prompt, 200, XP_GetString(SU_INSTALL_ASK_FOR_DIRECTORY), packageName); callback.prompt = prompt; FE_SetTimeout( pickDirectoryCallback, &callback, 1 ); while (!callback.done) /* Busy loop for now */ PR_Sleep(PR_INTERVAL_NO_WAIT); /* java_lang_Thread_yield(WHAT?); */ } return callback.fileName; } PRBool nsFolderSpec::NativeIsJavaDir() { char* folderName; /* Get the name of the package to prompt for */ folderName = folderID; PR_ASSERT( folderName ); if ( folderName != NULL) { int i; for (i=0; DirectoryTable[i].directoryName[0] != 0; i++ ) { if ( XP_STRCMP(folderName, DirectoryTable[i].directoryName) == 0 ) return DirectoryTable[i].bJavaDir; } } return PR_FALSE; } PR_END_EXTERN_C