char * xp_TempName (XP_FileType type, const char * prefix, char* buf, char* buf2, unsigned int *count) { #define NS_BUFFER_SIZE 1024 char *value = buf; time_t now; *buf = 0; XP_ASSERT (type != xpTemporaryNewsRC); if (type == xpCache || type == xpSARCache) { /* WH_TempName() must return relative pathnames for the cache files, so that relative paths get written into the cacheFAT database, making the directory relocatable. */ *buf = 0; } else if ( (type == xpURL) && prefix ) { if ( XP_STRRCHR(prefix, '/') ) { XP_StatStruct st; XP_SPRINTF (buf, "%.500s", prefix); if (XP_Stat (buf, &st, xpURL)) XP_MakeDirectoryR (buf, xpURL); prefix = "su"; } } else { char *tmp = FE_TempDir; if (!tmp || !*tmp) tmp = "/tmp"; XP_SPRINTF (buf, "%.500s", tmp); if (!prefix || !*prefix) prefix = "tmp"; } XP_ASSERT (!XP_STRCHR (prefix, '/')); if (*buf && buf[XP_STRLEN (buf)-1] != '/') XP_STRCAT (buf, "/"); /* It's good to have the cache file names be pretty long, with a bunch of inputs; this makes the variant part be 15 chars long, consisting of the current time (in seconds) followed by a counter (to differentiate documents opened in the same second) followed by the current pid (to differentiate simultanious processes.) This organization of the bits has the effect that they are ordered the same lexicographically as by creation time. If name length was an issue we could cut the character count a lot by printing them in base 72 [A-Za-z0-9@%-_=+.,~:]. */ now = time ((time_t *) 0); sprintf (buf2, "%08X%03X%04X", (unsigned int) now, (unsigned int) *count, (unsigned int) (getpid () & 0xFFFF)); if (++(*count) > 4095) (*count) = 0; /* keep it 3 hex digits */ #ifdef CACHE_SUBDIRS if (type == xpCache || type == xpSARCache) { XP_StatStruct st; char *s; char *tmp = (type == xpCache) ? FE_CacheDir : FE_SARCacheDir; if (!tmp || !*tmp) tmp = "/tmp"; sprintf (buf, "%.500s", tmp); if (buf [XP_STRLEN(buf)-1] != '/') XP_STRCAT (buf, "/"); s = buf + XP_STRLEN (buf); value = s; /* return a relative path! */ /* The name of the subdirectory is the bottom 5 bits of the time part, in hex (giving a total of 32 directories.) */ sprintf (s, "%02X", (now & 0x1F)); if (XP_Stat (buf, &st, xpURL)) /* create the dir if necessary */ XP_MakeDirectory (buf, type); s[2] = '/'; s[3] = 0; } #endif /* !CACHE_SUBDIRS */ XP_STRNCAT (value, prefix, NS_BUFFER_SIZE - XP_STRLEN(value)); XP_STRNCAT (value, buf2, NS_BUFFER_SIZE - XP_STRLEN(value)); /* Tao */ if (type == xpAddrBook) { XP_STRNCAT (value, ".nab", NS_BUFFER_SIZE - XP_STRLEN(value)); }/* if */ value[NS_BUFFER_SIZE - 1] = '\0'; /* just in case */ DO_TRACE(("WH_TempName called: returning: %s", value)); return(value); }
/* NativeComplete * copies the file to its final location * Tricky, we need to create the directories */ int nsInstallFile::NativeComplete() { char* currentName = NULL; char* finalName = NULL; char* finalNamePlatform; int result = 0; if (tempFile == NULL) { return -1; } /* Get the names */ currentName = tempFile->ToNewCString(); PR_ASSERT(finalFile != NULL); finalNamePlatform = finalFile->ToNewCString(); finalName = XP_PlatformFileToURL(finalNamePlatform); if ( finalName == NULL || currentName == NULL ) { /* memory or JRI problems */ result = -1; goto end; } else { /* convert finalName name to xpURL form by stripping "file://" */ char *temp = XP_STRDUP(&finalName[7]); XP_FREE(finalName); finalName = temp; } if (finalName != NULL) { if ( XP_STRCMP(finalName, currentName) == 0 ) { /* No need to rename, they are the same */ result = 0; } else { XP_StatStruct s; if ( XP_Stat( finalName, &s, xpURL ) != 0 ) { /* Target file doesn't exist, try to rename file */ result = XP_FileRename(currentName, xpURL, finalName, xpURL); } else { /* Target exists, can't trust XP_FileRename--do platform * specific stuff in FE_ReplaceExistingFile() */ result = -1; } } } else { /* memory problem */ result = -1; } if (result != 0) { XP_StatStruct s; if ( XP_Stat( finalName, &s, xpURL ) == 0 ) { /* File already exists, need to remove the original */ result = FE_ReplaceExistingFile(currentName, xpURL, finalName, xpURL, force); if ( result == SU_REBOOT_NEEDED ) { #ifdef XP_WIN16 if (!utilityScheduled) { utilityScheduled = PR_TRUE; FE_ScheduleRenameUtility(); } #endif } } else { /* Directory might not exist, check and create if necessary */ char separator; char * end; separator = '/'; end = XP_STRRCHR(finalName, separator); if (end) { end[0] = 0; result = XP_MakeDirectoryR( finalName, xpURL); end[0] = separator; if ( 0 == result ) result = XP_FileRename(currentName, xpURL, finalName, xpURL); } } #ifdef XP_UNIX /* Last try, can't rename() across file systems on UNIX */ if ( -1 == result ) { result = FE_CopyFile(currentName, finalName); } #endif } end: XP_FREEIF(finalName); delete currentName; delete finalNamePlatform; return result; }