static void _fileCreateDirectory(const char *fileName, unsigned short volRefNum) { #ifndef USE_FILE_API int i = 0; for (i = 0; i < stringLen(fileName); i++) { if (fileName[i] == '/') { char *tempPath = stringDup(fileName); if (tempPath) { FileRef fileRef; tempPath[i + 1] = 0; // Try to open the path, if that fails we need to create it if (!VFSFileOpen(volRefNum, tempPath, vfsModeRead, &fileRef)) { VFSFileClose(fileRef); } else { VFSDirCreate(volRefNum, tempPath); } memMgrChunkFree(tempPath); } else { // To bad, we'll just fail for now break; } } } #endif }
/* Open the specified database, return the result from the database call */ static Err OpenVFSDatabase ( UInt16 volumeRef, /* file's volume reference */ Char* path, /* path to file */ FileRef* fileRef, /* upon successful return, the access pointer */ UInt16* version, /* upon successful return, the specific version number */ Char* name, /* upon successful return, the name */ UInt32* date, /* upon successful return, the creation date */ UInt16* numRecords /* upon successful return, the number of records */ ) { Err err; if ( path == NULL || fileRef == NULL || version == NULL || name == NULL || date == NULL || numRecords == NULL ) return vfsErrBadData; err = VFSFileOpen( volumeRef, path, vfsModeRead, fileRef ); if ( err != errNone ) return err; err = VFSFileDBInfo( *fileRef, name, NULL, NULL, date, NULL, NULL, NULL, NULL, NULL, NULL, NULL, numRecords ); return err; }
int fileFlushDirectory(char *directory) { #ifndef USE_FILE_API FileRef dirRefNum; Err error = errNone; UInt32 volIterator = vfsIteratorStart; UInt32 dirIterator = vfsIteratorStart; UInt16 volRefNum = 0; FileInfoType info; char *fileName = memMgrChunkNew(1024); if (!fileName || !directory) goto fileEmptyDir_Error; error = VFSVolumeEnumerate(&volRefNum, &volIterator); if (error) { goto fileEmptyDir_Error; } error = VFSFileOpen(volRefNum, directory, vfsModeRead, &dirRefNum); if (error) { goto fileEmptyDir_Error; } info.nameP = fileName; info.nameBufLen = 1024; while ((dirIterator != vfsIteratorStop) && !error) { error = VFSDirEntryEnumerate(dirRefNum, &dirIterator, &info); if (error) goto fileEmptyDir_Error; if (!(info.attributes & vfsFileAttrDirectory)) { error = VFSFileDelete(volRefNum, info.nameP); // Ignore errors } } memMgrChunkFree(fileName); return 0; fileEmptyDir_Error: if (fileName) memMgrChunkFree(fileName); return -1; #endif }
FILE *fileOpen(const char *fileName, const char *mode) { Err error = errNone; FILE *fileOut = NULL; Boolean rw = 0; UInt32 openMode = 0; #ifndef USE_FILE_API UInt32 volIterator = vfsIteratorStart; #endif if (!fileName || !mode) return NULL; fileOut = (FILE *)memMgrChunkNew(sizeof(FILE)); if (!fileOut) return NULL; rw = ((mode[1] == '+') || (mode[1] && (mode[2] == '+'))); #ifdef USE_FILE_API switch (mode[0]) { case 'r': openMode = (rw)?fileModeReadWrite:fileModeReadOnly; break; case 'w': openMode = fileModeReadWrite; break; default: goto fileOpen_Error; break; } fileOut->fileHand = FileOpen(0, fileName, 0, 0, openMode, &error); #else switch (mode[0]) { case 'r': openMode = (rw)?vfsModeReadWrite:vfsModeRead; break; case 'w': openMode = vfsModeReadWrite; break; default: goto fileOpen_Error; break; } error = VFSVolumeEnumerate(&fileOut->volRefNum, &volIterator); if (error) { goto fileOpen_Error; } error = VFSFileOpen(fileOut->volRefNum, fileName, openMode, &fileOut->fileRef); if (error == vfsErrFileNotFound) { _fileCreateDirectory(fileName, fileOut->volRefNum); error = VFSFileCreate(fileOut->volRefNum, fileName); if (error) { goto fileOpen_Error; } error = VFSFileOpen(fileOut->volRefNum, fileName, openMode, &fileOut->fileRef); if (error) { goto fileOpen_Error; } } else if (error) { goto fileOpen_Error; } #endif return fileOut; fileOpen_Error: if (fileOut) memMgrChunkFree(fileOut); return NULL; }
/*============================================================================ Description: See documentation for standard C library fopen ==========================================================================*/ PALM_FILE* palm_fopen( const char* in_name, const char* in_mode, UInt16 in_volRef ) { Err err = errNone; UInt32 PalmMode = 0; UInt16 vfsMode = 0; PALM_FILE* file = NULL; FileHand fh = NULL; FileRef fr = NULL; /* supported modes: "r" "w" "a" "r+" "w+" "a+" */ /* Note: All files are opened as binary, unsupported modes: "c", "n" */ if( strstr( in_mode, "a+" ) ) { PalmMode = fileModeAppend; // Append doesn't appear to be possible in VFS ChASSERT(in_volRef == ((UInt16)-1)); } else if( strstr( in_mode, "w+" ) ) { PalmMode = fileModeReadWrite; vfsMode = vfsModeReadWrite; } else if( strstr( in_mode, "r+" ) ) { PalmMode = fileModeUpdate; vfsMode = vfsModeReadWrite; } else if( strstr( in_mode, "a" ) ) { PalmMode = fileModeAppend; // Append doesn't appear to be possible in VFS ChASSERT(in_volRef == ((UInt16)-1)); } else if( strstr( in_mode, "w" ) ) { PalmMode = fileModeReadWrite; vfsMode = vfsModeReadWrite; } else if( strstr( in_mode, "r" ) ) { PalmMode = fileModeReadOnly; vfsMode = vfsModeRead; } else { /* error */ return NULL; } if (in_volRef == ((UInt16)-1)) // If the file is on the Palm device itself { fh = FileOpen( 0, in_name, 0, 0, PalmMode, &err ); if( fh ) { file = (PALM_FILE*)MemPtrNew( sizeof(PALM_FILE) ); file->file.fh = fh; file->volRef = ((UInt16)-1); } else { /* ChTHROW(CS_INVALID_FILENAME); TODO raise error */ } } else // if the file is on an expansion card { err = VFSFileOpen(in_volRef, in_name, vfsMode, &fr); if ((err == errNone) && (fr != NULL)) { file = (PALM_FILE*)MemPtrNew( sizeof(PALM_FILE) ); if (file != NULL) { file->file.fr = fr; file->volRef = in_volRef; } } else { /* ChTHROW(CS_INVALID_FILENAME); TODO raise error */ } } return file; }
/* Add file to doc list */ static void AddVFSFile ( UInt16 volRefNum, FileInfoType* info, const Char* dir, UInt16 location, EnumerateCardType enumerateWhat ) { Err err; Char* path; FileRef ref; DocumentInfo docInfo; UInt32 type; UInt32 creatorID; /* Set path to document */ path = SafeMemPtrNew( StrLen( dir ) + StrLen( info->nameP ) + 2 ); StrCopy( path, dir ); StrCat( path, info->nameP ); err = VFSFileOpen( volRefNum, path, vfsModeRead, &ref ); if ( err == errNone ) { Char volumeLabel[ LABEL_LEN ]; err = VFSFileDBInfo( ref, docInfo.name, &docInfo.attributes, NULL, &docInfo.created, NULL, NULL, NULL, NULL, NULL, &type, &creatorID, NULL ); if ( err == errNone && IsDocScan( enumerateWhat ) && type == ViewerDocumentType && creatorID == ViewerAppID ) { DocumentData* handlePtr; MemHandle handle; UInt16 index; VFSFileSize( ref, &docInfo.size ); GetPluckerVolumeLabel( volRefNum, volumeLabel, LABEL_LEN ); docInfo.cardNo = 0; docInfo.filename = info->nameP; VFSFileClose( ref ); handle = FindDocData( docInfo.name, numOfElements, &index ); if ( handle != NULL ) { UInt16 categories; UInt32 oldCreated; UInt16 oldLocation; Boolean oldActive; Char oldVolumeLabel[ LABEL_LEN ]; UInt16 fileLen; UInt16 volumeLabelLen; UInt32 timestamp; SetFoundDocument( index ); handlePtr = MemHandleLock( handle ); oldCreated = handlePtr->created; oldLocation = handlePtr->location; oldActive = handlePtr->active; categories = handlePtr->categories; timestamp = handlePtr->timestamp; fileLen = StrLen( handlePtr->data ) + 1; volumeLabelLen = StrLen( handlePtr->data + fileLen ) + 1; StrNCopy( oldVolumeLabel, handlePtr->data + fileLen, volumeLabelLen ); MemHandleUnlock( handle ); /* If the document is newer than the stored one, or moved to external card then updated info */ if ( ! oldActive || oldCreated < docInfo.created || oldLocation != location || ! STREQ( volumeLabel, oldVolumeLabel ) ) { /* Assign remaining document data */ docInfo.location = location; docInfo.active = true; docInfo.categories = categories; /* A "new" document should be indicated as unread */ if ( ! oldActive || oldCreated < docInfo.created ) docInfo.timestamp = 0; else docInfo.timestamp = timestamp; /* If document has been moved to external card the meta database must be renamed */ if ( oldLocation != location ) VFSRenameMetaDocument( docInfo.name, oldLocation, &docInfo ); UpdateDocument( &docInfo, volumeLabel, index, &handle ); } } else { docInfo.location = location; docInfo.volumeRef = volRefNum; docInfo.active = true; docInfo.timestamp = 0; ErrTry { docInfo.categories = GetDefaultCategories( &docInfo ); } ErrCatch( UNUSED_PARAM( err ) ) { docInfo.categories = UNFILED_CATEGORY; } ErrEndCatch AddDocument( &docInfo, volumeLabel ); } }