Exemple #1
0
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;
}