diff --git a/mozilla/network/main/mkgeturl.c b/mozilla/network/main/mkgeturl.c index 6a2ff4cff0c..3df9f9900c8 100644 --- a/mozilla/network/main/mkgeturl.c +++ b/mozilla/network/main/mkgeturl.c @@ -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(""); diff --git a/mozilla/network/main/net_xp_file.h b/mozilla/network/main/net_xp_file.h index 3ba52144a2f..fbfda4feef6 100644 --- a/mozilla/network/main/net_xp_file.h +++ b/mozilla/network/main/net_xp_file.h @@ -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) diff --git a/mozilla/network/module/makefile.win b/mozilla/network/module/makefile.win index f94174001b9..29cecfc3bbd 100644 --- a/mozilla/network/module/makefile.win +++ b/mozilla/network/module/makefile.win @@ -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) #//------------------------------------------------------------------------ diff --git a/mozilla/network/module/nsINetFile.h b/mozilla/network/module/nsINetFile.h new file mode 100644 index 00000000000..af912f233c0 --- /dev/null +++ b/mozilla/network/module/nsINetFile.h @@ -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 diff --git a/mozilla/network/module/nsNetFile.cpp b/mozilla/network/module/nsNetFile.cpp new file mode 100644 index 00000000000..5ac76905d08 --- /dev/null +++ b/mozilla/network/module/nsNetFile.cpp @@ -0,0 +1,907 @@ +#include "nsNetFile.h" +#include "prmem.h" +#include "nsString.h" +#include "plstr.h" +#include "prerror.h" +#include "direct.h" +#include + +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> (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" */ \ No newline at end of file diff --git a/mozilla/network/module/nsNetFile.h b/mozilla/network/module/nsNetFile.h new file mode 100644 index 00000000000..eba62f187bc --- /dev/null +++ b/mozilla/network/module/nsNetFile.h @@ -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_ \ No newline at end of file diff --git a/mozilla/network/module/nsNetService.cpp b/mozilla/network/module/nsNetService.cpp index 18e0dae9a7a..81ca085bcbc 100644 --- a/mozilla/network/module/nsNetService.cpp +++ b/mozilla/network/module/nsNetService.cpp @@ -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; diff --git a/mozilla/network/module/nsNetStubs.cpp b/mozilla/network/module/nsNetStubs.cpp index fbd32ac7268..8b190f95e12 100644 --- a/mozilla/network/module/nsNetStubs.cpp +++ b/mozilla/network/module/nsNetStubs.cpp @@ -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)