home *** CD-ROM | disk | FTP | other *** search
- /* CFS.c - main packet loop.
- 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. */
-
- /* 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 <libraries/filehandler.h>
-
- #include <proto/exec.h>
- #include <proto/dos.h>
-
- #include <clib/alib_protos.h>
-
- #include <string.h>
- #include <stdarg.h>
- #include <stdio.h>
-
- #include <dossupport.h>
-
- struct ExecBase *SysBase;
- struct DosLibrary *DOSBase;
-
- const char versiontag[] = "\0$VER: XFH-Handler " VERSION " (" __DATE__ ")";
- const char cporighttag[]
- = "\0$COPYRIGHT: Copyright (C) 1991, 1992, 1993 Kristian Nielsen";
-
- /**************************************************************************
- * *
- * Handler entry point. *
- * *
- * Do initialisation and allocation, then enter main loop after returning *
- * our initial packet. *
- * *
- **************************************************************************/
-
- int __saveds NotReallyMain(void){
- glb glob;
- struct DosPacket *pkt;
- int ret=0;
- struct FileLock *parent;
- void handle_packet(glb glob, struct DosPacket *pkt);
-
- SysBase=(void *)*(ULONG *)4L;
- if(!(glob=AllocMem(sizeof(struct glob),MEMF_CLEAR))) return(100);
- glob->ioerr = ERROR_ACTION_NOT_KNOWN; /* Default error code. */
- #ifdef DEBUG
- opendebug();
- 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)));
- #endif
-
- 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){
- 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))){
- debug(("Error copying device name - exiting.\n"));
- OUTOFMEM;
- returnpkt(pkt,DOSFALSE,glob->ioerr,glob);
- ret=100;
- goto exitthis;
- }
- if(!glob->devname[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))){
- 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))){
- 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 ){
- 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);
- #ifdef DEBUG
- closedebug();
- #endif
-
- /*
- * 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);
- }
-
-
- 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 && fl1->fl_Task != glob->dosport){
- res = FALSE;
- }else if(fl2 && 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;
- }
- 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)1 << 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)
- dprintf("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;
- }
- 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;
- }
- 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;
- }
- strcpy(bcplname, fixroot ? XROOTNAME "_" : "");
- strcat(bcplname, &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;
- }
-
- /* End of CFS.c */
-