grub2: bring back build of aros-side grub2 tools
[AROS.git] / rom / filesys / afs / main.c
blob9a3d6d9b2008056a9134f243bfb9b977b2a37114
1 /*
2 Copyright © 1995-2010, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #ifndef DEBUG
7 #define DEBUG 0
8 #endif
10 #include <proto/dos.h>
11 #include <proto/exec.h>
13 #include <aros/macros.h>
14 #include <aros/debug.h>
16 #include "afshandler.h"
17 #include "cache.h"
18 #include "error.h"
19 #include "filehandles1.h"
20 #include "filehandles2.h"
21 #include "filehandles3.h"
22 #include "misc.h"
23 #include "volumes.h"
25 #include "baseredef.h"
27 static void replypkt(struct DosPacket *dp, SIPTR res1)
29 struct MsgPort *mp;
30 struct Message *mn;
32 mp = dp->dp_Port;
33 mn = dp->dp_Link;
34 mn->mn_Node.ln_Name = (char*)dp;
35 dp->dp_Port = &((struct Process*)FindTask(NULL))->pr_MsgPort;
36 dp->dp_Res1 = res1;
37 PutMsg(mp, mn);
40 static void replypkt2(struct DosPacket *dp, SIPTR res1, SIPTR res2)
42 dp->dp_Res2 = res2;
43 replypkt(dp, res1);
46 static struct AFSBase *AFS_alloc(void)
48 struct AFSBase *handler;
50 handler = AllocMem(sizeof(*handler), MEMF_ANY | MEMF_CLEAR);
51 if (handler == NULL)
52 return NULL;
54 handler->dosbase = (struct DosLibrary *)OpenLibrary("dos.library",0);
55 if (handler->dosbase != NULL) {
57 /* changeint task and sigbit */
58 handler->port.mp_SigTask = FindTask(0);
59 handler->port.mp_SigBit = SIGBREAKB_CTRL_F;
61 /* Port for device commands */
62 handler->timer_mp = CreateMsgPort();
63 /* Open timer */
64 handler->timer_request = (struct timerequest *)
65 CreateIORequest(handler->timer_mp, sizeof(struct timerequest));
66 if (handler->timer_request != NULL) {
67 if (OpenDevice("timer.device", UNIT_VBLANK,
68 (APTR)handler->timer_request, 0) == 0) {
69 return handler;
71 DeleteIORequest((struct IORequest *)handler->timer_request);
73 CloseLibrary((struct Library *)handler->dosbase);
76 return NULL;
79 static void AFS_free(struct AFSBase *handler)
81 if (handler->timer_flags & TIMER_ACTIVE) {
82 AbortIO((struct IORequest *)handler->timer_request);
83 WaitIO((struct IORequest *)handler->timer_request);
85 CloseDevice((struct IORequest *)handler->timer_request);
86 DeleteIORequest((struct IORequest *)handler->timer_request);
87 CloseLibrary((struct Library *)handler->dosbase);
88 FreeMem(handler, sizeof(*handler));
91 static struct Volume *AFS_open_volume(struct AFSBase *handler, struct DosPacket *dp, LONG *error)
93 struct FileSysStartupMsg *fssm = BADDR(dp->dp_Arg2);
95 D(bug("AFS: Volume on Device %b, Unit %ld, Flags %ld, Environ %p\n",
96 fssm->fssm_Device, fssm->fssm_Unit,
97 fssm->fssm_Flags, BADDR(fssm->fssm_Environ)));
98 return initVolume(handler,
99 NULL, AROS_BSTR_ADDR(fssm->fssm_Device),
100 fssm->fssm_Unit,
101 fssm->fssm_Flags,
102 BADDR(fssm->fssm_Environ),
103 error);
106 static BOOL AFS_close_volume(struct AFSBase *handler, struct Volume *volume, SIPTR *io_DosError)
108 if (!volume->locklist) {
109 uninitVolume(handler, volume);
110 return TRUE;
113 *io_DosError = ERROR_OBJECT_IN_USE;
114 return FALSE;
117 static BOOL AFS_protect_volume(struct AFSBase *handler, struct Volume *volume, BOOL on, ULONG key, SIPTR *io_DosError)
119 if (!volume->locklist)
121 LONG error = writeprotectVolume(handler, volume, on, key);
122 if (error == 0)
124 return TRUE;
125 } else {
126 *io_DosError = error;
127 return FALSE;
130 *io_DosError = ERROR_OBJECT_IN_USE;
131 return FALSE;
134 static VOID startFlushTimer(struct AFSBase *handler)
136 struct timerequest *request;
138 /* Set up delay for next flush */
139 if (handler->timer_flags & TIMER_ACTIVE) {
140 handler->timer_flags |= TIMER_RESTART;
141 } else {
142 /* D(bug("[afs] Starting timer\n")); */
143 request = handler->timer_request;
144 request->tr_node.io_Command = TR_ADDREQUEST;
145 request->tr_time.tv_secs = 1;
146 request->tr_time.tv_micro = 0;
147 SendIO((struct IORequest *)handler->timer_request);
148 handler->timer_flags = TIMER_ACTIVE;
152 static VOID onFlushTimer(struct AFSBase *handler, struct Volume *volume)
154 handler->timer_flags &= ~TIMER_ACTIVE;
156 if (handler->timer_flags & TIMER_RESTART) {
157 startFlushTimer(handler);
158 } else {
159 struct BlockCache *blockbuffer;
161 /* D(bug("[afs] Alarm rang.\n")); */
162 if ((volume->dostype == 0x444f5300) && mediumPresent(&volume->ioh))
164 /* Check if adding volume node needs to be retried */
165 if (volume->volumenode == NULL)
166 attemptAddDosVolume(handler, volume);
168 flushCache(handler, volume);
169 blockbuffer = getBlock(handler, volume, volume->rootblock);
170 if ((blockbuffer->flags & BCF_WRITE) != 0)
172 writeBlock(handler, volume, blockbuffer, -1);
173 blockbuffer->flags &= ~BCF_WRITE;
175 if (volume->ioh.flags & IOHF_MOTOR_OFF) {
176 D(bug("[afs 0x%08lX] turning off motor\n", volume));
177 motorOff(handler, &volume->ioh);
178 volume->ioh.flags &= ~IOHF_MOTOR_OFF;
184 static BOOL mediacheck(struct Volume *volume, SIPTR *ok, SIPTR *res2)
186 if (!mediumPresent(&volume->ioh)) {
187 *ok = DOSFALSE;
188 *res2 = ERROR_NO_DISK;
189 return FALSE;
191 return TRUE;
194 static LONG gethandletype(struct AFSBase *handler, struct AfsHandle *h)
196 UBYTE buffer[sizeof(struct ExAllData) + MAXFILENAMELENGTH];
197 struct ExAllData *ead = (APTR)&buffer[0];
198 ULONG size = sizeof(buffer);
199 ULONG mode = ED_TYPE;
200 IPTR dirpos;
201 LONG res2;
203 res2 = examine(handler, h, ead, size, mode, &dirpos);
204 if (res2 == 0)
205 return ead->ed_Type;
206 return 0;
209 static CONST_STRPTR skipdevname(CONST_STRPTR fn)
211 CONST_STRPTR cp;
212 /* Skip past device names */
213 for (cp = fn; *cp; cp++) {
214 if (*cp == '/')
215 break;
216 if (*cp == ':') {
217 fn = cp+1;
218 break;
221 return fn;
224 /*******************************************
225 Name : AFS_work
226 Descr.: main loop (get packets and answer (or not))
227 Input : proc - our process structure
228 Output: -
229 ********************************************/
230 LONG AFS_work(struct ExecBase *SysBase)
232 struct MsgPort *mp;
233 struct DosPacket *dp;
234 struct Message *mn;
235 struct AFSBase *handler;
236 struct Volume *volume;
237 LONG retval;
238 BOOL dead = FALSE;
240 D(bug("[AFS] started\n"));
241 mp = &((struct Process *)FindTask(NULL))->pr_MsgPort;
242 WaitPort(mp);
243 dp = (struct DosPacket *)GetMsg(mp)->mn_Node.ln_Name;
244 D(bug("[AFS] start message recevied. port=%p, path='%b'\n", mp, dp->dp_Arg1));
246 handler = AFS_alloc();
248 if (handler == NULL) {
249 D(bug("[AFS] Can't allocate an instance of the handler for this volume\n"));
250 replypkt(dp, DOSFALSE);
251 return RETURN_FAIL;
254 volume = AFS_open_volume(handler, dp, &retval);
255 if (volume == NULL) {
256 D(bug("[AFS] Can't open volume\n"));
257 replypkt2(dp, DOSFALSE, retval);
258 AFS_free(handler);
259 return RETURN_FAIL;
262 /* make non-packet functions to see our volume */
263 NEWLIST(&handler->device_list);
264 AddHead(&handler->device_list, &volume->ln);
266 /* Say that we are going to persist */
267 ((struct DeviceNode *)BADDR(dp->dp_Arg3))->dn_Task = mp;
269 replypkt(dp, DOSTRUE);
271 while (!dead) {
272 ULONG packetmask = 1L << mp->mp_SigBit;
273 ULONG timermask = 1L << handler->timer_mp->mp_SigBit;
274 ULONG changemask = 1L << SIGBREAKB_CTRL_F;
275 ULONG sigs;
277 sigs = Wait(packetmask | timermask | changemask);
279 if (sigs & timermask)
280 onFlushTimer(handler, volume);
281 if (sigs & changemask) {
282 checkDeviceFlags(handler);
285 if (!(sigs & packetmask))
286 continue;
288 /* DOS Packet processing */
290 while ((mn = GetMsg(mp)) != NULL) {
291 SIPTR res2 = 0;
292 SIPTR ok = DOSFALSE;
294 dp = (struct DosPacket *)mn->mn_Node.ln_Name;
296 D(bug("[AFS] packet %p:%d\n", dp, dp->dp_Type));
297 startFlushTimer(handler);
299 switch (dp->dp_Type) {
300 case ACTION_DIE:
301 if (!AFS_close_volume(handler, volume, &res2)) {
302 ok = FALSE;
303 break;
305 dead = DOSTRUE;
306 ok = TRUE;
307 break;
308 case ACTION_IS_FILESYSTEM:
309 ok = TRUE;
310 break;
311 case ACTION_INHIBIT:
312 res2 = inhibit(handler, volume, dp->dp_Arg1);
313 ok = res2 ? DOSFALSE : DOSTRUE;
314 break;
315 case ACTION_END:
316 closef(handler, (struct AfsHandle *)dp->dp_Arg1);
317 ok = DOSTRUE;
318 break;
319 case ACTION_MORE_CACHE:
321 LONG numbuff = dp->dp_Arg1;
323 if (numbuff) {
324 volume->numbuffers += numbuff;
326 if (volume->numbuffers < 1)
327 volume->numbuffers = 1;
329 flushCache(handler, volume);
330 Forbid();
331 freeCache(handler, volume->blockcache);
332 for (;;) {
333 volume->blockcache = initCache(handler, volume, volume->numbuffers);
334 if (volume->blockcache)
335 break;
336 volume->numbuffers /= 2;
337 if (volume->numbuffers < 1)
338 volume->numbuffers = 1;
341 ok = DOSTRUE;
342 res2 = volume->numbuffers;
344 break;
345 case ACTION_DISK_INFO:
346 ok = getDiskInfo(volume, BADDR(dp->dp_Arg1)) ? DOSFALSE : DOSTRUE;
347 break;
348 case ACTION_SAME_LOCK:
350 struct FileLock *f1 = BADDR(dp->dp_Arg1);
351 struct FileLock *f2 = BADDR(dp->dp_Arg2);
352 ok = (sameLock((struct AfsHandle*)f1->fl_Key, (struct AfsHandle*)f2->fl_Key) == LOCK_SAME) ? DOSTRUE : DOSFALSE;
353 break;
356 default:
358 switch (dp->dp_Type) {
359 case ACTION_FINDINPUT:
360 case ACTION_FINDOUTPUT:
361 case ACTION_FINDUPDATE:
363 struct FileHandle *fh = BADDR(dp->dp_Arg1);
364 struct FileLock *dl = BADDR(dp->dp_Arg2);
365 CONST_STRPTR fn = AROS_BSTR_ADDR(dp->dp_Arg3);
366 struct AfsHandle *dh;
367 struct AfsHandle *ah;
368 ULONG mode = 0;
370 if (!mediacheck(volume, &ok, &res2))
371 break;
373 if (dl == NULL)
374 dh = &volume->ah;
375 else
376 dh = (APTR)(dl->fl_Key);
378 /* MODE_* directly matches its
379 * corresponding ACTION_* counterpart.
381 mode = dp->dp_Type;
383 fn = skipdevname(fn);
385 if (dp->dp_Type == ACTION_FINDOUTPUT) {
386 ah = openfile(handler, dh, fn, mode, 0, &res2);
387 } else {
388 ah = openf(handler, dh, fn, mode, &res2);
390 ok = (ah != NULL) ? DOSTRUE : DOSFALSE;
391 if (ok) {
392 if (dp->dp_Type != ACTION_FINDOUTPUT) {
393 LONG type = gethandletype(handler, ah);
394 if (type >= 0) {
395 /* was directory */
396 res2 = ERROR_OBJECT_WRONG_TYPE;
397 ok = DOSFALSE;
398 closef(handler, ah);
399 break;
402 fh->fh_Arg1 = (SIPTR)ah;
404 break;
406 case ACTION_LOCATE_OBJECT:
408 struct FileLock *dl = BADDR(dp->dp_Arg1);
409 struct FileLock *fl;
410 CONST_STRPTR fn = AROS_BSTR_ADDR(dp->dp_Arg2);
411 struct AfsHandle *dh;
412 struct AfsHandle *ah;
413 ULONG mode = 0;
415 if (!mediacheck(volume, &ok, &res2))
416 break;
418 if (dl == NULL)
419 dh = &volume->ah;
420 else
421 dh = (APTR)(dl->fl_Key);
423 if (dp->dp_Arg3 == ACCESS_READ)
424 mode = MODE_OLDFILE;
425 else if (dp->dp_Arg3 == ACCESS_WRITE)
426 mode = MODE_NEWFILE;
428 fn = skipdevname(fn);
430 ah = openf(handler, dh, fn, mode, &res2);
431 if (ah == NULL) {
432 ok = DOSFALSE;
433 break;
435 fl = AllocMem(sizeof(*fl), MEMF_CLEAR);
436 if (fl != NULL) {
437 fl->fl_Link = BNULL;
438 fl->fl_Key = (SIPTR)ah;
439 fl->fl_Access = dp->dp_Arg3;
440 fl->fl_Task = mp;
441 fl->fl_Volume = MKBADDR(&volume->devicelist);
442 ok = (SIPTR)MKBADDR(fl);
443 res2 = 0;
444 } else {
445 closef(handler, ah);
446 ok = DOSFALSE;
447 res2 = ERROR_NO_FREE_STORE;
449 break;
451 case ACTION_COPY_DIR: /* Aka DupLock() */
452 case ACTION_COPY_DIR_FH:
454 struct FileLock *ol = BADDR(dp->dp_Arg1);
455 struct FileLock *fl;
456 struct AfsHandle *oh;
457 struct AfsHandle *ah;
459 if (!mediacheck(volume, &ok, &res2))
460 break;
462 if (dp->dp_Type == ACTION_COPY_DIR) {
463 oh = ol ? (APTR)ol->fl_Key : &volume->ah;
464 } else {
465 oh = (APTR)dp->dp_Arg1;
468 ah = openf(handler, oh, "", MODE_OLDFILE, &res2);
469 if (ah == NULL) {
470 ok = DOSFALSE;
471 break;
473 fl = AllocMem(sizeof(*fl), MEMF_CLEAR);
474 if (fl != NULL) {
475 fl->fl_Link = BNULL;
476 fl->fl_Key = (SIPTR)ah;
477 fl->fl_Access = ACCESS_READ;
478 fl->fl_Task = mp;
479 fl->fl_Volume = MKBADDR(&volume->devicelist);
480 ok = (SIPTR)MKBADDR(fl);
481 res2 = 0;
482 } else {
483 closef(handler, ah);
484 ok = DOSFALSE;
485 res2 = ERROR_NO_FREE_STORE;
487 break;
489 case ACTION_FREE_LOCK:
491 struct FileLock *fl;
492 struct AfsHandle *ah;
494 if (!mediacheck(volume, &ok, &res2))
495 break;
497 fl = BADDR(dp->dp_Arg1);
498 if (fl == NULL) {
499 ok = DOSTRUE;
500 break;
502 ah = (APTR)(fl->fl_Key);
503 closef(handler, ah);
504 FreeMem(fl, sizeof(*fl));
505 ok = DOSTRUE;
506 break;
508 case ACTION_READ:
509 if (!mediacheck(volume, &ok, &res2))
510 break;
511 ok = readf(handler, (struct AfsHandle *)(dp->dp_Arg1), (APTR)dp->dp_Arg2, (LONG)dp->dp_Arg3, &res2);
512 break;
513 case ACTION_WRITE:
514 if (!mediacheck(volume, &ok, &res2))
515 break;
516 ok = writef(handler, (struct AfsHandle *)(dp->dp_Arg1), (APTR)dp->dp_Arg2, (LONG)dp->dp_Arg3, &res2);
517 break;
518 case ACTION_SEEK:
519 if (!mediacheck(volume, &ok, &res2))
520 break;
521 ok = seek(handler, (struct AfsHandle *)(dp->dp_Arg1), (LONG)dp->dp_Arg2, (LONG)dp->dp_Arg3, &res2);
522 break;
523 case ACTION_SET_FILE_SIZE:
524 if (!mediacheck(volume, &ok, &res2))
525 break;
526 ok = setFileSize(handler, (struct AfsHandle *)(dp->dp_Arg1),(LONG)dp->dp_Arg2, (LONG)dp->dp_Arg3, &res2);
527 break;
528 case ACTION_FH_FROM_LOCK:
530 struct FileHandle *fh = BADDR(dp->dp_Arg1);
531 struct FileLock *fl = BADDR(dp->dp_Arg2);
532 fh->fh_Arg1 = (SIPTR)fl->fl_Key;
533 FreeMem(fl, sizeof(*fl));
534 break;
536 case ACTION_EXAMINE_OBJECT:
537 case ACTION_EXAMINE_FH:
539 struct FileLock *fl = BADDR(dp->dp_Arg1);
540 struct AfsHandle *ah;
541 struct FileInfoBlock *fib = BADDR(dp->dp_Arg2);
542 UBYTE buffer[sizeof(struct ExAllData) + MAXFILENAMELENGTH + MAXCOMMENTLENGTH];
543 struct ExAllData *ead = (APTR)&buffer[0];
544 ULONG size = sizeof(buffer);
545 ULONG mode = ED_OWNER;
546 SIPTR dirpos;
548 if (!mediacheck(volume, &ok, &res2))
549 break;
551 if (dp->dp_Type == ACTION_EXAMINE_OBJECT)
552 ah = fl ? (APTR)fl->fl_Key : &volume->ah;
553 else
554 ah = (APTR)dp->dp_Arg1;
556 if (fib == NULL) {
557 ok = DOSTRUE;
558 break;
561 res2 = examine(handler, ah, ead, size, mode, &dirpos);
562 if (res2 != 0) {
563 ok = DOSFALSE;
564 break;
567 if (ah == &volume->ah) {
568 fib->fib_DirEntryType = ST_ROOT;
569 } else {
570 fib->fib_DirEntryType = ead->ed_Type;
573 fib->fib_DiskKey = ah->header_block;
574 strncpy(&fib->fib_FileName[1], ead->ed_Name, sizeof(fib->fib_FileName)-1);
575 fib->fib_FileName[0] = strlen(&fib->fib_FileName[1]);
576 fib->fib_Protection = ead->ed_Prot;
577 fib->fib_EntryType = fib->fib_DirEntryType;
578 fib->fib_Size = ead->ed_Size;
579 fib->fib_NumBlocks = (ead->ed_Size + ah->volume->sectorsize - 1) / ah->volume->sectorsize;
580 fib->fib_Date.ds_Days = ead->ed_Days;
581 fib->fib_Date.ds_Minute = ead->ed_Mins;
582 fib->fib_Date.ds_Tick = ead->ed_Ticks;
583 if (ead->ed_Comment) {
584 strncpy(&fib->fib_Comment[1], ead->ed_Comment, sizeof(fib->fib_Comment)-1);
585 fib->fib_Comment[0] = strlen(&fib->fib_Comment[1]);
586 } else {
587 fib->fib_Comment[0] = 0;
589 fib->fib_OwnerUID = ead->ed_OwnerUID;
590 fib->fib_OwnerGID = ead->ed_OwnerGID;
591 ok = DOSTRUE;
592 break;
594 case ACTION_EXAMINE_NEXT:
596 struct FileLock *fl = BADDR(dp->dp_Arg1);
597 struct AfsHandle *ah;
598 struct FileInfoBlock *fib = BADDR(dp->dp_Arg2);
600 if (!mediacheck(volume, &ok, &res2))
601 break;
603 if (fib == NULL) {
604 ok = DOSTRUE;
605 break;
608 if (fl == NULL)
609 ah = &volume->ah;
610 else
611 ah = (APTR)fl->fl_Key;
613 res2 = examineNext(handler, ah, fib);
614 if (res2 != 0) {
615 ok = DOSFALSE;
616 break;
619 if (ah == &volume->ah) {
620 fib->fib_DirEntryType = ST_ROOT;
622 ok = DOSTRUE;
623 break;
625 case ACTION_PARENT:
626 case ACTION_PARENT_FH:
628 struct FileLock *opl = BADDR(dp->dp_Arg1);
629 struct FileLock *fl;
630 struct AfsHandle *oh;
631 struct AfsHandle *ah;
633 if (!mediacheck(volume, &ok, &res2))
634 break;
636 if (dp->dp_Type == ACTION_PARENT)
637 oh = (APTR)opl->fl_Key;
638 else
639 oh = (APTR)dp->dp_Arg1;
640 ah = openf(handler, oh, "/", MODE_OLDFILE, &res2);
641 if (ah == NULL) {
642 ok = DOSFALSE;
643 if (res2 == ERROR_OBJECT_NOT_FOUND && gethandletype(handler, oh) == ST_ROOT)
644 res2 = 0; /* need to return res2 = 0 (not 205) if oh == ST_ROOT */
645 break;
647 fl = AllocMem(sizeof(*fl), MEMF_CLEAR);
648 if (fl != NULL) {
649 fl->fl_Link = BNULL;
650 fl->fl_Key = (SIPTR)ah;
651 fl->fl_Access = ACCESS_READ;
652 fl->fl_Task = mp;
653 fl->fl_Volume = MKBADDR(&volume->devicelist);
654 ok = (SIPTR)MKBADDR(fl);
655 res2 = 0;
656 } else {
657 closef(handler, ah);
658 ok = DOSFALSE;
659 res2 = ERROR_NO_FREE_STORE;
661 break;
663 case ACTION_INFO:
665 struct FileLock *opl = BADDR(dp->dp_Arg1);
666 struct AfsHandle *oh;
667 if (opl == NULL)
668 oh = &volume->ah;
669 else
670 oh = (APTR)opl->fl_Key;
671 if (gethandletype(handler, oh) == 0 || !mediacheck(volume, &ok, &res2)) {
672 res2 = ERROR_OBJECT_NOT_FOUND;
673 ok = DOSFALSE;
675 res2 = getDiskInfo(volume, BADDR(dp->dp_Arg2));
676 ok = res2 ? DOSFALSE : DOSTRUE;
677 break;
679 break;
680 case ACTION_RENAME_OBJECT:
682 struct FileLock *opl = BADDR(dp->dp_Arg1);
683 //unused//struct FileLock *npl = BADDR(dp->dp_Arg3);
684 CONST_STRPTR on = AROS_BSTR_ADDR(dp->dp_Arg2);
685 CONST_STRPTR nn = AROS_BSTR_ADDR(dp->dp_Arg4);
686 struct AfsHandle *oh;
688 if (opl == NULL)
689 oh = &volume->ah;
690 else
691 oh = (APTR)opl->fl_Key;
692 on = skipdevname(on);
693 nn = skipdevname(nn);
694 res2 = renameObject(handler, oh, on, nn);
695 ok = res2 ? DOSFALSE : DOSTRUE;
696 break;
698 case ACTION_RENAME_DISK:
700 CONST_STRPTR n = AROS_BSTR_ADDR(dp->dp_Arg1);
701 ok = relabel(handler, volume, n, &res2);
702 break;
704 case ACTION_CREATE_DIR:
706 struct FileLock *fl = BADDR(dp->dp_Arg1), *flnew;
707 struct AfsHandle *h, *ah;
708 CONST_STRPTR n = AROS_BSTR_ADDR(dp->dp_Arg2);
709 if (fl == NULL)
710 h = &volume->ah;
711 else
712 h = (APTR)fl->fl_Key;
713 n = skipdevname(n);
714 flnew = AllocMem(sizeof(*flnew), MEMF_CLEAR);
715 if (flnew != NULL) {
716 ah = createDir(handler, h, n, 0, &res2);
717 ok = res2 ? DOSFALSE : DOSTRUE;
718 if (ok) {
719 flnew->fl_Link = BNULL;
720 flnew->fl_Key = (SIPTR)ah;
721 flnew->fl_Access = ACCESS_READ;
722 flnew->fl_Task = mp;
723 flnew->fl_Volume = MKBADDR(&volume->devicelist);
724 ok = (SIPTR)MKBADDR(flnew);
726 } else {
727 ok = DOSFALSE;
728 res2 = ERROR_NO_FREE_STORE;
730 break;
732 case ACTION_DELETE_OBJECT:
734 struct FileLock *fl = BADDR(dp->dp_Arg1);
735 struct AfsHandle *h;
736 CONST_STRPTR n = AROS_BSTR_ADDR(dp->dp_Arg2);
737 if (fl == NULL)
738 h = &volume->ah;
739 else
740 h = (APTR)fl->fl_Key;
741 n = skipdevname(n);
742 res2 = deleteObject(handler, h, n);
743 ok = res2 ? DOSFALSE : DOSTRUE;
744 break;
746 case ACTION_SET_COMMENT:
748 struct FileLock *fl = BADDR(dp->dp_Arg2);
749 struct AfsHandle *h;
750 CONST_STRPTR n = AROS_BSTR_ADDR(dp->dp_Arg3);
751 CONST_STRPTR c = AROS_BSTR_ADDR(dp->dp_Arg4);
752 if (fl == NULL)
753 h = &volume->ah;
754 else
755 h = (APTR)fl->fl_Key;
756 n = skipdevname(n);
757 res2 = setComment(handler, h, n, c);
758 ok = res2 ? DOSFALSE : DOSTRUE;
759 break;
761 case ACTION_SET_PROTECT:
763 struct FileLock *fl = BADDR(dp->dp_Arg2);
764 struct AfsHandle *h;
765 CONST_STRPTR n = AROS_BSTR_ADDR(dp->dp_Arg3);
766 ULONG p = dp->dp_Arg4;
767 if (fl == NULL)
768 h = &volume->ah;
769 else
770 h = (APTR)fl->fl_Key;
771 n = skipdevname(n);
772 res2 = setProtect(handler, h, n, p);
773 ok = res2 ? DOSFALSE : DOSTRUE;
774 break;
776 case ACTION_SET_DATE:
778 struct FileLock *fl = BADDR(dp->dp_Arg2);
779 struct AfsHandle *h;
780 CONST_STRPTR n = AROS_BSTR_ADDR(dp->dp_Arg3);
781 struct DateStamp *ds = (struct DateStamp*)dp->dp_Arg4;
782 if (fl == NULL)
783 h = &volume->ah;
784 else
785 h = (APTR)fl->fl_Key;
786 n = skipdevname(n);
787 res2 = setDate(handler, h, n, ds);
788 ok = res2 ? DOSFALSE : DOSTRUE;
789 break;
791 case ACTION_INHIBIT:
792 res2 = inhibit(handler, volume, dp->dp_Arg1);
793 ok = res2 ? DOSFALSE : DOSTRUE;
794 break;
795 case ACTION_FORMAT:
797 CONST_STRPTR n = AROS_BSTR_ADDR(dp->dp_Arg1);
798 res2 = format(handler, volume, n, dp->dp_Arg2);
799 ok = res2 ? DOSFALSE : DOSTRUE;
800 break;
802 case ACTION_SERIALIZE_DISK:
803 ok = relabel(handler, volume, NULL, &res2);
804 break;
805 case ACTION_WRITE_PROTECT:
806 ok = AFS_protect_volume(handler, volume, dp->dp_Arg1, dp->dp_Arg2, &res2) ? DOSFALSE : DOSTRUE;
807 break;
808 default:
809 ok = DOSFALSE;
810 res2 = ERROR_ACTION_NOT_KNOWN;
811 D(bug("[AFS] %d not implemented\n", dp->dp_Type));
812 break;
814 break;
817 replypkt2(dp, ok, res2);
821 AFS_free(handler);
822 replypkt(dp, DOSTRUE);
824 return RETURN_OK;