exec.library: Allocate/Deallocate functions must remain generic and not handler MemHe...
[AROS.git] / workbench / c / Mount.c
blobc8ae64a9533437a38061cf8321a42b9a9c5f5c42
1 /*
2 (C) 1995-2012 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) x
91 #define DEBUG_MOUNT(x) x
92 #define DEBUG_MAKEDOSNODE(x) x
93 #define DEBUG_CHECK(x) 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;
1299 MyFileSysEntry = NULL;
1300 MyFileSysRes = OpenResource(FSRNAME);
1301 if (MyFileSysRes)
1303 Forbid();
1304 CurrentFileSysEntry = (struct FileSysEntry*) MyFileSysRes->fsr_FileSysEntries.lh_Head;
1305 while (CurrentFileSysEntry->fse_Node.ln_Succ)
1307 if (CurrentFileSysEntry->fse_DosType == DosType)
1309 if (MyFileSysEntry)
1311 if (CurrentFileSysEntry->fse_Version > MyFileSysEntry->fse_Version)
1313 MyFileSysEntry = CurrentFileSysEntry;
1316 else
1318 MyFileSysEntry = CurrentFileSysEntry;
1321 CurrentFileSysEntry =(struct FileSysEntry*) CurrentFileSysEntry->fse_Node.ln_Succ;
1323 Permit();
1325 return MyFileSysEntry;
1328 /************************************************************************************************/
1329 /************************************************************************************************/
1331 #define PATCH_FIELD(f, name) \
1332 if (MyFileSysEntry->fse_PatchFlags & f) \
1333 MyDeviceNode->dn_ ## name = (typeof(MyDeviceNode->dn_ ## name))MyFileSysEntry->fse_ ## name
1335 void PatchDosNode(struct DeviceNode *MyDeviceNode, ULONG DosType)
1337 struct FileSysEntry *MyFileSysEntry;
1339 DEBUG_PATCHDOSNODE(Printf("MakeDosNode: DeviceNode 0x%P\n", MyDeviceNode));
1341 if ((MyFileSysEntry=GetFileSysEntry(DosType)))
1343 DEBUG_PATCHDOSNODE(Printf("PatchDosNode: FileSysEntry 0x%P PatchFlags 0x%08lx\n", MyFileSysEntry, MyFileSysEntry->fse_PatchFlags));
1345 PATCH_FIELD(0x0001, Type);
1346 PATCH_FIELD(0x0002, Task);
1347 PATCH_FIELD(0x0004, Lock);
1348 PATCH_FIELD(0x0008, Handler);
1349 PATCH_FIELD(0x0010, StackSize);
1350 PATCH_FIELD(0x0020, Priority);
1351 PATCH_FIELD(0x0040, Startup);
1352 PATCH_FIELD(0x0080, SegList);
1353 PATCH_FIELD(0x0100, GlobalVec);
1355 DEBUG_PATCHDOSNODE(else Printf("PatchDosNode: Can't get FileSysEntry..no bootnode\n"));
1359 /************************************************************************************************/
1360 /************************************************************************************************/
1364 #define DOSNAME_INDEX 0
1365 #define EXECNAME_INDEX 1
1366 #define UNIT_INDEX 2
1367 #define FLAGS_INDEX 3
1368 #define ENVIROMENT_INDEX 4
1370 struct DeviceNode *MyMakeDosNode(char *DosName, IPTR *ParameterPkt, char *StartupName)
1372 int DosNameSize;
1373 int ExecNameSize;
1374 int MyEnvSize = 0;
1375 struct DeviceNode *MyDeviceNode = NULL;
1376 struct FileSysStartupMsg *MyFileSysStartupMsg = NULL;
1377 struct DosEnvec *MyDosEnvec = NULL;
1378 char *MyString = NULL;
1379 ULONG Status = FALSE;
1380 DEBUG_MAKEDOSNODE(Printf("MakeDosNode: Pkt 0x%lx\n",(IPTR)ParameterPkt));
1382 if (ParameterPkt)
1384 DEBUG_MAKEDOSNODE(Printf("MakeDosNode: DosName <%s> DeviceName <%s> Unit ", DosName, ParameterPkt[EXECNAME_INDEX]));
1385 DEBUG_MAKEDOSNODE(if (UnitString)
1386 Printf("<%s>",ParameterPkt[UNIT_INDEX]);
1387 else
1388 Printf("%ld",ParameterPkt[UNIT_INDEX]);)
1389 DEBUG_MAKEDOSNODE(Printf(" Flags 0x%lx DE_TABLESIZE 0x%lx\n", ParameterPkt[FLAGS_INDEX], ParameterPkt[ENVIROMENT_INDEX]));
1391 else
1393 DEBUG_MAKEDOSNODE(Printf("MakeDosNode: DosName <%s> Startup <%s>\n", (IPTR)DosName, (IPTR)StartupName));
1396 DosNameSize = strlen(DosName);
1398 if (ParameterPkt)
1400 if (ParameterPkt[EXECNAME_INDEX])
1402 ExecNameSize = strlen((UBYTE *)ParameterPkt[EXECNAME_INDEX]);
1404 else
1406 ExecNameSize = 0;
1408 MyEnvSize = (ParameterPkt[ENVIROMENT_INDEX] + 1) * sizeof(IPTR);
1410 else
1412 ExecNameSize = StartupName ? strlen(StartupName) : 0;
1415 if ((MyDeviceNode = AllocVec(sizeof(struct DeviceNode), MEMF_PUBLIC | MEMF_CLEAR)))
1417 DEBUG_MAKEDOSNODE(Printf("MakeDosNode: MyDeviceNode 0x%lx\n", (IPTR)MyDeviceNode));
1419 MyDeviceNode->dn_StackSize = 600;
1420 MyDeviceNode->dn_Priority = 10;
1422 if ((MyString=AllocVec(((DosNameSize + BSTR_EXTRA + 4) & ~3) + ((ExecNameSize + BSTR_EXTRA + 4) & ~3), MEMF_PUBLIC | MEMF_CLEAR)))
1424 bstrcpy(MyString, DosName, DosNameSize);
1426 MyDeviceNode->dn_Name = MKBADDR(MyString);
1428 if (ParameterPkt)
1430 if ((MyFileSysStartupMsg = AllocVec(sizeof(struct FileSysStartupMsg), MEMF_PUBLIC | MEMF_CLEAR)))
1432 DEBUG_MAKEDOSNODE(Printf("MakeDosNode: MyFileSysStartupMsg 0x%lx\n", (IPTR)MyFileSysStartupMsg));
1434 if ((MyDosEnvec = AllocVec(MyEnvSize, MEMF_PUBLIC | MEMF_CLEAR)))
1436 char *ExecNamePtr;
1438 DEBUG_MAKEDOSNODE(Printf("MakeDosNode: MyDosEnvec 0x%lx\n", (IPTR)MyDosEnvec));
1439 ExecNamePtr = &MyString[(1 + DosNameSize + BSTR_EXTRA + 3) & ~3];
1441 /* .device name must absolutely **NOT** include the 0 in the
1442 * length!!
1444 * the string *MUST* be 0 terminated, however!
1446 if (ParameterPkt[EXECNAME_INDEX])
1448 bstrcpy(ExecNamePtr, (UBYTE *)ParameterPkt[EXECNAME_INDEX], ExecNameSize);
1450 else
1452 ExecNamePtr[0] = 0;
1453 #ifndef AROS_FAST_BPTR
1454 ExecNamePtr[1] = 0;
1455 #endif
1457 MyFileSysStartupMsg->fssm_Device = MKBADDR(ExecNamePtr);
1458 MyFileSysStartupMsg->fssm_Unit = ParameterPkt[UNIT_INDEX];
1459 MyFileSysStartupMsg->fssm_Flags = ParameterPkt[FLAGS_INDEX];
1460 MyFileSysStartupMsg->fssm_Environ = MKBADDR(MyDosEnvec);
1461 MyDeviceNode->dn_Startup = MKBADDR(MyFileSysStartupMsg);
1463 CopyMem(&ParameterPkt[ENVIROMENT_INDEX], MyDosEnvec, MyEnvSize);
1465 #if __WORDSIZE > 32
1467 * EXPERIMENTAL: Fix up BufMemType on 64 bits.
1468 * Many software (and users) set Mask to 0x7FFFFFFF, assuming 31-bit memory, with BufMemType = PUBLIC.
1469 * This is perfectly true on 32-bit architectures, where addresses from 0x80000000 and up
1470 * belong to MMIO, however on 64 bits we might have memory beyond this address.
1471 * And AllocMem(MEMF_PUBLIC) would prefer to return that memory. This might screw up
1472 * filesystems expecting AllocMem() to return memory fully corresponding to the mask.
1474 if ((MyDosEnvec->de_TableSize >= DE_MASK) && (!(MyDosEnvec->de_Mask & 0x7FFFFFFF)))
1475 MyDosEnvec->de_BufMemType |= MEMF_31BIT;
1476 #endif
1478 Status=TRUE;
1479 DEBUG_MAKEDOSNODE(Printf("MakeDosNode: done\n"));
1483 else
1485 if (StartupName && ExecNameSize)
1487 char *StartupNamePtr;
1489 StartupNamePtr = &MyString[(1 + DosNameSize + BSTR_EXTRA + 3) & ~3];
1490 bstrcpy(StartupNamePtr, StartupName, ExecNameSize);
1491 MyDeviceNode->dn_Startup = MKBADDR(StartupNamePtr);
1493 Status=TRUE;
1497 if (Status)
1499 DEBUG_MAKEDOSNODE(Printf("MakeDosNode: done\n"));
1500 return MyDeviceNode;
1502 else
1504 DEBUG_MAKEDOSNODE(Printf("MakeDosNode: failed\n"));
1505 FreeVec(MyFileSysStartupMsg);
1506 FreeVec(MyDeviceNode);
1507 FreeVec(MyString);
1508 return NULL;
1514 /************************************************************************************************/
1515 /************************************************************************************************/
1518 LONG parsemountfile(IPTR *params, STRPTR buf, LONG size)
1520 STRPTR args[NUM_ARGS];
1521 LONG error;
1522 struct RDArgs rda;
1524 DEBUG_MOUNT(KPrintF("ParseMountFile:\n"));
1526 memset(&args, 0, sizeof(args));
1527 memset(&rda,0,sizeof(struct RDArgs));
1529 rda.RDA_Source.CS_Buffer = buf;
1530 rda.RDA_Source.CS_Length = size;
1531 rda.RDA_Source.CS_CurChr = 0;
1532 rda.RDA_Flags = RDAF_NOPROMPT;
1534 DEBUG_MOUNT(KPrintF("ReadArgs..\n%s\n\n", (IPTR)rda.RDA_Source.CS_Buffer));
1536 if ((error=ReadMountArgs(params,
1537 &rda))!=RETURN_OK)
1539 DEBUG_MOUNT(KPrintF("Parse: ReadArgs failed\n"));
1541 return error;
1544 /************************************************************************************************/
1545 /************************************************************************************************/
1548 LONG parsemountlist(IPTR *params,
1549 STRPTR name,
1550 STRPTR buf,
1551 LONG size)
1553 STRPTR args[NUM_ARGS];
1554 UBYTE buffer[1024];
1555 LONG error=RETURN_OK, res;
1556 STRPTR end = buf + size;
1557 STRPTR s2;
1558 char *ptr;
1559 struct RDArgs rda;
1561 DEBUG_MOUNT(KPrintF("ParseMountList: <%s>\n", (IPTR)name));
1563 memset(&args,0,sizeof(args));
1564 memset(&rda,0,sizeof(struct RDArgs));
1566 rda.RDA_Source.CS_Buffer = buf;
1567 rda.RDA_Source.CS_Length = end - buf;
1568 rda.RDA_Source.CS_CurChr = 0;
1569 rda.RDA_Flags = RDAF_NOPROMPT;
1571 while (rda.RDA_Source.CS_CurChr < rda.RDA_Source.CS_Length)
1573 res = ReadItem(buffer, sizeof(buffer), &rda.RDA_Source);
1575 DEBUG_MOUNT(KPrintF("ParseMountList: buffer <%s>\n", (IPTR)buffer));
1576 DEBUG_MOUNT(KPrintF("ParseMountList: ReadItem res %ld\n",res));
1578 if (res == ITEM_ERROR)
1580 return IoErr();
1583 if (res == ITEM_NOTHING &&
1584 rda.RDA_Source.CS_CurChr == rda.RDA_Source.CS_Length)
1586 return ERR_DEVICENOTFOUND;
1589 if (res != ITEM_QUOTED && res != ITEM_UNQUOTED)
1591 return 1;
1594 s2 = buffer;
1596 while (*s2)
1598 s2++;
1601 if (s2 == buffer || s2[-1] != ':')
1603 DEBUG_MOUNT(KPrintF("ParseMountList: failure\n"));
1604 return ERR_DEVICENOTFOUND;
1607 *--s2 = 0;
1609 if (!Strnicmp(name, buffer, s2 - buffer) &&
1610 (!name[s2 - buffer] || (name[s2 - buffer] == ':' || !name[s2 - buffer + 1])))
1612 DEBUG_MOUNT(KPrintF("ParseMountList: found\n"));
1614 /* Copy the string so we get proper case - Piru */
1615 memcpy(name, buffer, s2 - buffer);
1616 name[s2 - buffer] = '\0';
1618 ptr = name;
1619 while (*ptr)
1621 if (*ptr++ == ':')
1623 ptr[-1] = '\0';
1624 break;
1628 DEBUG_MOUNT(KPrintF("ReadArgs..\n%s\n\n", (IPTR)&rda.RDA_Source.CS_Buffer[rda.RDA_Source.CS_CurChr]));
1630 if ((error=ReadMountArgs(params,
1631 &rda))!=RETURN_OK)
1633 DEBUG_MOUNT(KPrintF("ParseMountList: ReadArgs failed\n"));
1634 //return IoErr();
1637 return error;
1640 while (rda.RDA_Source.CS_CurChr < rda.RDA_Source.CS_Length)
1642 if (rda.RDA_Source.CS_Buffer[rda.RDA_Source.CS_CurChr++] == '\n')
1644 DEBUG_MOUNT(KPrintF("ParseMountList: reach the end of the block\n"));
1645 break;
1650 DEBUG_MOUNT(KPrintF("ParseMountList: mount found nothing\n"));
1651 return ERR_DEVICENOTFOUND;
1654 /************************************************************************************************/
1655 /************************************************************************************************/
1657 static LONG checkmount(STRPTR name, IPTR *params)
1659 struct DosEnvec *vec;
1661 vec = (struct DosEnvec *)&params[4];
1663 params[1] = (IPTR) DeviceString;
1665 if (IsFilesystem && (!flagargs[ARG_DEVICE]
1666 || !flagargs[ARG_SURFACES] || !flagargs[ARG_BLOCKSPERTRACK]
1667 || !flagargs[ARG_LOWCYL] || !flagargs[ARG_HIGHCYL]))
1669 ShowError(name, "Could not find some of the following keywords:\n"
1670 " Surfaces, BlocksPerTrack, LowCyl, HighCyl, Device");
1671 return ERR_INVALIDKEYWORD;
1673 /* bootpri -129 shouldn't be started and not automatic mounted..whatever that means */
1674 if ((vec->de_BootPri < -129) || (vec->de_BootPri > 127))
1676 ShowError(name, "BootPri %ld is not allowed. Legal range is -128..127", vec->de_BootPri);
1677 return ERROR_BAD_NUMBER;
1680 if (flagargs[ARG_GLOBVEC])
1682 if ((GlobalVec != -1) && (GlobalVec != -2))
1684 ShowError(name, "Globvec %ld is not supported. Only -1 and -2 are supported here", GlobalVec);
1685 return ERROR_BAD_NUMBER;
1689 if (flagargs[ARG_STARTUP] && !StartupString)
1691 if (StartupValue >= 0x100)
1693 ShowError(name, "Startup uses too large numeric value %ld", StartupValue);
1694 return ERROR_BAD_NUMBER;
1698 return RETURN_OK;
1701 /************************************************************************************************/
1702 /************************************************************************************************/
1704 LONG mount(IPTR *params, STRPTR name)
1706 struct DosEnvec *vec;
1707 LONG error = RETURN_OK;
1708 struct DeviceNode *dn;
1709 STRPTR cp;
1711 for (cp = name; *cp != 0; cp++)
1712 *cp = ToUpper(*cp);
1714 DEBUG_MOUNT(KPrintF("MountDev: <%s>\n", name));
1716 if ((error=checkmount(name, params))!=RETURN_OK)
1718 DEBUG_MOUNT(KPrintF("MountDev: checkmount failed\n"));
1719 return error;
1722 vec = (struct DosEnvec *)&params[4];
1724 DEBUG_MOUNT(KPrintF("MountDev: DosName <%s>\n", (IPTR)name));
1725 DEBUG_MOUNT(KPrintF("MountDev: Filesystem <%s>\n", (IPTR)HandlerString + BSTR_OFFSET));
1726 DEBUG_MOUNT(KPrintF("MountDev: Device <%s>\n", (IPTR)DeviceString));
1727 DEBUG_MOUNT(KPrintF("MountDev: TableSize %ld\n",vec->de_TableSize));
1728 DEBUG_MOUNT(KPrintF("MountDev: SizeBlock %ld\n",vec->de_SizeBlock));
1729 DEBUG_MOUNT(KPrintF("MountDev: SecOrg %ld\n",vec->de_SecOrg));
1730 DEBUG_MOUNT(KPrintF("MountDev: Surfaces %ld\n",vec->de_Surfaces));
1731 DEBUG_MOUNT(KPrintF("MountDev: SectorsPerBlock %ld\n",vec->de_SectorPerBlock));
1732 DEBUG_MOUNT(KPrintF("MountDev: BlocksPerTrack %ld\n",vec->de_BlocksPerTrack));
1733 DEBUG_MOUNT(KPrintF("MountDev: Reserved %ld\n",vec->de_Reserved));
1734 DEBUG_MOUNT(KPrintF("MountDev: PreAlloc %ld\n",vec->de_PreAlloc));
1735 DEBUG_MOUNT(KPrintF("MountDev: Interleave %ld\n",vec->de_Interleave));
1736 DEBUG_MOUNT(KPrintF("MountDev: LowCyl %ld\n",vec->de_LowCyl));
1737 DEBUG_MOUNT(KPrintF("MountDev: UpperCyl %ld\n",vec->de_HighCyl));
1738 DEBUG_MOUNT(KPrintF("MountDev: NumBuffers %ld\n",vec->de_NumBuffers));
1739 DEBUG_MOUNT(if (vec->de_TableSize >= DE_BUFMEMTYPE))
1740 DEBUG_MOUNT(KPrintF("MountDev: BufMemType 0x%lx\n",vec->de_BufMemType));
1741 DEBUG_MOUNT(KPrintF("MountDev: MaxTransfer 0x%lx\n",vec->de_MaxTransfer));
1742 DEBUG_MOUNT(if (vec->de_TableSize >= DE_MASK))
1743 DEBUG_MOUNT(KPrintF("MountDev: Mask 0x%lx\n",vec->de_Mask));
1744 DEBUG_MOUNT(if (vec->de_TableSize >= DE_BOOTPRI))
1745 DEBUG_MOUNT(KPrintF("MountDev: BootPri %ld\n",vec->de_BootPri));
1746 DEBUG_MOUNT(if (vec->de_TableSize >= DE_DOSTYPE))
1747 DEBUG_MOUNT(KPrintF("MountDev: DosType 0x%lx\n",vec->de_DosType));
1748 DEBUG_MOUNT(if (vec->de_TableSize >= DE_BAUD))
1749 DEBUG_MOUNT(KPrintF("MountDev: Baud %ld\n",vec->de_Baud));
1750 DEBUG_MOUNT(if (vec->de_TableSize >= DE_CONTROL))
1751 DEBUG_MOUNT(KPrintF("MountDev: Control 0x%lx\n",vec->de_Control));
1752 DEBUG_MOUNT(if (vec->de_TableSize >= DE_BOOTBLOCKS))
1753 DEBUG_MOUNT(KPrintF("MountDev: BootBlocks %ld\n",vec->de_BootBlocks));
1755 if ((dn=MyMakeDosNode(name, IsEHandler ? params : NULL, StartupString)))
1757 DEBUG_MOUNT(KPrintF("MountDev: DeviceNode 0x%lx\n", (IPTR)dn));
1759 dn->dn_StackSize = StackSize;
1760 dn->dn_Priority = Priority;
1761 dn->dn_GlobalVec = (BPTR)GlobalVec;
1763 if (!IsEHandler && !StartupString)
1765 dn->dn_Startup = (BPTR)(SIPTR)StartupValue;
1768 if (IsFilesystem && ((ForceLoad==0) || (HandlerString==NULL)))
1770 DEBUG_MOUNT(KPrintF("MountDev: patchdosnode\n"));
1771 PatchDosNode(dn,vec->de_DosType);
1774 if (ForceLoad || dn->dn_SegList==BNULL)
1776 DEBUG_MOUNT(KPrintF("MountDev: Load Handler\n"));
1777 dn->dn_Handler = MKBADDR(HandlerString);
1779 else
1782 * We don't need the HandlerString anymore...free it
1784 if (HandlerString)
1786 FreeVec(HandlerString);
1787 HandlerString = NULL;
1790 DEBUG_MOUNT(KPrintF("MountDev: Name %b\n",dn->dn_Name));
1791 DEBUG_MOUNT(KPrintF("MountDev: Handler 0x%lx <%b>\n",dn->dn_Handler,dn->dn_Handler));
1792 DEBUG_MOUNT(KPrintF("MountDev: SegList 0x%lx\n",dn->dn_SegList));
1793 DEBUG_MOUNT(KPrintF("MountDev: StackSize %ld\n",dn->dn_StackSize));
1794 DEBUG_MOUNT(KPrintF("MountDev: Priority %ld\n",dn->dn_Priority));
1795 DEBUG_MOUNT(KPrintF(!IsEHandler && StartupString ? "MountDev: Startup <%b>\n" : "MountDev: Startup 0x%lx\n", dn->dn_Startup));
1796 DEBUG_MOUNT(KPrintF("MountDev: GlobalVec %ld\n",dn->dn_GlobalVec));
1798 if (dn->dn_SegList || dn->dn_Handler)
1800 if (AddDosEntry((struct DosList *)dn))
1802 DEBUG_MOUNT(KPrintF("MountDev: AddDosEntry worked\n"));
1804 * Don't free these anymore as they belong to the dosnode
1806 HandlerString = NULL;
1807 if (IsEHandler)
1809 UnitString = NULL;
1810 FlagsString = NULL;
1811 ControlString = NULL;
1813 if (Activate)
1815 strcat(name, ":");
1816 DEBUG_MOUNT(KPrintF("Activating \"%s\"\n", (IPTR)name));
1817 DeviceProc(name);
1819 error = 0;
1821 else
1823 DEBUG_MOUNT(KPrintF("MountDev: AddDosEntry failed\n"));
1824 error = ERROR_INVALID_RESIDENT_LIBRARY;
1825 if (HandlerString)
1827 FreeVec(HandlerString);
1831 else
1833 DEBUG_MOUNT(KPrintF("MountDev: no loadseg and no handler specified\n"));
1834 error = ERROR_OBJECT_NOT_FOUND;
1837 else
1839 error = ERROR_NO_FREE_STORE;
1842 return error;
1845 void ShowErrorArgs(STRPTR name, char *s, IPTR *ap)
1847 NewRawDoFmt("Error mounting '%s'", RAWFMTFUNC_STRING, txtBuf, name);
1849 if (IsCli)
1851 PutStr(txtBuf);
1852 PutStr(": ");
1853 VPrintf(s, ap);
1854 PutStr("\n");
1856 else
1858 struct EasyStruct es =
1860 sizeof(struct EasyStruct),
1862 txtBuf,
1864 "OK"
1867 IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library", 36);
1868 if (IntuitionBase)
1870 EasyRequestArgs(NULL, &es, NULL, ap);
1871 CloseLibrary((struct Library *)IntuitionBase);
1876 void ShowFault(LONG code, char *s, ...)
1878 char buf[256];
1879 va_list ap;
1880 int l;
1882 va_start(ap, s);
1883 l = vsnprintf(buf, sizeof(buf) - 2, s, ap);
1884 va_end(ap);
1885 strcpy(&buf[l], ": ");
1886 l += 2;
1887 Fault(code, NULL, &buf[l], sizeof(buf) - l);
1888 if (buf[l] == 0)
1889 snprintf(&buf[l], sizeof(buf) - l, "%ld", (long)code);
1890 buf[sizeof(buf)-1] = 0;
1891 if (IsCli)
1893 PutStr(buf);
1894 PutStr("\n");
1896 else
1898 struct EasyStruct es =
1900 sizeof(struct EasyStruct),
1902 "Mount Failure",
1903 buf,
1904 "OK"
1907 IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library", 36);
1908 if (IntuitionBase)
1910 EasyRequestArgs(NULL, &es, NULL, NULL);
1911 CloseLibrary((struct Library *)IntuitionBase);