home *** CD-ROM | disk | FTP | other *** search
- /* file.c - file-handle stuff for the XFH file system handler.
- Copyright (C) 1991, 1992, 1993 Kristian Nielsen.
-
- This file is part of XFH, the compressing file system handler.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
-
- #include "CFS.h"
-
- #include <string.h>
-
- #include <dossupport.h>
-
-
- /*
- * RawCFSOpen() is the low-lewel Open() function of the CFS file
- * system. It takes a simple filename (that is, no path specification),
- * a lock to the parent directory, and a 'mode' value as arguments. A
- * special case occurs for a null name, in which case it opens the file
- * associated with the passed lock.
- */
-
- struct CFSFH *RawCFSOpen(glb glob, struct CFSLock *lock,
- char * name, LONG mode ){
- struct FileHandle *xfh;
- void *fh;
-
- /* Here is the place to check whether the lock refers to a
- * directory in the underlying file system, or if it is in fact
- * a directory in an archieve. This code is for the former case: */
-
- if( lock->objtype == XOBJECT ){
- LONG type;
- BOOL isnew = FALSE; /* Whether MODE_READWRITE file is new. */
-
- /* ToDo: Need better way to determine the correct action. */
- if( mode != MODE_OLDFILE && mode != MODE_NEWFILE && mode != MODE_READWRITE ){
- debug(("Error: RawCFSOpen(): Unsupported Open() mode %ld\n",mode));
- glob->ioerr = ERROR_ACTION_NOT_KNOWN;
- return NULL;
- }
-
- if(mode==MODE_READWRITE){
- /* Check that append mode is allowed. */
- if(!glob->allowappend){
- debug(("Append mode not set... failing.\n"));
- glob->ioerr = ERROR_ACTION_NOT_KNOWN;
- return NULL;
- }
- /* Try to determine whether file already exists. NOTE: this is
- * NOT fool-proof, since there is a (slight) change that the
- * file may suddenly appear just before the xOpen() call.
- */
- isnew = !xExists1(glob, lock->xlock, name);
- }
- if( !(xfh=xOpen(glob, lock->xlock, name, mode)) ){
- debug(("RawCFSOpen(): Object %s could not be opened: %d.\n",name,glob->ioerr));
- return NULL;
- }
- if( mode == MODE_NEWFILE ){
- /* NOTE: the name cannot be "" (since then it's already in use). */
- if(!strcmp(name,"")){
- debug(("Strange...empty name in open new file - failing.\n"));
- xClose(glob, xfh);
- xDeleteFile(glob, lock->xlock, name);
- glob->ioerr = ERROR_OBJECT_IN_USE;
- return NULL;
- }
- if(!(fh = XObjCreateFH(glob, xfh, mode, name, lock))){
- SAVEIOERR;
- xClose(glob, xfh);
- xDeleteFile(glob, lock->xlock, name);
- RESTIOERR;
- return NULL;
- }
- }else{ /* MODE_OLDFILE or MODE_READWRITE */
- type = xFileType( glob, xfh );
- /* 'type' will be XObj for new file created with MODE_READWRITE. */
- if( type == XPKOBJECT ){
- if( mode==MODE_OLDFILE ){
- struct CFSFH *newfh=(struct CFSFH *)XpkOpenOldFile( glob, xfh );
- if(!newfh){
- SAVEIOERR;
- xClose(glob,xfh);
- RESTIOERR;
- return NULL;
- }
- /* Ready for Write() if needed. */
- if(!XObjStuffFH(glob, newfh, name, lock)){
- SAVEIOERR;
- Xpk_Close(glob, (struct XpkFH *)newfh);
- RESTIOERR;
- return NULL;
- }
- fh = newfh;
- }else{ /* MODE_READWRITE */
- BOOL res;
-
- xClose(glob,xfh);
- debug(("Attempting to uncompress file %s.\n",name));
- res = TransformFile(glob, lock->xlock, name, UnPackFile2File, NULL);
- debug(("TransformFile() returned: %ld.\n",res));
- if(!res) return NULL;
- if( !(xfh=xOpen(glob, lock->xlock, name, mode)) ){
- debug(("Error: File %s could not be re-opened: %d.\n",name,glob->ioerr));
- return NULL;
- }
- fh = XObjCreateFH(glob, xfh, mode, name, lock);
- if(!fh){
- SAVEIOERR;
- xClose(glob, xfh);
- RESTIOERR;
- return NULL;
- }
- }
- }else{
- /* A plain file. If the mode is MODE_READWRITE and the file
- * was newly created, the user can request the file to be
- * autocompressed. Otherwise, the file will not be compressed.
- */
- if(mode==MODE_READWRITE && isnew && glob->compressreadwrite){
- fh = XObjCreateFH(glob, xfh, mode, name, lock);
- }else{
- fh = XObjCreateFH(glob, xfh, mode, NULL, NULL);
- }
- if(!fh){
- SAVEIOERR;
- xClose(glob, xfh);
- RESTIOERR;
- return NULL;
- }
- }
- }
- }else if( lock->objtype == XPKOBJECT ){ /* Allow Open(xpklock,""). */
- if( mode != MODE_OLDFILE ){
- debug(("Bad open from XpkLock (mode=%ld).\n",mode));
- if(!strcmp(name,"")){
- glob->ioerr = ERROR_OBJECT_IN_USE;
- }else{
- glob->ioerr = ERROR_OBJECT_WRONG_TYPE;
- }
- return NULL;
- }else if(strcmp(name,"")){
- debug(("Bad open (non-null filename) from Xpklock.\n"));
- glob->ioerr = ERROR_OBJECT_WRONG_TYPE;
- return NULL;
- }else{
- struct CFSFH *newfh = (struct CFSFH *)
- XpkOpenOldFileFromCopyOfLock( glob, (struct XpkLock *)lock );
- if(!newfh){
- return NULL;
- }
- /* Ready for Write() if needed. */
- if(!XObjStuffFH(glob, newfh, name, lock)){
- SAVEIOERR;
- Xpk_Close(glob, (struct XpkFH *)newfh);
- RESTIOERR;
- return NULL;
- }
- fh = newfh;
- }
- }else{
- debug(("** PANIC **: bad object type in lock: %ld\n",lock->objtype));
- glob->ioerr = ERROR_OBJECT_WRONG_TYPE;
- return NULL;
- }
- return fh;
- }
-
-
- struct CFSFH *CFSOpen(glb glob,struct CFSLock * parentlock,
- char * name,LONG mode){
- struct CFSLock *parent;
- struct CFSFH *fh;
- LONG saveioerr;
-
- /* Lock the parent directory, and set 'name' to point to the actual
- * name. For a path like 'name:', lock the file/dir and point name to
- * "".
- */
- if(!(parent = CFSLockParent(glob, parentlock, &name ))){
- debug(("Error: CFSOpen(): Could not CFSLockParent(): %ld.\n",glob->ioerr));
- return NULL;
- }
-
- /* Now Lock the file or dir. */
- fh = RawCFSOpen( glob, parent, name, mode );
- saveioerr = glob->ioerr;
- CFSUnLock( glob, parent );
- glob->ioerr = saveioerr;
-
- return fh;
- }
-
-
- BOOL CFSClose( glb glob, struct CFSFH *fh ){
-
- if( !fh ) return DOSTRUE;
- return (BOOL) (*fh->f->Close)( glob, fh );
- }
-
-
- LONG CFSRead( glb glob, struct CFSFH *fh, void *buf, LONG len ){
-
- if( !fh )
- return 0L;
- else
- return (*fh->f->Read)( glob, fh, buf, len );
- }
-
-
- LONG CFSWrite( glb glob, struct CFSFH *fh, void *buf, LONG len ){
-
- if( !fh )
- return 0L;
- else
- return (*fh->f->Write)( glob, fh, buf, len );
- }
-
-
- LONG CFSSeek( glb glob, struct CFSFH *fh, LONG pos, LONG offset ){
-
- if( !fh )
- return -1L;
- else if( !fh->f ){
- debug(("** PANIC **: CFSSeek(): NULL action func.\n"));
- glob->ioerr = ERROR_OBJECT_WRONG_TYPE;
- return -1L;
- }else
- return (*fh->f->Seek)( glob, fh, pos, offset );
- }
-
- /* End of file.c */
-