コード例 #1
0
/*
 * Make all the directories specified in the path
 */
int XP_MakeDirectoryR(const char* name, XP_FileType type)
{
    char separator;
    int result = 0;
    char * finalName;

#if defined(XP_WIN) || defined(XP_OS2)
    separator = '\\';
#elif defined XP_UNIX
    separator = '/';
#endif
    finalName = WH_FileName(name, type);
    if ( finalName )
    {
        char * dirPath;
        char * currentEnd;
        int err = 0;
        XP_StatStruct s;
        dirPath = XP_STRDUP( finalName );
        if (dirPath == NULL)
            return -1;

        currentEnd = XP_STRCHR(dirPath, separator);
        /* Loop through every part of the directory path */
        while (currentEnd != 0)
        {
            char savedChar;
            savedChar = currentEnd[1];
            currentEnd[1] = 0;
            if ( XP_Stat(dirPath, &s, xpURL ) != 0)
                err = XP_MakeDirectory(dirPath, xpURL);
            if ( err != 0)
            {
                XP_ASSERT( FALSE );	/* Could not create the directory? */
                break;
            }
            currentEnd[1] = savedChar;
            currentEnd = XP_STRCHR( &currentEnd[1], separator);
        }
        if ( err == 0 )
            /* If the path is not terminated with / */
        {
            if ( dirPath[XP_STRLEN( dirPath) - 1] != separator )
                if ( XP_Stat(dirPath, &s, xpURL ) != 0)
                    err = XP_MakeDirectory(dirPath, xpURL);
        }
        if ( 0 != err )
            result = err;
        if ( dirPath )
            XP_FREE( dirPath );
    }
    else
        result = -1;
    if ( finalName )
        XP_FREE( finalName );
    XP_ASSERT( result == 0 );	/* For debugging only */
    return result;
}
コード例 #2
0
/* Finds out if the file exists
 */
PRBool nsInstallFile::NativeDoesFileExist()
{
    char* fileName;
    char* fileNamePlatform;
    int32 err;
    XP_StatStruct statinfo;
    XP_Bool exists = FALSE;

    PR_ASSERT(finalFile != NULL);
    fileNamePlatform = finalFile->ToNewCString();
    fileName = XP_PlatformFileToURL(fileNamePlatform);
    if (fileName != NULL) {
        char * temp = XP_STRDUP(&fileName[7]);
        XP_FREEIF(fileName);
        fileName = temp;

        if (fileName) {
            err = XP_Stat(fileName, &statinfo, xpURL);
            if (err != -1) {
                exists = PR_TRUE;
            }
        }
    }
    XP_FREEIF(fileName);
    delete fileNamePlatform;
    return exists;

}
コード例 #3
0
/*
** This function deletes a directory and everything under it.
** Deleting directories with "non-file" files, such as links,
** will produce behavior of XP_RemoveFile, since that's what is
** ultimately called.
**
** Return values: zero on failure, non-zero for success.
*/
int XP_RemoveDirectoryRecursive(const char *name, XP_FileType type)
{
    XP_DirEntryStruct *entry;
    XP_StatStruct     statbuf;
    int 	 	  status;
    char*		child;
    char* 		dot    = ".";
    char* 		dotdot = "..";
    int			ret = 1;

    XP_Dir dir = XP_OpenDir(name, type);
    if (!dir) return 0;

    /*
    ** Go through the directory entries and delete appropriately
    */
    while ((entry = XP_ReadDir(dir)))
    {
        /*
        ** Allocate space for current name + path separator + directory name  + NULL
        */
        child = XP_ALLOC( strlen(name) + 2 + strlen(entry->d_name) );

        XP_STRCAT(child,"/");
        XP_STRCAT(child,entry->d_name);

        if (!(status = XP_Stat(child, &statbuf, type)))
        {
            if (entry->d_name == dot || entry->d_name == dotdot)
            {
                /* Do nothing, rmdir will clean these up */
            }
            else if (S_ISDIR(statbuf.st_mode))
            {
                /* Recursive call to clean out subdirectory */
                if (!XP_RemoveDirectoryRecursive(child, type))
                    ret = 0;
            }
            else
            {
                /* Everything that's not a directory is a file! */
                if (XP_FileRemove(child, type) != 0)
                    ret = 0;
            }
        }

        XP_FREE(child);
    }

    /* OK, remove the top-level directory if we can */
    if (XP_RemoveDirectory(name, type) != 0)
        ret = 0;

    XP_CloseDir(dir);

    return ret;
}
コード例 #4
0
XP_File XP_FileOpen( const char* name, XP_FileType type,
                     const XP_FilePerm permissions )
{
    char* newName = WH_FileName(name, type);
    XP_File result;
#ifdef XP_UNIX
    XP_StatStruct st;
    XP_Bool make_private_p = FALSE;
#endif

    /* One should never open newsrc for output directly. */
    XP_ASSERT (type != xpNewsRC || type != xpSNewsRC ||
               !strchr (permissions, 'w'));

    if (newName == NULL)
        return NULL;

#ifdef XP_UNIX
    switch (type)
    {
    /* These files are always private: if the user chmods them, we
     make them -rw------ again the next time we use them, because
     it's really important.
     */
    case xpHTTPCookie:
    case xpKeyChain:
    case xpSignedAppletDB:
    case xpSARCache:
    case xpSARCacheIndex:
    case xpCertDB:
    case xpCertDBNameIDX:
    case xpKeyDB:
    case xpSecModuleDB:
    /* Always make tmp files private, because of their short lifetime. */
    case xpTemporary:
    case xpTemporaryNewsRC:
    case xpFileToPost:
    case xpPKCS12File:
        if (strchr (permissions, 'w'))     /* opening for output */
            make_private_p = TRUE;
        break;

    /* These files are created private, but if the user then goes and
     chmods them, we let their changes stick, because it's reasonable
     for a user to decide to give away read permission on these
     (though by default, it makes sense for them to be more private
     than the user's other files.)
     */
    case xpCacheFAT:
    case xpCache:
    case xpRegistry:
    case xpGlobalHistory:
    case xpHotlist:
    case xpBookmarks:
    case xpMailFolder:
        if (strchr (permissions, 'w') &&   /* opening for output */
                XP_Stat (newName, &st, type))  /* and it doesn't exist yet */
            make_private_p = TRUE;
        break;


    case xpProxyConfig:
    case xpSocksConfig:
    case xpNewsRC:
    case xpSNewsRC:
    case xpNewsgroups:
    case xpSNewsgroups:
    case xpURL:
    case xpMimeTypes:
    case xpSignature:
    case xpMailFolderSummary:
    case xpFolderCache:
    case xpJSMailFilters:
    case xpJSHTMLFilters:
    case xpMailSort:
    case xpNewsSort:
    case xpMailPopState:
    case xpMailFilterLog:
    case xpNewsFilterLog:
    case xpExtCache:
    case xpExtCacheIndex:
    case xpXoverCache:
    case xpMailSubdirectory:

    case xpVCardFile:
    case xpLDIFFile:
    case xpAddrBook:
    case xpAddrBookNew:
    case xpJSCookieFilters:
        /* These files need not be more private than any other, so we
         always create them with the default umask. */
        break;
    default:
        XP_ASSERT(0);
    }
#endif /* XP_UNIX */

#ifndef MCC_PROXY
    /* At this point, we'd better have an absolute path, because passing a
     relative path to fopen() is undefined.  (For the client, at least -
     I gather the proxy is different?) */
#endif/* !MCC_PROXY */

    result = fopen(newName, permissions);

#ifdef XP_MAC
    if (result != 0)
    {
        int err;

        err = setvbuf(	result, 		/* file to buffer */
                        NULL,			/* allocate the buffer for us */
                        _IOFBF, 		/* fully buffer */
                        8 * 1024);		/* 8k buffer */

        XP_ASSERT(err == 0);
    }
#endif

#ifdef XP_UNIX
    if (make_private_p && result)
#ifdef SCO_SV
        chmod (newName, S_IRUSR | S_IWUSR); /* rw only by owner */
#else
        fchmod (fileno (result), S_IRUSR | S_IWUSR); /* rw only by owner */
#endif
#endif /* XP_UNIX */

    XP_FREE(newName);
    return result;
}
コード例 #5
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);
}
コード例 #6
0
/* 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;
}