Indentation fix, cleanup.
[AROS.git] / rom / filesys / ram / commands.c
blobd847528d7daca0b019932414b1bd60db2d6f41bc
1 /*
3 File: commands.c
4 Author: Neil Cafferkey
5 Copyright (C) 2001-2008 Neil Cafferkey
7 This file is free software; you can redistribute it and/or modify it
8 under the terms of the GNU Lesser General Public License as
9 published by the Free Software Foundation; either version 2.1 of the
10 License, or (at your option) any later version.
12 This file is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
17 You should have received a copy of the GNU Lesser General Public
18 License along with this file; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston,
20 MA 02111-1307, USA.
24 #include <aros/config.h>
25 #include <aros/debug.h>
27 #include "handler_protos.h"
30 static const TEXT default_vol_name[] = "RAM Disk";
33 static const UWORD examine_sizes[] =
35 (UWORD)OFFSET(ExAllData, ed_Type),
36 (UWORD)OFFSET(ExAllData, ed_Size),
37 (UWORD)OFFSET(ExAllData, ed_Prot),
38 (UWORD)OFFSET(ExAllData, ed_Days),
39 (UWORD)OFFSET(ExAllData, ed_Comment),
40 (UWORD)OFFSET(ExAllData, ed_OwnerUID)
45 /****i* ram.handler/CmdStartup *********************************************
47 * NAME
48 * CmdStartup --
50 * SYNOPSIS
51 * handler = CmdStartup(name, dev_node,
52 * proc_port)
54 * struct Handler *CmdStartup(STRPTR, struct DeviceNode *,
55 * struct MsgPort *);
57 * FUNCTION
59 * INPUTS
61 * RESULT
63 * EXAMPLE
65 * NOTES
67 * BUGS
69 * SEE ALSO
71 ****************************************************************************
75 BOOL CmdStartup(struct Handler *handler, STRPTR name, struct DeviceNode *dev_node,
76 struct MsgPort *proc_port)
78 struct DosList *volume;
79 struct Object *root_dir;
80 struct MsgPort *port;
81 LONG error;
82 APTR base;
84 /* Open extra libraries */
86 error = 0;
87 base = OpenLibrary(UTILITYNAME, UTILITY_VERSION);
88 if(base != NULL)
89 UtilityBase = base;
90 else
91 error = 1;
93 #if !(AROS_FLAVOUR & AROS_FLAVOUR_BINCOMPAT)
94 base = OpenLibrary("locale.library", LOCALE_VERSION);
95 if(base != NULL)
96 LocaleBase = base;
97 else
98 error = 1;
99 #endif
101 /* Initialise private handler structure */
103 if(error == 0)
105 handler->proc_port = proc_port;
106 handler->block_count = MEMBLOCKS(StrSize(default_vol_name)) +
107 MEMBLOCKS(sizeof(struct Handler));
108 handler->min_block_size = MIN_BLOCK_SIZE;
109 handler->max_block_size = MAX_BLOCK_SIZE;
110 NewList((APTR)&handler->examinations);
112 dev_node->dn_Task = proc_port;
114 /* Create pools for zeroed, non-zeroed and public zeroed memory */
116 handler->clear_pool = CreatePool(MEMF_CLEAR, CLEAR_PUDDLE_SIZE,
117 CLEAR_PUDDLE_THRESH);
118 if(handler->clear_pool == NULL)
119 error = IoErr();
120 handler->muddy_pool = CreatePool(MEMF_ANY, MUDDY_PUDDLE_SIZE,
121 MUDDY_PUDDLE_THRESH);
122 if(handler->muddy_pool == NULL)
123 error = IoErr();
124 handler->public_pool = CreatePool(MEMF_PUBLIC | MEMF_CLEAR,
125 PUBLIC_PUDDLE_SIZE, PUBLIC_PUDDLE_THRESH);
126 if(handler->public_pool == NULL)
127 error = IoErr();
129 /* Create a volume dos node */
131 volume = MyMakeDosEntry(handler, default_vol_name, DLT_VOLUME);
132 if(volume == NULL)
133 error = IoErr();
136 if(error == 0)
138 volume->dol_Task = proc_port;
139 DateStamp(&volume->dol_misc.dol_volume.dol_VolumeDate);
140 volume->dol_misc.dol_volume.dol_DiskType = ID_DOS_DISK;
142 /* Put volume node into dos list */
144 AddDosEntry(volume);
145 handler->volume = volume;
147 /* Open default locale */
148 if (LocaleBase)
149 handler->locale = OpenLocale(NULL);
151 /* Initialise notification handling */
153 NewList((APTR)&handler->notifications);
154 port = CreateMsgPort();
155 handler->notify_port = port;
156 if(port == NULL)
157 error = IoErr();
160 /* Create the root directory and get a shared lock on it */
162 if(error == 0)
164 root_dir = CreateObject(handler, default_vol_name, ST_ROOT, NULL);
165 handler->root_dir = root_dir;
166 if(root_dir != NULL)
168 if(LockObject(handler, root_dir, ACCESS_READ) == NULL)
169 error = IoErr();
171 else
172 error = IoErr();
175 /* Return result */
177 SetIoErr(error);
178 return error != 0;
183 /****i* ram.handler/CmdDie *************************************************
185 * NAME
186 * CmdDie --
188 * SYNOPSIS
189 * success = CmdDie(handler)
191 * BOOL CmdDie(struct Handler *);
193 * FUNCTION
195 * INPUTS
197 * RESULT
199 * EXAMPLE
201 * NOTES
203 * BUGS
205 * SEE ALSO
207 ****************************************************************************
211 BOOL CmdDie(struct Handler *handler)
213 struct Object *root_dir;
214 LONG error = 0;
216 root_dir = handler->root_dir;
217 if(IsListEmpty(&root_dir->elements)
218 && IsListEmpty(&handler->notifications)
219 && IsListEmpty(&root_dir->notifications)
220 && root_dir->lock->lock_count == 1)
221 DeleteHandler(handler);
222 else
223 error = ERROR_OBJECT_IN_USE;
225 /* Return success indicator */
227 SetIoErr(error);
228 return error == 0;
233 /****i* ram.handler/CmdIsFileSystem ****************************************
235 * NAME
236 * CmdIsFileSystem --
238 * SYNOPSIS
239 * result = CmdIsFileSystem()
241 * BOOL CmdIsFileSystem();
243 * FUNCTION
245 * INPUTS
247 * RESULT
249 * EXAMPLE
251 * NOTES
253 * BUGS
255 * SEE ALSO
257 ****************************************************************************
261 BOOL CmdIsFileSystem()
263 return TRUE;
268 /****i* ram.handler/CmdFind ************************************************
270 * NAME
271 * CmdFind --
273 * SYNOPSIS
274 * success = CmdFind(handler, handle, lock,
275 * name, mode)
277 * BOOL CmdFind(struct Handler *, struct FileHandle *, struct Lock *,
278 * TEXT *, ULONG);
280 * FUNCTION
282 * INPUTS
284 * RESULT
286 * EXAMPLE
288 * NOTES
290 * BUGS
292 * SEE ALSO
294 ****************************************************************************
298 BOOL CmdFind(struct Handler *handler, struct FileHandle *handle,
299 struct Lock *lock, const TEXT *name, ULONG type)
301 LONG error = 0;
302 ULONG mode;
303 struct Object *file, *parent;
305 /* Set access mode */
307 if(type == MODE_NEWFILE)
308 mode = ACCESS_WRITE;
309 else
310 mode = ACCESS_READ;
312 /* Get file */
314 if(type == MODE_NEWFILE && handler->locked)
315 error = ERROR_DISK_WRITE_PROTECTED;
317 if(error == 0)
319 file = GetHardObject(handler, lock, name, &parent);
320 if(parent == NULL)
321 error = IoErr();
324 /* Do any necessary file deletion or creation */
326 if(error == 0)
328 name = FilePart(name);
330 switch(type)
332 case MODE_NEWFILE:
333 if(file != NULL)
335 if((GetRealObject(file)->protection & FIBF_DELETE) != 0)
336 error = ERROR_DELETE_PROTECTED;
338 if(((struct Node *)file)->ln_Pri >= 0)
339 error = ERROR_OBJECT_EXISTS;
342 if(error == 0)
344 if(!AttemptDeleteObject(handler, file, FALSE))
345 error = IoErr();
346 file = NULL;
349 case MODE_READWRITE:
350 if(error == 0 && file == NULL)
351 file = CreateObject(handler, name, ST_FILE, parent);
353 default:
354 if(file == NULL)
355 error = IoErr();
359 /* Get a lock on the file */
361 if(error == 0)
363 lock = LockObject(handler, file, mode);
364 if(lock == NULL)
365 error = IoErr();
366 else if(type == MODE_NEWFILE)
367 lock->changed = TRUE;
370 /* Open file */
372 if(error == 0)
374 if(!CmdFHFromLock(handler, handle, lock))
376 error = IoErr();
377 CmdFreeLock(handler, lock);
381 /* Set error and return success code */
383 SetIoErr(error);
384 return error == 0;
389 /****i* ram.handler/CmdFHFromLock ******************************************
391 * NAME
392 * CmdFHFromLock --
394 * SYNOPSIS
395 * success = CmdFHFromLock(handle, lock)
397 * BOOL CmdFHFromLock(struct FileHandle *, struct Lock *);
399 * FUNCTION
401 * INPUTS
403 * RESULT
405 * EXAMPLE
407 * NOTES
409 * BUGS
411 * SEE ALSO
413 ****************************************************************************
417 BOOL CmdFHFromLock(struct Handler *handler, struct FileHandle *handle,
418 struct Lock *lock)
420 LONG error = 0;
421 struct Opening *opening = NULL;
422 struct Object *file;
424 /* Check if access is allowed */
426 file = (APTR)((struct FileLock *)lock)->fl_Key;
427 if(((struct Node *)file)->ln_Pri != ST_FILE)
428 error = ERROR_OBJECT_WRONG_TYPE;
430 /* Create and initialise "opening" */
432 if(error == 0)
434 opening = AllocPooled(handler->clear_pool, sizeof(struct Opening));
435 if(opening != NULL)
437 opening->file = file;
438 opening->block = (struct Block *)file->elements.mlh_Head;
439 AddTail((struct List *)&lock->openings, (struct Node *)opening);
441 else
442 error = IoErr();
445 /* Put address of opening in file handle */
447 handle->fh_Arg1 = (PINT)opening;
449 /* Set error and return success code */
451 SetIoErr(error);
452 return error == 0;
457 /****i* ram.handler/CmdEnd *************************************************
459 * NAME
460 * CmdEnd --
462 * SYNOPSIS
463 * success = CmdEnd(handler, opening)
465 * BOOL CmdEnd(struct Handler *, struct Opening *);
467 * FUNCTION
469 * INPUTS
471 * RESULT
473 * EXAMPLE
475 * NOTES
477 * BUGS
479 * SEE ALSO
481 ****************************************************************************
485 BOOL CmdEnd(struct Handler *handler, struct Opening *opening)
487 struct Object *file, *parent;
488 struct Lock *lock;
489 LONG error = 0;
491 /* Close file and update its date and flags */
493 file = opening->file;
494 lock = file->lock;
495 if(lock->changed)
497 if(!handler->locked)
499 file->protection &= ~FIBF_ARCHIVE;
500 DateStamp(&file->date);
501 parent = file->parent;
502 parent->protection &= ~FIBF_ARCHIVE;
503 CopyMem(&file->date, &parent->date, sizeof(struct DateStamp));
505 NotifyAll(handler, file, TRUE);
507 else
508 error = ERROR_DISK_WRITE_PROTECTED;
511 if(error == 0)
513 Remove((APTR)opening);
514 CmdFreeLock(handler, lock);
515 FreePooled(handler->clear_pool, opening, sizeof(struct Opening));
518 /* Return success indicator */
520 SetIoErr(error);
521 return error == 0;
526 /****i* ram.handler/CmdRead ************************************************
528 * NAME
529 * CmdRead --
531 * SYNOPSIS
532 * actual_length = CmdRead(opening, buffer, length)
534 * UPINT CmdRead(struct Opening *, UBYTE *, UPINT);
536 * FUNCTION
538 * INPUTS
540 * RESULT
542 * EXAMPLE
544 * NOTES
546 * BUGS
548 * SEE ALSO
550 ****************************************************************************
554 UPINT CmdRead(struct Handler *handler, struct Opening *opening, UBYTE *buffer, UPINT length)
556 LONG error = 0;
557 struct Object *file;
559 /* Read file if it isn't read protected */
561 file = opening->file;
563 if((file->protection & FIBF_READ) != 0)
564 error = ERROR_READ_PROTECTED;
566 if(error == 0)
568 length = ReadData(opening, buffer, length);
569 error = IoErr();
571 else
573 length = -1;
576 /* Return number of bytes read */
578 SetIoErr(error);
579 return length;
584 /****i* ram.handler/CmdWrite ***********************************************
586 * NAME
587 * CmdWrite --
589 * SYNOPSIS
590 * actual_length = CmdWrite(handler, opening, buffer, length)
592 * UPINT CmdWrite(struct Handler *, struct Opening *, UBYTE *, UPINT);
594 * FUNCTION
596 * INPUTS
598 * RESULT
600 * EXAMPLE
602 * NOTES
604 * BUGS
606 * SEE ALSO
608 ****************************************************************************
612 UPINT CmdWrite(struct Handler *handler, struct Opening *opening,
613 UBYTE *buffer, UPINT length)
615 LONG error = 0;
616 struct Object *file;
617 struct Lock *lock;
619 /* Write to file if it isn't write protected */
621 file = opening->file;
622 lock = file->lock;
624 if((file->protection & FIBF_WRITE) != 0)
625 error = ERROR_WRITE_PROTECTED;
627 if(handler->locked)
628 error = ERROR_DISK_WRITE_PROTECTED;
630 if(error == 0)
632 length = WriteData(handler, opening, buffer, length);
633 error = IoErr();
634 if(length > 0)
635 lock->changed = TRUE;
637 else
639 length = -1;
642 /* Return number of bytes written */
644 SetIoErr(error);
645 return length;
650 /****i* ram.handler/CmdSeek ************************************************
652 * NAME
653 * CmdSeek --
655 * SYNOPSIS
656 * old_pos = CmdSeek(opening, offset, mode)
658 * PINT CmdSeek(struct Opening *, PINT, LONG);
660 * FUNCTION
662 * INPUTS
664 * RESULT
666 * EXAMPLE
668 * NOTES
670 * BUGS
672 * SEE ALSO
674 ****************************************************************************
678 UPINT CmdSeek(struct Handler *handler, struct Opening *opening, PINT offset, LONG mode)
680 struct Block *block;
681 struct Object *file;
682 UPINT block_pos, block_length, remainder, old_pos, new_pos;
684 /* Get starting point */
686 file = opening->file;
687 old_pos = opening->pos;
689 if(mode == OFFSET_BEGINNING)
691 block = (APTR)file->elements.mlh_Head;
692 new_pos = block_pos = 0;
694 else if(mode == OFFSET_CURRENT)
696 block = opening->block;
697 block_pos = opening->block_pos;
698 new_pos = old_pos;
700 else
702 block = (APTR)file->elements.mlh_TailPred;
703 block_pos = file->end_length;
704 new_pos = file->length;
707 /* Check new position is within file */
709 new_pos += offset;
710 if(new_pos > file->length)
712 SetIoErr(ERROR_SEEK_ERROR);
713 return -1;
716 if(offset >= 0)
718 /* Go forwards */
720 block_length = GetBlockLength(file, block);
721 remainder = offset + block_pos;
722 while(remainder > block_length)
724 remainder -= block_length;
725 block = (APTR)((struct MinNode *)block)->mln_Succ;
726 block_length = GetBlockLength(file, block);
729 block_pos = remainder;
731 else
733 /* Go backwards */
735 block_length = block_pos;
736 remainder = -offset;
737 while(remainder >= block_length && remainder > 0)
739 remainder -= block_length;
740 block = (APTR)((struct MinNode *)block)->mln_Pred;
741 block_length = GetBlockLength(file, block);
744 block_pos = block_length - remainder;
747 /* Record new position for next access */
749 opening->block = block;
750 opening->block_pos = block_pos;
751 opening->pos = new_pos;
753 /* Return old position */
755 return old_pos;
760 /****i* ram.handler/CmdSetFileSize *****************************************
762 * NAME
763 * CmdSetFileSize --
765 * SYNOPSIS
766 * new_length = CmdSetFileSize(handler, opening, offset, mode)
768 * PINT CmdSetFileSize(struct Handler *, struct Opening *, PINT, LONG);
770 * FUNCTION
772 * INPUTS
774 * RESULT
776 * EXAMPLE
778 * NOTES
780 * BUGS
782 * SEE ALSO
784 ****************************************************************************
788 PINT CmdSetFileSize(struct Handler *handler, struct Opening *opening,
789 PINT offset, LONG mode)
791 LONG error = 0, new_size;
792 struct Object *file;
793 struct Lock *lock;
795 /* Change file size if it's open for writing */
797 file = opening->file;
798 lock = file->lock;
800 if((file->protection & FIBF_WRITE) != 0)
801 error = ERROR_WRITE_PROTECTED;
802 if(handler->locked)
803 error = ERROR_DISK_WRITE_PROTECTED;
805 if(error == 0)
807 new_size = ChangeFileSize(handler, opening, offset, mode);
808 if(new_size == -1)
809 error = IoErr();
810 else
811 lock->changed = TRUE;
813 else
814 new_size = -1;
816 /* Return new file size */
818 SetIoErr(error);
819 return new_size;
824 /****i* ram.handler/CmdLocateObject ****************************************
826 * NAME
827 * CmdLocateObject --
829 * SYNOPSIS
830 * lock = CmdLocateObject(handler, lock,
831 * name, mode)
833 * struct Lock *CmdLocateObject(struct Handler *, struct Lock *,
834 * TEXT *, ULONG);
836 * FUNCTION
838 * INPUTS
840 * RESULT
842 * EXAMPLE
844 * NOTES
846 * BUGS
848 * SEE ALSO
850 ****************************************************************************
854 struct Lock *CmdLocateObject(struct Handler *handler, struct Lock *lock,
855 const TEXT *name, ULONG mode)
857 struct Object *object;
859 /* Find the object and lock it */
861 object = GetHardObject(handler, lock, name, NULL);
863 if(object != NULL)
864 lock = LockObject(handler, object, mode);
865 else
866 lock = NULL;
868 /* Return result */
870 return lock;
875 /****i* ram.handler/CmdFreeLock ********************************************
877 * NAME
878 * CmdFreeLock --
880 * SYNOPSIS
881 * success = CmdFreeLock(handler, lock)
883 * BOOL CmdFreeLock(struct Handler *, struct Lock *);
885 * FUNCTION
887 * INPUTS
888 * lock - May be NULL.
890 * RESULT
892 * EXAMPLE
894 * NOTES
896 * BUGS
898 * SEE ALSO
900 ****************************************************************************
904 BOOL CmdFreeLock(struct Handler *handler, struct Lock *lock)
906 struct Object *object;
908 if(lock != NULL)
910 object = (APTR)((struct FileLock *)lock)->fl_Key;
912 handler->lock_count--;
913 if((--lock->lock_count) == 0)
915 FreePooled(handler->public_pool, lock, sizeof(struct Lock));
916 object->lock = NULL;
920 return TRUE;
925 /****i* ram.handler/CmdCopyDir *********************************************
927 * NAME
928 * CmdCopyDir --
930 * SYNOPSIS
931 * lock = CmdCopyDir(handler, lock)
933 * struct Lock *CmdCopyDir(struct Handler *, struct Lock *);
935 * FUNCTION
937 * INPUTS
939 * RESULT
941 * EXAMPLE
943 * NOTES
945 * BUGS
947 * SEE ALSO
949 ****************************************************************************
953 struct Lock *CmdCopyDir(struct Handler *handler, struct Lock *lock)
955 lock = FIXLOCK(handler, lock);
956 lock = LockObject(handler, (APTR)((struct FileLock *)lock)->fl_Key,
957 ACCESS_READ);
959 return lock;
964 /****i* ram.handler/CmdCopyDirFH *******************************************
966 * NAME
967 * CmdCopyDirFH --
969 * SYNOPSIS
970 * lock = CmdCopyDirFH(handler, opening)
972 * struct Lock *CmdCopyDirFH(struct Handler *, struct Opening *);
974 * FUNCTION
976 * INPUTS
978 * RESULT
980 * EXAMPLE
982 * NOTES
984 * BUGS
986 * SEE ALSO
988 ****************************************************************************
992 struct Lock *CmdCopyDirFH(struct Handler *handler,
993 struct Opening *opening)
995 return LockObject(handler, opening->file, ACCESS_READ);
1000 /****i* ram.handler/CmdParent **********************************************
1002 * NAME
1003 * CmdParent --
1005 * SYNOPSIS
1006 * lock = CmdParent(handler, lock)
1008 * struct Lock *CmdParent(struct Handler *, struct Lock *);
1010 * FUNCTION
1012 * INPUTS
1014 * RESULT
1016 * EXAMPLE
1018 * NOTES
1020 * BUGS
1022 * SEE ALSO
1024 ****************************************************************************
1028 struct Lock *CmdParent(struct Handler *handler, struct Lock *lock)
1030 struct Object *parent;
1031 LONG error = 0;
1033 lock = FIXLOCK(handler, lock);
1035 parent = ((struct Object *)((struct FileLock *)lock)->fl_Key)->parent;
1036 if(parent != NULL)
1038 lock = LockObject(handler, parent, ACCESS_READ);
1039 if(lock == NULL)
1040 error = IoErr();
1042 else
1043 lock = NULL;
1045 SetIoErr(error);
1046 return lock;
1051 /****i* ram.handler/CmdParentFH ********************************************
1053 * NAME
1054 * CmdParentFH --
1056 * SYNOPSIS
1057 * lock = CmdParentFH(handler, opening)
1059 * struct Lock *CmdParentFH(struct Handler *, struct Opening *);
1061 * FUNCTION
1063 * INPUTS
1065 * RESULT
1067 * EXAMPLE
1069 * NOTES
1071 * BUGS
1073 * SEE ALSO
1075 ****************************************************************************
1079 struct Lock *CmdParentFH(struct Handler *handler,
1080 struct Opening *opening)
1082 struct Object *parent;
1083 struct Lock *lock;
1085 parent = opening->file->parent;
1086 lock = LockObject(handler, parent, ACCESS_READ);
1088 return lock;
1093 /****i* ram.handler/CmdSameLock ********************************************
1095 * NAME
1096 * CmdSameLock --
1098 * SYNOPSIS
1099 * result = CmdSameLock(handler, lock1, lock2)
1101 * BOOL CmdSameLock(struct Handler *, struct Lock *, struct Lock *);
1103 * FUNCTION
1105 * INPUTS
1107 * RESULT
1109 * EXAMPLE
1111 * NOTES
1113 * BUGS
1115 * SEE ALSO
1117 ****************************************************************************
1121 BOOL CmdSameLock(struct Handler *handler, struct Lock *lock1, struct Lock *lock2)
1123 SetIoErr(0);
1124 return lock1 == lock2;
1129 /****i* ram.handler/CmdCreateDir *******************************************
1131 * NAME
1132 * CmdCreateDir --
1134 * SYNOPSIS
1135 * lock = CmdCreateDir(handler, lock, name)
1137 * struct Lock *CmdCreateDir(struct Handler *, struct Lock *, TEXT *);
1139 * FUNCTION
1141 * INPUTS
1143 * RESULT
1145 * EXAMPLE
1147 * NOTES
1149 * BUGS
1151 * SEE ALSO
1153 ****************************************************************************
1157 struct Lock *CmdCreateDir(struct Handler *handler,
1158 struct Lock *lock, const TEXT *name)
1160 struct Object *dir, *parent;
1161 LONG error = 0;
1163 /* Find parent directory and possible name clash */
1165 dir = GetHardObject(handler, lock, name, &parent);
1166 lock = NULL;
1168 /* Create a new directory */
1170 if(dir == NULL)
1172 if(parent != NULL)
1174 if(!handler->locked)
1176 dir = CreateObject(handler, FilePart(name), ST_USERDIR, parent);
1177 if(dir != NULL)
1179 lock = LockObject(handler, dir, ACCESS_WRITE);
1180 if(lock != NULL)
1182 MatchNotifyRequests(handler);
1183 NotifyAll(handler, dir, FALSE);
1185 else
1187 error = IoErr();
1188 DeleteObject(handler, dir);
1191 else
1192 error = IoErr();
1194 else
1195 error = ERROR_DISK_WRITE_PROTECTED;
1197 else
1198 error = IoErr();
1200 else
1201 error = ERROR_OBJECT_EXISTS;
1203 /* Set error code and return lock on new directory */
1205 SetIoErr(error);
1206 return lock;
1211 /****i* ram.handler/CmdExamineObject ***************************************
1213 * NAME
1214 * CmdExamineObject --
1216 * SYNOPSIS
1217 * success = CmdExamineObject(handler, lock,
1218 * info)
1220 * BOOL CmdExamineObject(struct Handler *, struct Lock *,
1221 * struct FileInfoBlock *);
1223 * FUNCTION
1225 * INPUTS
1227 * RESULT
1229 * EXAMPLE
1231 * NOTES
1233 * BUGS
1235 * SEE ALSO
1237 ****************************************************************************
1241 BOOL CmdExamineObject(struct Handler *handler, struct Lock *lock,
1242 struct FileInfoBlock *info)
1244 lock = FIXLOCK(handler, lock);
1245 return ExamineObject(handler, (APTR)((struct FileLock *)lock)->fl_Key,
1246 info);
1251 /****i* ram.handler/CmdExamineFH *******************************************
1253 * NAME
1254 * CmdExamineFH --
1256 * SYNOPSIS
1257 * success = CmdExamineFH(handler, opening,
1258 * info)
1260 * BOOL CmdExamineFH(struct Handler *, struct Opening *,
1261 * struct FileInfoBlock *);
1263 * FUNCTION
1265 * INPUTS
1267 * RESULT
1269 * EXAMPLE
1271 * NOTES
1273 * BUGS
1275 * SEE ALSO
1277 ****************************************************************************
1281 BOOL CmdExamineFH(struct Handler *handler, struct Opening *opening,
1282 struct FileInfoBlock *info)
1284 return ExamineObject(handler, opening->file, info);
1289 /****i* ram.handler/CmdExamineNext *****************************************
1291 * NAME
1292 * CmdExamineNext --
1294 * SYNOPSIS
1295 * success = CmdExamineNext(handler, info)
1297 * BOOL CmdExamineNext(struct Handler *, struct FileInfoBlock *);
1299 * FUNCTION
1301 * INPUTS
1303 * RESULT
1305 * EXAMPLE
1307 * NOTES
1309 * BUGS
1311 * SEE ALSO
1313 ****************************************************************************
1317 BOOL CmdExamineNext(struct Handler *handler, struct FileInfoBlock *info)
1319 return ExamineObject(handler, NULL, info);
1324 /****i* ram.handler/CmdExamineAll ******************************************
1326 * NAME
1327 * CmdExamineAll --
1329 * SYNOPSIS
1330 * success = CmdExamineAll(handler, opening, buffer, size,
1331 * type, control)
1333 * BOOL CmdExamineAll(struct Handler *, struct Lock *, UBYTE *, ULONG,
1334 * ULONG, struct ExAllControl *);
1336 * FUNCTION
1338 * INPUTS
1340 * RESULT
1342 * EXAMPLE
1344 * NOTES
1346 * BUGS
1348 * SEE ALSO
1350 ****************************************************************************
1352 * Note: we work under the assumption that if an error occurs, the caller
1353 * will have to start from scratch if they want the rest of the entries.
1357 BOOL CmdExamineAll(struct Handler *handler, struct Lock *lock,
1358 UBYTE *buffer, ULONG size, ULONG type, struct ExAllControl *control)
1360 BOOL match;
1361 ULONG entry_count = 0;
1362 struct Object *object, *next_object, *real_object;
1363 TEXT *name, *comment, *pattern, *name_copy, *comment_copy;
1364 LONG error = 0;
1365 struct ExAllData *entry, *prev_entry = NULL;
1366 struct Hook *match_hook;
1367 UWORD struct_size, name_size, comment_size, entry_size;
1368 struct Examination *examination;
1370 /* Check we support the requested format */
1372 if(type > ED_COMMENT)
1373 error = ERROR_BAD_NUMBER;
1375 /* Get starting point */
1377 examination = (APTR)control->eac_LastKey;
1379 if(examination != NULL)
1381 object = examination->next_object;
1383 else
1385 object = (APTR)((struct FileLock *)lock)->fl_Key;
1386 object = (APTR)object->elements.mlh_Head;
1389 while(error == 0)
1391 next_object = (struct Object *)((struct Node *)object)->ln_Succ;
1393 if(next_object != NULL)
1395 struct_size = examine_sizes[type - 1];
1396 name = ((struct Node *)object)->ln_Name;
1397 name_size = StrSize(name);
1398 if(((struct Node *)object)->ln_Pri == ST_SOFTLINK)
1399 comment = &((struct Node *)object)->ln_Type;
1400 else
1401 comment = object->comment;
1402 comment_size = StrSize(comment);
1403 entry_size = struct_size + name_size;
1404 if(type >= ED_COMMENT)
1405 entry_size += comment_size;
1406 entry_size = (entry_size + 1) & (~0x1);
1408 pattern = control->eac_MatchString;
1409 if(pattern != NULL)
1410 match = MatchPatternNoCase(pattern, name);
1411 else
1412 match = TRUE;
1414 if(match && entry_size <= size)
1416 /* Fill in entry */
1418 entry = (APTR)buffer;
1419 entry->ed_Next = NULL;
1421 real_object = GetRealObject(object);
1422 name_copy = buffer + struct_size;
1423 CopyMem(name, name_copy, name_size);
1424 entry->ed_Name = name_copy;
1426 if(type >= ED_TYPE)
1427 entry->ed_Type = ((struct Node *)object)->ln_Pri;
1429 if(type >= ED_SIZE)
1430 entry->ed_Size = real_object->length;
1432 if(type >= ED_PROTECTION)
1433 entry->ed_Prot = real_object->protection;
1435 if(type >= ED_DATE)
1437 entry->ed_Days = real_object->date.ds_Days;
1438 entry->ed_Mins = real_object->date.ds_Minute;
1439 entry->ed_Ticks = real_object->date.ds_Tick;
1442 if(type >= ED_COMMENT)
1444 comment_copy = buffer + struct_size + name_size;
1445 CopyMem(comment, comment_copy, comment_size);
1446 entry->ed_Comment = comment_copy;
1449 /* Call the filter hook if present */
1451 match_hook = control->eac_MatchFunc;
1452 if(match_hook != NULL)
1453 match = CallHookPkt(match_hook, &type, entry);
1454 else
1455 match = TRUE;
1457 /* Prepare for next entry if current one accepted */
1459 if(match)
1461 buffer += entry_size;
1462 size -= entry_size;
1463 entry_count++;
1464 if(prev_entry != NULL)
1465 prev_entry->ed_Next = entry;
1466 prev_entry = entry;
1469 else if(match)
1470 error = ERROR_NO_FREE_STORE;
1472 else
1473 error = ERROR_NO_MORE_ENTRIES;
1475 object = next_object;
1478 /* Running out of space isn't an error unless no entries could fit */
1480 if(error == ERROR_NO_FREE_STORE && entry_count != 0)
1481 error = 0;
1483 /* Prepare for subsequent call */
1485 if(error == 0 && examination == NULL)
1487 examination = AllocPooled(handler->clear_pool,
1488 sizeof(struct Examination));
1489 if(examination != NULL)
1490 AddTail((APTR)&handler->examinations, (APTR)examination);
1491 else
1492 error = IoErr();
1495 if(error == 0)
1497 examination->next_object = object;
1498 control->eac_LastKey = (UPINT)examination;
1500 else
1502 CmdExamineAllEnd(handler, lock, buffer, size, type, control);
1505 control->eac_Entries = entry_count;
1507 /* Return */
1509 SetIoErr(error);
1510 return error == 0;
1515 /****i* ram.handler/CmdExamineAllEnd ***************************************
1517 * NAME
1518 * CmdExamineAllEnd --
1520 * SYNOPSIS
1521 * CmdExamineAllEnd(handler, opening, buffer,
1522 * size, type, control)
1524 * VOID CmdExamineAllEnd(struct Handler *, struct Lock *, UBYTE *,
1525 * ULONG, ULONG, struct ExAllControl *);
1527 * FUNCTION
1529 * INPUTS
1531 * RESULT
1533 * EXAMPLE
1535 * NOTES
1537 * BUGS
1539 * SEE ALSO
1541 ****************************************************************************
1545 VOID CmdExamineAllEnd(struct Handler *handler, struct Lock *lock,
1546 UBYTE *buffer, ULONG size, ULONG type, struct ExAllControl *control)
1548 struct Examination *examination;
1550 examination = (APTR)control->eac_LastKey;
1551 if(examination != NULL)
1553 Remove((APTR)examination);
1554 FreePooled(handler->clear_pool, examination,
1555 sizeof(struct Examination));
1558 return;
1563 /****i* ram.handler/CmdInfo ************************************************
1565 * NAME
1566 * CmdInfo --
1568 * SYNOPSIS
1569 * success = CmdInfo(handler, info_data)
1571 * BOOL CmdExamineObject(struct Handler *, struct InfoData *);
1573 * FUNCTION
1575 * INPUTS
1577 * RESULT
1579 * EXAMPLE
1581 * NOTES
1583 * BUGS
1585 * SEE ALSO
1587 ****************************************************************************
1591 BOOL CmdInfo(struct Handler *handler, struct InfoData *info_data)
1593 LONG disk_state;
1595 info_data->id_NumSoftErrors = 0;
1596 info_data->id_UnitNumber = 0;
1597 if(handler->locked)
1598 disk_state = ID_WRITE_PROTECTED;
1599 else
1600 disk_state = ID_VALIDATED;
1601 info_data->id_DiskState = disk_state;
1602 info_data->id_NumBlocks = handler->block_count
1603 + MEMBLOCKS(AvailMem(MEMF_ANY));
1604 info_data->id_NumBlocksUsed = handler->block_count;
1605 info_data->id_BytesPerBlock = MEM_BLOCKSIZE;
1606 info_data->id_DiskType = ID_DOS_DISK;
1607 info_data->id_VolumeNode = MKBADDR(handler->volume);
1608 info_data->id_InUse = DOSBOOL(handler->lock_count > 1);
1610 return TRUE;
1615 /****i* ram.handler/CmdSetProtect ******************************************
1617 * NAME
1618 * CmdSetProtect --
1620 * SYNOPSIS
1621 * success = CmdSetProtect(handler, lock, name, flags)
1623 * BOOL CmdSetProtect(struct Handler *, struct Lock *, TEXT *, ULONG);
1625 * FUNCTION
1627 * INPUTS
1629 * RESULT
1631 * EXAMPLE
1633 * NOTES
1635 * BUGS
1637 * SEE ALSO
1639 ****************************************************************************
1643 BOOL CmdSetProtect(struct Handler *handler, struct Lock *lock,
1644 const TEXT *name, ULONG flags)
1646 LONG error = 0;
1647 struct Object *object;
1649 /* Set new protection flags if object isn't in use */
1651 object = GetHardObject(handler, lock, name, NULL);
1652 if(object != NULL)
1654 if(handler->locked)
1655 error = ERROR_DISK_WRITE_PROTECTED;
1657 if(error == 0)
1659 object = GetRealObject(object);
1660 object->protection = flags;
1661 NotifyAll(handler, object, TRUE);
1664 else
1665 error = IoErr();
1667 /* Return result */
1669 SetIoErr(error);
1670 return error == 0;
1675 /****i* ram.handler/CmdSetComment ******************************************
1677 * NAME
1678 * CmdSetComment --
1680 * SYNOPSIS
1681 * success = CmdSetComment(handler, lock, name, comment)
1683 * BOOL CmdSetComment(struct Handler *, struct Lock *, TEXT *, TEXT *);
1685 * FUNCTION
1687 * INPUTS
1689 * RESULT
1691 * EXAMPLE
1693 * NOTES
1695 * BUGS
1697 * SEE ALSO
1699 ****************************************************************************
1703 BOOL CmdSetComment(struct Handler *handler, struct Lock *lock,
1704 const TEXT *name, const TEXT *comment)
1706 LONG error = 0;
1707 struct Object *object;
1708 const TEXT *p;
1709 TEXT ch;
1710 struct Locale *locale;
1711 PINT block_diff;
1713 /* Get object */
1715 object = GetHardObject(handler, lock, name, NULL);
1716 if(object == NULL)
1717 error = IoErr();
1719 /* Check comment isn't too long */
1721 if(StrSize(comment)
1722 > sizeof(((struct FileInfoBlock *)NULL)->fib_Comment))
1723 error = ERROR_COMMENT_TOO_BIG;
1725 /* Check comment doesn't have any strange characters in it */
1726 if ((locale = handler->locale)) {
1727 for(p = comment; (ch = *p) != '\0'; p++)
1728 if((ch & 0x80) == 0 && (!IsPrint(locale, ch) || IsCntrl(locale, ch)))
1729 error = ERROR_INVALID_COMPONENT_NAME;
1732 /* Check volume isn't write-protected */
1734 if(handler->locked)
1735 error = ERROR_DISK_WRITE_PROTECTED;
1737 /* Store new comment */
1739 if(error == 0)
1741 block_diff = SetString(handler, &object->comment, comment);
1742 if(block_diff == -1)
1743 error = IoErr();
1744 else
1746 object->block_count += block_diff;
1747 handler->block_count += block_diff;
1751 /* Notify interested parties */
1753 if(error == 0)
1755 NotifyAll(handler, object, FALSE);
1758 /* Return result */
1760 SetIoErr(error);
1761 return error == 0;
1766 /****i* ram.handler/CmdRenameObject ****************************************
1768 * NAME
1769 * CmdRenameObject --
1771 * SYNOPSIS
1772 * success = CmdRenameObject(handler, old_lock, old_name,
1773 * new_lock, new_name)
1775 * BOOL CmdRenameObject(struct Handler *, struct Lock *, STRPTR,
1776 * struct Lock *, STRPTR);
1778 * FUNCTION
1780 * INPUTS
1782 * RESULT
1784 * EXAMPLE
1786 * NOTES
1788 * BUGS
1790 * SEE ALSO
1792 ****************************************************************************
1796 BOOL CmdRenameObject(struct Handler *handler, struct Lock *old_lock,
1797 STRPTR old_name, struct Lock *new_lock, STRPTR new_name)
1799 struct Object *parent, *object, *duplicate, *p;
1800 LONG error = 0;
1802 /* Get object to be moved */
1804 object = GetHardObject(handler, old_lock, old_name, NULL);
1805 if(object == NULL)
1806 error = IoErr();
1808 /* Get destination directory and check if a different object already has
1809 the target name */
1811 duplicate = GetHardObject(handler, new_lock, new_name, &parent);
1812 if(duplicate != NULL && duplicate != object)
1813 error = ERROR_OBJECT_EXISTS;
1814 if(parent == NULL)
1815 error = IoErr();
1817 /* Check for a circular rename */
1819 for(p = parent; p != NULL; p = p->parent)
1821 if(p == object)
1822 error = ERROR_OBJECT_NOT_FOUND;
1825 /* Check volume isn't write-protected */
1827 if(handler->locked)
1828 error = ERROR_DISK_WRITE_PROTECTED;
1830 /* Give the object its new name */
1832 if(error == 0)
1834 if(!SetName(handler, object, FilePart(new_name)))
1835 error = IoErr();
1838 if(error == 0)
1840 if(object->parent != parent)
1842 /* Remove object from old parent and place it in new parent */
1844 Remove((struct Node *)object);
1845 AddTail((struct List *)&parent->elements, (struct Node *)object);
1846 object->parent = parent;
1847 AdjustExaminations(handler, object);
1850 if(object != duplicate)
1852 /* Update notifications */
1854 NotifyAll(handler, object, FALSE);
1855 UnmatchNotifyRequests(handler, object);
1856 MatchNotifyRequests(handler);
1859 NotifyAll(handler, object, FALSE);
1862 /* Return success indicator */
1864 SetIoErr(error);
1865 return error == 0;
1870 /****i* ram.handler/CmdRenameDisk ******************************************
1872 * NAME
1873 * CmdRenameDisk --
1875 * SYNOPSIS
1876 * success = CmdRenameDisk(handler, new_name)
1878 * BOOL CmdRenameDisk(struct Handler *, STRPTR);
1880 * FUNCTION
1882 * INPUTS
1884 * RESULT
1886 * EXAMPLE
1888 * NOTES
1890 * BUGS
1892 * SEE ALSO
1894 ****************************************************************************
1898 BOOL CmdRenameDisk(struct Handler *handler, STRPTR new_name)
1900 LONG error = 0;
1902 /* Check volume isn't write-protected */
1904 if(handler->locked)
1905 error = ERROR_DISK_WRITE_PROTECTED;
1907 /* Rename volume's DOS entry and root directory */
1909 if(error == 0)
1910 if(!SetName(handler, handler->root_dir, new_name))
1911 error = IoErr();
1913 if(error == 0)
1914 if(!MyRenameDosEntry(handler, handler->volume, new_name))
1915 error = IoErr();
1917 /* Return success indicator */
1919 SetIoErr(error);
1920 return error == 0;
1925 /****i* ram.handler/CmdSetDate *********************************************
1927 * NAME
1928 * CmdSetDate --
1930 * SYNOPSIS
1931 * success = CmdSetDate(handler, lock, name,
1932 * date)
1934 * BOOL CmdSetDate(struct Handler *, struct Lock *, STRPTR,
1935 * struct DateStamp *);
1937 * FUNCTION
1939 * INPUTS
1941 * RESULT
1943 * EXAMPLE
1945 * NOTES
1947 * BUGS
1949 * SEE ALSO
1951 ****************************************************************************
1955 BOOL CmdSetDate(struct Handler *handler, struct Lock *lock, STRPTR name,
1956 struct DateStamp *date)
1958 struct Object *object;
1959 LONG error = 0;
1961 /* Check volume isn't write-protected */
1963 if(handler->locked)
1964 error = ERROR_DISK_WRITE_PROTECTED;
1966 /* Get object and set its new date */
1968 if(error == 0)
1970 object = GetHardObject(handler, lock, name, NULL);
1971 if(object != NULL)
1973 object = GetRealObject(object);
1974 CopyMem(date, &object->date, sizeof(struct DateStamp));
1976 else
1977 error = IoErr();
1980 /* Notify interested parties */
1982 if(error == 0)
1984 NotifyAll(handler, object, TRUE);
1987 /* Return result */
1989 SetIoErr(error);
1990 return error == 0;
1995 /****i* ram.handler/CmdDeleteObject ****************************************
1997 * NAME
1998 * CmdDeleteObject --
2000 * SYNOPSIS
2001 * success = CmdDeleteObject(handler, lock, name)
2003 * BOOL CmdDeleteObject(struct Handler *, struct Lock *, STRPTR);
2005 * FUNCTION
2007 * INPUTS
2009 * RESULT
2011 * EXAMPLE
2013 * NOTES
2015 * BUGS
2017 * SEE ALSO
2019 ****************************************************************************
2023 BOOL CmdDeleteObject(struct Handler *handler, struct Lock *lock,
2024 STRPTR name)
2026 LONG error = 0, pos = -1;
2027 struct Object *object;
2029 /* Find object and check it can be deleted */
2031 object = GetObject(handler, lock, name, NULL, &pos);
2032 if(object == NULL || pos != -1)
2033 error = IoErr();
2035 if(handler->locked)
2036 error = ERROR_DISK_WRITE_PROTECTED;
2038 if(error == 0)
2040 if((GetRealObject(object)->protection & FIBF_DELETE) != 0)
2041 error = ERROR_DELETE_PROTECTED;
2044 /* Attempt to delete object */
2046 if(error == 0)
2048 if(!AttemptDeleteObject(handler, object, TRUE))
2049 error = IoErr();
2052 /* Return result */
2054 SetIoErr(error);
2055 return error == 0;
2060 /****i* ram.handler/CmdCurrentVolume ***************************************
2062 * NAME
2063 * CmdCurrentVolume --
2065 * SYNOPSIS
2066 * volume = CmdCurrentVolume(handler)
2068 * struct DosList *CmdCurrentVolume(struct Handler *);
2070 * FUNCTION
2072 * INPUTS
2074 * RESULT
2076 * EXAMPLE
2078 * NOTES
2080 * BUGS
2082 * SEE ALSO
2084 ****************************************************************************
2088 struct DosList *CmdCurrentVolume(struct Handler *handler)
2090 SetIoErr(0);
2091 return handler->volume;
2096 /****i* ram.handler/CmdChangeMode ******************************************
2098 * NAME
2099 * CmdChangeMode --
2101 * SYNOPSIS
2102 * success = CmdChangeMode(handler, type, thing, new_mode)
2104 * BOOL CmdChangeMode(struct Handler *, ULONG, APTR, ULONG);
2106 * FUNCTION
2108 * INPUTS
2110 * RESULT
2112 * EXAMPLE
2114 * NOTES
2116 * BUGS
2118 * SEE ALSO
2120 ****************************************************************************
2124 BOOL CmdChangeMode(struct Handler *handler, ULONG type, APTR thing, ULONG new_mode)
2126 struct Lock *lock;
2127 struct Opening *opening;
2128 LONG error = 0;
2130 /* Get the lock */
2132 if(type == CHANGE_FH)
2134 opening = (APTR)((struct FileHandle *)thing)->fh_Arg1;
2135 lock = opening->file->lock;
2137 else
2138 lock = thing;
2140 /* Change mode if possible */
2142 if(new_mode == ACCESS_WRITE && lock->lock_count > 1)
2144 error = ERROR_OBJECT_IN_USE;
2146 else
2148 ((struct FileLock *)lock)->fl_Access = new_mode;
2151 /* Set error code and return result */
2153 SetIoErr(error);
2154 return error == 0;
2159 /****i* ram.handler/CmdMakeLink ********************************************
2161 * NAME
2162 * CmdMakeLink --
2164 * SYNOPSIS
2165 * success = CmdMakeLink(handler, lock, name, reference,
2166 * link_type)
2168 * BOOL CmdMakeLink(struct Handler *, struct Lock *, STRPTR, APTR,
2169 * LONG);
2171 * FUNCTION
2173 * INPUTS
2175 * RESULT
2177 * EXAMPLE
2179 * NOTES
2181 * BUGS
2183 * SEE ALSO
2185 ****************************************************************************
2189 BOOL CmdMakeLink(struct Handler *handler, struct Lock *lock, STRPTR name,
2190 APTR reference, LONG link_type)
2192 struct Object *link, *parent, *target = NULL, *master_link;
2193 LONG error = 0, object_type;
2194 PINT block_diff;
2195 struct MinNode *node;
2197 /* Find parent directory and possible name clash */
2199 link = GetHardObject(handler, lock, name, &parent);
2200 if(link != NULL)
2201 error = ERROR_OBJECT_EXISTS;
2202 else if(parent == NULL)
2203 error = IoErr();
2205 /* Determine link type */
2207 if(link_type == LINK_HARD)
2209 target = (APTR)((struct FileLock *)reference)->fl_Key;
2210 if(((struct Node *)target)->ln_Pri == ST_FILE)
2211 object_type = ST_LINKFILE;
2212 else
2213 object_type = ST_LINKDIR;
2215 else
2216 object_type = ST_SOFTLINK;
2218 /* Check volume isn't write-protected */
2220 if(error == 0)
2222 if(handler->locked)
2223 error = ERROR_DISK_WRITE_PROTECTED;
2226 /* Create a new link */
2228 if(error == 0)
2230 link = CreateObject(handler, FilePart(name), object_type, parent);
2231 if(link == NULL)
2232 error = IoErr();
2235 /* Store link target */
2237 if(error == 0)
2239 if(link_type == LINK_HARD)
2241 node = target->hard_link.mln_Succ;
2242 if(node == NULL)
2244 master_link = link;
2245 AddTail((APTR)&master_link->elements, (APTR)&target->hard_link);
2247 else
2248 master_link = HARDLINK(node);
2249 AddTail((APTR)&master_link->elements, (APTR)&link->hard_link);
2251 else
2253 block_diff =
2254 SetString(handler, (APTR)&link->soft_link_target, reference);
2255 if(block_diff == -1)
2256 error = IoErr();
2257 else
2259 link->block_count += block_diff;
2260 handler->block_count += block_diff;
2265 /* Notify */
2267 if(error == 0)
2268 NotifyAll(handler, link, FALSE);
2270 /* Return success indicator */
2272 SetIoErr(error);
2273 return error == 0;
2278 /****i* ram.handler/CmdReadLink ********************************************
2280 * NAME
2281 * CmdReadLink --
2283 * SYNOPSIS
2284 * success = CmdReadLink(handler, lock, name, buffer,
2285 * buffer_size)
2287 * BOOL CmdReadLink(struct Handler *, struct Lock *, const TEXT *,
2288 * TEXT *, LONG);
2290 * FUNCTION
2292 * INPUTS
2294 * RESULT
2296 * EXAMPLE
2298 * NOTES
2300 * BUGS
2302 * SEE ALSO
2304 ****************************************************************************
2308 LONG CmdReadLink(struct Handler *handler, struct Lock *lock,
2309 const TEXT *name, TEXT *buffer, LONG buffer_size)
2311 struct Object *link;
2312 LONG error = 0, pos, length;
2313 const TEXT *p;
2315 /* Get link object */
2317 link = GetObject(handler, lock, name, NULL, &pos);
2318 if(link == NULL)
2319 error = IoErr();
2320 else if(((struct Node *)link)->ln_Pri != ST_SOFTLINK)
2321 error = ERROR_OBJECT_WRONG_TYPE;
2323 if(error == 0)
2325 /* Copy part of path preceding link to buffer so that returned path
2326 will be relative to lock passed in */
2328 if(pos == -1)
2329 p = name + StrLen(name) - 1;
2330 else
2331 p = name + pos - 2;
2333 while(p != name && *p != '/' && *p != ':')
2334 p--;
2336 length = p - name;
2337 if(*p == '/' || *p == ':')
2338 length++;
2339 if(buffer_size >= length + 1)
2341 CopyMem(name, buffer, length);
2342 buffer[length] = '\0';
2344 else
2345 error = ERROR_BUFFER_OVERFLOW;
2348 if(error == 0)
2350 /* Add link target to link's parent path */
2352 if(AddPart(buffer, link->soft_link_target, buffer_size))
2354 /* Add remainder of original path after link */
2356 if(pos != -1)
2358 if(!AddPart(buffer, name + pos, buffer_size))
2359 error = ERROR_LINE_TOO_LONG;
2362 else
2363 error = ERROR_BUFFER_OVERFLOW;
2366 /* Return path length or error indicator */
2368 if(error == ERROR_BUFFER_OVERFLOW)
2369 length = -2;
2370 else if(error != 0)
2371 length = -1;
2372 else
2373 length = StrLen(buffer);
2375 SetIoErr(error);
2376 return length;
2381 /****i* ram.handler/CmdWriteProtect ****************************************
2383 * NAME
2384 * CmdWriteProtect --
2386 * SYNOPSIS
2387 * success = CmdWriteProtect(handler, on, key)
2389 * BOOL CmdWriteProtect(struct Handler *, BOOL, ULONG);
2391 * FUNCTION
2393 * INPUTS
2395 * RESULT
2397 * EXAMPLE
2399 * NOTES
2401 * BUGS
2403 * SEE ALSO
2405 ****************************************************************************
2409 BOOL CmdWriteProtect(struct Handler *handler, BOOL on, ULONG key)
2411 LONG error = 0;
2412 struct Object *root_dir;
2414 root_dir = handler->root_dir;
2416 if(on)
2418 if(!handler->locked)
2419 root_dir->length = key;
2420 else
2421 error = ERROR_DISK_WRITE_PROTECTED;
2423 else
2425 if(root_dir->length != 0 && root_dir->length != key)
2426 error = ERROR_INVALID_COMPONENT_NAME;
2427 else
2428 root_dir->length = 0;
2431 if(error == 0)
2432 handler->locked = on;
2434 /* Return success indicator */
2436 SetIoErr(error);
2437 return error == 0;
2442 /****i* ram.handler/CmdFlush ***********************************************
2444 * NAME
2445 * CmdFlush --
2447 * SYNOPSIS
2448 * success = CmdFlush()
2450 * BOOL CmdFlush();
2452 * FUNCTION
2454 * INPUTS
2456 * RESULT
2458 * EXAMPLE
2460 * NOTES
2462 * BUGS
2464 * SEE ALSO
2466 ****************************************************************************
2470 BOOL CmdFlush()
2472 return TRUE;
2477 /****i* ram.handler/CmdAddNotify *******************************************
2479 * NAME
2480 * CmdAddNotify --
2482 * SYNOPSIS
2483 * success = CmdAddNotify(handler, request)
2485 * BOOL CmdAddNotify(struct Handler *, struct NotifyRequest *);
2487 * FUNCTION
2489 * INPUTS
2491 * RESULT
2493 * EXAMPLE
2495 * NOTES
2497 * BUGS
2499 * SEE ALSO
2501 ****************************************************************************
2505 BOOL CmdAddNotify(struct Handler *handler, struct NotifyRequest *request)
2507 LONG error = 0;
2508 struct Notification *notification;
2509 struct Object *object;
2511 notification = AllocPooled(handler->clear_pool,
2512 sizeof(struct Notification));
2513 if(notification == NULL)
2514 error = IoErr();
2516 if(error == 0)
2518 notification->request = request;
2519 request->nr_Flags &= ~NRF_MAGIC;
2521 object = GetHardObject(handler, NULL, request->nr_FullName, NULL);
2523 if(object != NULL)
2525 AddTail((APTR)&object->notifications, (APTR)notification);
2526 if((request->nr_Flags & NRF_NOTIFY_INITIAL) != 0)
2527 Notify(handler, notification);
2529 else
2530 AddTail((APTR)&handler->notifications, (APTR)notification);
2533 /* Return success indicator */
2535 SetIoErr(error);
2536 return error == 0;
2541 /****i* ram.handler/CmdRemoveNotify ****************************************
2543 * NAME
2544 * CmdRemoveNotify --
2546 * SYNOPSIS
2547 * success = CmdRemoveNotify(handler, request)
2549 * BOOL CmdRemoveNotify(struct Handler *, struct NotifyRequest *);
2551 * FUNCTION
2553 * INPUTS
2555 * RESULT
2557 * EXAMPLE
2559 * NOTES
2561 * BUGS
2563 * SEE ALSO
2565 ****************************************************************************
2569 BOOL CmdRemoveNotify(struct Handler *handler, struct NotifyRequest *request)
2571 struct Notification *notification;
2573 notification = FindNotification(handler, request);
2574 Remove((APTR)notification);
2575 FreePooled(handler->clear_pool, notification,
2576 sizeof(struct Notification));
2578 return TRUE;