2 Copyright © 1995-2007, The AROS Development Team. All rights reserved.
5 Desc: a virtual filesystem that emulates the unixish root dir
10 #include <aros/debug.h>
12 #include <exec/errors.h>
13 #include <exec/resident.h>
14 #include <exec/memory.h>
15 #include <exec/devices.h>
16 #include <exec/lists.h>
17 #include <exec/nodes.h>
18 #include <proto/exec.h>
19 #include <utility/tagitem.h>
20 #include <dos/dosextens.h>
21 #include <dos/filesystem.h>
22 #include <proto/dos.h>
23 #include <aros/libcall.h>
24 #include <aros/asmcall.h>
25 #if defined(__GNUC__) || defined(__INTEL_COMPILER)
26 #include "rootfs_handler_gcc.h"
32 static const char name
[];
33 static const char version
[];
34 static const APTR inittabl
[4];
35 static void *const functable
[];
36 struct rootfsbase
*AROS_SLIB_ENTRY(init
,rootfs_handler
)();
37 void AROS_SLIB_ENTRY(open
,rootfs_handler
)();
38 BPTR
AROS_SLIB_ENTRY(close
,rootfs_handler
)();
39 BPTR
AROS_SLIB_ENTRY(expunge
,rootfs_handler
)();
40 int AROS_SLIB_ENTRY(null
,rootfs_handler
)();
41 void AROS_SLIB_ENTRY(beginio
,rootfs_handler
)();
42 LONG
AROS_SLIB_ENTRY(abortio
,rootfs_handler
)();
44 AROS_UFH3(LONG
, rootfsproc
,
45 AROS_UFHA(char *,argstr
,A0
),
46 AROS_UFHA(ULONG
,argsize
,D0
),
47 AROS_UFHA(struct ExecBase
*,sysbase
,A6
));
49 static const char end
;
59 struct Device
*device
;
67 struct ExecBase
*sysbase
;
68 struct DosLibrary
*dosbase
;
79 struct IOFileSys newiofs
;
80 struct IOFileSys
*oldiofs
;
87 /* If the handler was executed by accident return error code. */
91 const struct Resident rootfs_handler_resident
=
94 (struct Resident
*)&rootfs_handler_resident
,
105 static const char name
[]="rootfs.handler";
107 static const char version
[]="$VER: rootfs-handler 41.1 (10.6.2001)\r\n";
109 static const APTR inittabl
[4]=
111 (APTR
)sizeof(struct rootfsbase
),
114 &AROS_SLIB_ENTRY(init
,rootfs_handler
)
117 static void *const functable
[]=
119 &AROS_SLIB_ENTRY(open
,rootfs_handler
),
120 &AROS_SLIB_ENTRY(close
,rootfs_handler
),
121 &AROS_SLIB_ENTRY(expunge
,rootfs_handler
),
122 &AROS_SLIB_ENTRY(null
,rootfs_handler
),
123 &AROS_SLIB_ENTRY(beginio
,rootfs_handler
),
124 &AROS_SLIB_ENTRY(abortio
,rootfs_handler
),
128 static inline void initIOFS(struct rootfsbase
*rootfsbase
, struct IOFileSys
*iofs
,
131 struct Process
*me
= (struct Process
*)FindTask(NULL
);
133 iofs
->IOFS
.io_Message
.mn_Node
.ln_Type
= NT_REPLYMSG
;
134 iofs
->IOFS
.io_Message
.mn_ReplyPort
= &me
->pr_MsgPort
;
135 iofs
->IOFS
.io_Message
.mn_Length
= sizeof(struct IOFileSys
);
136 iofs
->IOFS
.io_Command
= type
;
137 iofs
->IOFS
.io_Flags
= 0;
140 static inline BOOL
redirect(struct rootfsbase
*rootfsbase
, struct IOFileSys
*iofs
,
141 struct Device
*device
, struct Unit
*unit
, struct Unit
**newunit
)
143 struct IOFileSys iofs2
;
145 /* Prepare I/O request. */
146 initIOFS(rootfsbase
, &iofs2
, iofs
->IOFS
.io_Command
);
148 iofs2
.IOFS
.io_Device
= device
;
149 iofs2
.IOFS
.io_Unit
= unit
;
151 iofs2
.io_Union
= iofs
->io_Union
;
153 kprintf("Sending the request... Device = %s - Unit = %p\n", device
->dd_Library
.lib_Node
.ln_Name
, unit
);
155 kprintf("Done! Return Code: %d\n", iofs2
.io_DosError
);
156 iofs
->io_DosError
= iofs2
.io_DosError
;
157 iofs
->io_Union
= iofs2
.io_Union
;
160 *newunit
= iofs2
.IOFS
.io_Unit
;
162 return !iofs2
.io_DosError
;
166 static BOOL
redirect(struct rootfsbase
*rootfsbase
, struct IOFileSys
*iofs
,
167 struct Device
*device
, struct Unit
*unit
)
169 const struct filehandle
*handle
= (struct filehandle
*)iofs
->IOFS
.io_Unit
;
170 struct rootmessage
*msg
;
172 kprintf(">>>>>>>>>>> In SEND REQUEST <<<<<<<<<\n");
174 if (namePtr
) kprintf("=== name: %s\n", *namePtr
);
177 msg
= AllocVec(sizeof(struct rootmessage
), MEMF_PUBLIC
| MEMF_CLEAR
);
180 iofs
->io_DosError
= ERROR_NO_FREE_STORE
;
184 kprintf(">>>>>>>>>>> In SEND REQUEST - 2 - <<<<<<<<<\n");
186 msg
->msg
.mn_Length
= sizeof(struct rootmessage
);
190 struct FileHandle
*fh
= (struct FileHandle
*)BADDR(handle
->lock
);
191 msg
->iofs
.oldiofs
= iofs
;
192 kprintf(">>>>>>>>>>> In SEND REQUEST - 3 - <<<<<<<<<\n");
195 msg
->iofs
.newiofs
.io_Union
.io_NamedFile
.io_Filename
= *namePtr
;
196 kprintf(">>>>>>>>>>> In SEND REQUEST - 5 - <<<<<<<<<\n");
198 iofs
->IOFS
.io_Flags
&= ~IOF_QUICK
;
199 iofs
->IOFS
.io_Message
.mn_Node
.ln_Type
= NT_MESSAGE
;
200 msg
->iofs
.newiofs
= *iofs
;
202 msg
->iofs
.newiofs
.IOFS
.io_Device
= fh
->fh_Device
;
203 msg
->iofs
.newiofs
.IOFS
.io_Unit
= fh
->fh_Unit
;
206 PutMsg(&(rootfsbase
->proc
->pr_MsgPort
), (struct Message
*)msg
);
212 static STRPTR
myStrDup(struct rootfsbase
*rootfsbase
, STRPTR old
)
215 int len
= strlen(old
);
217 /* Use +2 instead of +1 because we migth want to hold also a ':' */
218 new = AllocVec(len
+2, MEMF_ANY
);
221 CopyMem(old
, new, len
);
230 static struct filehandle
*allocFHandle(struct rootfsbase
*rootfsbase
, struct root
*root
,
231 struct Device
*device
, struct Unit
*unit
,
234 struct filehandle
*handle
= AllocVec(sizeof(struct filehandle
), MEMF_ANY
);
238 handle
->device
= device
;
240 handle
->depth
= depth
;
247 static void freeFHandle(struct rootfsbase
*rootfsbase
, struct filehandle
*handle
)
249 handle
->root
->openfiles
--;
254 static STRPTR
skipVol(STRPTR path
)
258 while (*ptr
!= ':' && *ptr
!= '\0') ptr
++;
260 if (*ptr
== ':') path
= ptr
+1;
265 static struct filehandle
* getFileHandle_1(struct rootfsbase
* rootfsbase
, struct dnode
*curdir
,
266 STRPTR path
, struct FileInfoBlock
*fib
,
267 struct IOFileSys
*iofs
, STRPTR tmp
)
269 struct filehandle
*handle
;
270 BPTR olddirlock
, lock
;
273 kprintf("PATH requested: %s\n", s1
);
275 if (handle
->depth
== 0 && *path
!= '/')
284 kprintf("OOPS... where the heck do you want to go, huh??\n");
285 iofs
->io_DosError
= ERROR_OBJECT_NOT_FOUND
;
288 kprintf("ascending...\n");
296 /* get next part in the path */
297 for (s1
= path
; *s1
!= '/' && *s1
!= '\0'; s1
++);
298 if (*s1
== '/') *s1
++ = '\0';
302 kprintf("Searching....\n");
305 child
= GetHead((struct List
*)&curdir
->children
);
307 child
= GetSucc(child
)
310 kprintf("Comparing: %s - %s\n", tmp
, child
->name
);
311 if (!strcasecmp(tmp
, child
->name
)) break;
313 kprintf("....Search finished\n");
317 itsadirectory
= TRUE
;
320 /* if it's a device add the ':' to the name */
325 kprintf("Trying to lock '%s'... ", tmp
);
326 olddirlock
= CurrentDir(curdir
->lock
);
327 lock
= Lock(tmp
, SHARED_LOCK
);
328 (void)CurrentDir(olddirlock
);
332 kprintf("Failed :(\n", tmp
);
333 iofs
->io_DosError
= IoErr();
336 kprintf("Succeeded!!\n", tmp
);
338 if (!Examine(lock
, fib
))
340 int len
= strlen(tmp
);
341 /* if Examine() fails assume that the object is a plain file */
342 fib
->fib_DirEntryType
= ST_FILE
;
343 if (tmp
[len
] == ':') tmp
[len
] = '\0';
347 strcpy(tmp
, fib
->fib_FileName
);
350 /* A file cannot be in the middle of a path */
351 if (*s1
&& fib
->fib_DirEntryType
<= 0)
353 kprintf("AHA... what do you want to do, huh?\n");
355 iofs
->io_DosError
= ERROR_DIR_NOT_FOUND
;
359 /* It's a directory or a device */
360 if (fib
->fib_DirEntryType
> 0)
367 curdir
= allocDNode(rootfsbase
, curdir
, tmp
, lock
);
371 iofs
->io_DosError
= ERROR_NO_FREE_STORE
;
375 } /* Is a directory or a device */
378 /*Is there somthing else in the path? */
381 kprintf("Recursiiiiiinggggggg......\n");
382 return getFileHandle_1(rootfsbase
, curdir
, s1
, fib
, iofs
, tmp
);
385 kprintf("Forwarding the request - Current directory is: %S\n", curdir
->name
);
387 /* send the request to the proprer device */
389 struct FileHandle
*fh
= (struct FileHandle
*)BADDR(lock
);
390 STRPTR oldfilename
= iofs
->io_Union
.io_OPEN_FILE
.io_Filename
;
393 iofs
->io_Union
.io_OPEN_FILE
.io_Filename
= "";
395 redirect(rootfsbase
, iofs
, fh
->fh_Device
, fh
->fh_Unit
, &unit
);
397 iofs
->io_Union
.io_OPEN_FILE
.io_Filename
= oldfilename
;
399 if (!iofs
->io_DosError
)
402 handle
= allocFHandle(rootfsbase
, curdir
, fh
->fh_Device
, unit
);
405 if (lock
!= curdir
->lock
)
411 iofs
->io_DosError
= ERROR_NO_FREE_STORE
;
413 /* close the file just opened */
415 struct IOFileSys dummy
;
416 dummy
.IOFS
.io_Command
= FSA_CLOSE
;
417 redirect(rootfsbase
, &dummy
, fh
->fh_Device
, fh
->fh_Unit
, NULL
);
421 /* Did we try to open a directory? */
422 if (lock
== curdir
->lock
)
423 freeDNode(rootfsbase
, curdir
);
427 //Fault(iofs->io_DosError, "", tmp, MAXFILENAMELENGTH+1);
428 kprintf("Error trying to open the file: %d", iofs
->io_DosError
);
434 kprintf("Ok... this is the end!! %s\n", curdir
->name
);
436 if (iofs
->IOFS
.io_Command
== FSA_OPEN
)
438 struct FileHandle
*fh
= (struct FileHandle
*)BADDR(curdir
->lock
);
439 struct Device
*device
= fh
?fh
->fh_Device
:NULL
;
440 struct Unit
*unit
= fh
?fh
->fh_Unit
:NULL
;
442 handle
= allocFHandle(rootfsbase
, curdir
, device
, unit
);
447 iofs
->io_DosError
= ERROR_NO_FREE_STORE
;
450 if (!iofs
->io_DosError
)
451 iofs
->io_DosError
= ERROR_OBJECT_WRONG_TYPE
;
456 static struct filehandle
* getFileHandle(struct rootfsbase
* rootfsbase
, ,
457 STRPTR path
, struct IOFileSys
*iofs
)
459 struct FileInfoBlock
*fib
= NULL
;
460 UBYTE tmp
[MAXFILENAMELENGTH
+2];
461 struct filehandle
*handle
;
463 fib
= AllocDosObject(DOS_FIB
, NULL
);
466 iofs
->io_DosError
= ERROR_NO_FREE_STORE
;
470 handle
= getFileHandle_1(rootfsbase
, dir
, path
, fib
, iofs
, tmp
);
472 FreeDosObject(DOS_FIB
, fib
);
477 static STRPTR
getPath(STRPTR path
, ULONG
*depth
)
479 STRPTR ret
= myStrDup(skipVol(path
));
482 kprintf("PATH requested: %s\n", path
);
486 *depth
= ERROR_NO_FREE_STORE
;
496 *depth
= ERROR_OBJECT_NOT_FOUND
;
504 for (; *ret
!= '/' && *ret
!= '\0'; ret
++);
517 static BOOL
open_(struct rootfsbase
*rootfsbase
, struct IOFileSys
*iofs
)
520 struct filehandle
*handle
= (struct filehandle
*)iofs
->IOFS
.io_Unit
;
521 ULONG depth
= handle
->depth
;
522 BOOL redirected
= FALSE
;
524 path
= getPath(iofs
->io_Union
.io_OPEN
.io_Filename
, &depth
);
528 getFileHandle(rootfsbase
, path
, depth
, iofs
);
531 (struct filehandle
*)iofs
->IOFS
.io_Unit
= handle
;
538 static BOOL
close_(struct rootfsbase
*rootfsbase
, struct IOFileSys
*iofs
)
540 BOOL redirected
= FALSE
;
542 struct filehandle
*handle
= (struct filehandle
*)iofs
->IOFS
.io_Unit
;
544 /* check we're not the root */
547 kprintf("Closing... Device = %p - Unit = %p\n", handle
->device
, handle
->unit
);
548 redirect(rootfsbase
, iofs
, handle
->device
, handle
->unit
, NULL
);
551 kprintf("CLOSE %p\n", iofs
->IOFS
.io_Unit
);
553 freeFHandle(rootfsbase
, handle
);
559 static BOOL
examine(struct rootfsbase
*rootfsbase
, struct IOFileSys
*iofs
)
561 struct ExAllData
*ead
= iofs
->io_Union
.io_EXAMINE
.io_ead
;
562 const struct filehandle
*handle
= (struct filehandle
*)iofs
->IOFS
.io_Unit
;
563 const ULONG type
= iofs
->io_Union
.io_EXAMINE
.io_Mode
;
564 const ULONG size
= iofs
->io_Union
.io_EXAMINE
.io_Size
;
567 static const ULONG sizes
[]=
570 offsetof(struct ExAllData
,ed_Type
),
571 offsetof(struct ExAllData
,ed_Size
),
572 offsetof(struct ExAllData
,ed_Prot
),
573 offsetof(struct ExAllData
,ed_Days
),
574 offsetof(struct ExAllData
,ed_Comment
),
575 offsetof(struct ExAllData
,ed_OwnerUID
),
576 sizeof(struct ExAllData
)
579 kprintf("In examine...\n");
582 return ERROR_BAD_NUMBER
;
585 next
= (STRPTR
)ead
+ sizes
[type
];
586 end
= (STRPTR
)ead
+ size
;
588 if(next
>end
) /* > is correct. Not >= */
589 return ERROR_BUFFER_OVERFLOW
;
591 iofs
->io_DirPos
= (LONG
)handle
->dir
;
593 /* it's not the root */
596 /* Get pointer to I/O request. Use stackspace for now. */
597 kprintf("*NOT* Examining the root\n");
598 kprintf("Our parent is: %s\n", handle
->dir
->parent
->name
);
599 kprintf("Our dir is: %s\n", handle
->dir
->name
);
601 redirect(rootfsbase
, iofs
, handle
->device
, handle
->unit
, NULL
);
603 kprintf("Redirection happened...\n");
604 if (ead
->ed_Type
== ST_ROOT
)
605 ead
->ed_Type
= ST_USERDIR
;
607 kprintf("Name: %s - Size: %d - Type: %d\n", ead
->ed_Name
, ead
->ed_Size
, ead
->ed_Type
);
611 kprintf("*Examining* the root\n");
617 ead
->ed_OwnerUID
= 0;
618 ead
->ed_OwnerGID
= 0;
622 ead
->ed_Comment
= NULL
;
640 ead
->ed_Type
= ST_ROOT
;
644 ead
->ed_Name
= handle
->dir
->name
;
647 ead
->ed_Next
= (struct ExAllData
*)(((IPTR
)next
+ AROS_PTRALIGN
- 1) & ~(AROS_PTRALIGN
- 1));
648 kprintf("exiting from examine...\n");
654 AROS_UFH3(struct rootfsbase
*, AROS_SLIB_ENTRY(init
,rootfs_handler
),
655 AROS_UFHA(struct rootfsbase
*, rootfsbase
, D0
),
656 AROS_UFHA(BPTR
, segList
, A0
),
657 AROS_UFHA(struct ExecBase
*, sysBase
, A6
)
662 /* Store arguments */
663 rootfsbase
->sysbase
=sysBase
;
664 rootfsbase
->seglist
=segList
;
666 rootfsbase
->dosbase
= (struct DosLibrary
*)OpenLibrary("dos.library",39);
667 if(rootfsbase
->dosbase
)
669 struct TagItem taglist
[]=
671 {NP_Entry
, (IPTR
)rootfsproc
},
672 {NP_Name
, (IPTR
)"rootfs.handler process"},
673 {NP_UserData
, (IPTR
)rootfsbase
},
677 rootfsbase
->proc
= CreateNewProc(taglist
);
679 if (rootfsbase
->proc
)
683 CloseLibrary((struct Library
*)rootfsbase
->dosbase
);
691 AROS_LHA(struct IOFileSys
*, iofs
, A1
),
692 AROS_LHA(ULONG
, unitnum
, D0
),
693 AROS_LHA(ULONG
, flags
, D1
),
694 struct rootfsbase
*, rootfsbase
, 1, rootfs_handler
)
700 /* Get compiler happy */
703 /* Mark Message as recently used. */
704 iofs
->IOFS
.io_Message
.mn_Node
.ln_Type
=NT_REPLYMSG
;
706 iofs
->IOFS
.io_Device
=&rootfsbase
->device
;
707 iofs
->IOFS
.io_Error
= 0;
709 root
= AllocVec(sizeof(struct root
), MEMF_ANY
| MEMF_CLEAR
);
712 struct filehandle
*handle
;
714 handle
= allocFHandle(rootfsbase
, root
, NULL
, NULL
, 0);
717 /* I have one more opener. */
718 rootfsbase
->device
.dd_Library
.lib_OpenCnt
++;
719 rootfsbase
->device
.dd_Library
.lib_Flags
&=~LIBF_DELEXP
;
720 (struct filehandle
*)iofs
->IOFS
.io_Unit
= handle
;
727 iofs
->IOFS
.io_Error
= ERROR_NO_FREE_STORE
;
733 AROS_LH1(BPTR
, close
,
734 AROS_LHA(struct IOFileSys
*, iofs
, A1
),
735 struct rootfsbase
*, rootfsbase
, 2, rootfs_handler
)
738 struct filehandle
*handle
;
740 handle
= (struct filehandle
*)iofs
->IOFS
.io_Unit
;
744 iofs
->io_DosError
= ERROR_OBJECT_WRONG_TYPE
;
748 if (handle
->root
->opencount
)
750 iofs
->io_DosError
= ERROR_OBJECT_IN_USE
;
754 freeFHandle(rootfsbase
, handle
);
756 /* Let any following attemps to use the device crash hard. */
757 iofs
->IOFS
.io_Device
=(struct Device
*)-1;
761 /* I have one fewer opener. */
762 if(!--rootfsbase
->device
.dd_Library
.lib_OpenCnt
)
764 /* Delayed expunge pending? */
765 if(rootfsbase
->device
.dd_Library
.lib_Flags
&LIBF_DELEXP
)
766 /* Then expunge the device */
773 AROS_LH0(BPTR
, expunge
, struct rootfsbase
*, rootfsbase
, 3, rootfs_handler
)
779 This function is single-threaded by exec by calling Forbid.
780 Never break the Forbid() or strange things might happen.
783 /* Test for openers. */
784 if(rootfsbase
->device
.dd_Library
.lib_OpenCnt
)
786 /* Set the delayed expunge flag and return. */
787 rootfsbase
->device
.dd_Library
.lib_Flags
|=LIBF_DELEXP
;
792 /* Tell the helper process to die */
795 /* Free all resources */
796 CloseLibrary((struct Library
*)rootfsbase
->dosbase
);
798 /* Get rid of the device. Remove it from the list. */
799 Remove(&rootfsbase
->device
.dd_Library
.lib_Node
);
801 /* Get returncode here - FreeMem() will destroy the field. */
802 ret
=rootfsbase
->seglist
;
804 /* Free the memory. */
805 FreeMem((char *)rootfsbase
-rootfsbase
->device
.dd_Library
.lib_NegSize
,
806 rootfsbase
->device
.dd_Library
.lib_NegSize
+rootfsbase
->device
.dd_Library
.lib_PosSize
);
812 AROS_LH0I(int, null
, struct rootfsbase
*, rootfsbase
, 4, rootfs_handler
)
819 AROS_LH1(void, beginio
,
820 AROS_LHA(struct IOFileSys
*, iofs
, A1
),
821 struct rootfsbase
*, rootfsbase
, 5, rootfs_handler
)
824 BOOL redirected
= FALSE
;
827 Do everything quick no matter what. This is possible
828 because I never need to Wait().
831 kprintf("COMMAND = %d\n", iofs
->IOFS
.io_Command
);
832 iofs
->io_DosError
= 0;
834 switch(iofs
->IOFS
.io_Command
)
839 redirected
= open_(rootfsbase
, iofs
);
840 kprintf("OPEN %p\n", iofs
->IOFS
.io_Unit
);
844 redirected
= close_(rootfsbase
, iofs
);
847 redirected = examine(rootfsbase, iofs);
849 case FSA_EXAMINE_NEXT: */
851 Get information about the next object
852 struct FileInfoBlock *fib;
854 error = examine_next(iofs->io_Union.io_EXAMINE_NEXT.io_fib);
857 iofs
->io_DosError
= ERROR_ACTION_NOT_KNOWN
;
861 /* If the quick bit is not set send the message to the port */
862 if(!(iofs
->IOFS
.io_Flags
&IOF_QUICK
) && !redirected
)
864 kprintf("Che ci faccio qui??\n");
865 ReplyMsg(&iofs
->IOFS
.io_Message
);
871 AROS_LH1(LONG
, abortio
,
872 AROS_LHA(struct IOFileSys
*, iofs
, A1
),
873 struct rootfsbase
*, rootfsbase
, 6, rootfs_handler
)
876 /* Everything already done. */
881 AROS_UFH3(LONG
, rootfsproc
,
882 AROS_UFHA(char *,argstr
,A0
),
883 AROS_UFHA(ULONG
,argsize
,D0
),
884 AROS_UFHA(struct ExecBase
*,SysBase
,A6
))
886 struct Process
*me
= (struct Process
*)FindTask(0);
887 struct rootmessage
*msg
;
892 WaitPort(&(me
->pr_MsgPort
));
896 (msg
=(struct rootmessage
*)GetMsg(&(me
->pr_MsgPort
))) &&
897 (cont
= (msg
->iofs
.oldiofs
!= 0))
900 if (msg
->msg
.mn_Node
.ln_Type
== NT_REPLYMSG
)
902 struct filehandle
*handle
;
904 msg
= ((struct rootmessage
*)(((char *)(msg
)) - offsetof(struct rootmessage
, iofs
.newiofs
)));
906 kprintf("Hurray!! We've received the message back :)\n");
908 handle
= (struct filehandle
*)msg
->iofs
.oldiofs
->IOFS
.io_Unit
;
910 msg
->iofs
.oldiofs
->io_DosError
= msg
->iofs
.newiofs
.io_DosError
;
911 msg
->iofs
.oldiofs
->io_Union
= msg
->iofs
.newiofs
.io_Union
;
913 ReplyMsg(&(msg
->iofs
.oldiofs
->IOFS
.io_Message
));
918 struct filehandle
*handle
;
920 handle
= (struct filehandle
*)msg
->iofs
.oldiofs
->IOFS
.io_Unit
;
921 kprintf("GOT A MESSAGE: command = %d -\n", msg
->iofs
.newiofs
.IOFS
.io_Command
);
923 msg
->iofs
.newiofs
.IOFS
.io_Message
.mn_ReplyPort
= &(me
->pr_MsgPort
);
925 /* Call BeginIO() vector */
927 AROS_LCA(struct IORequest
*,&(msg
->iofs
.newiofs
.IOFS
),A1
),
928 struct Device
*, msg
->iofs
.newiofs
.IOFS
.io_Device
,5,
940 static const char end
=0;