nsLocalFileOS2.cpp revision 677833bc953b6cb418c701facbdcf4aa18d6c44e
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Communicator client code, released
* March 31, 1998.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998-2000
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Henry Sobotka <sobotka@axess.com>
* IBM Corp.
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsCOMPtr.h"
#include "nsMemory.h"
#include "nsLocalFile.h"
#include "nsNativeCharsetUtils.h"
#include "nsISimpleEnumerator.h"
#include "nsIComponentManager.h"
#include "prtypes.h"
#include "prio.h"
#include <ctype.h> // needed for toupper
#include <string.h>
#include "nsXPIDLString.h"
#include "nsReadableUtils.h"
#include "prproces.h"
#include "prthread.h"
static unsigned char* PR_CALLBACK
extern unsigned char*
static nsresult PR_CALLBACK
static int isleadbyte(int c);
#include <unistd.h>
#include <io.h>
{
switch (err)
{
case ERROR_FILE_NOT_FOUND:
case ERROR_PATH_NOT_FOUND:
case ERROR_INVALID_DRIVE:
break;
case ERROR_ACCESS_DENIED:
case ERROR_NOT_SAME_DEVICE:
break;
case ERROR_NOT_ENOUGH_MEMORY:
case ERROR_INVALID_BLOCK:
case ERROR_INVALID_HANDLE:
case ERROR_ARENA_TRASHED:
break;
case ERROR_CURRENT_DIRECTORY:
break;
case ERROR_WRITE_PROTECT:
break;
case ERROR_HANDLE_DISK_FULL:
break;
case ERROR_FILE_EXISTS:
case ERROR_ALREADY_EXISTS:
case ERROR_CANNOT_MAKE:
break;
case 0:
default:
}
return rv;
}
static void
{
// only one PRInt64, but these are macros,
// and I am a wimp.
// shift the hi word to the low word, then push it into a long.
// shift the low word to the hi word first, then shift it back.
}
class nsDirEnumerator : public nsISimpleEnumerator
{
public:
{
}
{
{
}
{
return NS_ERROR_UNEXPECTED;
}
return NS_ERROR_FAILURE;
return NS_OK;
}
{
{
{
// end of dir entries
if (status != PR_SUCCESS)
return NS_ERROR_FAILURE;
return NS_OK;
}
return rv;
return rv;
// make sure the thing exists. If it does, try the next one.
{
return HasMoreElements(result);
}
}
return NS_OK;
}
{
return NS_OK;
}
private:
{
if (mDir)
{
}
}
protected:
};
{
MakeDirty();
}
{
}
/* nsISupports interface implementation. */
{
return NS_ERROR_OUT_OF_MEMORY;
{
delete inst;
return rv;
}
return NS_OK;
}
// This function resets any cached information about the file.
void
{
}
nsLocalFile::Stat()
{
if (!mDirty)
return NS_OK;
char temp[4];
const char* nsprPath = workingFilePath;
temp[0] = workingFilePath[0];
}
if ( status == PR_SUCCESS )
return NS_OK;
return NS_ERROR_FILE_NOT_FOUND;
}
{
// Just copy-construct ourselves
*file = new nsLocalFile(*this);
if (!*file)
return NS_ERROR_OUT_OF_MEMORY;
return NS_OK;
}
{
MakeDirty();
// input string must not be empty
return NS_ERROR_FAILURE;
char secondChar = *(++begin);
// just do a sanity check. if it has any forward slashes, it is not a Native path
// on windows. Also, it must have a colon at after the first char.
{
// This is a native path
}
return NS_ERROR_FILE_UNRECOGNIZED_PATH;
// kill any trailing '\' provided it isn't the second char of DBCS
{
}
return NS_OK;
}
{
return rv;
if (*_retval)
return NS_OK;
return NS_ErrorAccordingToNSPR();
}
{
return rv;
if (*_retval)
return NS_OK;
return NS_ERROR_FAILURE;
}
{
return NS_ERROR_FILE_UNKNOWN_TYPE;
return rv;
// create nested directories to target
if (slash)
{
// skip the first '\\'
++slash;
while (slash)
{
*slash = '\0';
if (rv) {
}
*slash = '\\';
++slash;
}
}
if (type == NORMAL_FILE_TYPE)
{
PRFileDesc* file = PR_Open(mWorkingPath.get(), PR_RDONLY | PR_CREATE_FILE | PR_APPEND | PR_EXCL, attributes);
if (!file) return NS_ERROR_FILE_ALREADY_EXISTS;
return NS_OK;
}
if (type == DIRECTORY_TYPE)
{
if (rv)
return ConvertOS2Error(rv);
else
return NS_OK;
}
return NS_ERROR_FILE_UNKNOWN_TYPE;
}
{
return NS_OK;
// Append only one component. Check for subdirs.
// XXX can we avoid the PromiseFlatCString call?
return NS_ERROR_FILE_UNRECOGNIZED_PATH;
return AppendRelativeNativePath(node);
}
{
// Cannot start with a / or have .. or have / anywhere
{
return NS_ERROR_FILE_UNRECOGNIZED_PATH;
}
MakeDirty();
return NS_OK;
}
{
return NS_OK;
}
{
return NS_ERROR_FILE_UNRECOGNIZED_PATH;
// if the working path is just a node without any lashes.
else
leaf++;
return NS_OK;
}
{
MakeDirty();
return NS_ERROR_FILE_UNRECOGNIZED_PATH;
// cannot use nsCString::RFindChar() due to 0x5c problem
if (offset)
{
}
return NS_OK;
}
{
return NS_OK;
}
nsLocalFile::CopySingleFile(nsIFile *sourceFile, nsIFile *destParent, const nsACString &newName, PRBool move)
{
{
}
else
{
}
return rv;
if( move )
{
}
/* will get an error if the destination and source files aren't on the
* same drive. "MoveFile()" on Windows will go ahead and move the
* file without error, so we need to do the same IBM-AKR
*/
do {
if (rc == ERROR_TOO_MANY_OPEN_FILES) {
break;
}
}
} while (rc == ERROR_TOO_MANY_OPEN_FILES);
/* WSOD2 HACK */
DosExecPgm(NULL, 0,
rc = 0; // Assume it worked
} /* rc == 65 */
/* moving the file is supposed to act like a rename, so delete the
* original file if we got this far without error
*/
{
}
} /* !move or ERROR */
if (rc)
return rv;
}
{
return rv;
if (!newParentDir)
{
// no parent was specified. We must rename.
return NS_ERROR_INVALID_ARG;
return rv;
}
if (!newParentDir)
// make sure it exists and is a directory. Create it if not there.
{
return rv;
}
else
{
{
}
}
// check to see if we are a directory, if so enumerate it.
IsDirectory(&isDir);
if (!isDir)
{
return rv;
}
else
{
// create a new target destination in the new parentDir;
return rv;
{
}
else
{
}
return rv;
return rv;
if (!dirEnum)
return NS_ERROR_OUT_OF_MEMORY;
while (more)
{
if (move)
{
}
else
{
}
}
// we've finished moving all the children of this directory
// in the new directory. so now delete the directory
// note, we don't need to do a recursive delete.
// MoveTo() is recursive. At this point,
// we've already moved the children of the current folder
// to the new location. nothing should be left in the folder.
if (move)
{
}
}
// If we moved, we want to adjust this.
if (move)
{
MakeDirty();
if (newParentPath.IsEmpty())
return NS_ERROR_FAILURE;
{
}
else
{
}
}
return NS_OK;
}
{
}
{
}
{
}
{
return rv;
if (! isFile)
return NS_ERROR_FILE_IS_DIRECTORY;
if (*_retval)
return NS_OK;
return NS_ERROR_NULL_POINTER;
}
{
return rv;
if (isDir)
{
if (recursive)
{
return NS_ERROR_OUT_OF_MEMORY;
while (more)
{
}
}
}
else
{
}
MakeDirty();
return rv;
}
{
*aLastModifiedTime = 0;
return rv;
// microseconds -> milliseconds
return NS_OK;
}
{
return NS_ERROR_NOT_IMPLEMENTED;
}
{
}
{
return NS_ERROR_NOT_IMPLEMENTED;
}
{
return rv;
FIL_STANDARD, // Level 1 info
&pathInfo,
sizeof(pathInfo));
{
return rv;
}
// PR_ExplodeTime expects usecs...
/* fdateLastWrite.year is based off of 1980 */
else
pathInfo.fdateLastWrite.month = pret.tm_month + 1; // Convert start offset -- Win32: Jan=1; NSPR: Jan=0
// ???? OS2TODO st.wDayOfWeek = pret.tm_wday;
// ??? OS2TODO st.wMilliseconds = pret.tm_usec/1000;
FIL_STANDARD, // Level 1 info
&pathInfo,
sizeof(pathInfo),
0UL);
return rv;
MakeDirty();
return rv;
}
{
return rv;
return NS_OK;
}
{
return NS_ERROR_NOT_IMPLEMENTED;
}
{
return rv;
return NS_ERROR_FAILURE;
return NS_OK;
}
{
return NS_ERROR_NOT_IMPLEMENTED;
}
{
*aFileSize = 0;
return rv;
return NS_OK;
}
{
return rv;
&hFile,
0,
NULL);
{
MakeDirty();
return NS_ERROR_FAILURE;
}
// Seek to new, desired end of file
else
goto error;
MakeDirty();
return NS_OK;
MakeDirty();
return NS_ERROR_FAILURE;
}
{
return NS_ERROR_NOT_IMPLEMENTED;
}
{
sizeof(fsAllocate));
return NS_ERROR_FAILURE;
return NS_OK;
}
{
// cannot use nsCString::RFindChar() due to 0x5c problem
- (const unsigned char *) parentPath.get());
if (offset < 0)
return NS_ERROR_FILE_UNRECOGNIZED_PATH;
{
}
return rv;
}
{
MakeDirty();
return NS_OK;
}
{
return rv;
FIL_STANDARD, // Level 1 info
&pathInfo,
sizeof(pathInfo));
{
return rc;
}
return NS_OK;
}
{
return rv;
return NS_OK;
}
{
return rv;
} else {
}
return NS_OK;
}
{
return rv;
return NS_OK;
}
{
return rv;
return rv;
}
{
return rv;
FIL_STANDARD, // Level 1 info
&pathInfo,
sizeof(pathInfo));
{
return rc;
}
return NS_OK;
}
{
// No Symlinks on OS/2
return NS_OK;
}
{
return rv;
FIL_STANDARD, // Level 1 info
&pathInfo,
sizeof(pathInfo));
{
return rc;
}
return NS_OK;
}
{
return NS_OK;
}
{
{
// now make sure that the |inFile|'s path has a trailing
// separator.
{
}
}
return NS_OK;
}
{
return NS_OK;
}
/* attribute PRBool followLinks; */
{
*aFollowLinks = PR_TRUE;
return NS_OK;
}
{
return NS_OK;
}
{
return rv;
if (!isDir)
return NS_ERROR_FILE_NOT_DIRECTORY;
return NS_ERROR_OUT_OF_MEMORY;
{
return rv;
}
return NS_OK;
}
{
return GetNativePath(aPersistentDescriptor);
}
{
return InitWithNativePath(aPersistentDescriptor);
}
#ifndef OPEN_DEFAULT
#define OPEN_DEFAULT 0
#define OPEN_CONTENTS 1
#endif
{
if (isDirectory)
{
}
else
{
if (parent)
}
// we don't care if it succeeded or failed.
return NS_OK;
}
{
// we don't care if it succeeded or failed.
return NS_OK;
}
{
return NS_ERROR_OUT_OF_MEMORY;
return rv;
}
}
return NS_OK;
}
// Locates the first occurrence of charToSearchFor in the stringToSearch
static unsigned char* PR_CALLBACK
{
const unsigned char* p = stringToSearch;
do {
if (*p == charToSearchFor)
break;
p = (const unsigned char*)WinNextChar(0,0,0,(char*)p);
} while (*p); /* enddo */
// Result is p or NULL
return *p ? (unsigned char*)p : NULL;
}
// Locates last occurence of charToSearchFor in the stringToSearch
extern unsigned char*
{
const unsigned char* p = stringToSearch+length;
do {
if (*p == charToSearchFor)
break;
p = (const unsigned char*)WinPrevChar(0,0,0,(char*)stringToSearch,(char*)p);
} while (p > stringToSearch); /* enddo */
// Result is p or NULL
return (*p == charToSearchFor) ? (unsigned char*)p : NULL;
}
// Implement equivalent of Win32 CreateDirectoryA
static nsresult PR_CALLBACK
{
// Check if directory already exists and if so, reflect that in the return value
FIL_STANDARD, // Level 1 info
&pathInfo,
sizeof(pathInfo));
}
else
return rv;
}
static int isleadbyte(int c)
{
12 bytes is sufficient */
if( !bDBCSFilled ) {
COUNTRYCODE ctrycodeInfo = { 0 };
DBCSInfo );
/* we had an error, do something? */
return FALSE;
}
}
/* DBCSInfo returned by DosQueryDBCSEnv is terminated with two '0' bytes in a row */
break;
}
curr+=2;
}
return retval;
}
{
return InitWithNativePath(nsCString());
if (NS_SUCCEEDED(rv))
return InitWithNativePath(tmp);
return rv;
}
{
return NS_OK;
if (NS_SUCCEEDED(rv))
return AppendNative(tmp);
return rv;
}
{
return NS_OK;
if (NS_SUCCEEDED(rv))
return AppendRelativeNativePath(tmp);
return rv;
}
{
if (NS_SUCCEEDED(rv))
return rv;
}
{
return SetNativeLeafName(nsCString());
if (NS_SUCCEEDED(rv))
return SetNativeLeafName(tmp);
return rv;
}
{
}
{
if (NS_SUCCEEDED(rv))
return rv;
}
{
if (NS_SUCCEEDED(rv))
return rv;
}
{
if (NS_SUCCEEDED(rv))
return rv;
}
{
if (NS_SUCCEEDED(rv))
return rv;
}
{
return rv;
}
}
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
void
{
}
void
{
}