home *** CD-ROM | disk | FTP | other *** search
- /* CFS.c - main packet loop.
- Copyright (C) 1991, 1992, 1993, 1994 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. */
-
- /* This file replaces the startup code! Make sure the object file
- * corresponding to this source is linked into the head of the final
- * executeable.
- */
-
- #include "CFS.h"
-
- #include <exec/ports.h>
- #include <exec/memory.h>
- #include <exec/execbase.h>
-
- #include <clib/alib_protos.h>
-
- #include <string.h>
- #include <stdarg.h>
-
- #include <dossupport.h>
-
- struct ExecBase *SysBase;
- struct DosLibrary *DOSBase;
-
- char Version[] = "$VER: XFH-Handler " VERSION " " __AMIGADATE__ "";
- char Copyright[] = "$COPYRIGHT: Copyright (C) 1991, 1992, 1993, 1994 Kristian Nielsen";
-
- /**************************************************************************
- * *
- * Handler entry point. *
- * *
- * Do initialisation and allocation, then enter main loop after returning *
- * our initial packet. *
- * *
- **************************************************************************/
-
- LONG __saveds NotReallyMain(void)
-
- {
- glb glob;
- struct DosPacket *pkt;
- int ret=0;
- struct FileLock *parent;
- void handle_packet(glb glob, struct DosPacket *pkt);
-
- SysBase=*(struct ExecBase **)4L;
- if ((glob=AllocMem(sizeof(struct glob),MEMF_CLEAR))==NULL) return(100);
-
- glob->ioerr=ERROR_ACTION_NOT_KNOWN; /* Default error code. */
-
- debug (("XFH/CFS compressing file system handler v" VERSION ".\n"
- "Copyright (C) 1991,1992,1993 Kristian Nielsen.\n"));
- debug (("Starting handler with task at 0x%lx.\n",FindTask(0L)));
-
- glob->dosport=&(glob->myproc=(struct Process *)(glob->mytask=FindTask(0L)))->pr_MsgPort;
-
- pkt=getpkt(glob);
- glob->devnode=(struct DeviceNode *)b2c(pkt->dp_Arg3);
- if (glob->devnode->dn_Name==NULL)
- {
- debug (("Error: NULL device name - exiting.\n"));
- glob->ioerr=ERROR_INVALID_COMPONENT_NAME;
- returnpkt (pkt,DOSFALSE,glob->ioerr,glob);
- ret=100;
- goto exitthis;
- }
-
- if ((glob->devname=copybstr(glob->devnode->dn_Name))==NULL)
- {
- debug (("Error copying device name - exiting.\n"));
- OUTOFMEM;
- returnpkt (pkt,DOSFALSE,glob->ioerr,glob);
- ret=100;
- goto exitthis;
- }
- if (glob->devname[0]=='\0')
- {
- debug (("Error: Empty device name - exiting.\n"));
- glob->ioerr=ERROR_INVALID_COMPONENT_NAME;
- returnpkt (pkt,DOSFALSE,glob->ioerr,glob);
- ret=100;
- goto exitthis;
- }
-
- debug (("Using device name '%s'.\n",glob->devname));
-
- glob->bcplstartup=glob->devnode->dn_Startup;
-
- if ((glob->ioport=CreatePort(NULL,0L))==NULL)
- {
- OUTOFMEM;
- returnpkt (pkt,DOSFALSE,glob->ioerr,glob);
- ret=100;
- debug (("Error creating message port - exiting.\n"));
- goto exitthis;
- }
-
- if ((glob->DOSBase=OpenLibrary("dos.library",0L))==NULL)
- {
- glob->ioerr=ERROR_INVALID_RESIDENT_LIBRARY;
- returnpkt (pkt,DOSFALSE,glob->ioerr,glob);
- debug (("Error opening dos.library - exiting.\n"));
- ret=100;
- goto exitthis;
- }
- DOSBase=glob->DOSBase;
-
- /* Set primary options (from S:.xfhrc.<unit>, if available). */
- if (!InitOptions(glob))
- {
- returnpkt (pkt,DOSFALSE,ERROR_BAD_TEMPLATE,glob);
- debug (("Error setting primary options - exiting.\n"));
- ret=100;
- goto exitthis;
- }
-
- if (!InitXpk(glob))
- {
- returnpkt (pkt,DOSFALSE,glob->ioerr,glob);
- debug (("Error initialising Xpk routines - exiting.\n"));
- ret=100;
- goto exitthis;
- }
-
- debug (("Using '%s' as root directory...\n",glob->xRootName));
- glob->xprocid=DoDeviceProc( (LONG *)&glob->xrootlock,glob->xRootName,glob);
- if (!glob->xprocid)
- {
- glob->xrootlock=0L; /* Don't xUnLock() */
- returnpkt (pkt,DOSFALSE,ERROR_OBJECT_NOT_FOUND,glob);
- ret=100;
- debug (("Error doing DeviceProc(%s) - exiting.\n",glob->xRootName));
- goto exitthis;
- }
- glob->xrootlock=b2c(glob->xrootlock);
- debug (("DeviceProc(%s) returned: %lx %lx\n",glob->xRootName,
- glob->xprocid,glob->xrootlock));
- glob->xrootlock=xLock(glob,glob->xrootlock,glob->xRootName,ACCESS_READ);
- if (glob->xrootlock==NULL)
- {
- returnpkt (pkt,DOSFALSE,glob->ioerr,glob);
- ret=100;
- debug (("Error obtaining xrootlock: %ld - exiting.\n",glob->ioerr,
- glob->xRootName));
- goto exitthis;
- }
- debug (("Obtained xrootlock: %lx\n",glob->xrootlock ));
-
- if (!SetOptionsFromFile(glob,glob->xrootlock,ALTOPTIONPATH))
- {
- returnpkt (pkt,DOSFALSE,glob->ioerr,glob);
- ret=100;
- debug (("Error setting secondary options.\n"));
- goto exitthis;
- }
-
- if (!xInfo(glob, glob->xrootlock,&glob->infodata))
- {
- returnpkt (pkt,DOSFALSE,glob->ioerr,glob);
- ret=100;
- debug (("Error obtaining disk info: %ld\n",glob->ioerr));
- goto exitthis;
- }
- glob->bytesperblock=glob->infodata.id_BytesPerBlock;
-
- if (parent=xParentDir(glob,glob->xrootlock)) xUnLock(glob,parent);
-
- if (!xExamine(glob,glob->xrootlock,&glob->fib1))
- {
- returnpkt (pkt,DOSFALSE,glob->ioerr,glob);
- ret=100;
- debug (("Error finding name for volume: %ld\n",glob->ioerr));
- goto exitthis;
- }
-
- if (!(glob->rootlock=makerootlockdayone(glob)))
- {
- returnpkt (pkt,DOSFALSE,glob->ioerr,glob);
- ret=100;
- debug (("Error creating rootlock: %ld - exiting.\n",glob->ioerr));
- goto exitthis;
- }
-
- if (!createvolnode(glob, parent == NULL, &glob->fib1))
- {
- returnpkt (pkt,DOSFALSE,glob->ioerr,glob);
- ret=100;
- debug (("Error creating volume node - exiting.\n"));
- goto exitthis;
- }
-
- if (!InitArexx(glob))
- {
- returnpkt (pkt,DOSFALSE,glob->ioerr,glob);
- ret=100;
- debug (("Error initialising AREXX stuff.\n"));
- goto exitthis;
- }
-
- if (!UpdateXFHNode(glob))
- {
- debug (("Error initialising XFHNode.\n"));
- /* Carry on... */
- }
-
- /* Handler opened succesfully. Patch in task address so that we will
- * stay in control for all future references.
- */
- glob->devnode->dn_Task=glob->dosport;
-
- debug (("1: Packet type received: %lx\n",pkt->dp_Type));
- returnpkt (pkt,DOSTRUE,0L,glob);
-
- glob->opencnt=0; /* Just for good measure... */
- /* Ready to go for the main loop.
- * Lets pray that we get no new messages before the initial ReplyPkt()
- * (otherwise we may loose the signal for the message port).
- */
- for (glob->done=FALSE; !glob->done;)
- {
- ULONG signals=Wait(arexxsigmask(glob)|getpktsigmask(glob)|guisigmask(glob));
-
- if (signals&arexxsigmask(glob)) checkarexxmsg(glob);
- if (signals&guisigmask(glob))
- if (!UpdateXFHNode(glob))
- debug (("Error during UpdateXFHNode().\n"));
-
- if (signals&getpktsigmask(glob))
- while (!glob->done&&(pkt=checkpkt(glob)))
- handle_packet (glob,pkt);
- }
-
- exitthis:
- debug (("CFS exiting...\n"));
- CleanupArexx (glob);
- if (glob->volnode) freevolnode (glob);
- if (glob->rootlock) CFSUnLock (glob,glob->rootlock);
- CleanupXpk (glob);
- CleanupOptions (glob);
- if (glob->ioport) DeletePort (glob->ioport);
- if (glob->devname) freestr (glob->devname);
-
- /*
- * Unload the code. This is mostly to serve the ACTION_DIE packet.
- * Useful for debugging (otherwise countless copies might end up in memory.
- * It is rather ugly, however, and propably not really useful.
- */
- Forbid();
- UnLoadSeg (glob->devnode->dn_SegList);
- glob->devnode->dn_SegList=NULL;
-
- if (glob->DOSBase) CloseLibrary(glob->DOSBase);
- FreeMem (glob,sizeof(struct glob));
-
- return ret;
- }
-
- #ifndef ACTION_GET_DISK_FSSM
- #define ACTION_GET_DISK_FSSM 4201
- #endif
-
- void handle_packet(glb glob,struct DosPacket *pkt)
-
- {
- glob->ioerr=0L;
- switch(pkt->dp_Type)
- {
- case ACTION_LOCATE_OBJECT:
- {
- struct FileLock *mylock;
- struct CFSLock *mycfslock;
-
- debug (("ACTION_LOCATE_OBJECT(%lx,\"%s\",%ld)",
- pkt->dp_Arg1,
- bstr2c(pkt->dp_Arg2,glob->debugbuf1),
- pkt->dp_Arg3));
- mylock=b2c(pkt->dp_Arg1);
- mycfslock=mylock?(struct CFSLock *)mylock->fl_Key:glob->rootlock;
- mycfslock=CFSLock(glob,
- mycfslock,
- bstr2c(pkt->dp_Arg2,glob->pktstringbuf),
- pkt->dp_Arg3);
- if (mycfslock)
- if (mylock=CreateFileLock(glob,mycfslock)) glob->opencnt++;
- else
- {
- LONG saveioerr;
-
- saveioerr=glob->ioerr;
- CFSUnLock(glob, mycfslock);
- glob->ioerr=saveioerr;
- }
- else mylock=NULL;
-
- debug (("=%lx\n",c2b(mylock)));
- returnpkt (pkt,c2b(mylock),glob->ioerr,glob);
- break;
- }
-
- case ACTION_COPY_DIR:
- {
- struct FileLock *mylock;
- struct CFSLock *mycfslock;
-
- debug (("ACTION_COPY_DIR(%lx)",pkt->dp_Arg1));
- mylock=b2c(pkt->dp_Arg1);
- mycfslock=mylock?(struct CFSLock *)mylock->fl_Key:glob->rootlock;
- if (mycfslock=CFSDupLock(glob,mycfslock))
- {
- if (mylock=CreateFileLock(glob, mycfslock )) glob->opencnt++;
- else
- {
- LONG saveioerr;
-
- saveioerr=glob->ioerr;
- CFSUnLock(glob,mycfslock);
- glob->ioerr=saveioerr;
- }
- }
- else mylock=NULL;
-
- debug (("=%lx\n",c2b(mylock)));
- returnpkt (pkt, c2b(mylock), glob->ioerr, glob);
- break;
- }
-
- case ACTION_PARENT:
- {
- struct FileLock *mylock;
- struct CFSLock *mycfslock;
-
- debug (("ACTION_PARENT(%lx)",pkt->dp_Arg1));
- mylock=b2c(pkt->dp_Arg1);
- mycfslock=mylock?(struct CFSLock *)mylock->fl_Key:glob->rootlock;
- if (mycfslock=CFSParentDir(glob,mycfslock))
- {
- if (mylock=CreateFileLock(glob,mycfslock)) glob->opencnt++;
- else
- {
- LONG saveioerr;
-
- saveioerr=glob->ioerr;
- CFSUnLock(glob, mycfslock);
- glob->ioerr=saveioerr;
- }
- }
- else mylock=NULL;
-
- debug (("=%lx\n",c2b(mylock)));
- returnpkt (pkt, c2b(mylock), glob->ioerr, glob);
- break;
- }
-
- case ACTION_FREE_LOCK:
- {
- BOOL err;
- struct FileLock *mylock;
-
- debug (("ACTION_FREE_LOCK(%lx)\n",pkt->dp_Arg1));
- mylock=b2c(pkt->dp_Arg1);
- if (mylock)
- {
- err=CFSUnLock(glob,(void *)mylock->fl_Key);
- if (err)
- {
- dfree(mylock);
- glob->opencnt--;
- }
- }
- else err=ERROR_OBJECT_WRONG_TYPE;
-
- returnpkt (pkt,err,glob->ioerr,glob);
- break;
- }
-
- /* ToDo: Handle NULL locks correct (but what is correct?)
- * Now, a NULL lock is equal to out root lock.
- */
- case ACTION_SAME_LOCK:
- {
- struct FileLock *fl1,*fl2;
- BOOL res;
-
- fl1=b2c(pkt->dp_Arg1);
- fl2=b2c(pkt->dp_Arg2);
- debug (("ACTION_SAME_LOCK(%lx,%lx)",fl1,fl2));
- /* ToDo: This bit tests that both locks belong to us - this
- * is probably bogus.
- */
- if ((fl1!=NULL)&&(fl1->fl_Task!=glob->dosport)) res=FALSE;
- else
- if ((fl2!=NULL)&&(fl2->fl_Task!=glob->dosport)) res=FALSE;
- else
- {
- struct CFSLock *f1,*f2;
-
- f1=fl1?(struct CFSLock *)fl1->fl_Key:glob->rootlock;
- f2=fl2?(struct CFSLock *)fl2->fl_Key:glob->rootlock;
- res=CFSSameLock(glob,f1,f2);
- }
-
- debug (("=%ld\n",res));
- /* ToDo: DOCS mention error code in case of zero return.
- * Not currently implemented.
- */
- returnpkt (pkt,res,glob->ioerr,glob);
- break;
- }
-
- case ACTION_FINDINPUT: /* (filehandle, lock, name)->BOOL */
- case ACTION_FINDOUTPUT:
- case ACTION_FINDUPDATE:
- {
- struct FileHandle *fh;
- struct CFSFH *cfsfh;
- char *name;
- struct FileLock *parentlock;
- struct CFSLock *cfsparentlock;
-
- debug (("%s(%lx,%lx,\"%s\")\n",
- pkt->dp_Type==ACTION_FINDINPUT ?"ACTION_FINDINPUT":
- pkt->dp_Type==ACTION_FINDOUTPUT?"ACTION_FINDOUTPUT":
- "ACTION_FINDUPDATE",
- pkt->dp_Arg1,pkt->dp_Arg2,
- bstr2c(pkt->dp_Arg3,glob->debugbuf1)));
-
- fh=b2c(pkt->dp_Arg1);
- parentlock=b2c(pkt->dp_Arg2);
- cfsparentlock=parentlock?(struct CFSLock *)parentlock->fl_Key:glob->rootlock;
- name=bstr2c(pkt->dp_Arg3, glob->pktstringbuf);
- cfsfh=CFSOpen(glob,cfsparentlock,name,pkt->dp_Type);
- debug (("(=%lx)\n",cfsfh));
- if (cfsfh)
- {
- glob->opencnt++;
- fh->fh_Arg1=c2b(cfsfh);
- returnpkt (pkt,DOSTRUE,glob->ioerr,glob);
- }
- else returnpkt (pkt,DOSFALSE,glob->ioerr,glob);
- break;
- }
-
- case ACTION_READ: /* (fh->arg1, buf, len)->actlen */
- {
- struct CFSFH *cfsfh;
- LONG len;
- void *buf;
-
- debug (("ACTION_READ(%lx,%lx,%ld)\n",
- pkt->dp_Arg1,pkt->dp_Arg2,pkt->dp_Arg3));
- cfsfh=b2c(pkt->dp_Arg1);
- buf=(void *)pkt->dp_Arg2;
- len=pkt->dp_Arg3;
- len=CFSRead(glob, cfsfh, buf, len);
- returnpkt (pkt, len, glob->ioerr, glob);
- break;
- }
-
- case ACTION_WRITE: /* (fh->arg1, buf, len)->actlen */
- {
- struct CFSFH *cfsfh;
- LONG len;
- void *buf;
-
- debug (("ACTION_WRITE(%lx,%lx,%ld)\n",
- pkt->dp_Arg1,pkt->dp_Arg2,pkt->dp_Arg3));
- cfsfh=b2c(pkt->dp_Arg1);
- buf=(void *)pkt->dp_Arg2;
- len=pkt->dp_Arg3;
- len=CFSWrite(glob, cfsfh, buf, len);
- debug (("ACTION_WRITE returns %ld %ld.\n",len, glob->ioerr));
- returnpkt (pkt, len, glob->ioerr, glob);
- break;
- }
-
- case ACTION_SEEK: /* (fh->arg1, pos, offset)->actlen */
- {
- struct CFSFH *cfsfh;
- LONG pos;
- LONG offset;
-
- debug (("ACTION_SEEK(%lx,%lx,%ld)\n",
- pkt->dp_Arg1,pkt->dp_Arg2,pkt->dp_Arg3));
- cfsfh=b2c(pkt->dp_Arg1);
- pos=pkt->dp_Arg2;
- offset=pkt->dp_Arg3;
- pos=CFSSeek(glob, cfsfh, pos, offset);
- returnpkt (pkt, pos, glob->ioerr, glob);
- break;
- }
-
- case ACTION_END: /* (fh->arg1) -> BOOL */
- {
- struct CFSFH *cfsfh;
- BOOL res;
-
- cfsfh=b2c(pkt->dp_Arg1);
- debug (("ACTION_END(%lx)\n",cfsfh));
- res=CFSClose( glob, cfsfh );
- if (res ) glob->opencnt--;
- debug (("Closing file - still %ld files open.\n",glob->opencnt));
- returnpkt (pkt,res,pkt->dp_Res2,glob);
- break;
- }
-
- case ACTION_DIE:
- debug (("ACTION_DIE()\n"));
- Forbid();
- if (!glob->opencnt)
- {
- glob->done=TRUE;
- returnpkt (pkt,DOSTRUE,pkt->dp_Res2,glob);
- glob->devnode->dn_Task=NULL;
- debug (("No open files - Handler exiting.\n"));
- }
- else
- {
- returnpkt (pkt,DOSFALSE,ERROR_OBJECT_IN_USE,glob);
- debug (("Cannot end yet - still %ld open files.\n",glob->opencnt));
- }
- Permit();
- break;
-
- case ACTION_EXAMINE_OBJECT:
- {
- struct FileInfoBlock *fib;
- struct FileLock *mylock;
- BOOL err;
-
- debug (("ACTION_EXAMINE_OBJECT(%lx,%lx)\n",pkt->dp_Arg1,pkt->dp_Arg2));
- mylock=b2c(pkt->dp_Arg1);
- fib=b2c(pkt->dp_Arg2);
- err=CFSExamine(glob,mylock?(struct CFSLock *)mylock->fl_Key:glob->rootlock,fib);
- debug (("NAME: %s DirEntryType: %ld err: %ld\n",
- fib->fib_FileName, fib->fib_DirEntryType,err));
- cstr2binplace(&fib->fib_FileName[0]);
- cstr2binplace(&fib->fib_Comment[0]);
- returnpkt (pkt,err,glob->ioerr,glob);
- break;
- }
-
- case ACTION_EXAMINE_NEXT:
- {
- struct FileInfoBlock *fib;
- struct FileLock *mylock;
- BOOL err;
-
- debug (("ACTION_EXAMINE_NEXT(%lx,%lx)\n",pkt->dp_Arg1,pkt->dp_Arg2));
- mylock=b2c(pkt->dp_Arg1);
- fib=b2c(pkt->dp_Arg2);
- bstr2cinplace (&fib->fib_FileName[0]);
- safebstr2cinplace (&fib->fib_Comment[0],80);
- err=CFSExamineNext(glob,
- mylock?(struct CFSLock *)mylock->fl_Key:glob->rootlock,
- fib);
- debug (("NAME: %s DirEntryType: %ld err: %ld\n",
- fib->fib_FileName, fib->fib_DirEntryType,err));
- cstr2binplace (&fib->fib_FileName[0]);
- cstr2binplace (&fib->fib_Comment[0]);
- returnpkt (pkt,err,glob->ioerr,glob);
- break;
- }
-
- case ACTION_CREATE_DIR:
- { /* (parentlock, name) -> lock */
- struct FileLock *mylock;
- struct CFSLock *lock;
-
- debug (("ACTION_CREATE_DIR(%lx,\"%s\") ",
- pkt->dp_Arg1,bstr2c(pkt->dp_Arg2,glob->debugbuf1)));
- mylock=b2c(pkt->dp_Arg1);
- lock=CFSCreateDir(glob,
- mylock?(struct CFSLock *)mylock->fl_Key:glob->rootlock,
- bstr2c(pkt->dp_Arg2,glob->pktstringbuf));
- if (lock)
- {
- if (mylock=CreateFileLock(glob,lock)) glob->opencnt++;
- else
- {
- LONG saveioerr;
-
- saveioerr=glob->ioerr;
- CFSUnLock (glob,lock);
- glob->ioerr=saveioerr;
- }
- }
- else mylock=NULL;
-
- debug (("= %lx\n",mylock));
- returnpkt (pkt, c2b(mylock), glob->ioerr, glob);
- break;
- }
-
- case ACTION_DELETE_OBJECT:
- { /* (parentlock, name) -> succes */
- struct FileLock *mylock;
- BOOL err;
-
- debug (("ACTION_DELETE_OBJECT(%lx,\"%s\")\n", pkt->dp_Arg1,
- bstr2c(pkt->dp_Arg2,glob->debugbuf1)));
- mylock=b2c(pkt->dp_Arg1);
- err=CFSDeleteFile(glob,
- mylock?(struct CFSLock *)mylock->fl_Key:glob->rootlock,
- bstr2c(pkt->dp_Arg2,glob->pktstringbuf));
- if (!err) debug (("Error deleting file!\n"));
- returnpkt (pkt, err, glob->ioerr, glob);
- break;
- }
-
- case ACTION_RENAME_OBJECT:
- { /* (lock1,name1,lock2,name2) -> succes */
- struct FileLock *mylock1, *mylock2;
- BOOL err;
-
- /* ToDo: Check that both locks belong to us? */
- debug (("ACTION_RENAME_OBJECT(%lx,\"%s\", %lx,\"%s\")\n",pkt->dp_Arg1,
- bstr2c(pkt->dp_Arg2,glob->debugbuf1),
- pkt->dp_Arg3,
- bstr2c(pkt->dp_Arg4,glob->debugbuf2)));
- mylock1=b2c(pkt->dp_Arg1);
- mylock2=b2c(pkt->dp_Arg3);
-
- err=CFSRename(glob,
- mylock1?(struct CFSLock *)mylock1->fl_Key:glob->rootlock,
- bstr2c(pkt->dp_Arg2,glob->pktstringbuf),
- mylock2?(struct CFSLock *)mylock2->fl_Key:glob->rootlock,
- bstr2c(pkt->dp_Arg4,glob->pktstringbuf2));
- if (!err) debug (("Error renaming file!\n"));
- returnpkt (pkt, err, glob->ioerr, glob);
- break;
- }
-
- case ACTION_SET_PROTECT:
- { /* (dummy, parentlock, name, bits) -> succes */
- struct FileLock *mylock;
- BOOL err;
-
- debug (("ACTION_SET_PROTECT([%lx] %lx,\"%s\",%lx)\n",
- pkt->dp_Arg1,pkt->dp_Arg2,
- bstr2c(pkt->dp_Arg3,glob->debugbuf1),
- pkt->dp_Arg4));
- mylock=b2c(pkt->dp_Arg2);
- err=CFSSetProtection(glob,
- mylock?(struct CFSLock *)mylock->fl_Key:glob->rootlock,
- bstr2c(pkt->dp_Arg3,glob->pktstringbuf),
- pkt->dp_Arg4);
-
- if (!err) debug (("Error changing protection bits!\n"));
- returnpkt (pkt,err,glob->ioerr,glob);
- break;
- }
-
- case ACTION_SET_COMMENT:
- { /* (dummy, parentlock, name, comment) -> succes */
- struct FileLock *mylock;
- BOOL err;
-
- debug (("ACTION_SET_COMMENT([%lx] %lx,\"%s\",\"%s\")\n",
- pkt->dp_Arg1,pkt->dp_Arg2,
- bstr2c(pkt->dp_Arg3,glob->debugbuf1),
- bstr2c(pkt->dp_Arg4,glob->debugbuf2)));
- mylock=b2c(pkt->dp_Arg2);
- err=CFSSetComment(glob,
- mylock?(struct CFSLock *)mylock->fl_Key:glob->rootlock,
- bstr2c(pkt->dp_Arg3,glob->pktstringbuf),
- bstr2c(pkt->dp_Arg4,glob->pktstringbuf2));
- if (!err) debug (("Error changing file comment!\n"));
- returnpkt (pkt,err,glob->ioerr,glob);
- break;
- }
-
- case ACTION_SET_DATE:
- { /* (dummy, parentlock, name, datestamp) -> succes */
- struct FileLock *mylock;
- BOOL err;
-
- debug (("ACTION_SET_DATE([%lx] %lx,\"%s\",%ld,%ld,%ld)\n",
- pkt->dp_Arg1,pkt->dp_Arg2,
- bstr2c(pkt->dp_Arg3,glob->debugbuf1),
- ((struct DateStamp *)(pkt->dp_Arg4))->ds_Days,
- ((struct DateStamp *)(pkt->dp_Arg4))->ds_Minute,
- ((struct DateStamp *)(pkt->dp_Arg4))->ds_Tick));
- mylock=b2c(pkt->dp_Arg2);
- err=CFSSetDate(glob,
- mylock?(struct CFSLock *)mylock->fl_Key:glob->rootlock,
- bstr2c(pkt->dp_Arg3,glob->pktstringbuf),
- (struct DateStamp *)pkt->dp_Arg4);
- if (!err) debug (("Error changing objects date!\n"));
- returnpkt (pkt, err, glob->ioerr, glob);
- break;
- }
-
- case ACTION_DISK_INFO:
- /* (infodata)=BOOL */
- debug (("ACTION_DISK_INFO(%lx)\n",pkt->dp_Arg1));
- returnpkt (pkt,diskinfo(glob,b2c(pkt->dp_Arg1)),0L,glob);
- break;
-
- case ACTION_INFO:
- /* (lock,infodata)=BOOL */
- debug (("ACTION_INFO(%lx,%lx)\n",pkt->dp_Arg1,pkt->dp_Arg2));
- returnpkt (pkt,diskinfo(glob,b2c(pkt->dp_Arg2)),0L,glob);
- break;
-
- case ACTION_RENAME_DISK:
- { /* (BCPLNAME)=BOOL */
- BOOL res;
-
- debug (("ACTION_RENAME_DISK(%s)\n",
- bstr2c(pkt->dp_Arg1,glob->debugbuf1)));
- res=SetOptionPermanent(glob, "VOLUMENAME",
- bstr2c(pkt->dp_Arg1,glob->pktstringbuf));
- if (!res) debug (("Error during relabel: %ld.\n",glob->ioerr));
- returnpkt (pkt,res,glob->ioerr,glob);
- break;
- }
-
- case ACTION_IS_FILESYSTEM:
- debug (("ACTION_IS_FILESYSTEM\n"));
- returnpkt (pkt,DOSTRUE,0L,glob);
- break;
-
- case ACTION_PARENT_FH:
- {
- struct FileLock *mylock;
- struct CFSLock *mycfslock;
-
- debug (("ACTION_PARENT_FH(%lx)",pkt->dp_Arg1));
- if (mycfslock=CFSParentFH(glob,b2c(pkt->dp_Arg1)))
- if (mylock=CreateFileLock(glob, mycfslock )) glob->opencnt++;
- else
- {
- LONG saveioerr;
-
- saveioerr=glob->ioerr;
- CFSUnLock (glob,mycfslock);
- glob->ioerr=saveioerr;
- }
- else mylock=NULL;
-
- debug (("=%lx\n",c2b(mylock)));
- returnpkt (pkt, c2b(mylock), glob->ioerr, glob);
- break;
- }
-
- case ACTION_EXAMINE_FH:
- {
- struct FileInfoBlock *fib;
- struct CFSFH *fh;
- BOOL err;
-
- debug (("ACTION_EXAMINE_FH(%lx,%lx)\n",pkt->dp_Arg1,pkt->dp_Arg2));
- fh=b2c(pkt->dp_Arg1);
- fib=b2c(pkt->dp_Arg2);
- err=CFSExamineFH(glob, fh, fib);
- debug (("NAME: %s DirEntryType: %ld err: %ld\n",
- fib->fib_FileName, fib->fib_DirEntryType,err));
- cstr2binplace (&fib->fib_FileName[0]);
- cstr2binplace (&fib->fib_Comment[0]);
- returnpkt (pkt,err,glob->ioerr,glob);
- break;
- }
-
- case ACTION_MAKE_LINK:
- {
- struct FileLock *mylock;
- BOOL succ;
-
- debug (("ACTION_MAKE_LINK(%lx,\"%s\",%lx,%ld)\n",
- pkt->dp_Arg1,bstr2c(pkt->dp_Arg2,glob->debugbuf1),
- pkt->dp_Arg3,pkt->dp_Arg4));
-
- mylock=b2c(pkt->dp_Arg1);
- succ=CFSMakeLink(glob,
- mylock?(struct CFSLock *)mylock->fl_Key:glob->rootlock,
- bstr2c(pkt->dp_Arg2,glob->pktstringbuf),
- pkt->dp_Arg3,pkt->dp_Arg4);
-
- #ifdef DEBUG
- if (!succ) debug (("Error making link!\n"));
- #endif
-
- returnpkt (pkt,succ,glob->ioerr,glob);
- break;
- }
-
- case ACTION_READ_LINK:
- {
- struct FileLock *mylock;
- BOOL succ;
-
- debug (("ACTION_READ_LINK(%lx,\"%s\")\n",pkt->dp_Arg1,pkt->dp_Arg2));
-
- mylock=b2c(pkt->dp_Arg1);
- succ=CFSReadLink(glob,
- mylock?(struct CFSLock *)mylock->fl_Key:glob->rootlock,
- (char *)pkt->dp_Arg2,(char *)pkt->dp_Arg3,pkt->dp_Arg4);
-
- #ifdef DEBUG
- if (succ) debug (("ReadLink: \"%s\"\n",pkt->dp_Arg3));
- #endif
-
- returnpkt (pkt,succ,glob->ioerr,glob);
- break;
- }
-
- case ACTION_GET_DISK_FSSM:
- returnpkt (pkt,DOSFALSE,ERROR_OBJECT_WRONG_TYPE,glob);
- break;
-
- default:
- debug (("Unknown packet received: %ld\n",pkt->dp_Type));
- returnpkt (pkt,DOSFALSE,ERROR_ACTION_NOT_KNOWN,glob);
- }
- }
-
- struct DosPacket *getpkt(glb glob)
-
- {
- struct Message *msg;
-
- while (!(msg=GetMsg(glob->dosport))) WaitPort(glob->dosport);
- return (struct DosPacket *)msg->mn_Node.ln_Name;
- }
-
-
- ULONG getpktsigmask(glb glob)
-
- {
- return (ULONG)(1L<<glob->dosport->mp_SigBit);
- }
-
-
- struct DosPacket *checkpkt(glb glob)
-
- {
- struct Message *msg;
-
- if (msg=GetMsg(glob->dosport)) return (struct DosPacket *)msg->mn_Node.ln_Name;
- else return NULL;
- }
-
-
- void returnpkt (struct DosPacket *pkt,LONG res1,LONG res2,glb glob)
-
- {
- struct MsgPort *port;
- struct Message *msg;
-
- port=pkt->dp_Port;
- msg=pkt->dp_Link;
-
- msg->mn_Node.ln_Succ=msg->mn_Node.ln_Pred=NULL;
- msg->mn_Node.ln_Name=(char *)pkt;
-
- pkt->dp_Res1=res1;
- pkt->dp_Res2=res2;
- pkt->dp_Port=glob->dosport;
-
- PutMsg(port,msg);
- }
-
- struct devprocmsg
-
- {
- struct Message msg;
- void (*func)();
- char *filedesc;
- struct MsgPort *procid;
- LONG res2;
- };
-
- void __asm CallDeviceProc(register __a0 struct devprocmsg *msg)
-
- {
- msg->procid=DeviceProc(msg->filedesc);
- msg->res2=IoErr();
- }
-
- struct MsgPort *DoDeviceProc(LONG *res2,char *filedesc,glb glob)
-
- {
- struct devprocmsg msg,*msg2;
- extern void DoDOSSeg();
- struct MsgPort *procid;
-
- msg.msg.mn_Node.ln_Succ=NULL;
- msg.msg.mn_Node.ln_Pred=NULL;
- msg.msg.mn_Node.ln_Name=NULL;
- msg.msg.mn_Node.ln_Type=NT_MESSAGE;
- msg.msg.mn_Node.ln_Pri=0;
- msg.msg.mn_ReplyPort=glob->ioport;
- msg.msg.mn_Length=sizeof(msg);
- msg.func=(void (*)())CallDeviceProc;
- msg.filedesc=filedesc;
-
- if (!(procid=CreateProc("DoDOS",glob->mytask->tc_Node.ln_Pri,
- (BPTR)((ULONG)DoDOSSeg>>2),4000L))) return 0L;
-
- PutMsg(procid,(struct Message *)&msg);
- do WaitPort(glob->ioport);
- while (!(msg2=(struct devprocmsg *)GetMsg(glob->ioport)));
-
- #ifdef DEBUG
- if (msg2!=&msg) KPrintF ("ERROR: bogus return message: &msg=%lx msg2=%lx\n",&msg,msg2);
- #endif
- if (res2) *res2=msg2->res2;
- return msg2->procid;
- }
-
- /* DOS device list locking.
- * ToDo: Use correct 2.0 locking calls.
- */
-
- static void MyLockDosList(glb glob)
-
- {
- Forbid();
- }
-
- static void MyUnlockDosList(glb glob)
-
- {
- Permit();
- }
-
-
- void addvolnode(glb glob,struct DeviceList *volnode)
-
- {
- struct DosInfo *dosinfo;
-
- MyLockDosList(glob);
- dosinfo=b2c( ((struct RootNode *)DOSBase->dl_Root)->rn_Info);
- volnode->dl_Next=dosinfo->di_DevInfo;
- dosinfo->di_DevInfo=c2b(volnode);
- MyUnlockDosList(glob);
- }
-
- BOOL removevolnode(glb glob,struct DeviceList *volnode)
-
- {
- struct DosInfo *dosinfo;
- BPTR *p;
-
- /* ToDo: check for 2.0 device list locking. */
- MyLockDosList(glob);
- dosinfo=b2c( ((struct RootNode *)DOSBase->dl_Root)->rn_Info);
- p=&dosinfo->di_DevInfo;
-
- while(*p)
- if (b2c(*p) == volnode)
- {
- *p=volnode->dl_Next;
- MyUnlockDosList(glob);
- return TRUE;
- }
- else p=&( ((struct DeviceList *)b2c(*p)) -> dl_Next);
-
- MyUnlockDosList(glob);
- /* Hey - we didn't find the node in the list! */
- debug (("WARNING!:removevolnode(): volume node not found.\n"));
- return FALSE;
- }
-
- /* Used to update the 'Startup' field in our device node (used in option
- * 'KILLSTARTUP').
- */
-
- void DevNode_Stuff_Startup_String(glb glob,BSTR value)
-
- {
- MyLockDosList(glob);
- glob->devnode->dn_Startup=value;
- MyUnlockDosList (glob);
- }
-
-
- /* NOTE: this function assumes properly dos device list locking!
- * This function will fail if 'name' is NULL.
- * NOTE: createvolnode(), below does this in it's own way.
- */
- static BOOL stuffvolnamevolnode(glb glob,char *name)
-
- {
- UBYTE *bcplname,*oldbcplname;
-
- /* NASTY BUG: It seems that the volume name is expected to be zero
- * terminated even though it is a BSTR. Hence strlen()+2 in alloc. */
- /* Check if user specified a volume name. */
-
- if (name)
- {
- if (!(bcplname=dosalloc(strlen(name)+2)))
- {
- OUTOFMEM;
- return FALSE;
- }
- /* Free any old name. */
- oldbcplname=b2c(glob->volnode->dl_Name);
- if (oldbcplname) dosfree (oldbcplname);
-
- strcpy(bcplname,name);
- cstr2binplace(bcplname);
- glob->volnode->dl_Name=c2b(bcplname);
- debug (("Using user suplied volumename '%s'.\n",bcplname+1));
- return TRUE;
- }
- else
- {
- glob->ioerr=ERROR_INVALID_COMPONENT_NAME;
- return FALSE;
- }
- }
-
-
- /* This function creates our volumenode. The argument 'fixroot' is
- * a hack, telling whether the volumename should be changed to prevent
- * name-clashing with the volume name of the UFS.
- */
- BOOL createvolnode(glb glob,BOOL fixroot,struct FileInfoBlock *fib)
-
- {
- UBYTE *bcplname;
-
- if (!dalloc(glob->volnode)) return FALSE;
-
- /* NASTY BUG: It seems that the volume name is expected to be zero
- * terminated even though it is a BSTR. Hence strlen()+2 in alloc. */
- /* Check if user specified a volume name. */
-
- if (glob->uservolname)
- {
- if (!(bcplname=dosalloc(strlen(glob->uservolname)+2)))
- {
- dfree(glob->volnode);
- return FALSE;
- }
-
- (void)strcpy(bcplname,glob->uservolname);
- debug (("Using user suplied volumename '%s'.\n",bcplname));
- }
- else
- {
- if (!(bcplname=dosalloc(strlen(fib->fib_FileName)+2+
- (fixroot?strlen(XROOTNAME)+1:0))))
- {
- dfree(glob->volnode);
- return FALSE;
- }
-
- (void)strcat(strcpy(bcplname,fixroot?XROOTNAME "_":""),&fib->fib_FileName[0]);
- debug (("Using default volume name '%s'.\n",bcplname));
- }
-
- glob->volnode->dl_Type=DLT_VOLUME;
- glob->volnode->dl_Task=glob->dosport;
- glob->volnode->dl_Lock=c2b(NULL);
- glob->volnode->dl_VolumeDate=fib->fib_Date;
- glob->volnode->dl_LockList=c2b(NULL);
- glob->volnode->dl_DiskType=ID_DOS_DISK; /*Wonder what would be right*/
- glob->volnode->dl_unused=0L;
- cstr2binplace (bcplname);
- glob->volnode->dl_Name=c2b(bcplname);
-
- /* Check if user requested that we create a volume node. */
- /* if (glob->createvolnode) */
- addvolnode (glob,glob->volnode);
-
- return TRUE;
- }
-
- /* Set the volume name in the volnode. */
- BOOL SetVolumeNameVolNode(glb glob,char *name)
-
- {
- BOOL res;
-
- MyLockDosList(glob);
- res=stuffvolnamevolnode(glob,name);
- MyUnlockDosList(glob);
- return res;
- }
-
- BOOL freevolnode(glb glob)
-
- {
- /* Check if user requested that we create a volume node. */
- /* if (glob->createvolnode)*/
- if (!removevolnode(glob,glob->volnode)) return FALSE;
-
- dosfree (b2c(glob->volnode->dl_Name));
- dfree (glob->volnode);
-
- return TRUE;
- }
-
-
- BOOL diskinfo(glb glob,struct InfoData *infodata)
-
- {
- if (!xInfo(glob,glob->xrootlock,infodata))
- {
- debug (("Error: diskinfo(): xInfo() returned zero (%ld).\n",glob->ioerr));
- return DOSFALSE;
- }
-
- /* infodata->id_NumSoftErrors=0;*/
- /* infodata->id_UnitNumber=glob->fsstartup ?*/
- /* glob->fsstartup->fssm_Unit : 0;*/
- /* infodata->id_DiskState=ID_VALIDATED;*/
- /* infodata->id_NumBlocks=1;*/
- /* infodata->id_NumBlocksUsed=1;*/
- /* infodata->id_BytesPerBlock=1;*/
- /* infodata->id_DiskType=ID_DOS_DISK;*/
-
- infodata->id_VolumeNode=c2b(glob->volnode);
- infodata->id_InUse=glob->opencnt?1:0;
- debug (("diskinfo(): U=%ld DS=%lx #=%ld #u=%ld #b=%ld IU=%ld.\n",
- infodata->id_UnitNumber,infodata->id_DiskState,infodata->id_NumBlocks,
- infodata->id_NumBlocksUsed,infodata->id_BytesPerBlock,
- infodata->id_InUse));
-
- return DOSTRUE;
- }
-
- UWORD PutChar[2] = {0x16C0,0x4E75};
-
- /* dirty hack to avoid assembler part :-)
-
- 16C0: move.b d0,(a3)+
- 4E75: rts
- */
-
- void SPrintF(char *Buffer,char *FormatString,...)
-
- {
- RawDoFmt (FormatString,(APTR)((LONG *)&FormatString+1L),(void *)PutChar,Buffer);
- }
-
- /* End of CFS.c */
-