Removed/merged a duplicate AutoDoc.
[AROS.git] / workbench / c / Mount.c
blob0552021205f41a0ca726e519ebb9725d9852e8c9
1 /*
2 (C) 1995-2014 The AROS Development Team
3 (C) 2002-2005 Harry Sintonen
4 (C) 2005-2007 Pavel Fedin
5 $Id$
7 Desc: Mount CLI command
8 Lang: English
9 */
11 /******************************************************************************
13 NAME
15 Mount
17 FORMAT
19 Mount <Device> <From>
21 SYNOPSIS
23 DEVICE/M, FROM/K
25 LOCATION
29 FUNCTION
31 Loads and mounts a device
33 INPUTS
35 DEVICE -- The device type to be mounted
36 FROM -- Search device in this mountlist
38 RESULT
40 Standard DOS error codes.
42 NOTES
44 EXAMPLE
46 Mount DEVS:FAT0
47 (Mounts a FAT device defined in the DEVS:FAT0 file)
49 BUGS
51 SEE ALSO
53 INTERNALS
55 HISTORY
57 ******************************************************************************/
59 #include <clib/debug_protos.h>
60 #include <exec/devices.h>
61 #include <exec/io.h>
62 #include <exec/memory.h>
63 #include <exec/rawfmt.h>
64 #include <exec/semaphores.h>
65 #include <dos/dosextens.h>
66 #include <dos/exall.h>
67 #include <dos/filehandler.h>
68 #include <dos/rdargs.h>
69 #include <libraries/configvars.h>
70 #include <libraries/expansion.h>
71 #include <workbench/workbench.h>
72 #include <workbench/startup.h>
74 #include <proto/exec.h>
75 #include <proto/dos.h>
76 #include <proto/intuition.h>
77 #include <proto/utility.h>
78 #include <proto/icon.h>
79 #include <proto/expansion.h>
81 #ifdef __SASC
82 typedef unsigned long IPTR;
83 #endif
85 #include <resources/filesysres.h>
86 #include <string.h>
87 #include <stdio.h>
88 #include <stdlib.h>
90 #define DEBUG_PATCHDOSNODE(x)
91 #define DEBUG_MOUNT(x)
92 #define DEBUG_MAKEDOSNODE(x)
93 #define DEBUG_CHECK(x)
95 #define MOUNTLIST "DEVS:MountList"
96 #define DOSDRIVERS "DEVS:DOSDrivers/"
97 #define STORAGEDRIVERS "SYS:Storage/DOSDrivers/"
98 #define PARAMSLENGTH (sizeof(struct DosEnvec) + sizeof(IPTR)*4)
100 enum
102 ERR_SPECIAL = 5000,
103 ERR_DEVICENOTFOUND,
104 ERR_INVALIDKEYWORD
107 const char *SearchTable[]=
110 "DEVS:DOSDrivers/",
111 #ifdef __MORPHOS__
112 "MOSSYS:DEVS/DOSDrivers/",
113 #endif
114 "SYS:Storage/DOSDrivers/",
115 #ifdef __MORPHOS__
116 "MOSSYS:Storage/DOSDrivers/",
117 #endif
118 NULL
122 * startup,control need to be handled differently.
125 enum
127 ARG_HANDLER,
128 ARG_EHANDLER,
129 ARG_FILESYSTEM,
130 ARG_DEVICE,
131 ARG_UNIT,
132 ARG_FLAGS,
133 ARG_BLOCKSIZE,
134 ARG_SURFACES,
135 ARG_BLOCKSPERTRACK,
136 ARG_SECTORSPERBLOCK,
137 ARG_RESERVED,
138 ARG_PREALLOC,
139 ARG_INTERLEAVE,
140 ARG_LOWCYL,
141 ARG_HIGHCYL,
142 ARG_BUFFERS,
143 ARG_BUFMEMTYPE,
144 ARG_MAXTRANSFER,
145 ARG_MASK,
146 ARG_BOOTPRI,
147 ARG_DOSTYPE,
148 ARG_BAUD,
149 ARG_CONTROL,
150 ARG_STACKSIZE,
151 ARG_PRIORITY,
152 ARG_GLOBVEC,
153 ARG_STARTUP,
154 ARG_ACTIVATE,
155 ARG_FORCELOAD,
156 NUM_ARGS
159 const UBYTE options[]=
160 "HANDLER/K,"
161 "EHANDLER/K,"
162 "FILESYSTEM/K,"
163 "DEVICE/K,"
164 "UNIT/K,"
165 "FLAGS/K,"
166 "SECTORSIZE=BLOCKSIZE/K,"
167 "SURFACES/K,"
168 "SECTORSPERTRACK=BLOCKSPERTRACK/K,"
169 "SECTORSPERBLOCK/K,"
170 "RESERVED/K,"
171 "PREALLOC/K,"
172 "INTERLEAVE/K,"
173 "LOWCYL/K,"
174 "HIGHCYL/K,"
175 "BUFFERS/K,"
176 "BUFMEMTYPE/K,"
177 "MAXTRANSFER/K,"
178 "MASK/K,"
179 "BOOTPRI/K,"
180 "DOSTYPE/K,"
181 "BAUD/K,"
182 "CONTROL/K,"
183 "STACKSIZE/K,"
184 "PRIORITY/K,"
185 "GLOBVEC/K,"
186 "STARTUP/K,"
187 "MOUNT=ACTIVATE/K,"
188 "FORCELOAD/K";
190 #ifdef __MORPHOS__
191 #define PROGNAME "Mount unofficial"
192 typedef struct Library *UtilityBase_t;
193 #else
194 #define PROGNAME "Mount"
195 typedef struct UtilityBase *UtilityBase_t;
196 #endif
198 #ifdef __AROS__
199 #define _WBenchMsg WBenchMsg
200 #endif
202 #ifdef AROS_FAST_BPTR
203 #define BSTR_EXTRA 1
204 #define BSTR_OFFSET 0
205 #define bstrcpy(dest, src, len) strcpy(dest, src)
206 #else
207 #define BSTR_EXTRA 2
208 #define BSTR_OFFSET 1
209 #define bstrcpy(dest, src, len) \
210 dest[0] = len; \
211 strcpy(&dest[1], src);
212 #endif
214 static const int __nocommandline;
215 const TEXT version[] = "\0$VER: " PROGNAME " 50.14 (" ADATE ")";
217 ULONG CheckDevice(char *name);
218 void InitParams(IPTR *params);
219 LONG readfile(STRPTR name, STRPTR *mem, LONG *size);
220 ULONG readmountlist(IPTR *params, STRPTR name, char *mountlist);
221 ULONG readmountfile(IPTR *params, STRPTR name);
222 void preparefile(STRPTR buf, LONG size);
223 LONG parsemountfile(IPTR *params, STRPTR buf, LONG size);
224 LONG parsemountlist(IPTR *params, STRPTR name, STRPTR buf, LONG size);
225 LONG mount(IPTR *params, STRPTR name);
226 void ShowErrorArgs(STRPTR name, char *s, IPTR *ap);
227 void ShowFault(LONG code, char *s, ...);
229 #define ShowError(name, s, ...) \
231 IPTR __args[] = { AROS_PP_VARIADIC_CAST2IPTR(__VA_ARGS__) }; \
232 ShowErrorArgs(name, s, __args); \
235 struct DosLibrary *DOSBase;
236 struct IntuitionBase *IntuitionBase;
237 UtilityBase_t UtilityBase;
238 struct Process *MyProcess;
240 ULONG StartupValue;
241 char *StartupString = NULL;
242 char *ControlString = NULL;
243 char *UnitString = NULL;
244 char *FlagsString = NULL;
245 ULONG StackSize;
246 ULONG Priority;
247 ULONG Activate;
248 SIPTR GlobalVec;
249 ULONG ForceLoad;
250 char *HandlerString;
251 char *DeviceString;
252 BOOL IsEHandler, IsFilesystem;
253 BOOL IsCli;
254 BOOL flagargs[NUM_ARGS];
255 char txtBuf[256];
256 extern struct WBStartup *_WBenchMsg;
258 int main(void)
260 IPTR args[2];
261 IPTR *params;
262 LONG error = RETURN_FAIL;
263 struct RDArgs *rda;
264 char dirname[512];
266 if ((DOSBase = (struct DosLibrary *)OpenLibrary("dos.library",37))!=0)
268 if ((UtilityBase = (UtilityBase_t)OpenLibrary("utility.library",37)))
270 memset(&flagargs, 0, sizeof(flagargs));
271 IsEHandler = TRUE;
272 IsFilesystem = TRUE;
273 if (!_WBenchMsg)
275 memset(args,0,sizeof(args));
276 if ((rda = ReadArgs("DEVICE/M,FROM/K", args, NULL)))
278 STRPTR *MyDevPtr;
279 int len;
281 error = 0;
283 MyDevPtr =(STRPTR *)args[0];
284 if (MyDevPtr)
286 while (*MyDevPtr)
288 DEBUG_MOUNT(KPrintF("Mount: Current DevName <%s>\n",
289 (IPTR)*MyDevPtr));
291 if ((params = AllocVec(PARAMSLENGTH, MEMF_PUBLIC | MEMF_CLEAR)))
293 StackSize = 8192;
294 Priority = 5;
295 GlobalVec = -1;
296 HandlerString = NULL;
297 DeviceString = NULL;
298 StartupString = NULL;
300 len = strlen(*MyDevPtr);
301 if ((*MyDevPtr)[len-1] == ':')
303 /* search for a devicename */
304 DEBUG_MOUNT(KPrintF("Mount: search for devname <%s>\n",
305 (IPTR)*MyDevPtr));
307 strcpy(dirname, *MyDevPtr);
308 dirname[len-1] = '\0';
310 if ((error=CheckDevice(dirname))!=RETURN_OK)
312 DEBUG_MOUNT(KPrintF("Mount: is already mounted..stop\n"));
314 else
316 if (args[1])
318 error=readmountlist(params, dirname, (STRPTR)(args[1]));
319 DEBUG_MOUNT(KPrintF("Mount: readmountlist(%s) returned %ld\n", args[1], error));
321 else
323 char **SearchPtr;
324 ULONG slen;
326 DEBUG_MOUNT(KPrintF("Mount: search device definition <%s>\n",
327 (IPTR)*MyDevPtr));
328 for (SearchPtr=(char**) SearchTable;
329 *SearchPtr;
330 SearchPtr++)
332 if(SetSignal(0L,SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C)
334 error = RETURN_FAIL;
335 SetIoErr(ERROR_BREAK);
336 break;
339 slen = strlen(*SearchPtr);
340 strcpy(dirname, *SearchPtr);
341 dirname[slen] = '\0';
342 strcat(dirname, *MyDevPtr);
343 dirname[slen+len-1] = '\0';
344 DEBUG_MOUNT(KPrintF("Mount: try File <%s>\n", (IPTR)dirname));
346 error=readmountfile(params, dirname);
347 DEBUG_MOUNT(KPrintF("Mount: readmountfile returned %ld\n", error));
348 if (error != ERROR_OBJECT_NOT_FOUND)
349 break;
351 if (error == ERROR_OBJECT_NOT_FOUND)
353 DEBUG_MOUNT(KPrintF("Mount: try from mountlist\n"));
354 dirname[0] = '\0';
355 strcat(dirname, *MyDevPtr);
356 dirname[len-1] = '\0';
357 error=readmountlist(params, dirname, MOUNTLIST);
358 DEBUG_MOUNT(KPrintF("Mount: readmountlist(default) returned %ld\n", error));
363 else
365 /* search for a filename */
367 LONG err;
369 UBYTE stack_ap[sizeof(struct AnchorPath) + 3];
370 struct AnchorPath *MyAp = (struct AnchorPath *) (((IPTR) stack_ap + 3) & ~3);
372 DEBUG_MOUNT(KPrintF("Mount: search for mountfile <%s>\n", *MyDevPtr));
374 memset(MyAp,0,sizeof(struct AnchorPath));
376 dirname[0] = '\0';
377 for (err = MatchFirst(*MyDevPtr,MyAp);
378 err == 0;
379 err = MatchNext(MyAp))
381 if (MyAp->ap_Flags & APF_DirChanged)
383 DEBUG_MOUNT(KPrintF("Mount: Changed directories...\n"));
386 DEBUG_MOUNT(KPrintF("Mount: NameFromLock(0x%p)...\n", MyAp->ap_Current->an_Lock));
387 if (NameFromLock(MyAp->ap_Current->an_Lock,
388 dirname,
389 sizeof(dirname)) == FALSE)
391 ShowFault(IoErr(), "Error on NameFromLock");
392 break;
395 DEBUG_MOUNT(KPrintF("Mount: ...Dir name: %s\n", dirname));
396 if (AddPart(dirname,
397 &(MyAp->ap_Info.fib_FileName[0]),
398 sizeof(dirname)) == FALSE)
400 ShowFault(IoErr(), "Error on AddPart");
401 break;
403 if (MyAp->ap_Info.fib_DirEntryType > 0)
405 if (MyAp->ap_Flags & APF_DIDDIR)
407 DEBUG_MOUNT(KPrintF("Mount: Ascending from directory %s\n",
408 (IPTR)dirname));
410 else
412 DEBUG_MOUNT(KPrintF("Mount: The next dir is ... %s\n", (IPTR)dirname));
414 /* clear the completed directory flag */
415 MyAp->ap_Flags &= ~APF_DIDDIR;
418 else
420 /* Here is code for handling each particular file */
422 DEBUG_MOUNT(KPrintF("Mount: try File <%s>\n",
423 (IPTR)dirname));
425 memset(&flagargs, 0, sizeof(flagargs));
426 IsEHandler = TRUE;
427 IsFilesystem = TRUE;
428 error=readmountfile(params, dirname);
429 DEBUG_MOUNT(KPrintF("Mount: readmount file returned %ld\n", error));
432 /* This absolutely, positively must be called, all of the time. */
433 MatchEnd(MyAp);
435 if (err == ERROR_NO_MORE_ENTRIES)
437 SetIoErr(0);
439 else
441 /* if it was real error promote it - Piru */
442 error = err;
445 FreeVec(params);
447 else
449 error = ERROR_NO_FREE_STORE;
450 break;
452 MyDevPtr++;
455 FreeArgs(rda);
456 } /* if (rda != NULL) */
457 else
459 error = IoErr();
462 if (error && error != ERROR_NO_MORE_ENTRIES && error < ERR_SPECIAL)
464 ShowFault(error, "ERROR");
466 error = RETURN_FAIL;
468 else
470 error = error < ERR_SPECIAL ? RETURN_OK : RETURN_FAIL;
474 else
476 /* wb startup */
477 if (_WBenchMsg->sm_NumArgs >= 2)
479 if ((params = AllocVec(PARAMSLENGTH,
480 MEMF_PUBLIC | MEMF_CLEAR)))
482 int i;
484 for (i = 1; i < _WBenchMsg->sm_NumArgs; i++)
486 BPTR olddir;
488 DEBUG_MOUNT(KPrintF("Mount: try File <%s>\n",
489 (IPTR) _WBenchMsg->sm_ArgList[i].wa_Name));
491 olddir = CurrentDir(_WBenchMsg->sm_ArgList[i].wa_Lock);
493 error=readmountfile(params, _WBenchMsg->sm_ArgList[i].wa_Name);
494 DEBUG_MOUNT(KPrintF("Mount: readmountfile returned %ld\n", error));
495 if (error && error != ERROR_NO_MORE_ENTRIES && error < ERR_SPECIAL)
496 ShowFault(error, "ERROR");
498 (void) CurrentDir(olddir);
501 FreeVec(params);
503 else
505 error = ERROR_NO_FREE_STORE;
509 CloseLibrary((struct Library *)UtilityBase);
511 CloseLibrary((struct Library *)DOSBase);
514 return error;
517 /************************************************************************************************/
518 /************************************************************************************************/
519 ULONG CheckDevice(char *name)
521 struct DosList *dl;
522 ULONG Status;
524 DEBUG_CHECK(KPrintF("CheckDevice: <%s>\n",
525 name));
527 dl = LockDosList(LDF_DEVICES | LDF_VOLUMES | LDF_ASSIGNS | LDF_READ);
528 if ((dl = FindDosEntry(dl,name,LDF_DEVICES | LDF_VOLUMES | LDF_ASSIGNS)))
530 Status = ERROR_OBJECT_EXISTS;
532 else
534 Status = 0;
536 UnLockDosList(LDF_DEVICES | LDF_VOLUMES | LDF_ASSIGNS | LDF_READ);
538 DEBUG_CHECK(KPrintF("CheckDevice: object %s exist\n", Status ? "does" : "doesn't"));
540 return Status;
543 /************************************************************************************************/
544 /************************************************************************************************/
546 void InitParams(IPTR *params)
548 struct DosEnvec *vec;
550 memset(params,0, PARAMSLENGTH);
552 vec = (struct DosEnvec *)&params[4];
554 vec->de_TableSize = DE_BOOTBLOCKS;
555 vec->de_SizeBlock = 512 >> 2;
556 vec->de_Surfaces = 2;
557 vec->de_SectorPerBlock = 1;
558 vec->de_BlocksPerTrack = 11;
559 vec->de_Reserved = 2;
561 /* memset above
562 vec->de_SecOrg = 0;
563 vec->de_BootBlocks = 0;
564 vec->de_BootPri = 0;
565 vec->de_PreAlloc = 0;
566 vec->de_Interleave = 0;
567 vec->de_LowCyl = 0;
570 vec->de_HighCyl = 79;
571 vec->de_NumBuffers = 20; /* On AmigaOS 3.9 it's 5 */
572 vec->de_BufMemType = 3;
573 vec->de_Baud = 1200;
574 vec->de_MaxTransfer = 0x7fffffff;
575 vec->de_Mask = -2; /* 0xfffffffe, sign-extended on 64 bits */
576 vec->de_DosType = ID_DOS_DISK;
578 StackSize = 8192;
579 Priority = 5;
580 GlobalVec = -1;
581 HandlerString = NULL;
582 DeviceString = NULL;
583 StartupString = NULL;
586 void FreeStuff(void)
588 if (UnitString)
590 FreeVec(UnitString);
591 UnitString = NULL;
593 if (FlagsString)
595 FreeVec(FlagsString);
596 FlagsString = NULL;
598 if (ControlString)
600 FreeVec(ControlString);
601 ControlString = NULL;
603 if (HandlerString)
605 FreeVec(HandlerString);
606 HandlerString = NULL;
608 if (DeviceString)
610 FreeVec(DeviceString);
611 DeviceString = NULL;
613 if (StartupString)
615 FreeVec(StartupString);
616 StartupString = NULL;
620 /************************************************************************************************/
621 /************************************************************************************************/
623 static long GetValue(IPTR bufp, char **end)
625 char *buf = (char *)bufp;
626 char *c = buf;
628 if ((c[0]=='-') || (c[0]=='+'))
629 c++;
631 * If it's a hexadecimal number, use strtoul(), otherwise we can lose our 31st bit.
632 * Should be okay since i've never seen any usage of minus sign with hexadecimals.
633 * For decimals we do support sign, because it makes it very convenient to use negative
634 * masks for sign extension on 64 bits.
636 if ((c[0] == '0') && (((c[1])=='x') || (c[1])=='X'))
637 return strtoul(buf, end, 16);
638 else
639 return strtol(buf, end, 10);
642 /************************************************************************************************/
643 /************************************************************************************************/
645 ULONG ReadMountArgs(IPTR *params, struct RDArgs *rda)
647 struct DosEnvec *vec;
648 IPTR args[NUM_ARGS];
649 struct RDArgs *MyRDA;
650 ULONG result = RETURN_OK;
651 int i;
652 char *s = NULL;
654 DEBUG_MOUNT(KPrintF("ReadMountArgs:\n%s\n\n", (IPTR)&rda->RDA_Source.CS_Buffer[rda->RDA_Source.CS_CurChr]));
656 memset(&args, 0, sizeof(args));
658 if (!(MyRDA = ReadArgs((STRPTR)options, &args[0], rda)))
660 DEBUG_MOUNT(KPrintF("ReadMountArgs: ReadArgs failed, error %u\n", IoErr()));
661 return ERR_INVALIDKEYWORD;
664 for (i = 0; i < NUM_ARGS; i++)
666 if (args[i] != 0)
667 flagargs[i] = TRUE;
670 if (args[ARG_HANDLER] != 0)
672 s = (STRPTR)args[ARG_HANDLER];
673 IsEHandler = FALSE;
674 IsFilesystem = FALSE;
676 else if (args[ARG_EHANDLER] != 0)
678 s = (STRPTR)args[ARG_EHANDLER];
679 IsEHandler = TRUE;
680 IsFilesystem = FALSE;
682 else if (args[ARG_FILESYSTEM] != 0)
684 s = (STRPTR)args[ARG_FILESYSTEM];
685 IsEHandler = TRUE;
686 IsFilesystem = TRUE;
687 } else
688 s = NULL;
690 if (s)
692 int len;
694 DEBUG_MOUNT(KPrintF("ReadMountArgs: Handler <%s>\n",s));
695 len = strlen(s);
697 if (HandlerString)
698 FreeVec(HandlerString);
700 if ((HandlerString = AllocVec(len + BSTR_EXTRA, MEMF_PUBLIC|MEMF_CLEAR)))
701 bstrcpy(HandlerString, s, len);
704 if (args[ARG_STACKSIZE] != 0)
705 StackSize = GetValue(args[ARG_STACKSIZE], NULL);
707 if (args[ARG_PRIORITY] != 0)
708 Priority = GetValue(args[ARG_PRIORITY], NULL);
710 if (args[ARG_GLOBVEC] != 0)
711 GlobalVec = GetValue(args[ARG_GLOBVEC], NULL);
713 if (args[ARG_FORCELOAD] != 0)
714 ForceLoad = GetValue(args[ARG_FORCELOAD], NULL);
716 if (args[ARG_ACTIVATE] != 0)
717 Activate = GetValue(args[ARG_ACTIVATE], NULL);
719 if (args[ARG_DEVICE] != 0)
721 int len;
723 DEBUG_MOUNT(KPrintF("ReadMountArgs: Device <%s>\n",(STRPTR)args[ARG_DEVICE]));
725 len = strlen((STRPTR)args[ARG_DEVICE]);
727 if (DeviceString)
728 FreeVec(DeviceString);
730 if ((DeviceString = AllocVec(len+1,MEMF_PUBLIC|MEMF_CLEAR)))
731 strcpy(DeviceString, (STRPTR)args[ARG_DEVICE]);
734 if (args[ARG_UNIT] != 0)
736 if (UnitString)
738 FreeVec(UnitString);
739 UnitString = NULL;
741 params[2] = GetValue(args[ARG_UNIT], &s);
742 if (*s)
744 int len = strlen((STRPTR)args[ARG_UNIT]);
746 DEBUG_MOUNT(KPrintF("ReadMountArgs: len %ld\n",len));
748 if ((UnitString = AllocVec(len + 1, MEMF_PUBLIC|MEMF_CLEAR)))
750 strcpy(UnitString, (STRPTR)args[ARG_UNIT]);
751 params[2] = (IPTR)UnitString;
752 DEBUG_MOUNT(KPrintF("ReadMountArgs: Unit String <%s>\n", (STRPTR)params[2]));
754 else
756 result = ERROR_NO_FREE_STORE;
757 goto error;
760 else
761 DEBUG_MOUNT(KPrintF("ReadMountArgs: Unit Value %ld\n",params[2]));
764 if (args[ARG_FLAGS] != 0)
766 DEBUG_MOUNT(KPrintF("ReadMountArgs: Flags <%s>\n",(STRPTR)args[ARG_FLAGS]));
767 if (FlagsString)
769 FreeVec(FlagsString);
770 FlagsString = NULL;
773 params[3] = GetValue(args[ARG_FLAGS], &s);
774 if (*s)
776 int len = strlen((STRPTR)args[ARG_FLAGS]);
778 DEBUG_MOUNT(KPrintF("ReadMountArgs: len %ld\n",len));
780 if ((FlagsString = AllocVec(len + 1, MEMF_PUBLIC|MEMF_CLEAR)))
782 strcpy(FlagsString, (STRPTR)args[ARG_FLAGS]);
783 params[3] = (IPTR) FlagsString;
784 DEBUG_MOUNT(KPrintF("ReadMountArgs: Flags String <%s>\n",(STRPTR)params[3]));
786 else
788 result = ERROR_NO_FREE_STORE;
789 goto error;
792 else
793 DEBUG_MOUNT(KPrintF("ReadMountArgs: Flag Value %ld\n",params[3]));
796 vec = (struct DosEnvec *)&params[4];
798 if (args[ARG_BLOCKSIZE] != 0)
799 vec->de_SizeBlock = GetValue(args[ARG_BLOCKSIZE], NULL) >> 2;
801 if (args[ARG_SURFACES] != 0)
802 vec->de_Surfaces = GetValue(args[ARG_SURFACES], NULL);
804 if (args[ARG_SECTORSPERBLOCK] != 0)
805 vec->de_SectorPerBlock = GetValue(args[ARG_SECTORSPERBLOCK], NULL);
807 if (args[ARG_BLOCKSPERTRACK] != 0)
808 vec->de_BlocksPerTrack = GetValue(args[ARG_BLOCKSPERTRACK], NULL);
810 if (args[ARG_RESERVED] != 0)
811 vec->de_Reserved = GetValue(args[ARG_RESERVED], NULL);
813 if (args[ARG_PREALLOC] != 0)
814 vec->de_PreAlloc = GetValue(args[ARG_PREALLOC], NULL);
816 if (args[ARG_INTERLEAVE] != 0)
817 vec->de_Interleave = GetValue(args[ARG_INTERLEAVE], NULL);
819 if (args[ARG_LOWCYL] != 0)
820 vec->de_LowCyl = GetValue(args[ARG_LOWCYL], NULL);
822 if (args[ARG_HIGHCYL] != 0)
823 vec->de_HighCyl = GetValue(args[ARG_HIGHCYL], NULL);
825 if (args[ARG_BUFFERS] != 0)
826 vec->de_NumBuffers = GetValue(args[ARG_BUFFERS], NULL);
828 if (args[ARG_BUFMEMTYPE] != 0)
829 vec->de_BufMemType = GetValue(args[ARG_BUFMEMTYPE], NULL);
831 if (args[ARG_BOOTPRI] != 0)
832 vec->de_BootPri = GetValue(args[ARG_BOOTPRI], NULL);
834 if (args[ARG_BAUD] != 0)
835 vec->de_Baud = GetValue(args[ARG_BAUD], NULL);
837 if (args[ARG_MAXTRANSFER] != 0)
838 vec->de_MaxTransfer = GetValue(args[ARG_MAXTRANSFER], NULL);
840 if (args[ARG_MASK] != 0)
841 vec->de_Mask = GetValue(args[ARG_MASK], NULL);
843 if (args[ARG_DOSTYPE] != 0)
844 vec->de_DosType = (IPTR)GetValue(args[ARG_DOSTYPE], NULL);
846 if (args[ARG_CONTROL] != 0)
848 int len;
850 DEBUG_MOUNT(KPrintF("ReadMountArgs: Control <%s>\n",args[ARG_CONTROL]));
851 if (ControlString)
853 FreeVec(ControlString);
854 ControlString = NULL;
857 len = strlen((STRPTR)args[ARG_CONTROL]);
858 if (len < 0x100)
860 if ((ControlString=AllocVec(len + BSTR_EXTRA, MEMF_PUBLIC|MEMF_CLEAR)))
862 bstrcpy(ControlString, (STRPTR)args[ARG_CONTROL], len);
863 vec->de_Control = (IPTR)MKBADDR(ControlString);
865 else
867 result = ERROR_NO_FREE_STORE;
868 goto error;
871 else
873 result = ERROR_LINE_TOO_LONG;
874 SetIoErr(result);
875 goto error;
879 if (args[ARG_STARTUP] != 0)
881 DEBUG_MOUNT(KPrintF("ReadMountArgs: Startup <%s>\n",args[ARG_STARTUP]));
882 if (StartupString)
884 FreeVec(StartupString);
885 StartupString = NULL;
888 StartupValue = GetValue(args[ARG_STARTUP], &s);
889 if (*s)
891 int len = strlen((STRPTR)args[ARG_STARTUP]);
893 DEBUG_MOUNT(KPrintF("ReadMountArgs: len %ld\n",len));
895 if ((StartupString = AllocVec(len + 1, MEMF_PUBLIC|MEMF_CLEAR)))
896 strcpy(StartupString,(STRPTR)args[ARG_STARTUP]);
897 else
899 result = ERROR_NO_FREE_STORE;
900 goto error;
905 error:
906 FreeArgs(MyRDA);
907 return result;
910 /************************************************************************************************/
911 /************************************************************************************************/
913 ULONG readmountlist(IPTR *params,
914 STRPTR name,
915 char *mountlist)
917 STRPTR MountListBuf;
918 LONG MountListBufSize;
919 ULONG error;
921 DEBUG_MOUNT(KPrintF("ReadMountList: find <%s> in mountlist <%s>\n",
922 name,
923 mountlist));
925 error = readfile(mountlist,
926 &MountListBuf,
927 &MountListBufSize);
928 if (error==RETURN_OK)
930 preparefile(MountListBuf,
931 MountListBufSize);
934 InitParams(params);
936 if ((error=parsemountlist(params,
937 name,
938 MountListBuf,
939 MountListBufSize))==RETURN_OK)
941 if ((error = mount(params,name))!=RETURN_OK)
943 DEBUG_MOUNT(KPrintF("ReadMountList: mount failed error %ld\n",
944 error));
947 else
949 switch (error)
951 case ERR_DEVICENOTFOUND:
952 case ERR_INVALIDKEYWORD:
953 ShowError(name, "Device not found in file '%s'", name, mountlist);
954 break;
958 FreeStuff();
959 FreeVec(MountListBuf);
961 return error;
964 /************************************************************************************************/
965 /************************************************************************************************/
967 ULONG readmountfile(IPTR *params, STRPTR filename)
969 struct Library *IconBase;
970 struct DiskObject *diskobj;
971 char **myargv;
972 STRPTR MountListBuf;
973 LONG MountListBufSize;
974 struct RDArgs rda;
975 ULONG error = RETURN_FAIL;
976 UBYTE *nameptr;
977 int toollen;
978 BOOL mountinfo=FALSE;
979 char name[256+1];
981 DEBUG_MOUNT(KPrintF("ReadMountFile: <%s>\n", (IPTR)filename));
984 struct Process *me = (APTR) FindTask(NULL);
985 APTR oldwinptr;
986 BPTR lock;
988 name[0] = '\0';
990 oldwinptr = me->pr_WindowPtr;
991 me->pr_WindowPtr = (APTR) -1;
992 lock = Lock(filename, SHARED_LOCK);
993 if (lock)
995 struct FileInfoBlock *fib = (struct FileInfoBlock*)AllocDosObject(DOS_FIB, NULL);
996 if (fib)
998 if (Examine(lock, fib))
1000 nameptr = fib->fib_FileName;
1001 memmove(name, nameptr, strlen(nameptr) + 1);
1003 FreeDosObject(DOS_FIB, fib);
1005 UnLock(lock);
1007 me->pr_WindowPtr = oldwinptr;
1009 if (name[0] == '\0')
1011 nameptr = FilePart(filename);
1012 strcpy(name,
1013 nameptr);
1017 DEBUG_MOUNT(KPrintF("ReadMountFile: mount <%s>\n", (IPTR)name));
1019 if ((error=CheckDevice(name))!=RETURN_OK)
1021 return error;
1024 InitParams(params);
1026 DEBUG_MOUNT(KPrintF("ReadMountFile: readfile\n"));
1028 error = readfile(filename,
1029 &MountListBuf,
1030 &MountListBufSize);
1031 if (error==RETURN_OK)
1033 DEBUG_MOUNT(KPrintF("ReadMountFile: preparsefile\n"));
1034 preparefile(MountListBuf, MountListBufSize);
1037 DEBUG_MOUNT(KPrintF("ReadMountFile: parsemountfile\n"));
1038 if ((error = parsemountfile(params, MountListBuf, MountListBufSize))!=RETURN_OK)
1040 DEBUG_MOUNT(KPrintF("ReadMountFile: parsemountfile error %ld\n", error));
1041 ShowFault(IoErr(), "Mountfile '%s' is invalid", filename);
1043 else
1045 mountinfo = TRUE;
1047 FreeVec(MountListBuf);
1049 else
1051 DEBUG_MOUNT(KPrintF("ReadMountFile: mountfile not found..search for <%s.info>\n",
1052 filename));
1055 if ((error==RETURN_OK) ||
1056 (error==ERROR_OBJECT_NOT_FOUND))
1058 DEBUG_MOUNT(KPrintF("ReadMountFile: look for icon '%s'\n", filename));
1060 if ((IconBase = OpenLibrary("icon.library", 37)))
1062 if ((diskobj = GetDiskObject(filename)))
1064 myargv =(char**) diskobj->do_ToolTypes;
1065 if (myargv)
1067 while (*myargv)
1069 char *ToolPtr;
1070 ToolPtr = *myargv;
1071 DEBUG_MOUNT(KPrintF("ReadMountFile: ToolType <%s>\n",
1072 ToolPtr));
1073 if ((ToolPtr[0] != '(') && (ToolPtr[0] != '*') &&
1074 !((ToolPtr[0] == 'I') && (ToolPtr[1] == 'M') && (ToolPtr[3] == '=')))
1076 char *ToolString;
1077 toollen = strlen(ToolPtr);
1078 if ((ToolString = AllocVec(toollen + 2,MEMF_ANY)))
1080 memcpy(ToolString,ToolPtr,toollen);
1081 ToolString[toollen] = '\n';
1082 ToolString[toollen+1] = '\0';
1083 memset(&rda,0,sizeof(struct RDArgs));
1084 rda.RDA_Source.CS_Buffer = ToolString;
1085 rda.RDA_Source.CS_Length = toollen+1;
1086 rda.RDA_Source.CS_CurChr = 0;
1087 rda.RDA_Flags = RDAF_NOPROMPT;
1088 if ((ReadMountArgs(params, &rda)==RETURN_OK))
1090 mountinfo = TRUE;
1092 else
1094 DEBUG_MOUNT(KPrintF("ReadMountFile: ReadArgs failed error %ld\n",
1095 error));
1097 FreeVec(ToolString);
1099 else
1101 error = ERROR_NO_FREE_STORE;
1102 break;
1105 else
1107 DEBUG_MOUNT(KPrintF("ReadMountFile: skipped\n"));
1109 myargv++;
1112 FreeDiskObject(diskobj);
1114 else
1117 CloseLibrary(IconBase);
1121 if (mountinfo)
1123 DEBUG_MOUNT(KPrintF("ReadMountFile: mount information exists\n"));
1125 if ((error = mount(params,name)) != RETURN_OK)
1127 DEBUG_MOUNT(KPrintF("ReadMountFile: mount failed error %ld\n",
1128 error));
1132 FreeStuff();
1134 return error;
1137 /************************************************************************************************/
1138 /************************************************************************************************/
1141 LONG readfile(STRPTR name, STRPTR *mem, LONG *size)
1143 BPTR ml;
1144 ULONG rest,sub;
1145 STRPTR buf;
1146 struct Process *me = (struct Process *) FindTask(NULL);
1147 APTR oldwinptr;
1149 oldwinptr = me->pr_WindowPtr;
1150 me->pr_WindowPtr = (APTR) -1;
1151 ml = Open(name, MODE_OLDFILE);
1152 me->pr_WindowPtr = oldwinptr;
1154 DEBUG_MOUNT(KPrintF("ReadFile: <%s>\n", (IPTR) name));
1156 if (ml)
1158 if (Seek(ml, 0, OFFSET_END) != -1)
1160 *size = Seek(ml, 0, OFFSET_BEGINNING);
1162 if (*size != -1)
1164 *mem = (STRPTR)AllocVec(*size+2, MEMF_ANY);
1166 if (*mem)
1168 rest = *size;
1169 buf = *mem;
1171 for (;;)
1173 if (!rest)
1175 Close(ml);
1177 *buf++ = '\n';
1178 *buf = '\0';
1180 return 0;
1183 sub = Read(ml, buf, rest);
1185 if (sub == -1)
1187 break;
1190 rest -= sub;
1191 buf += sub;
1194 FreeVec(*mem);
1196 else
1198 SetIoErr(ERROR_NO_FREE_STORE);
1203 Close(ml);
1206 DEBUG_MOUNT(KPrintF("ReadFile: error %ld\n", IoErr()));
1207 return IoErr();
1210 /************************************************************************************************/
1211 /************************************************************************************************/
1214 void preparefile(STRPTR buf, LONG size)
1216 STRPTR end = buf + size;
1218 while (buf < end)
1220 /* Convert comments to spaces */
1221 if (buf + 1 < end && *buf == '/' && buf[1] == '*')
1223 *buf++ = ' ';
1224 *buf++ = ' ';
1226 while (buf < end)
1228 if (*buf == '*')
1230 *buf++ = ' ';
1232 if (buf >= end)
1234 break;
1237 if (*buf == '/')
1239 *buf++ = ' ';
1240 break;
1243 else
1245 *buf++=' ';
1249 continue;
1252 /* Skip strings */
1253 if (*buf=='\"')
1256 * skip first
1258 buf++;
1259 while (buf < end && *buf != '\"')
1261 buf++;
1264 * skip last "
1266 buf++;
1267 continue;
1270 /* Convert '\n' and ';' to spaces */
1271 if (*buf == '\n' || *buf == ';')
1273 *buf++ = ' ';
1274 continue;
1277 /* Convert '#' to \n */
1278 if (*buf == '#')
1280 *buf++ = '\n';
1281 continue;
1284 /* Skip all other characters */
1285 buf++;
1289 /************************************************************************************************/
1290 /************************************************************************************************/
1292 struct FileSysEntry *GetFileSysEntry(ULONG DosType)
1295 struct FileSysResource *MyFileSysRes;
1296 struct FileSysEntry *MyFileSysEntry;
1297 struct FileSysEntry *CurrentFileSysEntry;
1298 BOOL Matched;
1300 MyFileSysEntry = NULL;
1301 MyFileSysRes = OpenResource(FSRNAME);
1302 if (MyFileSysRes)
1304 Forbid();
1305 CurrentFileSysEntry = (struct FileSysEntry*) MyFileSysRes->fsr_FileSysEntries.lh_Head;
1306 while (CurrentFileSysEntry->fse_Node.ln_Succ)
1308 if (HandlerString != NULL)
1309 Matched = strcmp(HandlerString + BSTR_OFFSET,
1310 AROS_BSTR_ADDR(CurrentFileSysEntry->fse_Handler)) == 0;
1311 else
1312 Matched = CurrentFileSysEntry->fse_DosType == DosType;
1313 if (Matched)
1315 if (MyFileSysEntry)
1317 if (CurrentFileSysEntry->fse_Version > MyFileSysEntry->fse_Version)
1319 MyFileSysEntry = CurrentFileSysEntry;
1322 else
1324 MyFileSysEntry = CurrentFileSysEntry;
1327 CurrentFileSysEntry =(struct FileSysEntry*) CurrentFileSysEntry->fse_Node.ln_Succ;
1329 Permit();
1331 return MyFileSysEntry;
1334 /************************************************************************************************/
1335 /************************************************************************************************/
1337 #define PATCH_FIELD(f, name) \
1338 if (MyFileSysEntry->fse_PatchFlags & f) \
1339 MyDeviceNode->dn_ ## name = (typeof(MyDeviceNode->dn_ ## name))MyFileSysEntry->fse_ ## name
1341 void PatchDosNode(struct DeviceNode *MyDeviceNode, ULONG DosType)
1343 struct FileSysEntry *MyFileSysEntry;
1345 DEBUG_PATCHDOSNODE(Printf("MakeDosNode: DeviceNode 0x%P\n", MyDeviceNode));
1347 if ((MyFileSysEntry=GetFileSysEntry(DosType)))
1349 DEBUG_PATCHDOSNODE(Printf("PatchDosNode: FileSysEntry 0x%P PatchFlags 0x%08lx\n", MyFileSysEntry, MyFileSysEntry->fse_PatchFlags));
1351 PATCH_FIELD(0x0001, Type);
1352 PATCH_FIELD(0x0002, Task);
1353 PATCH_FIELD(0x0004, Lock);
1354 PATCH_FIELD(0x0008, Handler);
1355 PATCH_FIELD(0x0010, StackSize);
1356 PATCH_FIELD(0x0020, Priority);
1357 PATCH_FIELD(0x0040, Startup);
1358 PATCH_FIELD(0x0080, SegList);
1359 PATCH_FIELD(0x0100, GlobalVec);
1361 DEBUG_PATCHDOSNODE(else Printf("PatchDosNode: Can't get FileSysEntry..no bootnode\n"));
1365 /************************************************************************************************/
1366 /************************************************************************************************/
1370 #define DOSNAME_INDEX 0
1371 #define EXECNAME_INDEX 1
1372 #define UNIT_INDEX 2
1373 #define FLAGS_INDEX 3
1374 #define ENVIROMENT_INDEX 4
1376 struct DeviceNode *MyMakeDosNode(char *DosName, IPTR *ParameterPkt, char *StartupName)
1378 int DosNameSize;
1379 int ExecNameSize;
1380 int MyEnvSize = 0;
1381 struct DeviceNode *MyDeviceNode = NULL;
1382 struct FileSysStartupMsg *MyFileSysStartupMsg = NULL;
1383 struct DosEnvec *MyDosEnvec = NULL;
1384 char *MyString = NULL;
1385 ULONG Status = FALSE;
1386 DEBUG_MAKEDOSNODE(Printf("MakeDosNode: Pkt 0x%lx\n",(IPTR)ParameterPkt));
1388 if (ParameterPkt)
1390 DEBUG_MAKEDOSNODE(Printf("MakeDosNode: DosName <%s> DeviceName <%s> Unit ", DosName, ParameterPkt[EXECNAME_INDEX]));
1391 DEBUG_MAKEDOSNODE(if (UnitString)
1392 Printf("<%s>",ParameterPkt[UNIT_INDEX]);
1393 else
1394 Printf("%ld",ParameterPkt[UNIT_INDEX]);)
1395 DEBUG_MAKEDOSNODE(Printf(" Flags 0x%lx DE_TABLESIZE 0x%lx\n", ParameterPkt[FLAGS_INDEX], ParameterPkt[ENVIROMENT_INDEX]));
1397 else
1399 DEBUG_MAKEDOSNODE(Printf("MakeDosNode: DosName <%s> Startup <%s>\n", (IPTR)DosName, (IPTR)StartupName));
1402 DosNameSize = strlen(DosName);
1404 if (ParameterPkt)
1406 if (ParameterPkt[EXECNAME_INDEX])
1408 ExecNameSize = strlen((UBYTE *)ParameterPkt[EXECNAME_INDEX]);
1410 else
1412 ExecNameSize = 0;
1414 MyEnvSize = (ParameterPkt[ENVIROMENT_INDEX] + 1) * sizeof(IPTR);
1416 else
1418 ExecNameSize = StartupName ? strlen(StartupName) : 0;
1421 if ((MyDeviceNode = AllocVec(sizeof(struct DeviceNode), MEMF_PUBLIC | MEMF_CLEAR)))
1423 DEBUG_MAKEDOSNODE(Printf("MakeDosNode: MyDeviceNode 0x%lx\n", (IPTR)MyDeviceNode));
1425 MyDeviceNode->dn_StackSize = 600;
1426 MyDeviceNode->dn_Priority = 10;
1428 if ((MyString=AllocVec(((DosNameSize + BSTR_EXTRA + 4) & ~3) + ((ExecNameSize + BSTR_EXTRA + 4) & ~3), MEMF_PUBLIC | MEMF_CLEAR)))
1430 bstrcpy(MyString, DosName, DosNameSize);
1432 MyDeviceNode->dn_Name = MKBADDR(MyString);
1434 if (ParameterPkt)
1436 if ((MyFileSysStartupMsg = AllocVec(sizeof(struct FileSysStartupMsg), MEMF_PUBLIC | MEMF_CLEAR)))
1438 DEBUG_MAKEDOSNODE(Printf("MakeDosNode: MyFileSysStartupMsg 0x%lx\n", (IPTR)MyFileSysStartupMsg));
1440 if ((MyDosEnvec = AllocVec(MyEnvSize, MEMF_PUBLIC | MEMF_CLEAR)))
1442 char *ExecNamePtr;
1444 DEBUG_MAKEDOSNODE(Printf("MakeDosNode: MyDosEnvec 0x%lx\n", (IPTR)MyDosEnvec));
1445 ExecNamePtr = &MyString[(1 + DosNameSize + BSTR_EXTRA + 3) & ~3];
1447 /* .device name must absolutely **NOT** include the 0 in the
1448 * length!!
1450 * the string *MUST* be 0 terminated, however!
1452 if (ParameterPkt[EXECNAME_INDEX])
1454 bstrcpy(ExecNamePtr, (UBYTE *)ParameterPkt[EXECNAME_INDEX], ExecNameSize);
1456 else
1458 ExecNamePtr[0] = 0;
1459 #ifndef AROS_FAST_BPTR
1460 ExecNamePtr[1] = 0;
1461 #endif
1463 MyFileSysStartupMsg->fssm_Device = MKBADDR(ExecNamePtr);
1464 MyFileSysStartupMsg->fssm_Unit = ParameterPkt[UNIT_INDEX];
1465 MyFileSysStartupMsg->fssm_Flags = ParameterPkt[FLAGS_INDEX];
1466 MyFileSysStartupMsg->fssm_Environ = MKBADDR(MyDosEnvec);
1467 MyDeviceNode->dn_Startup = MKBADDR(MyFileSysStartupMsg);
1469 CopyMem(&ParameterPkt[ENVIROMENT_INDEX], MyDosEnvec, MyEnvSize);
1471 #if __WORDSIZE > 32
1473 * EXPERIMENTAL: Fix up BufMemType on 64 bits.
1474 * Many software (and users) set Mask to 0x7FFFFFFF, assuming 31-bit memory, with BufMemType = PUBLIC.
1475 * This is perfectly true on 32-bit architectures, where addresses from 0x80000000 and up
1476 * belong to MMIO, however on 64 bits we might have memory beyond this address.
1477 * And AllocMem(MEMF_PUBLIC) would prefer to return that memory. This might screw up
1478 * filesystems expecting AllocMem() to return memory fully corresponding to the mask.
1480 if ((MyDosEnvec->de_TableSize >= DE_MASK) && (!(MyDosEnvec->de_Mask & 0x7FFFFFFF)))
1481 MyDosEnvec->de_BufMemType |= MEMF_31BIT;
1482 #endif
1484 Status=TRUE;
1485 DEBUG_MAKEDOSNODE(Printf("MakeDosNode: done\n"));
1489 else
1491 if (StartupName && ExecNameSize)
1493 char *StartupNamePtr;
1495 StartupNamePtr = &MyString[(1 + DosNameSize + BSTR_EXTRA + 3) & ~3];
1496 bstrcpy(StartupNamePtr, StartupName, ExecNameSize);
1497 MyDeviceNode->dn_Startup = MKBADDR(StartupNamePtr);
1499 Status=TRUE;
1503 if (Status)
1505 DEBUG_MAKEDOSNODE(Printf("MakeDosNode: done\n"));
1506 return MyDeviceNode;
1508 else
1510 DEBUG_MAKEDOSNODE(Printf("MakeDosNode: failed\n"));
1511 FreeVec(MyFileSysStartupMsg);
1512 FreeVec(MyDeviceNode);
1513 FreeVec(MyString);
1514 return NULL;
1520 /************************************************************************************************/
1521 /************************************************************************************************/
1524 LONG parsemountfile(IPTR *params, STRPTR buf, LONG size)
1526 STRPTR args[NUM_ARGS];
1527 LONG error;
1528 struct RDArgs rda;
1530 DEBUG_MOUNT(KPrintF("ParseMountFile:\n"));
1532 memset(&args, 0, sizeof(args));
1533 memset(&rda,0,sizeof(struct RDArgs));
1535 rda.RDA_Source.CS_Buffer = buf;
1536 rda.RDA_Source.CS_Length = size;
1537 rda.RDA_Source.CS_CurChr = 0;
1538 rda.RDA_Flags = RDAF_NOPROMPT;
1540 DEBUG_MOUNT(KPrintF("ReadArgs..\n%s\n\n", (IPTR)rda.RDA_Source.CS_Buffer));
1542 if ((error=ReadMountArgs(params,
1543 &rda))!=RETURN_OK)
1545 DEBUG_MOUNT(KPrintF("Parse: ReadArgs failed\n"));
1547 return error;
1550 /************************************************************************************************/
1551 /************************************************************************************************/
1554 LONG parsemountlist(IPTR *params,
1555 STRPTR name,
1556 STRPTR buf,
1557 LONG size)
1559 STRPTR args[NUM_ARGS];
1560 UBYTE buffer[1024];
1561 LONG error=RETURN_OK, res;
1562 STRPTR end = buf + size;
1563 STRPTR s2;
1564 char *ptr;
1565 struct RDArgs rda;
1567 DEBUG_MOUNT(KPrintF("ParseMountList: <%s>\n", (IPTR)name));
1569 memset(&args,0,sizeof(args));
1570 memset(&rda,0,sizeof(struct RDArgs));
1572 rda.RDA_Source.CS_Buffer = buf;
1573 rda.RDA_Source.CS_Length = end - buf;
1574 rda.RDA_Source.CS_CurChr = 0;
1575 rda.RDA_Flags = RDAF_NOPROMPT;
1577 while (rda.RDA_Source.CS_CurChr < rda.RDA_Source.CS_Length)
1579 res = ReadItem(buffer, sizeof(buffer), &rda.RDA_Source);
1581 DEBUG_MOUNT(KPrintF("ParseMountList: buffer <%s>\n", (IPTR)buffer));
1582 DEBUG_MOUNT(KPrintF("ParseMountList: ReadItem res %ld\n",res));
1584 if (res == ITEM_ERROR)
1586 return IoErr();
1589 if (res == ITEM_NOTHING &&
1590 rda.RDA_Source.CS_CurChr == rda.RDA_Source.CS_Length)
1592 return ERR_DEVICENOTFOUND;
1595 if (res != ITEM_QUOTED && res != ITEM_UNQUOTED)
1597 return 1;
1600 s2 = buffer;
1602 while (*s2)
1604 s2++;
1607 if (s2 == buffer || s2[-1] != ':')
1609 DEBUG_MOUNT(KPrintF("ParseMountList: failure\n"));
1610 return ERR_DEVICENOTFOUND;
1613 *--s2 = 0;
1615 if (!Strnicmp(name, buffer, s2 - buffer) &&
1616 (!name[s2 - buffer] || (name[s2 - buffer] == ':' || !name[s2 - buffer + 1])))
1618 DEBUG_MOUNT(KPrintF("ParseMountList: found\n"));
1620 /* Copy the string so we get proper case - Piru */
1621 memcpy(name, buffer, s2 - buffer);
1622 name[s2 - buffer] = '\0';
1624 ptr = name;
1625 while (*ptr)
1627 if (*ptr++ == ':')
1629 ptr[-1] = '\0';
1630 break;
1634 DEBUG_MOUNT(KPrintF("ReadArgs..\n%s\n\n", (IPTR)&rda.RDA_Source.CS_Buffer[rda.RDA_Source.CS_CurChr]));
1636 if ((error=ReadMountArgs(params,
1637 &rda))!=RETURN_OK)
1639 DEBUG_MOUNT(KPrintF("ParseMountList: ReadArgs failed\n"));
1640 //return IoErr();
1643 return error;
1646 while (rda.RDA_Source.CS_CurChr < rda.RDA_Source.CS_Length)
1648 if (rda.RDA_Source.CS_Buffer[rda.RDA_Source.CS_CurChr++] == '\n')
1650 DEBUG_MOUNT(KPrintF("ParseMountList: reach the end of the block\n"));
1651 break;
1656 DEBUG_MOUNT(KPrintF("ParseMountList: mount found nothing\n"));
1657 return ERR_DEVICENOTFOUND;
1660 /************************************************************************************************/
1661 /************************************************************************************************/
1663 static LONG checkmount(STRPTR name, IPTR *params)
1665 struct DosEnvec *vec;
1667 vec = (struct DosEnvec *)&params[4];
1669 params[1] = (IPTR) DeviceString;
1671 if (IsFilesystem && (!flagargs[ARG_DEVICE]
1672 || !flagargs[ARG_SURFACES] || !flagargs[ARG_BLOCKSPERTRACK]
1673 || !flagargs[ARG_LOWCYL] || !flagargs[ARG_HIGHCYL]))
1675 ShowError(name, "Could not find some of the following keywords:\n"
1676 " Surfaces, BlocksPerTrack, LowCyl, HighCyl, Device");
1677 return ERR_INVALIDKEYWORD;
1679 /* bootpri -129 shouldn't be started and not automatic mounted..whatever that means */
1680 if ((vec->de_BootPri < -129) || (vec->de_BootPri > 127))
1682 ShowError(name, "BootPri %ld is not allowed. Legal range is -128..127", vec->de_BootPri);
1683 return ERROR_BAD_NUMBER;
1686 if (flagargs[ARG_GLOBVEC])
1688 if ((GlobalVec != -1) && (GlobalVec != -2))
1690 ShowError(name, "Globvec %ld is not supported. Only -1 and -2 are supported here", GlobalVec);
1691 return ERROR_BAD_NUMBER;
1695 if (flagargs[ARG_STARTUP] && !StartupString)
1697 if (StartupValue >= 0x100)
1699 ShowError(name, "Startup uses too large numeric value %ld", StartupValue);
1700 return ERROR_BAD_NUMBER;
1704 return RETURN_OK;
1707 /************************************************************************************************/
1708 /************************************************************************************************/
1710 LONG mount(IPTR *params, STRPTR name)
1712 struct DosEnvec *vec;
1713 LONG error = RETURN_OK;
1714 struct DeviceNode *dn;
1715 STRPTR cp;
1717 for (cp = name; *cp != 0; cp++)
1718 *cp = ToUpper(*cp);
1720 DEBUG_MOUNT(KPrintF("MountDev: <%s>\n", name));
1722 if ((error=checkmount(name, params))!=RETURN_OK)
1724 DEBUG_MOUNT(KPrintF("MountDev: checkmount failed\n"));
1725 return error;
1728 vec = (struct DosEnvec *)&params[4];
1730 DEBUG_MOUNT(KPrintF("MountDev: DosName <%s>\n", (IPTR)name));
1731 DEBUG_MOUNT(KPrintF("MountDev: Filesystem <%s>\n", (IPTR)HandlerString + BSTR_OFFSET));
1732 DEBUG_MOUNT(KPrintF("MountDev: Device <%s>\n", (IPTR)DeviceString));
1733 DEBUG_MOUNT(KPrintF("MountDev: TableSize %ld\n",vec->de_TableSize));
1734 DEBUG_MOUNT(KPrintF("MountDev: SizeBlock %ld\n",vec->de_SizeBlock));
1735 DEBUG_MOUNT(KPrintF("MountDev: SecOrg %ld\n",vec->de_SecOrg));
1736 DEBUG_MOUNT(KPrintF("MountDev: Surfaces %ld\n",vec->de_Surfaces));
1737 DEBUG_MOUNT(KPrintF("MountDev: SectorsPerBlock %ld\n",vec->de_SectorPerBlock));
1738 DEBUG_MOUNT(KPrintF("MountDev: BlocksPerTrack %ld\n",vec->de_BlocksPerTrack));
1739 DEBUG_MOUNT(KPrintF("MountDev: Reserved %ld\n",vec->de_Reserved));
1740 DEBUG_MOUNT(KPrintF("MountDev: PreAlloc %ld\n",vec->de_PreAlloc));
1741 DEBUG_MOUNT(KPrintF("MountDev: Interleave %ld\n",vec->de_Interleave));
1742 DEBUG_MOUNT(KPrintF("MountDev: LowCyl %ld\n",vec->de_LowCyl));
1743 DEBUG_MOUNT(KPrintF("MountDev: UpperCyl %ld\n",vec->de_HighCyl));
1744 DEBUG_MOUNT(KPrintF("MountDev: NumBuffers %ld\n",vec->de_NumBuffers));
1745 DEBUG_MOUNT(if (vec->de_TableSize >= DE_BUFMEMTYPE))
1746 DEBUG_MOUNT(KPrintF("MountDev: BufMemType 0x%lx\n",vec->de_BufMemType));
1747 DEBUG_MOUNT(KPrintF("MountDev: MaxTransfer 0x%lx\n",vec->de_MaxTransfer));
1748 DEBUG_MOUNT(if (vec->de_TableSize >= DE_MASK))
1749 DEBUG_MOUNT(KPrintF("MountDev: Mask 0x%lx\n",vec->de_Mask));
1750 DEBUG_MOUNT(if (vec->de_TableSize >= DE_BOOTPRI))
1751 DEBUG_MOUNT(KPrintF("MountDev: BootPri %ld\n",vec->de_BootPri));
1752 DEBUG_MOUNT(if (vec->de_TableSize >= DE_DOSTYPE))
1753 DEBUG_MOUNT(KPrintF("MountDev: DosType 0x%lx\n",vec->de_DosType));
1754 DEBUG_MOUNT(if (vec->de_TableSize >= DE_BAUD))
1755 DEBUG_MOUNT(KPrintF("MountDev: Baud %ld\n",vec->de_Baud));
1756 DEBUG_MOUNT(if (vec->de_TableSize >= DE_CONTROL))
1757 DEBUG_MOUNT(KPrintF("MountDev: Control 0x%lx\n",vec->de_Control));
1758 DEBUG_MOUNT(if (vec->de_TableSize >= DE_BOOTBLOCKS))
1759 DEBUG_MOUNT(KPrintF("MountDev: BootBlocks %ld\n",vec->de_BootBlocks));
1761 if ((dn=MyMakeDosNode(name, IsEHandler ? params : NULL, StartupString)))
1763 DEBUG_MOUNT(KPrintF("MountDev: DeviceNode 0x%lx\n", (IPTR)dn));
1765 dn->dn_StackSize = StackSize;
1766 dn->dn_Priority = Priority;
1767 dn->dn_GlobalVec = (BPTR)GlobalVec;
1769 if (!IsEHandler && !StartupString)
1771 dn->dn_Startup = (BPTR)(SIPTR)StartupValue;
1774 if (IsFilesystem && ((ForceLoad==0) || (HandlerString==NULL)))
1776 DEBUG_MOUNT(KPrintF("MountDev: patchdosnode\n"));
1777 PatchDosNode(dn,vec->de_DosType);
1780 if (ForceLoad || dn->dn_SegList==BNULL)
1782 DEBUG_MOUNT(KPrintF("MountDev: Load Handler\n"));
1783 dn->dn_Handler = MKBADDR(HandlerString);
1785 else
1788 * We don't need the HandlerString anymore...free it
1790 if (HandlerString)
1792 FreeVec(HandlerString);
1793 HandlerString = NULL;
1796 DEBUG_MOUNT(KPrintF("MountDev: Name %b\n",dn->dn_Name));
1797 DEBUG_MOUNT(KPrintF("MountDev: Handler 0x%lx <%b>\n",dn->dn_Handler,dn->dn_Handler));
1798 DEBUG_MOUNT(KPrintF("MountDev: SegList 0x%lx\n",dn->dn_SegList));
1799 DEBUG_MOUNT(KPrintF("MountDev: StackSize %ld\n",dn->dn_StackSize));
1800 DEBUG_MOUNT(KPrintF("MountDev: Priority %ld\n",dn->dn_Priority));
1801 DEBUG_MOUNT(KPrintF(!IsEHandler && StartupString ? "MountDev: Startup <%b>\n" : "MountDev: Startup 0x%lx\n", dn->dn_Startup));
1802 DEBUG_MOUNT(KPrintF("MountDev: GlobalVec %ld\n",dn->dn_GlobalVec));
1804 if (dn->dn_SegList || dn->dn_Handler)
1806 if (AddDosEntry((struct DosList *)dn))
1808 DEBUG_MOUNT(KPrintF("MountDev: AddDosEntry worked\n"));
1810 * Don't free these anymore as they belong to the dosnode
1812 HandlerString = NULL;
1813 if (IsEHandler)
1815 UnitString = NULL;
1816 FlagsString = NULL;
1817 ControlString = NULL;
1819 if (Activate)
1821 strcat(name, ":");
1822 DEBUG_MOUNT(KPrintF("Activating \"%s\"\n", (IPTR)name));
1823 DeviceProc(name);
1825 error = 0;
1827 else
1829 DEBUG_MOUNT(KPrintF("MountDev: AddDosEntry failed\n"));
1830 error = ERROR_INVALID_RESIDENT_LIBRARY;
1831 if (HandlerString)
1833 FreeVec(HandlerString);
1837 else
1839 DEBUG_MOUNT(KPrintF("MountDev: no loadseg and no handler specified\n"));
1840 error = ERROR_OBJECT_NOT_FOUND;
1843 else
1845 error = ERROR_NO_FREE_STORE;
1848 return error;
1851 void ShowErrorArgs(STRPTR name, char *s, IPTR *ap)
1853 NewRawDoFmt("Error mounting '%s'", RAWFMTFUNC_STRING, txtBuf, name);
1855 if (IsCli)
1857 PutStr(txtBuf);
1858 PutStr(": ");
1859 VPrintf(s, ap);
1860 PutStr("\n");
1862 else
1864 struct EasyStruct es =
1866 sizeof(struct EasyStruct),
1868 txtBuf,
1870 "OK"
1873 IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library", 36);
1874 if (IntuitionBase)
1876 EasyRequestArgs(NULL, &es, NULL, ap);
1877 CloseLibrary((struct Library *)IntuitionBase);
1882 void ShowFault(LONG code, char *s, ...)
1884 char buf[256];
1885 va_list ap;
1886 int l;
1888 va_start(ap, s);
1889 l = vsnprintf(buf, sizeof(buf) - 2, s, ap);
1890 va_end(ap);
1891 strcpy(&buf[l], ": ");
1892 l += 2;
1893 Fault(code, NULL, &buf[l], sizeof(buf) - l);
1894 if (buf[l] == 0)
1895 snprintf(&buf[l], sizeof(buf) - l, "%ld", (long)code);
1896 buf[sizeof(buf)-1] = 0;
1897 if (IsCli)
1899 PutStr(buf);
1900 PutStr("\n");
1902 else
1904 struct EasyStruct es =
1906 sizeof(struct EasyStruct),
1908 "Mount Failure",
1909 buf,
1910 "OK"
1913 IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library", 36);
1914 if (IntuitionBase)
1916 EasyRequestArgs(NULL, &es, NULL, NULL);
1917 CloseLibrary((struct Library *)IntuitionBase);