The changes apply to MODULAR_NETLIB only
mozilla/module/nsINetFile.h MODULAR_NETLIB only. Added the nsINetFile interface header. mozilla/module/nsNetFile.cpp MODULAR_NETLIB only. Added the nsINetFile interface implementation. mozilla/module/nsNetFile.h MODULAR_NETLIB only. Added the nsNetFile header. mozilla/main/mkgeturl.c MODULAR_NETLIB only. Added directory and file token initialization for new ns_net_file code. mozilla/main/net_xp_file.h MODULAR_NETLIB only. Added the new readline routine for ns_net_file. mozilla/module/makefile.win MODULAR_NETLIB only. Added the nsNetFile.cpp file to compilation list. mozilla/module/nsNetService.cpp MODULAR_NETLIB only. Added the static nsNetFile instance so it gets initailized. mozilla/module/nsNetStubs.cpp MODULAR_NETLIB only. Added NET_I_XP_FILE* versions of XP_FILE routines. These routines are compiled and used when NS_NET_FILE is defined.
This commit is contained in:
Родитель
0d56ed3c3c
Коммит
9bc115a2f8
|
@ -698,12 +698,23 @@ MODULE_PRIVATE int PR_CALLBACK NET_PrefChangedFunc(const char *pref, void *data)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
#ifdef NS_NET_FILE
|
||||
extern PRBool NET_InitFilesAndDirs(void);
|
||||
#endif
|
||||
/* finish the init of 'netlib'. inits cookies, cache, history
|
||||
*
|
||||
*/
|
||||
PUBLIC void
|
||||
NET_FinishInitNetLib()
|
||||
{
|
||||
#ifdef NS_NET_FILE
|
||||
// Initialize all the directories and files that netlib needs.
|
||||
if (!NET_InitFilesAndDirs())
|
||||
; // do something.
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef MOZILLA_CLIENT
|
||||
NET_CacheInit();
|
||||
NET_ReadCookies("");
|
||||
|
|
|
@ -51,7 +51,8 @@ extern XP_File NET_I_XP_FileOpen(const char *name, XP_FileType type, const XP_Fi
|
|||
extern int NET_I_XP_FileRead(char *outBuf, int outBufLen, XP_File fp);
|
||||
#define NET_XP_FileRead(dest, count, file) NET_I_XP_FileRead(dest, count, file)
|
||||
|
||||
#define NET_XP_FileReadLine(destBuf, bufSize, file) XP_FileReadLine(destBuf, bufSize, file)
|
||||
extern char *NET_I_XP_FileReadLine(char *outBuf, int outBufLen, XP_File fp);
|
||||
#define NET_XP_FileReadLine(destBuf, bufSize, file) NET_I_XP_FileReadLine(destBuf, bufSize, file)
|
||||
|
||||
extern int NET_I_XP_FileWrite(char *buf, int bufLen, XP_File fp);
|
||||
#define NET_XP_FileWrite(source, count, file) NET_I_XP_FileWrite(source, count, file)
|
||||
|
|
|
@ -31,7 +31,8 @@ EXPORTS = nsIStreamListener.h \
|
|||
nsIRelatedLinks.h \
|
||||
nsINetContainerApplication.h \
|
||||
nsIRefreshUrl.h \
|
||||
nsIConnectionInfo.h \
|
||||
nsIConnectionInfo.h \
|
||||
nsINetFile.h \
|
||||
$(NULL)
|
||||
|
||||
DIRS = tests
|
||||
|
@ -67,7 +68,8 @@ OBJS= \
|
|||
.\$(OBJDIR)\nsHttpUrl.obj \
|
||||
.\$(OBJDIR)\nsStubContext.obj \
|
||||
.\$(OBJDIR)\nsNetStubs.obj \
|
||||
.\$(OBJDIR)\nsNetIDs.obj \
|
||||
.\$(OBJDIR)\nsNetIDs.obj \
|
||||
.\$(OBJDIR)\nsNetFile.obj \
|
||||
$(NULL)
|
||||
|
||||
#//------------------------------------------------------------------------
|
||||
|
|
|
@ -0,0 +1,148 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
#ifndef __nsINetFile_h
|
||||
#define __nsINetFile_h
|
||||
#include "nsISupports.h"
|
||||
#include "nsString.h"
|
||||
#include "prio.h"
|
||||
|
||||
// These defines are for temporary use until we get a real dir manager.
|
||||
#define USER_DIR_TOK "%USER%"
|
||||
#define USER_DIR "e:\\projects\\ng"
|
||||
#define CACHE_DIR_TOK "%CACHE_D%"
|
||||
#define CACHE_DIR "e:\\projects\\ng\\cache"
|
||||
#define COOKIE_FILE_TOK "%COOKIE_F%"
|
||||
|
||||
#define CACHE_DB_F_TOK "%CACHE_DB_F%"
|
||||
#define CACHE_DB_FILE "fat.db"
|
||||
|
||||
#ifdef XP_PC
|
||||
#define COOKIE_FILE "cookies.txt"
|
||||
#else
|
||||
#define COOKIE_FILE "cookies"
|
||||
#endif
|
||||
|
||||
#define DEF_DIR_TOK "%DEF_D%"
|
||||
#define DEF_DIR "e:\\projects\\ng"
|
||||
|
||||
|
||||
// {9E04ADC2-2B1D-11d2-B6EB-00805F8A2676}
|
||||
#define NS_INETFILE_IID \
|
||||
{ 0x9e04adc2, 0x2b1d, 0x11d2, \
|
||||
{0xb6, 0xeb, 0x00, 0x80, 0x5f, 0x8a, 0x26, 0x76} }
|
||||
|
||||
// Represents a file for use with nsINetFile routines.
|
||||
typedef struct _nsFile {
|
||||
PRFileDesc *fd;
|
||||
} nsFile;
|
||||
|
||||
// Represents a directory for use with nsINetFile routines.
|
||||
typedef struct _nsDir {
|
||||
PRDir *dir;
|
||||
} nsDir;
|
||||
|
||||
// Open flags. Used with nsINetFile::OpenFile.
|
||||
typedef enum {
|
||||
nsRead = 1,
|
||||
nsWrite = 2,
|
||||
nsReadWrite = 3,
|
||||
nsReadBinary = 5,
|
||||
nsWriteBinary = 6,
|
||||
nsReadWriteBinary = 7,
|
||||
nsOverWrite = 8
|
||||
} nsFileMode;
|
||||
|
||||
class nsINetFile: public nsISupports {
|
||||
public:
|
||||
/*
|
||||
* File methods
|
||||
*/
|
||||
|
||||
// Convert a generic file names into a platform file path
|
||||
// Currently generic file location information is prepended to the
|
||||
// begining of aName. For example, if I wanted to open the cookie file,
|
||||
// I'd pass in "%USER%\cookies.txt . aName is platform specific.
|
||||
NS_IMETHOD GetFilePath(const char *aName, char **aRes) = 0;
|
||||
NS_IMETHOD GetTemporaryFilePath(const char *aName, char **aRes) = 0;
|
||||
NS_IMETHOD GetUniqueFilePath(const char *aName, char **aRes) = 0;
|
||||
NS_IMETHOD GetCacheFileName(char *aDirTok, char **aRes) = 0;
|
||||
|
||||
// Open a file
|
||||
NS_IMETHOD OpenFile(const char *aPath, nsFileMode aMode,
|
||||
nsFile** aRes) = 0;
|
||||
|
||||
// Close a file
|
||||
NS_IMETHOD CloseFile(nsFile* aFile) = 0;
|
||||
|
||||
// Read a file
|
||||
NS_IMETHOD FileRead(nsFile *aFile, char **aBuf,
|
||||
PRInt32 *aBuflen,
|
||||
PRInt32 *aBytesRead) = 0;
|
||||
|
||||
NS_IMETHOD FileReadLine(nsFile *aFile, char **aBuf,
|
||||
PRInt32 *aBuflen,
|
||||
PRInt32 *aBytesRead) = 0;
|
||||
|
||||
// Write a file
|
||||
NS_IMETHOD FileWrite(nsFile *aFile, const char *aBuf,
|
||||
PRInt32 *aLen,
|
||||
PRInt32 *aBytesWritten) = 0;
|
||||
|
||||
// Sync a file with disk
|
||||
NS_IMETHOD FileSync(nsFile *aFile) = 0;
|
||||
|
||||
// Remove a file
|
||||
NS_IMETHOD FileRemove(const char *aPath) = 0;
|
||||
|
||||
// Rename a file
|
||||
NS_IMETHOD FileRename(const char *aPathOld, const char *aPathNew) = 0;
|
||||
|
||||
/*
|
||||
* Directory Methods
|
||||
*/
|
||||
|
||||
// Open a directory
|
||||
NS_IMETHOD OpenDir(const char *aPath, nsDir** aRes) = 0;
|
||||
|
||||
// Close a directory
|
||||
NS_IMETHOD CloseDir(nsDir *aDir) = 0;
|
||||
|
||||
// Create a directory
|
||||
NS_IMETHOD CreateDir(const char *aPath, PRBool aRecurse) = 0;
|
||||
|
||||
// Assocaite a token with a directory.
|
||||
NS_IMETHOD SetDirectory(const char *aToken, const char *aDir) = 0;
|
||||
|
||||
// Associate a filename with a token, and optionally a dir token.
|
||||
NS_IMETHOD SetFileAssoc(const char *aToken, const char *aFile, const char *aDirToken) = 0;
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Create an instance of the INetFile
|
||||
*
|
||||
*/
|
||||
extern "C" NS_NET nsresult NS_NewINetFile(nsINetFile** aInstancePtrResult,
|
||||
nsISupports* aOuter);
|
||||
|
||||
|
||||
extern "C" NS_NET nsresult NS_InitINetFile(void);
|
||||
|
||||
extern "C" NS_NET nsresult NS_ShutdownINetFile();
|
||||
|
||||
#endif __nsINetFile_h
|
|
@ -0,0 +1,907 @@
|
|||
#include "nsNetFile.h"
|
||||
#include "prmem.h"
|
||||
#include "nsString.h"
|
||||
#include "plstr.h"
|
||||
#include "prerror.h"
|
||||
#include "direct.h"
|
||||
#include <time.h>
|
||||
|
||||
static NS_DEFINE_IID(kINetFileIID, NS_INETFILE_IID);
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsNetFile, kINetFileIID);
|
||||
|
||||
typedef struct _nsFileAssoc {
|
||||
nsString name;
|
||||
nsString dirTok;
|
||||
} nsFileAssoc;
|
||||
|
||||
// Comparison routine for the fileAssoc objects.
|
||||
PR_IMPLEMENT(int)
|
||||
PL_CompareFileAssoc(const void *v1, const void *v2)
|
||||
{
|
||||
nsFileAssoc *a = (nsFileAssoc*)v1;
|
||||
nsFileAssoc *b = (nsFileAssoc*)v2;
|
||||
|
||||
return *a->name == *b->name;
|
||||
}
|
||||
|
||||
nsNetFile::nsNetFile() {
|
||||
|
||||
#ifdef XP_PC
|
||||
mDirDel = '\\';
|
||||
#elif XP_MAC
|
||||
mDirDel = ':';
|
||||
#else
|
||||
mDirDel = '/';
|
||||
#endif
|
||||
|
||||
mTokDel = '%';
|
||||
|
||||
mHTDirs = PL_NewHashTable(5, PL_HashString, PL_CompareStrings,
|
||||
PL_CompareStrings, nsnull, nsnull);
|
||||
|
||||
mHTFiles = PL_NewHashTable(10, PL_HashString, PL_CompareStrings,
|
||||
PL_CompareFileAssoc, nsnull, nsnull);
|
||||
}
|
||||
|
||||
PR_CALLBACK PRIntn
|
||||
NS_RemoveStringEntries(PLHashEntry* he, PRIntn i, void* arg)
|
||||
{
|
||||
char *entry = (char*)he->value;
|
||||
|
||||
NS_ASSERTION(entry != nsnull, "null entry");
|
||||
delete entry;
|
||||
return HT_ENUMERATE_REMOVE;
|
||||
}
|
||||
|
||||
nsNetFile::~nsNetFile() {
|
||||
// Clear the hash table.
|
||||
PL_HashTableEnumerateEntries(mHTDirs, NS_RemoveStringEntries, 0);
|
||||
PL_HashTableDestroy(mHTDirs);
|
||||
|
||||
PL_HashTableEnumerateEntries(mHTFiles, NS_RemoveStringEntries, 0);
|
||||
PL_HashTableDestroy(mHTFiles);
|
||||
}
|
||||
|
||||
nsresult nsNetFile::GetFilePath(const char *aName, char **aRes) {
|
||||
nsString newPath, fileName;
|
||||
char *path = nsnull, *locName = nsnull;
|
||||
char *tokBegin, *dirTok, *fileTok, *nextTok;
|
||||
nsFileAssoc *faFile = nsnull;
|
||||
|
||||
|
||||
NS_PRECONDITION( (aName != nsnull), "Null pointer.");
|
||||
|
||||
locName = URLSyntaxToLocal(aName);
|
||||
if (!locName)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
// If we were handed an absolute path, spit it back.
|
||||
if ( (*locName == mDirDel) // mac and unix
|
||||
||
|
||||
(*locName && (*(locName + 1) == ':') ) ) // pc
|
||||
{
|
||||
newPath = locName;
|
||||
PR_Free(locName);
|
||||
locName = nsnull;
|
||||
path = newPath.ToNewCString();
|
||||
if (!path)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
*aRes = path;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// First see if this has been explicitly registered
|
||||
faFile = (nsFileAssoc*)PL_HashTableLookup(mHTFiles, locName);
|
||||
if (faFile) {
|
||||
char *dir = nsnull;
|
||||
if (faFile->dirTok.Length()) {
|
||||
char *csDT = faFile->dirTok.ToNewCString();
|
||||
if (!csDT) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
dir = (char*)PL_HashTableLookup(mHTDirs, csDT);
|
||||
PR_Free(csDT);
|
||||
}
|
||||
// If it wasn't in the table give the file a default dir.
|
||||
if (!dir) {
|
||||
dir = (char*)PL_HashTableLookup(mHTDirs, DEF_DIR_TOK);
|
||||
NS_PRECONDITION( (dir != nsnull), "No default dir registered.");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
newPath = dir;
|
||||
if (dir[PL_strlen(path)-1] != mDirDel) {
|
||||
newPath.Append(mDirDel);
|
||||
}
|
||||
newPath.Append(faFile->name);
|
||||
*aRes = newPath.ToNewCString();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// If we've gotten this far, this file wasn't registered, or the user wants
|
||||
// to use a different directory with the file.
|
||||
|
||||
// Lookup the token(s) in our hash table(s).
|
||||
dirTok = nsnull;
|
||||
fileTok = nsnull;
|
||||
|
||||
tokBegin = PL_strchr(locName, mTokDel);
|
||||
if (tokBegin) {
|
||||
nextTok = PL_strchr(tokBegin+1, mTokDel);
|
||||
if (nextTok) {
|
||||
// Check for more (could be another token or a filename).
|
||||
if (*(nextTok+1)) {
|
||||
// Set the first one as the dir.
|
||||
char tmp = *(nextTok+1);
|
||||
*(nextTok+1) = '\0';
|
||||
dirTok = PL_strdup(tokBegin);
|
||||
*(nextTok+1) = tmp;
|
||||
tokBegin = nextTok+1;
|
||||
nextTok = PL_strchr(tokBegin+1, mTokDel);
|
||||
}
|
||||
if (nextTok) {
|
||||
*(nextTok+1) = '\0';
|
||||
fileTok = PL_strdup(tokBegin);
|
||||
*(nextTok+1) = mTokDel;
|
||||
} else {
|
||||
// no file token
|
||||
fileTok = PL_strdup(tokBegin);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If the user passed in a dir token, use it.
|
||||
if (dirTok) {
|
||||
char *path = (char*)PL_HashTableLookup(mHTDirs, dirTok);
|
||||
PR_Free(dirTok);
|
||||
// If it wasn't in the table, fail.
|
||||
if (!path) {
|
||||
PR_Free(fileTok);
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
newPath = path;
|
||||
if (path[PL_strlen(path)-1] != mDirDel) {
|
||||
newPath.Append(mDirDel);
|
||||
}
|
||||
}
|
||||
|
||||
faFile = (nsFileAssoc*)PL_HashTableLookup(mHTFiles, fileTok);
|
||||
if (faFile)
|
||||
fileName = faFile->name;
|
||||
else
|
||||
fileName = fileTok; // It wasn't a token after all;
|
||||
|
||||
newPath.Append(fileName);
|
||||
PR_Free(fileTok);
|
||||
*aRes = newPath.ToNewCString();
|
||||
PR_FREEIF(locName);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsNetFile::GetTemporaryFilePath(const char *aName, char **aRes) {
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsNetFile::GetUniqueFilePath(const char *aName, char **aRes) {
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void nsNetFile::GenerateGlobalRandomBytes(void *aDest, size_t aLen) {
|
||||
/* This is a temporary implementation to avoid */
|
||||
/* the cache filename horkage. This needs to have a more */
|
||||
/* secure/free implementation here - Gagan */
|
||||
|
||||
char* output=(char*)aDest;
|
||||
size_t i;
|
||||
srand((unsigned int) PR_IntervalToMilliseconds(PR_IntervalNow()));
|
||||
for (i=0;i<aLen; i++)
|
||||
{
|
||||
int t = rand();
|
||||
*output = (char) (t % 256);
|
||||
output++;
|
||||
}
|
||||
}
|
||||
|
||||
#define MAX_PATH_LEN 512
|
||||
|
||||
nsresult nsNetFile::GetCacheFileName(char *aDirTok, char **aRes) {
|
||||
char file_buf[MAX_PATH_LEN];
|
||||
char *ext = ".MOZ";
|
||||
char *prefix = "M";
|
||||
PRStatus status;
|
||||
PRFileInfo statinfo;
|
||||
char *dir = (char*)PL_HashTableLookup(mHTDirs, aDirTok);
|
||||
if (!dir)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
|
||||
// We need to base our temporary file names on time, and not on sequential
|
||||
// addition because of the cache not being updated when the user
|
||||
// crashes and files that have been deleted are over written with
|
||||
// other files; bad data.
|
||||
// The 52 valid DOS file name characters are
|
||||
// 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_^$~!#%&-{}@`'()
|
||||
// We will only be using the first 32 of the choices.
|
||||
//
|
||||
// Time name format will be M+++++++.MOZ
|
||||
// Where M is the single letter prefix (can be longer....)
|
||||
// Where +++++++ is the 7 character time representation (a full 8.3
|
||||
// file name will be made).
|
||||
// Where .MOZ is the file extension to be used.
|
||||
//
|
||||
// In the event that the time requested is the same time as the last call
|
||||
// to this function, then the current time is incremented by one,
|
||||
// as is the last time called to facilitate unique file names.
|
||||
// In the event that the invented file name already exists (can't
|
||||
// really happen statistically unless the clock is messed up or we
|
||||
// manually incremented the time), then the times are incremented
|
||||
// until an open name can be found.
|
||||
//
|
||||
// time_t (the time) has 32 bits, or 4,294,967,296 combinations.
|
||||
// We will map the 32 bits into the 7 possible characters as follows:
|
||||
// Starting with the lsb, sets of 5 bits (32 values) will be mapped
|
||||
// over to the appropriate file name character, and then
|
||||
// incremented to an approprate file name character.
|
||||
// The left over 2 bits will be mapped into the seventh file name
|
||||
// character.
|
||||
//
|
||||
|
||||
int i_letter, i_timechars, i_numtries = 0;
|
||||
char ca_time[8];
|
||||
time_t this_call = (time_t)0;
|
||||
|
||||
// We have to base the length of our time string on the length
|
||||
// of the incoming prefix....
|
||||
//
|
||||
i_timechars = 8 - PL_strlen(prefix);
|
||||
|
||||
// Infinite loop until the conditions are satisfied.
|
||||
// There is no danger, unless every possible file name is used.
|
||||
//
|
||||
while(1) {
|
||||
// We used to use the time to generate this.
|
||||
// Now, we use some crypto to avoid bug #47027
|
||||
GenerateGlobalRandomBytes((void *)&this_call, sizeof(this_call));
|
||||
|
||||
// Convert the time into a 7 character string.
|
||||
// Strip only the signifigant 5 bits.
|
||||
// We'll want to reverse the string to make it look coherent
|
||||
// in a directory of file names.
|
||||
//
|
||||
for(i_letter = 0; i_letter < i_timechars; i_letter++) {
|
||||
ca_time[i_letter] = (char)((this_call >> (i_letter * 5)) & 0x1F);
|
||||
|
||||
// Convert any numbers to their equivalent ascii code
|
||||
//
|
||||
if(ca_time[i_letter] <= 9) {
|
||||
ca_time[i_letter] += '0';
|
||||
// Convert the character to it's equivalent ascii code
|
||||
//
|
||||
} else {
|
||||
ca_time[i_letter] += 'A' - 10;
|
||||
}
|
||||
}
|
||||
|
||||
// End the created time string.
|
||||
//
|
||||
ca_time[i_letter] = '\0';
|
||||
|
||||
// Reverse the time string.
|
||||
//
|
||||
_strrev(ca_time);
|
||||
|
||||
// Create the fully qualified path and file name.
|
||||
//
|
||||
sprintf(file_buf, "%s\\%s%s%s", dir, prefix, ca_time, ext);
|
||||
|
||||
// Determine if the file exists, and mark that we've tried yet
|
||||
// another file name (mark to be used later).
|
||||
//
|
||||
// Use the system call instead of XP_Stat since we already
|
||||
// know the name and we don't want recursion
|
||||
//
|
||||
status = PR_GetFileInfo(file_buf, &statinfo);
|
||||
i_numtries++;
|
||||
|
||||
// If it does not exists, we are successful, return the name.
|
||||
//
|
||||
if(status == PR_FAILURE) {
|
||||
/* don't generate a directory as part of the
|
||||
* cache temp names. When the cache file name
|
||||
* is passed into the other XP_File functions
|
||||
* we will append the cache directory to the name
|
||||
* to get the complete path.
|
||||
* This will allow the cache to be moved around
|
||||
* and for netscape to be used to generate external
|
||||
* cache FAT's. :lou
|
||||
*/
|
||||
sprintf(file_buf, "%s%s%s", prefix, ca_time, ext);
|
||||
|
||||
*aRes = file_buf;
|
||||
break;
|
||||
}
|
||||
} // End while
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
||||
// Here for reference.
|
||||
PUBLIC char *
|
||||
xp_TempFileName(int type, const char * request_prefix, const char * extension,
|
||||
char* file_buf)
|
||||
{
|
||||
const char * directory = NULL;
|
||||
char * ext = NULL; // file extension if any
|
||||
char * prefix = NULL; // file prefix if any
|
||||
XP_Bool bDirSlash = FALSE;
|
||||
|
||||
XP_StatStruct statinfo;
|
||||
int status;
|
||||
|
||||
//
|
||||
// based on the type of request determine what directory we should be
|
||||
// looking into
|
||||
//
|
||||
switch(type) {
|
||||
case xpCache:
|
||||
directory = theApp.m_pCacheDir;
|
||||
ext = ".MOZ";
|
||||
prefix = CACHE_PREFIX;
|
||||
break;
|
||||
#ifdef MOZ_MAIL_NEWS
|
||||
case xpSNewsRC:
|
||||
case xpNewsRC:
|
||||
case xpNewsgroups:
|
||||
case xpSNewsgroups:
|
||||
case xpTemporaryNewsRC:
|
||||
directory = g_MsgPrefs.m_csNewsDir;
|
||||
ext = (char *)extension;
|
||||
prefix = (char *)request_prefix;
|
||||
break;
|
||||
case xpMailFolderSummary:
|
||||
case xpMailFolder:
|
||||
directory = g_MsgPrefs.m_csMailDir;
|
||||
ext = (char *)extension;
|
||||
prefix = (char *)request_prefix;
|
||||
break;
|
||||
case xpAddrBook:
|
||||
//changed jonm-- to support multi-profile
|
||||
//directory = theApp.m_pInstallDir->GetCharValue();
|
||||
directory = (const char *)theApp.m_UserDirectory;
|
||||
if ((request_prefix == 0) || (XP_STRLEN (request_prefix) == 0))
|
||||
prefix = "abook";
|
||||
ext = ".nab";
|
||||
break;
|
||||
#endif // MOZ_MAIL_NEWS
|
||||
case xpCacheFAT:
|
||||
directory = theApp.m_pCacheDir;
|
||||
prefix = "fat";
|
||||
ext = "db";
|
||||
break;
|
||||
case xpJPEGFile:
|
||||
directory = theApp.m_pTempDir;
|
||||
ext = ".jpg";
|
||||
prefix = (char *)request_prefix;
|
||||
break;
|
||||
case xpPKCS12File:
|
||||
directory = theApp.m_pTempDir;
|
||||
ext = ".p12";
|
||||
prefix = (char *)request_prefix;
|
||||
break;
|
||||
case xpURL:
|
||||
{
|
||||
if (request_prefix)
|
||||
{
|
||||
if ( XP_STRRCHR(request_prefix, '/') )
|
||||
{
|
||||
const char *end;
|
||||
XP_StatStruct st;
|
||||
|
||||
directory = (char *)request_prefix;
|
||||
end = directory + XP_STRLEN(directory) - 1;
|
||||
if ( *end == '/' || *end == '\\' ) {
|
||||
bDirSlash = TRUE;
|
||||
}
|
||||
if (XP_Stat (directory, &st, xpURL))
|
||||
XP_MakeDirectoryR (directory, xpURL);
|
||||
ext = (char *)extension;
|
||||
prefix = (char *)"su";
|
||||
break;
|
||||
}
|
||||
}
|
||||
// otherwise, fall through
|
||||
}
|
||||
case xpTemporary:
|
||||
default:
|
||||
directory = theApp.m_pTempDir;
|
||||
ext = (char *)extension;
|
||||
prefix = (char *)request_prefix;
|
||||
break;
|
||||
}
|
||||
|
||||
if(!directory)
|
||||
return(NULL);
|
||||
|
||||
if(!prefix)
|
||||
prefix = "X";
|
||||
|
||||
if(!ext)
|
||||
ext = ".TMP";
|
||||
|
||||
// We need to base our temporary file names on time, and not on sequential
|
||||
// addition because of the cache not being updated when the user
|
||||
// crashes and files that have been deleted are over written with
|
||||
// other files; bad data.
|
||||
// The 52 valid DOS file name characters are
|
||||
// 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_^$~!#%&-{}@`'()
|
||||
// We will only be using the first 32 of the choices.
|
||||
//
|
||||
// Time name format will be M+++++++.MOZ
|
||||
// Where M is the single letter prefix (can be longer....)
|
||||
// Where +++++++ is the 7 character time representation (a full 8.3
|
||||
// file name will be made).
|
||||
// Where .MOZ is the file extension to be used.
|
||||
//
|
||||
// In the event that the time requested is the same time as the last call
|
||||
// to this function, then the current time is incremented by one,
|
||||
// as is the last time called to facilitate unique file names.
|
||||
// In the event that the invented file name already exists (can't
|
||||
// really happen statistically unless the clock is messed up or we
|
||||
// manually incremented the time), then the times are incremented
|
||||
// until an open name can be found.
|
||||
//
|
||||
// time_t (the time) has 32 bits, or 4,294,967,296 combinations.
|
||||
// We will map the 32 bits into the 7 possible characters as follows:
|
||||
// Starting with the lsb, sets of 5 bits (32 values) will be mapped
|
||||
// over to the appropriate file name character, and then
|
||||
// incremented to an approprate file name character.
|
||||
// The left over 2 bits will be mapped into the seventh file name
|
||||
// character.
|
||||
//
|
||||
|
||||
int i_letter, i_timechars, i_numtries = 0;
|
||||
char ca_time[8];
|
||||
time_t this_call = (time_t)0;
|
||||
|
||||
// We have to base the length of our time string on the length
|
||||
// of the incoming prefix....
|
||||
//
|
||||
i_timechars = 8 - strlen(prefix);
|
||||
|
||||
// Infinite loop until the conditions are satisfied.
|
||||
// There is no danger, unless every possible file name is used.
|
||||
//
|
||||
while(1) {
|
||||
// We used to use the time to generate this.
|
||||
// Now, we use some crypto to avoid bug #47027
|
||||
RNG_GenerateGlobalRandomBytes((void *)&this_call, sizeof(this_call));
|
||||
|
||||
// Convert the time into a 7 character string.
|
||||
// Strip only the signifigant 5 bits.
|
||||
// We'll want to reverse the string to make it look coherent
|
||||
// in a directory of file names.
|
||||
//
|
||||
for(i_letter = 0; i_letter < i_timechars; i_letter++) {
|
||||
ca_time[i_letter] = (char)((this_call >> (i_letter * 5)) & 0x1F);
|
||||
|
||||
// Convert any numbers to their equivalent ascii code
|
||||
//
|
||||
if(ca_time[i_letter] <= 9) {
|
||||
ca_time[i_letter] += '0';
|
||||
}
|
||||
// Convert the character to it's equivalent ascii code
|
||||
//
|
||||
else {
|
||||
ca_time[i_letter] += 'A' - 10;
|
||||
}
|
||||
}
|
||||
|
||||
// End the created time string.
|
||||
//
|
||||
ca_time[i_letter] = '\0';
|
||||
|
||||
// Reverse the time string.
|
||||
//
|
||||
_strrev(ca_time);
|
||||
|
||||
// Create the fully qualified path and file name.
|
||||
//
|
||||
if (bDirSlash)
|
||||
sprintf(file_buf, "%s%s%s%s", directory, prefix, ca_time, ext);
|
||||
else
|
||||
sprintf(file_buf, "%s\\%s%s%s", directory, prefix, ca_time, ext);
|
||||
|
||||
// Determine if the file exists, and mark that we've tried yet
|
||||
// another file name (mark to be used later).
|
||||
//
|
||||
// Use the system call instead of XP_Stat since we already
|
||||
// know the name and we don't want recursion
|
||||
//
|
||||
status = _stat(file_buf, &statinfo);
|
||||
i_numtries++;
|
||||
|
||||
// If it does not exists, we are successful, return the name.
|
||||
//
|
||||
if(status == -1) {
|
||||
/* don't generate a directory as part of the
|
||||
* cache temp names. When the cache file name
|
||||
* is passed into the other XP_File functions
|
||||
* we will append the cache directory to the name
|
||||
* to get the complete path.
|
||||
* This will allow the cache to be moved around
|
||||
* and for netscape to be used to generate external
|
||||
* cache FAT's. :lou
|
||||
*/
|
||||
if(type == xpCache )
|
||||
sprintf(file_buf, "%s%s%s", prefix, ca_time, ext);
|
||||
|
||||
// TRACE("Temp file name is %s\n", file_buf);
|
||||
return(file_buf);
|
||||
}
|
||||
|
||||
// If there is no room for additional characters in the time,
|
||||
// we'll have to return NULL here, or we go infinite.
|
||||
// This is a one case scenario where the requested prefix is
|
||||
// actually 8 letters long.
|
||||
// Infinite loops could occur with a 7, 6, 5, etc character prefixes
|
||||
// if available files are all eaten up (rare to impossible), in
|
||||
// which case, we should check at some arbitrary frequency of
|
||||
// tries before we give up instead of attempting to Vulcanize
|
||||
// this code. Live long and prosper.
|
||||
//
|
||||
if(i_timechars == 0) {
|
||||
break;
|
||||
}
|
||||
else if(i_numtries == 0x00FF) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Requested name is thought to be impossible to generate.
|
||||
//
|
||||
TRACE("No more temp file names....\n");
|
||||
return(NULL);
|
||||
|
||||
}
|
||||
#endif // 0
|
||||
|
||||
|
||||
nsresult nsNetFile::OpenFile(const char *aPath, nsFileMode aMode, nsFile** aRes) {
|
||||
nsFile *file = nsnull;
|
||||
char *path = nsnull;
|
||||
NS_PRECONDITION( (aPath != nsnull), "Null pointer.");
|
||||
|
||||
if (!aPath)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
if (!*aPath)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
file = (nsFile*) PR_Malloc(sizeof(nsFile));
|
||||
if (!file)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
// Get the correct path.
|
||||
if (GetFilePath(aPath, &path) == NS_ERROR_OUT_OF_MEMORY)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
// We should never be opening a relative file.
|
||||
NS_PRECONDITION( ( (*path != mDirDel) && (*path && (*path+1 != ':'))), "Opening a relative path.");
|
||||
|
||||
file->fd = PR_Open(path, (convertToPRFlag(aMode)), 0600);
|
||||
|
||||
delete path;
|
||||
path = nsnull;
|
||||
|
||||
if (!file->fd) {
|
||||
PR_Free(file);
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
|
||||
*aRes = file;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsNetFile::CloseFile(nsFile* aFile) {
|
||||
|
||||
PRStatus rv;
|
||||
NS_PRECONDITION( (aFile != nsnull), "Null pointer.");
|
||||
|
||||
if (!aFile->fd)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
rv = PR_Close(aFile->fd);
|
||||
|
||||
if (rv == PR_FAILURE)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
PR_Free(aFile);
|
||||
aFile = nsnull;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsNetFile::FileRead(nsFile *aFile, char **aBuf,
|
||||
PRInt32 *aBuflen,
|
||||
PRInt32 *aBytesRead) {
|
||||
NS_PRECONDITION( (aFile != nsnull), "Null pointer.");
|
||||
|
||||
if (*aBuflen < 1)
|
||||
return NS_OK;
|
||||
|
||||
*aBytesRead = PR_Read(aFile->fd, *aBuf, *aBuflen);
|
||||
|
||||
if (*aBytesRead == -1) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsNetFile::FileReadLine(nsFile *aFile, char **aBuf,
|
||||
PRInt32 *aBuflen,
|
||||
PRInt32 *aBytesRead) {
|
||||
PRInt32 readBytes;
|
||||
PRInt32 idx = 0;
|
||||
char *tmpBuf = nsnull;
|
||||
|
||||
NS_PRECONDITION( (aFile != nsnull), "Null pointer.");
|
||||
|
||||
if (*aBuflen < 1) {
|
||||
*aBytesRead = 0;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
readBytes = PR_Read(aFile->fd, *aBuf, *aBuflen);
|
||||
tmpBuf = *aBuf;
|
||||
|
||||
if (readBytes > 0) {
|
||||
while (idx < readBytes) {
|
||||
if (tmpBuf[idx] == 10) { // LF
|
||||
if (tmpBuf[idx+1])
|
||||
tmpBuf[idx+1] = '\0';
|
||||
// Back the file pointer up.
|
||||
PR_Seek(aFile->fd, ((idx+1) - readBytes), PR_SEEK_CUR);
|
||||
*aBytesRead = idx+1;
|
||||
return NS_OK;
|
||||
}
|
||||
idx++;
|
||||
}
|
||||
}
|
||||
|
||||
if (readBytes == *aBuflen)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsresult nsNetFile::FileWrite(nsFile *aFile, const char *aBuf,
|
||||
PRInt32 *aLen,
|
||||
PRInt32 *aBytesWritten) {
|
||||
PRErrorCode error; // for testing, not propogated.
|
||||
NS_PRECONDITION( (aFile != nsnull), "Null pointer.");
|
||||
|
||||
if (*aLen < 1)
|
||||
return NS_OK;
|
||||
|
||||
*aBytesWritten = PR_Write(aFile->fd, aBuf, *aLen);
|
||||
|
||||
if (*aBytesWritten == -1) {
|
||||
error = PR_GetError();
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsNetFile::FileSync(nsFile *aFile) {
|
||||
NS_PRECONDITION( (aFile != nsnull), "Null pointer.");
|
||||
|
||||
if (PR_Sync(aFile->fd) == PR_FAILURE)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsNetFile::FileRemove(const char *aPath) {
|
||||
char *path = nsnull;
|
||||
NS_PRECONDITION( (aPath != nsnull), "Null pointer.");
|
||||
|
||||
// Only remove absolute paths.
|
||||
if (GetFilePath(aPath, &path) == NS_ERROR_OUT_OF_MEMORY)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
// We should never be deleting a relative file.
|
||||
NS_PRECONDITION( ( (*path != mDirDel) && (*path && (*path+1 != ':'))), "Deleting a relative path.");
|
||||
|
||||
if (PR_Delete(aPath) == PR_FAILURE)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsNetFile::FileRename(const char *aPathOld, const char *aPathNew) {
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsNetFile::OpenDir(const char *aPath, nsDir** aRes) {
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsNetFile::CloseDir(nsDir *aDir) {
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsNetFile::CreateDir(const char *aPath, PRBool aRecurse) {
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsNetFile::SetDirectory(const char *aToken, const char *aDir) {
|
||||
nsString tok(aToken);
|
||||
nsString val(aDir);
|
||||
char *t = tok.ToNewCString();
|
||||
char *v = val.ToNewCString();
|
||||
|
||||
if (!PL_HashTableAdd(mHTDirs, t, v)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Associate a filename with a token, and optionally a dir token.
|
||||
nsresult nsNetFile::SetFileAssoc(const char *aToken,
|
||||
const char *aFile,
|
||||
const char *aDirToken) {
|
||||
nsString val(aFile);
|
||||
nsFileAssoc *theFile = new nsFileAssoc;
|
||||
|
||||
if (aDirToken) {
|
||||
// Check for existence.
|
||||
char *dir = (char*)PL_HashTableLookup(mHTDirs, aDirToken);
|
||||
if (!dir)
|
||||
return NS_ERROR_FAILURE;
|
||||
theFile->dirTok = aDirToken;
|
||||
}
|
||||
|
||||
theFile->name = aFile;
|
||||
|
||||
if (!PL_HashTableAdd(mHTFiles, aToken, theFile)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
PRIntn nsNetFile::convertToPRFlag(nsFileMode aMode) {
|
||||
|
||||
switch (aMode) {
|
||||
case nsRead:
|
||||
return PR_RDONLY;
|
||||
case nsWrite:
|
||||
return PR_WRONLY;
|
||||
case nsReadWrite:
|
||||
return PR_RDWR;
|
||||
case nsReadBinary:
|
||||
return PR_RDONLY;
|
||||
case nsWriteBinary:
|
||||
return PR_WRONLY;
|
||||
case nsReadWriteBinary:
|
||||
return PR_RDWR;
|
||||
case nsOverWrite:
|
||||
return (PR_TRUNCATE | PR_WRONLY);
|
||||
default:
|
||||
return PR_RDONLY;
|
||||
}
|
||||
}
|
||||
|
||||
char *nsNetFile::URLSyntaxToLocal(const char *aPath)
|
||||
|
||||
#ifdef XP_PC
|
||||
{
|
||||
char *p, *newName;
|
||||
|
||||
if(!aPath)
|
||||
return nsnull;
|
||||
|
||||
// If the name is only '/' or begins '//' keep the
|
||||
// whole name else strip the leading '/'
|
||||
PRBool bChopSlash = PR_FALSE;
|
||||
|
||||
if(aPath[0] == '/')
|
||||
bChopSlash = PR_TRUE;
|
||||
|
||||
// save just / as a path
|
||||
if(aPath[0] == '/' && aPath[1] == '\0')
|
||||
bChopSlash = PR_FALSE;
|
||||
|
||||
// spanky Win9X path name
|
||||
if(aPath[0] == '/' && aPath[1] == '/')
|
||||
bChopSlash = PR_FALSE;
|
||||
|
||||
if(bChopSlash)
|
||||
newName = PL_strdup(&(aPath[1]));
|
||||
else
|
||||
newName = PL_strdup(aPath);
|
||||
|
||||
if(!newName)
|
||||
return nsnull;
|
||||
|
||||
if( newName[1] == '|' )
|
||||
newName[1] = ':';
|
||||
|
||||
for(p = newName; *p; p++){
|
||||
if( *p == '/' )
|
||||
*p = '\\';
|
||||
}
|
||||
|
||||
return(newName);
|
||||
}
|
||||
#elif XP_MAC
|
||||
{
|
||||
return nsnull;
|
||||
}
|
||||
#else // UNIX
|
||||
{
|
||||
return nsnull;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
extern "C" {
|
||||
/*
|
||||
* Factory for creating instance of the NetFile...
|
||||
*/
|
||||
NS_NET nsresult NS_NewINetFile(nsINetFile** aInstancePtrResult,
|
||||
nsISupports* aOuter)
|
||||
{
|
||||
if (nsnull != aOuter) {
|
||||
return NS_ERROR_NO_AGGREGATION;
|
||||
}
|
||||
|
||||
#ifdef XP_MAC
|
||||
// Perform static initialization...
|
||||
if (nsnull == netFileInit) {
|
||||
netFileInit = new nsNetFileInit;
|
||||
}
|
||||
#endif /* XP_MAC */ // XXX on the mac this never gets shutdown
|
||||
|
||||
// The Netlib Service is created by the nsNetFileInit class...
|
||||
if (nsnull == gNetFile) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
return gNetFile->QueryInterface(kINetFileIID, (void**)aInstancePtrResult);
|
||||
}
|
||||
|
||||
|
||||
NS_NET nsresult NS_InitINetFile(void)
|
||||
{
|
||||
/* XXX: For now only allow a single instance of the Netlib Service */
|
||||
if (nsnull == gNetFile) {
|
||||
gNetFile = new nsNetFile();
|
||||
if (nsnull == gNetFile) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
|
||||
NS_ADDREF(gNetFile);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_NET nsresult NS_ShutdownINetFile()
|
||||
{
|
||||
nsNetFile *service = gNetFile;
|
||||
|
||||
// Release the container...
|
||||
if (nsnull != service) {
|
||||
NS_RELEASE(service);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
}; /* extern "C" */
|
|
@ -0,0 +1,104 @@
|
|||
#include "prio.h"
|
||||
#include "nsINetFile.h"
|
||||
#include "plhash.h"
|
||||
|
||||
|
||||
#ifndef ns_net_file_h_
|
||||
#define ns_net_file_h_
|
||||
|
||||
/* This is a singleton implementation. */
|
||||
|
||||
class nsNetFile : public nsINetFile {
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
nsNetFile();
|
||||
|
||||
// Convert a generic file names into a platform file path
|
||||
NS_IMETHOD GetFilePath(const char *aName, char **aRes);
|
||||
NS_IMETHOD GetTemporaryFilePath(const char *aName, char **aRes);
|
||||
NS_IMETHOD GetUniqueFilePath(const char *aName, char **aRes);
|
||||
NS_IMETHOD GetCacheFileName(char *aDirTok, char **aRes);
|
||||
|
||||
// Open a file
|
||||
NS_IMETHOD OpenFile(const char *aPath, nsFileMode aMode,
|
||||
nsFile** aRes);
|
||||
|
||||
// Close a file
|
||||
NS_IMETHOD CloseFile(nsFile* aFile);
|
||||
|
||||
// Read a file
|
||||
NS_IMETHOD FileRead(nsFile *aFile, char **aBuf,
|
||||
PRInt32 *aBuflen,
|
||||
PRInt32 *aBytesRead);
|
||||
|
||||
// Read a line from a file
|
||||
NS_IMETHOD FileReadLine(nsFile *aFile, char **aBuf,
|
||||
PRInt32 *aBuflen,
|
||||
PRInt32 *aBytesRead);
|
||||
|
||||
// Write a file
|
||||
NS_IMETHOD FileWrite(nsFile *aFile, const char *aBuf,
|
||||
PRInt32 *aLen,
|
||||
PRInt32 *aBytesWritten);
|
||||
|
||||
// Sync a file with disk
|
||||
NS_IMETHOD FileSync(nsFile *aFile);
|
||||
|
||||
// Remove a file
|
||||
NS_IMETHOD FileRemove(const char *aPath);
|
||||
|
||||
// Rename a file
|
||||
NS_IMETHOD FileRename(const char *aPathOld, const char *aPathNew);
|
||||
|
||||
/*
|
||||
* Directory Methods
|
||||
*/
|
||||
|
||||
// Open a directory
|
||||
NS_IMETHOD OpenDir(const char *aPath, nsDir** aRes);
|
||||
|
||||
// Close a directory
|
||||
NS_IMETHOD CloseDir(nsDir *aDir);
|
||||
|
||||
// Create a directory
|
||||
NS_IMETHOD CreateDir(const char *aPath, PRBool aRecurse);
|
||||
|
||||
// Set the internal directories
|
||||
NS_IMETHOD SetDirectory(const char *aToken, const char *aDir);
|
||||
|
||||
// Associate a filename with a token, and optionally a dir token.
|
||||
NS_IMETHOD SetFileAssoc(const char *aToken, const char *aFile, const char *aDirToken);
|
||||
|
||||
protected:
|
||||
virtual ~nsNetFile();
|
||||
|
||||
private:
|
||||
void GenerateGlobalRandomBytes(void *aDest, size_t aLen);
|
||||
PRIntn convertToPRFlag(nsFileMode aMode);
|
||||
char * URLSyntaxToLocal(const char * aPath);
|
||||
char mTokDel; // token delimiter
|
||||
char mDirDel; // directory delimiter
|
||||
PLHashTable *mHTDirs; // directory registry
|
||||
PLHashTable *mHTFiles; // file registry
|
||||
};
|
||||
|
||||
// The one and only singleton pointer to an nsNetFile.
|
||||
static nsNetFile *gNetFile = nsnull;
|
||||
|
||||
//
|
||||
// Class to manage static initialization
|
||||
//
|
||||
struct nsNetFileInit {
|
||||
nsNetFileInit() {
|
||||
gNetFile = nsnull;
|
||||
(void) NS_InitINetFile();
|
||||
}
|
||||
|
||||
~nsNetFileInit() {
|
||||
NS_ShutdownINetFile();
|
||||
gNetFile = nsnull;
|
||||
}
|
||||
};
|
||||
|
||||
#endif // ns_net_file_h_
|
|
@ -21,6 +21,7 @@
|
|||
#include "nsNetService.h"
|
||||
#include "nsNetStream.h"
|
||||
#include "net.h"
|
||||
#include "nsNetFile.h"
|
||||
extern "C" {
|
||||
#include "mkutils.h"
|
||||
#include "mkgeturl.h"
|
||||
|
@ -36,6 +37,21 @@ extern "C" {
|
|||
#include "nsIProtocolConnection.h"
|
||||
#include "nsINetContainerApplication.h"
|
||||
|
||||
|
||||
// Declare the nsFile struct here so it's state is initialized before
|
||||
// we initialize netlib.
|
||||
#ifdef NS_NET_FILE
|
||||
|
||||
#include "nsNetFile.h"
|
||||
#ifdef XP_MAC
|
||||
static nsNetFileInit* netFileInit = nsnull;
|
||||
#else
|
||||
static nsNetFileInit netFileInit;
|
||||
#endif
|
||||
|
||||
#endif // NS_NET_FILE
|
||||
// End nsFile specific
|
||||
|
||||
/* XXX: Legacy definitions... */
|
||||
// Global count of active urls from mkgeturl.c
|
||||
extern "C" int NET_TotalNumberOfProcessingURLs;
|
||||
|
|
|
@ -29,6 +29,27 @@
|
|||
#include "nsString.h"
|
||||
#include "nsNetStream.h"
|
||||
|
||||
#ifdef NS_NET_FILE
|
||||
|
||||
// For xp to ns file translation
|
||||
#include "nsINetFile.h"
|
||||
#include "nsVoidArray.h"
|
||||
|
||||
// The nsINetfile
|
||||
static nsINetFile *fileMgr = nsnull;
|
||||
|
||||
typedef struct _xp_to_nsFile {
|
||||
nsFile *nsFp;
|
||||
XP_File xpFp;
|
||||
} xpNSFile;
|
||||
|
||||
// Array of translation structs from xp to ns file.
|
||||
static nsVoidArray switchBack;
|
||||
|
||||
// end xp to ns file translation
|
||||
|
||||
#endif // NS_NET_FILE
|
||||
|
||||
extern "C" {
|
||||
#include "secnav.h"
|
||||
#include "preenc.h"
|
||||
|
@ -367,7 +388,7 @@ char *WH_FilePlatformName(const char *pName)
|
|||
|
||||
NS_DEFINE_IID(kRefreshURLIID, NS_IREFRESHURL_IID);
|
||||
|
||||
void FE_SetRefreshURLTimer(MWContext *pContext, URL_Struct *URL_s)
|
||||
void FE_SetRefreshURLTimer(MWContext *pContext, URL_Struct *URL_s)
|
||||
{
|
||||
nsresult rv;
|
||||
nsIRefreshUrl* IRefreshURL=nsnull;
|
||||
|
@ -773,23 +794,53 @@ SHIST_GetCurrent(History * hist)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
#ifdef NS_NET_FILE
|
||||
// XXXXXXXXXXXXXXXXXXXXXXXXX NS_NET_FILE BEGIN XXXXXXXXXXXXXXXXXXXXXXXXX
|
||||
|
||||
// Begin nsNetFile versions of xp_file routines. These stubs utilize the new
|
||||
// nsINetFile interface to do file i/o type things.
|
||||
|
||||
|
||||
// Utility routine to remove a transator object from the array and free it.
|
||||
nsresult deleteTrans(nsFile *nsFp) {
|
||||
xpNSFile *trans = nsnull;
|
||||
|
||||
if (!nsFp)
|
||||
return NS_OK;
|
||||
|
||||
for (PRInt32 i = switchBack.Count(); i > 0; i--) {
|
||||
trans = (xpNSFile*)switchBack.ElementAt(i-1);
|
||||
if (trans && trans->nsFp == nsFp) {
|
||||
switchBack.RemoveElement(trans);
|
||||
if (trans->xpFp) {
|
||||
PR_Free(trans->xpFp);
|
||||
trans->xpFp = nsnull;
|
||||
}
|
||||
PR_Free(trans);
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
#ifdef XP_MAC
|
||||
char *
|
||||
WH_TempName(XP_FileType type, const char * prefix)
|
||||
{
|
||||
MOZ_FUNCTION_STUB;
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Utility routine to convert an xpFile pointer to a ns file pointer.
|
||||
nsFile * XpToNsFp(XP_File xpFp) {
|
||||
nsFile *nsFp = nsnull;
|
||||
xpNSFile *trans = nsnull;
|
||||
|
||||
if (!xpFp)
|
||||
return nsnull;
|
||||
for (PRInt32 i = switchBack.Count(); i > 0; i--) {
|
||||
trans = (xpNSFile*)switchBack.ElementAt(i-1);
|
||||
if (trans && trans->xpFp == xpFp) {
|
||||
nsFp = trans->nsFp;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return nsFp;
|
||||
}
|
||||
|
||||
/*
|
||||
*---------------------------------------------------------------------------
|
||||
* From ns/cmd/winfe/fegui.cpp
|
||||
*---------------------------------------------------------------------------
|
||||
*/
|
||||
#ifdef XP_PC
|
||||
/*
|
||||
//
|
||||
// Open a file with the given name
|
||||
|
@ -797,31 +848,322 @@ WH_TempName(XP_FileType type, const char * prefix)
|
|||
// out of the preferences list
|
||||
//
|
||||
*/
|
||||
PUBLIC XP_File
|
||||
XP_FileOpen(const char * name, XP_FileType type, const XP_FilePerm perm)
|
||||
{
|
||||
MOZ_FUNCTION_STUB;
|
||||
|
||||
/* List of old xpFile enums we need to support
|
||||
* Don't need cache stuff as new cache module will do it's own disk i/o
|
||||
xpCacheFAT
|
||||
xpCache
|
||||
xpSARCache
|
||||
xpExtCacheIndex
|
||||
|
||||
xpProxyConfig
|
||||
xpURL
|
||||
xpJSConfig
|
||||
xpTemporary
|
||||
xpJSCookieFilters
|
||||
xpFileToPost
|
||||
xpMimeTypes
|
||||
xpHTTPCookie
|
||||
*/
|
||||
|
||||
// Caller is repsonsible for freeing string.
|
||||
|
||||
PRIVATE
|
||||
char *xpFileTypeToName(XP_FileType type) {
|
||||
char *name = nsnull;
|
||||
switch (type) {
|
||||
case xpURL:
|
||||
case xpFileToPost:
|
||||
case xpHTTPCookie:
|
||||
{
|
||||
XP_File fp;
|
||||
char* newName = WH_FileName(name, type);
|
||||
case (xpCache):
|
||||
return PL_strdup(CACHE_DIR_TOK);
|
||||
break;
|
||||
case (xpCacheFAT):
|
||||
return PL_strdup(CACHE_DIR_TOK CACHE_DB_F_TOK);
|
||||
break;
|
||||
case (xpProxyConfig):
|
||||
break;
|
||||
case (xpURL):
|
||||
break;
|
||||
case (xpJSConfig):
|
||||
break;
|
||||
case (xpTemporary):
|
||||
break;
|
||||
case (xpJSCookieFilters):
|
||||
break;
|
||||
case (xpFileToPost):
|
||||
break;
|
||||
case (xpMimeTypes):
|
||||
break;
|
||||
case (xpHTTPCookie):
|
||||
return PL_strdup("%USER%%COOKIE_F%");
|
||||
|
||||
if (!newName) return NULL;
|
||||
|
||||
fp = fopen(newName, (char *) perm);
|
||||
XP_FREE(newName);
|
||||
|
||||
return fp;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
/*
|
||||
// The caller is responsible for XP_FREE()ing the return string
|
||||
*/
|
||||
PUBLIC char *
|
||||
WH_FileName (const char *NetName, XP_FileType type)
|
||||
{
|
||||
char *path = nsnull, *aName = nsnull;
|
||||
nsresult rv;
|
||||
|
||||
if (!NetName || !*NetName) {
|
||||
aName = xpFileTypeToName(type);
|
||||
if (!aName) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (!fileMgr) {
|
||||
if (NS_NewINetFile(&fileMgr, nsnull) != NS_OK) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
rv = fileMgr->GetFilePath( (aName ? aName : NetName), &path);
|
||||
if (rv != NS_OK)
|
||||
return NULL;
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
char *
|
||||
WH_TempName(XP_FileType type, const char * prefix)
|
||||
{
|
||||
char *path = nsnull, *aName = nsnull;
|
||||
nsresult rv;
|
||||
|
||||
aName = xpFileTypeToName(type);
|
||||
if (!aName) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
if (!fileMgr) {
|
||||
if (NS_NewINetFile(&fileMgr, nsnull) != NS_OK) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
rv = fileMgr->GetCacheFileName(aName, &path);
|
||||
if (rv != NS_OK)
|
||||
return NULL;
|
||||
|
||||
return PL_strdup(path);
|
||||
}
|
||||
|
||||
PUBLIC int
|
||||
NET_I_XP_Fileno(XP_File fp) {
|
||||
nsFile *nsFp = XpToNsFp(fp); // nsnull ok.
|
||||
|
||||
NS_PRECONDITION( (nsFp != nsnull), "Null pointer.");
|
||||
|
||||
return (int) nsFp->fd;
|
||||
}
|
||||
|
||||
PUBLIC int
|
||||
NET_I_XP_FileSeek(XP_File fp, long offset, int origin) {
|
||||
nsFile *nsFp = XpToNsFp(fp); // nsnull ok.
|
||||
PRSeekWhence sw;
|
||||
|
||||
NS_PRECONDITION( (nsFp != nsnull), "Null pointer.");
|
||||
|
||||
/* Need to confirm the origin to PRSeekWhence mapping */
|
||||
|
||||
switch (origin) {
|
||||
case (0):
|
||||
sw = PR_SEEK_SET;
|
||||
break;
|
||||
case (1):
|
||||
sw = PR_SEEK_CUR;
|
||||
break;
|
||||
case (2):
|
||||
sw = PR_SEEK_END;
|
||||
break;
|
||||
default:
|
||||
sw = PR_SEEK_SET;
|
||||
}
|
||||
|
||||
return PR_Seek(nsFp->fd, offset, sw);
|
||||
}
|
||||
|
||||
// Initialization routine for nsNetFile. This registers all the directories
|
||||
// and files in the nsNetFile instance. Use the form:
|
||||
// token = %token%
|
||||
// value = opaque string
|
||||
//
|
||||
// Directories and files are platform specific.
|
||||
PUBLIC PRBool
|
||||
NET_InitFilesAndDirs(void) {
|
||||
|
||||
if (!fileMgr) {
|
||||
if (NS_NewINetFile(&fileMgr, nsnull) != NS_OK) {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
// Setup directories.
|
||||
fileMgr->SetDirectory(USER_DIR_TOK, USER_DIR);
|
||||
fileMgr->SetDirectory(CACHE_DIR_TOK, CACHE_DIR);
|
||||
fileMgr->SetDirectory(DEF_DIR_TOK, DEF_DIR);
|
||||
|
||||
// Setup files.
|
||||
fileMgr->SetFileAssoc(COOKIE_FILE_TOK, COOKIE_FILE, USER_DIR_TOK);
|
||||
fileMgr->SetFileAssoc(CACHE_DB_F_TOK, CACHE_DB_FILE, CACHE_DIR_TOK);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
PUBLIC XP_File
|
||||
NET_I_XP_FileOpen(const char * name, XP_FileType type, const XP_FilePerm perm)
|
||||
{
|
||||
XP_File xpFp;
|
||||
xpNSFile *trans = (xpNSFile*)PR_Malloc(sizeof(xpNSFile));
|
||||
nsFile *nsFp = nsnull;
|
||||
nsresult rv;
|
||||
nsFileMode mode;
|
||||
char *aName = nsnull;
|
||||
|
||||
if (!fileMgr) {
|
||||
if (NS_NewINetFile(&fileMgr, nsnull) != NS_OK) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// Just get some random address.
|
||||
xpFp = (XP_File) PR_Malloc(1);
|
||||
|
||||
trans->xpFp= xpFp;
|
||||
|
||||
if (!PL_strcasecmp(perm,XP_FILE_READ)) {
|
||||
mode = nsRead;
|
||||
} else if (!PL_strcasecmp(perm,XP_FILE_WRITE)) {
|
||||
mode = nsOverWrite;
|
||||
} else if (!PL_strcasecmp(perm,XP_FILE_WRITE_BIN)) {
|
||||
mode = nsOverWrite;
|
||||
} else {
|
||||
mode = nsReadWrite;
|
||||
}
|
||||
|
||||
/* call OpenFile with nsNetFile syntax if necesary. */
|
||||
if ( (!name || !*name)
|
||||
|| type == xpCache ) {
|
||||
nsString newName;
|
||||
newName = xpFileTypeToName(type);
|
||||
if (newName.Length() < 1) {
|
||||
PR_Free(trans);
|
||||
PR_Free(xpFp);
|
||||
return NULL;
|
||||
}
|
||||
newName.Append(name);
|
||||
aName = newName.ToNewCString();
|
||||
}
|
||||
|
||||
rv = fileMgr->OpenFile( (aName ? aName : name), mode, &nsFp);
|
||||
PR_Free(aName);
|
||||
if (NS_OK != rv) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
trans->nsFp = nsFp;
|
||||
|
||||
switchBack.AppendElement(trans);
|
||||
|
||||
return xpFp;
|
||||
}
|
||||
|
||||
PUBLIC char *
|
||||
NET_I_XP_FileReadLine(char *outBuf, int outBufLen, XP_File fp) {
|
||||
nsFile *nsFp = XpToNsFp(fp); // nsnull ok.
|
||||
PRInt32 readBytes;
|
||||
nsresult rv;
|
||||
|
||||
NS_PRECONDITION( (nsFp != nsnull), "Null pointer");
|
||||
|
||||
if (!nsFp)
|
||||
return NULL;
|
||||
|
||||
if (!fileMgr)
|
||||
return NULL;
|
||||
|
||||
rv = fileMgr->FileReadLine( nsFp, &outBuf, &outBufLen, &readBytes);
|
||||
if (NS_OK != rv) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return outBuf;
|
||||
}
|
||||
|
||||
PUBLIC int
|
||||
NET_I_XP_FileRead(char *outBuf, int outBufLen, XP_File fp) {
|
||||
nsFile *nsFp = XpToNsFp(fp); // nsnull ok.
|
||||
PRInt32 readBytes;
|
||||
nsresult rv;
|
||||
|
||||
NS_PRECONDITION( (nsFp != nsnull), "Null pointer");
|
||||
|
||||
if (!nsFp)
|
||||
return -1;
|
||||
|
||||
if (!fileMgr)
|
||||
return -1;
|
||||
|
||||
rv = fileMgr->FileRead( nsFp, &outBuf, &outBufLen, &readBytes);
|
||||
if (NS_OK != rv) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return (int) readBytes;
|
||||
}
|
||||
|
||||
PUBLIC int
|
||||
NET_I_XP_FileWrite(const char *buf, int bufLen, XP_File fp) {
|
||||
nsFile *nsFp = XpToNsFp(fp); // nsnull ok.
|
||||
PRInt32 wroteBytes;
|
||||
PRInt32 len;
|
||||
nsresult rv;
|
||||
|
||||
if (bufLen < 0)
|
||||
len = PL_strlen(buf);
|
||||
else
|
||||
len = bufLen;
|
||||
|
||||
if (!nsFp)
|
||||
return -1;
|
||||
|
||||
if (!fileMgr)
|
||||
return NULL;
|
||||
|
||||
rv = fileMgr->FileWrite(nsFp, buf, &len, &wroteBytes);;
|
||||
if (rv != NS_OK)
|
||||
return NULL;
|
||||
|
||||
return (int) wroteBytes;
|
||||
}
|
||||
|
||||
PUBLIC int
|
||||
NET_I_XP_FileClose(XP_File fp) {
|
||||
nsFile *nsFp = XpToNsFp(fp); // nsnull ok.
|
||||
nsresult rv;
|
||||
|
||||
NS_PRECONDITION( (nsFp != nsnull), "Null pointer");
|
||||
|
||||
if (!fileMgr) {
|
||||
if (NS_NewINetFile(&fileMgr, nsnull) != NS_OK) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
rv = fileMgr->CloseFile(nsFp);
|
||||
if (rv != NS_OK)
|
||||
return 0;
|
||||
|
||||
deleteTrans(nsFp);
|
||||
fp = nsnull;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
@ -831,32 +1173,81 @@ XP_FileOpen(const char * name, XP_FileType type, const XP_FilePerm perm)
|
|||
//
|
||||
*/
|
||||
PUBLIC int
|
||||
XP_FileRemove(const char * name, XP_FileType type)
|
||||
NET_I_XP_FileRemove(const char * name, XP_FileType type)
|
||||
{
|
||||
MOZ_FUNCTION_STUB;
|
||||
return -1;
|
||||
char *path = nsnull, *aName = nsnull;
|
||||
nsresult rv;
|
||||
|
||||
if ( (!name || !*name)
|
||||
|| type == xpCache ) {
|
||||
nsString newName;
|
||||
newName = xpFileTypeToName(type);
|
||||
if (newName.Length() < 1) {
|
||||
return NULL;
|
||||
}
|
||||
newName.Append(name);
|
||||
aName = newName.ToNewCString();
|
||||
}
|
||||
|
||||
if (!fileMgr) {
|
||||
if (NS_NewINetFile(&fileMgr, nsnull) != NS_OK) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
rv = fileMgr->FileRemove((aName ? aName : name));
|
||||
if (rv != NS_OK)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
//
|
||||
// Mimic unix stat call
|
||||
// Return -1 on error
|
||||
//
|
||||
*/
|
||||
PUBLIC int
|
||||
XP_Stat(const char * name, XP_StatStruct * info, XP_FileType type)
|
||||
NET_I_XP_Stat(const char * name, XP_StatStruct * info, XP_FileType type)
|
||||
{
|
||||
int result = -1;
|
||||
MOZ_FUNCTION_STUB;
|
||||
PRFileInfo fileInfo;
|
||||
PRStatus status;
|
||||
char *newName;
|
||||
nsString ourName;
|
||||
char *path;
|
||||
nsresult rv;
|
||||
|
||||
switch (type) {
|
||||
case xpCache:
|
||||
ourName = xpFileTypeToName(type);
|
||||
if (ourName.Length() < 1) {
|
||||
return NULL;
|
||||
}
|
||||
ourName.Append(name);
|
||||
newName = ourName.ToNewCString();
|
||||
|
||||
if (!fileMgr) {
|
||||
if (NS_NewINetFile(&fileMgr, nsnull) != NS_OK) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
rv = fileMgr->GetFilePath(newName, &path);
|
||||
if (rv != NS_OK)
|
||||
return -1;
|
||||
status = PR_GetFileInfo(path, &fileInfo);
|
||||
delete path;
|
||||
delete newName;
|
||||
if (status == PR_SUCCESS) {
|
||||
// transfer the pr stat info over to the xp stat object.
|
||||
// right now just moving over the size.
|
||||
info->st_size = fileInfo.size;
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
case xpURL:
|
||||
case xpFileToPost: {
|
||||
char *newName = WH_FileName(name, type);
|
||||
newName = WH_FileName(name, type);
|
||||
|
||||
if (!newName) return -1;
|
||||
result = _stat( newName, info );
|
||||
XP_FREE(newName);
|
||||
delete newName;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
@ -865,6 +1256,43 @@ XP_Stat(const char * name, XP_StatStruct * info, XP_FileType type)
|
|||
return result;
|
||||
}
|
||||
|
||||
PUBLIC XP_Dir
|
||||
NET_I_XP_OpenDir(const char * name, XP_FileType type)
|
||||
{
|
||||
MOZ_FUNCTION_STUB;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PUBLIC void
|
||||
NET_I_XP_CloseDir(XP_Dir dir)
|
||||
{
|
||||
MOZ_FUNCTION_STUB;
|
||||
}
|
||||
/*
|
||||
//
|
||||
// Close the directory
|
||||
//
|
||||
*/
|
||||
|
||||
PUBLIC XP_DirEntryStruct *
|
||||
NET_I_XP_ReadDir(XP_Dir dir)
|
||||
{
|
||||
MOZ_FUNCTION_STUB;
|
||||
return NULL;
|
||||
}
|
||||
// XXXXXXXXXXXXXXXXXXXXXXXXX NS_NET_FILE END XXXXXXXXXXXXXXXXXXXXXXXXX
|
||||
#endif /* NS_NET_FILE */
|
||||
|
||||
// Begin vanilla versions of xp_file routines. These are simply stubs.
|
||||
|
||||
#ifndef NS_NET_FILE
|
||||
char *
|
||||
WH_TempName(XP_FileType type, const char * prefix)
|
||||
{
|
||||
MOZ_FUNCTION_STUB;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
// The caller is responsible for XP_FREE()ing the return string
|
||||
*/
|
||||
|
@ -879,6 +1307,9 @@ WH_FileName (const char *NetName, XP_FileType type)
|
|||
#else
|
||||
return PL_strdup("cookies");
|
||||
#endif
|
||||
} else if (type == xpCacheFAT) {
|
||||
;// sprintf(newName, "%s\\fat.db", (const char *)theApp.m_pCacheDir);
|
||||
|
||||
} else if ((type == xpURL) || (type == xpFileToPost)) {
|
||||
/*
|
||||
* This is the body of XP_NetToDosFileName(...) which is implemented
|
||||
|
@ -924,15 +1355,69 @@ WH_FileName (const char *NetName, XP_FileType type)
|
|||
|
||||
return NULL;
|
||||
}
|
||||
#endif // !NS_NET_FILE
|
||||
|
||||
|
||||
char *
|
||||
WH_TempName(XP_FileType type, const char * prefix)
|
||||
PUBLIC XP_File
|
||||
XP_FileOpen(const char * name, XP_FileType type, const XP_FilePerm perm)
|
||||
{
|
||||
MOZ_FUNCTION_STUB;
|
||||
switch (type) {
|
||||
case xpURL:
|
||||
case xpFileToPost:
|
||||
case xpHTTPCookie:
|
||||
{
|
||||
XP_File fp;
|
||||
char* newName = WH_FileName(name, type);
|
||||
|
||||
if (!newName) return NULL;
|
||||
|
||||
fp = fopen(newName, (char *) perm);
|
||||
XP_FREE(newName);
|
||||
return fp;
|
||||
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PUBLIC int
|
||||
XP_FileRemove(const char * name, XP_FileType type)
|
||||
{
|
||||
if (PR_Delete(name) == PR_SUCCESS)
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
//
|
||||
// Mimic unix stat call
|
||||
// Return -1 on error
|
||||
//
|
||||
*/
|
||||
PUBLIC int
|
||||
XP_Stat(const char * name, XP_StatStruct * info, XP_FileType type)
|
||||
{
|
||||
int result = -1;
|
||||
MOZ_FUNCTION_STUB;
|
||||
|
||||
switch (type) {
|
||||
case xpURL:
|
||||
case xpFileToPost: {
|
||||
char *newName = WH_FileName(name, type);
|
||||
|
||||
if (!newName) return -1;
|
||||
result = _stat( newName, info );
|
||||
XP_FREE(newName);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
PUBLIC XP_Dir
|
||||
XP_OpenDir(const char * name, XP_FileType type)
|
||||
|
@ -941,12 +1426,6 @@ XP_OpenDir(const char * name, XP_FileType type)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
//
|
||||
// Close the directory
|
||||
//
|
||||
*/
|
||||
|
||||
PUBLIC void
|
||||
XP_CloseDir(XP_Dir dir)
|
||||
{
|
||||
|
@ -960,8 +1439,6 @@ XP_ReadDir(XP_Dir dir)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
#endif /* XP_PC */
|
||||
|
||||
PUBLIC void *
|
||||
FE_AboutData (const char *which,
|
||||
char **data_ret, int32 *length_ret, char **content_type_ret)
|
||||
|
|
Загрузка…
Ссылка в новой задаче