Tech Note 23: VFSLib

October 21 2003

© NSB Corporation. All rights reserved.

Contents:

    Introduction

    Function Index and Quick Reference

    Function Reference

    Error codes

Introduction:

The NSBVFSLib Shared Library contains functions that provide access to the external storage card(s).

The functions in this library are divided into the following categories:

Volume, Directory, File, File and Directory, Import/Export
This document, with its examples, should provide all the information necessary to use the functions in the NSBVFSLib. If more information about the underlying PalmOS functions is desired, please consult the PalmOS SDK Reference or the SDK C header files (*.h). The PalmOS SDK Reference can be downloaded from:
    http://www.palmos.com/dev/tech/docs/
The PalmOS SDK (Software Development Kit) can be downloaded from:
    http://www.palmos.com/dev/tech/tools/
In order to use the NSBVFSLib Shared Library, the library must be loaded using the NSBasic LoadLibrary statement. This statement should be located in the program's Startup code so that the functions will be available throughout the program. The LoadLibrary statement has an optional second parameter to allow you to specify an abbreviated reference name for the library's functions. The examples in this document use "VFS" for this reference name. Example:
 
Program's Startup code:



        Sub main()

            LoadLibrary "NSBVFSLib", "VFS"

        End Sub

Also, in order to use the NSBVFSLib Shared Library, the NSBVFSLib.INF file must be present in your "nsbasic\lib" directory and the NSBVFSLib.prc file must be downloaded to your device.

Function Index and Quick Reference:

Internal Information

Version result = Version()
GetLastError result = GetLastError()
Init result = Init()

Volume functions

BeginVolumeEnumerate BeginVolumeEnumerate()
GetNextVolume volume = GetNextVolume()
SetCurVolume SetCurVolume(Integer volume)
GetVolumeLabel result = GetVolumeLabel()
SetVolumeLabel SetVolumeLabel(String label)
IsVolumeReadOnly result = IsVolumeReadOnly()
IsVolumeHidden result = IsVolumeHidden()
VolumeUsedSize size = VolumeUsedSize()
VolumeTotalSize size =VolumeTotalSize()
VolumeFormat VolumeFormat()
GetVolumeMediaType mediaType = GetVolumeMediaType()

Directory Functions

DirCreate DirCreate(dirName)
BeginDirEntryEnumerate BeginDirEntryEnumerate(dir)
EndDirEntryEnumerate EndDirEntryEnumerate()
DirEntryEnumerate FileOrDirName = DirEntryEnumerate()
RegisterDefaultDirectory RegisterDefaultDirectory(fileType,indexMediaType, path)
UnregisterDefaultDirectory UnregisterDefaultDirectory(fileType, indexMediaType)
GetDefaultDirectory path = GetDefaultDirectory(fileType)

File Functions

IsEOF eof = IsEof(fileRef)
FileCreate FileCreate(path)
Read16 res = Read16(fileRef)
Read32 res = Read32(fileRef)
Read64 res = Read64(fileRef)
ReadString res = ReadString(fileRef)
Write16 Write16(fileRef, data)
Write32 Write32(fileRef,data)
Write64 Write64(fileRef, data)
WriteString WriteString(fileRef, str)
FileTell pos = FileTell(fileRef)
FileSize size = FileSize(fileRef)
FileResize FileResize(fileRef, newSize)
FileSeekBegin FileSeekBegin(fileRef, offset)
FileSeekCurrent FileSeekCurrent(fileRef, offset)
FileSeekEnd FileSeekEnd(fileRef, offset)

File and directory functions

Delete Delete(path)
Close Close(fileRef)
Rename Rename(pathName, newName)
SetDateCreated SetDateCreated(fileRef, date)
SetDateModified SetDateModified(fileRef, date)
SetDateAccessed SetDateModified(fileRef, date)
GetDateCreated date = GetDateCreated(fileRef)
GetDateModified date = GetDateModified(fileRef)
GetDateAccessed date = GetDateAccessed(fileRef)
SetAttributes SetAttributes(fileRef, attributes)
ResetAttributes ResetAttributes(fileRef, attributes)
GetAttributes coinside = GetAttributes(fileRef,  checkAttributes)
Open fileRef = Open(pathName, openMode)

Import/Export

Import dbName = Import(pathName)
Export Export(dbName, pathName)
ImportDialog dbName = ImportDialog(pathName, dialogTitle, actionStr)
ExportDialog ExportDialog(dbName, pathName , dialogTitle, actionStr)

Card Info

GetDeviceUniqueIDStr DeviceUniqueIDStr = GetDeviceUniqueIDStr
 

NSBVFSLib Function Reference:


Internal Information

Version

version = VFS.Version()
Returns the version number of the NSBVFSLib Shared Library.

Returns 

version as Integer

Example

Dim version as Integer 
version = VFS.Version()

GetLastError

error = VFS.GetLastError()
Returns an error of the last fullfilled lib function.

Returns 

error as Integer.

Example

Dim err as Integer 
err = VFS.GetLastError()

Init

result = VFS.Init()
returns 0 if VFS and EXPANSION managers are present and an error otherwise If 0 does not returned any function must not be called.

Returns 

result as Integer.

Example

Dim err as Integer 
err = VFS.Init()

Volume functions

BeginVolumeEnumerate

VFS.BeginVolumeEnumerate()
Initialize the lib before the enumeration of volumes.

Example

VFS.BeginVolumeEnumerate()

GetNextVolume

volume = VFS.GetNextVolume()
Returns next volume number. Returns correct volume ONLY if GetLastError returns 0.

Returns 

volume as Integer.

Example


Global volRef(4) as Integer
Global numVol as Integer
Dim err as Integer
Dim i as Integer
list.clear
VFS.BeginVolumeEnumerate()
numVol = 0
Do
i = VFS.GetNextVolume()
err = VFS.GetLastError()
If err = 0 Then
    numVol = numVol + 1
    volRef(numVol) = i
Else
    Exit Do
EndIf
Loop

SetCurVolume

VFS.SetCurVolume(volume)
Makes active chosen volume.

Parameter 

volume as Integer.

Example 

VFS.SetCurVolume(volRef(0))

GetVolumeLabel

label = VFS.GetVolumeLabel()
Returns label of the active volume

Returns 

label as String.

Example 

Dim label as String 
label = VFS.GetVolumeLabel()

SetVolumeLabel

VFS.SetVolumeLabel(label)
Sets label to an active volume

Parameter 

label as string.

Example

Dim label as String 
label = "my volume label" 
VFS.SetVolumeLabel(label)

IsVolumeReadOnly

result = VFS.IsVolumeReadOnly()
Returns 1 if the active volume is read only.

Returns 

result as Integer.

Example

Dim volumeReadOnly as Integer
Dim VROStr as String
volumeReadOnly = VFS.IsVolumeReadOnly()
VROStr = "Read/Write"
if volumeReadOnly = 1 then VROStr = "Read"

IsVolumeHidden

result = VFS.IsVolumeHidden()
Returns 1 if the active volume is hidden.

Returns 

result as Integer.

Example

Dim volumeHidden as Integer
Dim HStr as String
volumeHidden = VFS.IsVolumeHidden()
HStr = "Visible"
if volumeHidden = 1 then HStr = "Hidden"

VolumeUsedSize

size = VFS.VolumeUsedSize()
Returns number of used bytes of the active volume.

Returns 

size as Integer.

Example

Dim volUsedSize as Integer 
volUsedSize =VFS.VolumeUsedSize()

VolumeTotalSize

size = VFS.VolumeTotalSize()
Returns number of bytes of the active volume.

Returns 

size as Integer.

Example

Dim volTotalSize as Integer  
volTotalSize= VFS.VolumeTotalSize()

VolumeFormat

VFS.VolumeFormat()
Formats the active volume.

Example
VFS.VolumeFormat()

GetVolumeMediaType

mediaType = VFS.GetVolumeMediaType()
Returns media type of the active volume.

Returns 

mediaType as Integer.
 
Possible MEDIATYPEs
0 Matches all media types when looking up a default directory
1 Memory stick
2 Compact Flash
3 Secure Digital
4 MultiMedia Card
5 SmartMedia
6 A RAM disk based media
7 Host file system emulated by the Palm OS® Emulator
8 Host file system emulated by the Mac Simulator 

Example


Dim t(9) as String
Dim err as Integer
Dim m as Integer
t(1) = "Wild"
t(2) = "Memory stick"
t(3) = "Compact Flash"
t(4) = "Secure Digital"
t(5) = "MultiMedia Card"
t(6) = "SmartMedia"
t(7) = "A RAM disk based media"
t(8) = "HFS POSE"
t(9) = "HFS Mac Simulator"
m = VFS.GetVolumeMediaType()
fld.text = t(m+1)

Directory Functions

DirCreate

VFS.DirCreate(dirName)
Creates the directory with dirName  at the active volume.

Parameter 

dirName as string

Example

Dim path as Strin 
path = "/palm/My directory/" 
VFS.DirCreate(path)

BeginDirEntryEnumerate

VFS.BeginDirEntryEnumerate(directory)
Initialize the lib before the enumeration of a directory.

Parameter 

directory as String.

Example

Dim path as String 
path = "/palm/My directory/" 
VFS.BeginDirEntryEnumerate(path)

EndDirEntryEnumerate

VFS.EndDirEntryEnumerate()
Must be called after enumeration for a normal flow of the program.

Example&
VFS.EndDirEntryEnumerate()

DirEntryEnumerate

FileOrDirName = VFS.DirEntryEnumerate()
Enumerates the directory. Returns correct FileOrDirName ONLY if GetLastError returns 0.

Returns 

FileOrDirName as String.

Example

Dim dir as String
Dim err as Integer
Dim name as String
dir = "/palm/My directory/"
VFS.BeginDirEntryEnumerate(dir)
err = VFS.GetLastError
If err>0 Then GoTo ex
Do
name = VFS.DirEntryEnumerate()
err = VFS.GetLastError()    '10509 end of loop
If err > 0 Then Exit Do
lst.add name
Loop
ex:
VFS.EndDirEntryEnumerate

RegisterDefaultDirectory

VFS.RegisterDefaultDirectory(fileType, indexMediaType, path)
Registers a specific directory as the default location for files of a given type on a particular kind of external storage card. This function is generally called by a slot driver for files and media types that are supported by that slot driver. The file type may either be a MIME media type/subtype pair, such as "image/jpeg", “text/plain”, or “audio/basic”; or a file extension, such as “.jpeg.”.

Parameters 

fileType as String, IndexMediaType as Integer, path as String.

indexMediaType see GetVolumeMediaType.

Example

Dim fileType as String
Dim indexMediaType as Integer
Dim path as String
fileType = ".txt"
indexMediaType = 3 'Secure Digital
path = "/text/"
VFS.RegisterDefaultDirectory(fileType, indexMediaType, path)

UnregisterDefaultDirectory

VFS.UnregisterDefaultDirectory(string fileType, integer indexMediaType)
Sever the association between a particular file type and a default directory for a given type of card media.

Parameters 

fileType  as String, indexMediaType as Integer.

Example

Dim fileType as String
Dim indexMediaType as Integer
fileType = ".txt"
indexMediaType = 3 'Secure Digital
VFS.UnregisterDefaultDirectory(fileType, indexMediaType)

GetDefaultDirectory

path = VFS.GetDefaultDirectory(fileType)
Determine the default location on the given volume for files of a particular type.

Parameter 

fileType as String.

Returns

path as String

Example

Dim fileType as String
Dim path as String
fileType = ".txt"
path = VFS.GetDefaultDirectory(fileType)

File Functions

IsEOF

eof = VFS.IsEof(fileRef)
Returns 1 if the EOF of the opend file is reached and 0 otherwise.

Parameter 

fileRef as Integer. Returns

eof as Integer.

Example

Dim sh as Short
Dim eof as Integer
Dim fileRef as Integer
...' open file
Do
sh = VFS.Read16(fileRef)
eof = VFS.IsEof(fileRef)
If eof = 1 Then Exit Do
Loop
...' close file

FileCreate

VFS.FileCreate(path)
Creates file. The full PATH is needed.

Parameter 

path as String.

Example

Dim pathName as String 
pathName = "/palm/My directory/Sample.txt" 
VFS.FileCreate(pathName)

Read16

res = VFS.Read16(fileRef)
Reads a short from the file specified by fileRef.

Parameter 

fileRef as Integer. Returns

res as Short.

Example

Dim data16 as Short 
data16 = VFS.Read16(fileRef)

Read32

res = VFS.Read32(fileRef)
Reads a single from the file specified by fileRef.

Parameter 

fileRef as Integer. Returns

res as Integer.

Example 

Dim data32 as Integer 
data32 = VFS.Read32(fileRef)

Read64

res = VFS.Read64(fileRef)
Reads a double from the file specified by fileRef.

Parameter 

fileRef as Integer. Returns

res as double.

Example 

Dim data64 as Double 
data64 = VFS.Read64(fileRef)

ReadString

res = VFS.ReadString(fileRef)
Reads a string from the file specified by fileRef.

Parameter 

fileRef as Integer. Returns

res as String.

Example

Dim dataStr as String 
dataStr = VFS.ReadString(fileRef)

Write16

VFS.Write16(fileRef, data) Writes a short to the file specified by fileRef.

Parameters 

fileRef as Integer, data as Short.

Example

Dim data16 as Short 
VFS.Write16(fileRef, data16)

Write32

VFS.Write32(fileRef, data)
Writes a single to the file specified by fileRef.

Parameters 

fileRef as Integer, data as Integer.

Example

Dim data32 as Integer 
VFS.Write32(fileRef, data32)

Write64

VFS.Write64(fileRef, data)
Writes a double to the file specified by fileRef.

Parameters 

fileRef as Integer, data as Double.

Example

Dim data64 as Double 
VFS.Write64(fileRef, data64)

WriteString

VFS.WriteString(Integer fileRef, string str)
Writes a string to the file specified by fileRef.

Parameters 

fileRef as Integer, str as String.

Example

Dim dataStr as String 
VFS.WriteString(fileRef, dataStr)

FileTell

pos = VFS.FileTell(fileRef)
Returns position in the file specified by fileRef.

Parameter  

fileRef as Integer. Returns

pos as Integer.

Example

Dim pos as Integer 
pos = VFS.FileTell(fileRef)

FileSize

size = VFS.FileSize(fileRef)
Returns size of the file specified by fileRef.

Parameter  

fileRef as Integer. Returns

size as Integer.

Example

Dim size as Integer 
size = VFS.FileSize(fileRef)

FileResize

VFS.FileResize(fileRef, newSize)
Change (decrease) size of the file specified by fileRef. newSize is the new file size.

Parameters  

fileRef as Integer, newSize as Integer.

Example

Dim newSize as Integer 
VFS.FileResize(fileRef, newSize)

FileSeekBegin

VFS.FileSeekBegin(fileRef, offset)
Positions offset bytes from the beginning of  the file specified by fileRef.

Parameters  

fileRef as Integer, offset as Integer.

Example

Dim offset as Integer 
offset = 10 
VFS.FileSeekBegin(fileRef, offset)

FileSeekCurrent

VFS.FileSeekCurrent(fileRef, offset)
Shifts offset bytes from the current position in the file specified by fileRef.

Parameters 

fileRef as Integer, offset as Integer.

Example

Dim offset as Integer 
offset = 10 
VFS.FileSeekCurrent(fileRef, offset)

FileSeekEnd

VFS.FileSeekEnd(fileRef, offset)
Positions offset bytes backward from the end of the file specified by fileRef.

Parameters  

fileRef as Integer, offset as Integer.

Example

Dim offset as Integer 
offset = 10 
VFS.FileSeekEnd(fileRef, offset)

File and directory functions

Delete

VFS.Delete(path)
Deletes closed file or directory specified by full path path.

Parameter 

path as String.

Example

Dim path as String 
path = "/palm/My directory/Sample.dat" 
VFS.Delete(path)

Close

VFS.Close(fileRef)
Closes file or directory specified by fileRef.

Parameter  

fileRef as Integer.

Example

VFS.Close(fileRef)

Rename

VFS.Rename(pathName, newName)
Renames closed file or directory. It works ONLY within same directory. pathName is the full path, newName is the short one.

Parameters 

pathName as String, newName as String.

Example

Dim pathName as String
Dim newName as String
pathName = "/palm/My directory/Sample.dat"
newName = "Test.dat"
VFS.Rename(pathName, newName)

SetDateCreated

VFS.SetDateCreated(fileRef,date)
Sets the creation date of the file specified by fileRef.
Note:  this function is not supported by all file systems.

Parameters 

fileRef as Integer, date as Integer.

Example

Dim dateCreated as Integer
dateCreated = 123456789        ' seconds
VFS.SetDateCreated(fileRef,dateCreated)

SetDateModified

VFS.SetDateModified(fileRef, date)
Sets the modified date of the file specified by fileRef.
Note:  this function is not supported by all file systems.

Parameters 

fileRef as Integer, date as Integer.

Example

Dim dateModified as Integer
dateModified = 123456789        ' seconds
VFS.SetDateModified(fileRef,dateModified)

SetDateAccessed

VFS.SetDateAccessed(fileRef,date)
Sets the last access date of the file specified by fileRef
Note:  this function is not supported by all file systems.

Parameters 

fileRef as Integer, date as Integer.

Example

Dim dateAccessed as Integer
dateAccessed = 123456789        ' seconds
VFS.SetDateAccessed(fileRef,dateAccessed)

GetDateCreated

date = VFS.GetDateCreated(fileRef)
Returns the creation date of the file specified by fileRef.

Parameter 

fileRef as Integer. Returns

date as Integer.

Example

Dim dateCreated as Integer 
dateCreated = VFS.GetDateCreated(fileRef)

GetDateModified

date = VFS.GetDateModified(fileRef)
Returns the modified date of the file specified by fileRef.

Parameter 

fileRef as Integer. Returns

date as Integer.

Example

Dim dateModified as Integer 
dateModified = VFS.GetDateModified(fileRef)

GetDateAccessed

date = VFS.GetDateAccessed(fileRef)
Returns the last access date of the file specified by fileRef.

Parameter 

fileRef as Integer. Returns

date as Integer.

Example

Dim dateAccessed as Integer 
dateAccessed = VFS.GetDateAccessed(fileRef)

SetAttributes

VFS.SetAttributes(fileRef, attributes)
Sets attributes of the file specified by fileRef.

Parameters 

fileRef as Integer, attributes as Integer.
 
List of attributes
1 Read-only file or directory
2 Hidden file or directory
4 System file or directory
8 Volume label
16 Directory
32 Archived file or directory
64 Link to another file or directory

NOTE: SetAttributes  subroutine must not be used to change
Volume label(8) and Directory(16) attributes

Example

VFS.SetAttributes(fileRef,2)' 2 - hidden

ResetAttributes

VFS.ResetAttributes(fileRef, attributes)
Resets attributes of the file specified by fileRef.

Parameters 

fileRef as Integer, attributes as Integer.

NOTE: ResetAttributes  subroutine must not be used to change
Volume label(8) and Directory(16) attributes

Example

VFS.ResetAttributes(fileRef,2)' 2 - hidden

GetAttributes

coinside = VFS.GetAttributes(fileRef, checkAttributes)
Returns attributes of the file or directory specified by fileRef.

Parameters 

fileRef as Integer, checkAttributes as Integer. Returns

coinside as Integer.

Example

Dim coinside as Integer 
coinside = VFS.GetAttributes(fileRef, 2)' is it hidden?

Open

fileRef = VFS.Open(pathName, openMode)
Opens file or directory specified by full path pathName.

Parameters 

pathName as String, openMode as Integer. Returns

fileRef as Integer.
 
OPENMODE constants
2 Open for read access
3 Open and lock for read access
7 Open and lock for read/write access
15 Open and lock for read/write access; create if file not exists

Example

Dim pathName as String
Dim fileRef as Integer
pathName ="/palm/My directory/Sample.dat"
fileRef = VFS.Open(pathName,7)

Import/Export

Import

dbName = VFS.Import(pathName)
Creates a database from a .pdb or .prc file on an external storage card.

Parameter 

pathName as String is the full path for .pdb or .prc. Returns

dbName as String.

Example

Dim pathName as String
Dim dbName as String
pathName="/palm/My directory/Puzzle.prc"
dbName = VFS.Import(pathName)

Export

VFS.Export(dbName, pathName)
Saves the specified database to a .pdb or
.prc file on an external storage card.

Parameters 

dbName as String is the database name, pathName as String is the full path for .pdb or .prc.

Example

Dim pathName as String
Dim dbName as String
dbName="15-Puzzle"
pathName="/palm/My directory/Puzzle.prc"
VFS.Export(dbName, pathName)

ImportDialog

dbName = VFS.ImportDialog(pathName, dialogTitle, actionStr)
Creates a database from a .pdb or .prc file on an external storage card.
This function differs from Import in that it allows you to cancel the import operation.

Parameters 

pathName as String is the full path for .pdb or .prc., dialogTitle as String is the title of dialog, actionStr as String is the dialog message. Returns

dbName as String.

Example

Dim pathName as String
Dim dbName as String
Dim dialogTitle as String
Dim actionStr as String
pathName="/palm/My directory/Puzzle.prc"
dialogTitle="Import file"
actionStr="Importing Puzzle.prc"
dbName = VFS.ImportDialog(pathName, dialogTitle, actionStr)

ExportDialog

VFS.ExportDialog(dbName, pathName , dialogTitle, actionStr)
Saves the specified database to a .pdb or .prc file on an external storage card.
This function differs from Export in that it allows you to cancel the export operation.

Parameters 

dbName as String is the database name, pathName as String is the full path for .pdb or .prc, dialogTitle as String is the title of dialog, actionStr as String is the dialog message.

Example

Dim pathName as String
Dim dbName as String
Dim dialogTitle as String
Dim actionStr as String
dbName="15-Puzzle"
pathName="/palm/My directory/Puzzle.prc"
dialogTitle="Export file"
actionStr="Exporting "
actionStr= actionStr + dbName
VFS.ExportDialog(dbName,pathName , dialogTitle, actionStr)

Card Info

GetDeviceUniqueIDStr

DeviceUniqueIDStr = VFS.GetDeviceUniqueIDStr
Returns unique identifier for the product of the external storage card. A serial number for example. This value is set to the empty string if no identifier exist.

Returns 

DeviceUniqueIDStr as String.

Example

Dim GetDeviceUniqueIDStr as String
GetDeviceUniqueIDStr = VFS.GetDeviceUniqueIDStr

Error codes

0 errNone No error
537 dmErrAlreadyExists Another database with the same name already exists in RAM store.
1282 sysErrParamErr Wrong input parameter
10497 expErrUnsupportedOperation unsupported or undefined opcode and/or creator
10498 expErrNotEnoughPower the required power is not available
10499 expErrCardNotPresent no card is present
10500 expErrInvalidSlotRefNum slot reference number is bad
10501 expErrSlotDeallocated slot reference number is within valid range, but has been deallocated
10502 expErrCardNoSectorReadWrite the card does not support the SlotDriver block read/write API
10503 expErrCardReadOnly the card does support R/W API but the card is read only
10504 expErrCardBadSector the card does support R/W API but the sector is bad
10505 expErrCardProtectedSector The card does support R/W API but the sector is protected
10506 expErrNotOpen slot driver library has not been opened
10507 expErrStillOpen slot driver library is still open - maybe it was opened > once
10508 expErrUnimplemented Call is unimplemented
10509 expErrEnumerationEmpty No values remaining to enumerate
10510 expErrIncompatibleAPIVer The API version of this slot driver is not supported by this version of ExpansionMgr.
10753 vfsErrBufferOverflow passed in buffer is too small
10754 vfsErrFileGeneric Generic file error.
10755 vfsErrFileBadRef the fileref is invalid (has been closed, or was not obtained from VFS.Open() )
10756 vfsErrFileStillOpen returned from VFS.Delete if the file is still open
10757 vfsErrFilePermissionDenied The file is read only
10758 vfsErrFileAlreadyExists a file of this name exists already in this location
10759 vfsErrFileEOF file pointer is at end of file
10760 vfsErrFileNotFound file was not found at the path specified
10761 vfsErrVolumeBadRef the volume refnum is invalid
10762 vfsErrVolumeStillMounted returned if the volume is still mounted
10763 vfsErrNoFileSystem no installed filesystem supports this operation
10764 vfsErrBadData operation could not be completed because of invalid data (i.e., import DB from .PRC file)
10765 vfsErrDirNotEmpty can't delete a non-empty directory
10766 vfsErrBadName invalid filename, or path, or volume label or something...
10767 vfsErrVolumeFull not enough space left on volume
10768 vfsErrUnimplemented this call is not implemented
10769 vfsErrNotADirectory This operation requires a directory
10770 vfsErrIsADirectory This operation requires a regular file, not a directory
10771 vfsErrDirectoryNotFound Returned from VFS.FileCreate when the path leading up to the new file does not exist
10772 vfsErrNameShortened A volume name or filename was automatically shortened to conform to filesystem spec