don't check when its clang masquerading as gcc
[AROS.git] / workbench / c / Mount.c
blob0d48f57d795fe98b32ba966430ea38b2b79ae2e7
1 /*
2 (C) 1995-2018 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) \
211 dest[0] = len; \
212 strcpy(&dest[1], src); \
214 #endif
216 static const int __nocommandline __attribute__((used));
217 const TEXT version[] = "\0$VER: " PROGNAME " 50.14 (" ADATE ")";
219 ULONG CheckDevice(char *name);
220 void InitParams(IPTR *params);
221 LONG readfile(STRPTR name, STRPTR *mem, LONG *size);
222 ULONG readmountlist(IPTR *params, STRPTR name, char *mountlist);
223 ULONG readmountfile(IPTR *params, STRPTR name);
224 void preparefile(STRPTR buf, LONG size);
225 LONG parsemountfile(IPTR *params, STRPTR buf, LONG size);
226 LONG parsemountlist(IPTR *params, STRPTR name, STRPTR buf, LONG size);
227 LONG mount(IPTR *params, STRPTR name);
228 void ShowError(STRPTR name, const char *s, ...);
229 void ShowFault(LONG code, const char *s, ...);
231 struct DosLibrary *DOSBase;
232 struct IntuitionBase *IntuitionBase;
233 UtilityBase_t UtilityBase;
234 struct Process *MyProcess;
236 ULONG StartupValue;
237 char *StartupString = NULL;
238 char *ControlString = NULL;
239 char *UnitString = NULL;
240 char *FlagsString = NULL;
241 ULONG StackSize;
242 ULONG Priority;
243 ULONG Activate;
244 SIPTR GlobalVec;
245 ULONG ForceLoad;
246 char *HandlerString;
247 char *DeviceString;
248 BOOL IsEHandler, IsFilesystem;
249 BOOL IsCli;
250 BOOL flagargs[NUM_ARGS];
251 char txtBuf[256];
252 extern struct WBStartup *_WBenchMsg;
254 int main(void)
256 IPTR args[2];
257 IPTR *params;
258 LONG error = RETURN_FAIL;
259 struct RDArgs *rda;
260 char dirname[512];
262 if ((DOSBase = (struct DosLibrary *)OpenLibrary("dos.library",37))!=0)
264 if ((UtilityBase = (UtilityBase_t)OpenLibrary("utility.library",37)))
266 memset(&flagargs, 0, sizeof(flagargs));
267 IsEHandler = TRUE;
268 IsFilesystem = TRUE;
269 if (!_WBenchMsg)
271 memset(args,0,sizeof(args));
272 if ((rda = ReadArgs("DEVICE/M,FROM/K", args, NULL)))
274 STRPTR *MyDevPtr;
275 int len;
277 error = 0;
279 MyDevPtr =(STRPTR *)args[0];
280 if (MyDevPtr)
282 while (*MyDevPtr)
284 DEBUG_MOUNT(KPrintF("Mount: Current DevName <%s>\n",
285 (IPTR)*MyDevPtr));
287 if ((params = AllocVec(PARAMSLENGTH, MEMF_PUBLIC | MEMF_CLEAR)))
289 StackSize = 8192;
290 Priority = 5;
291 GlobalVec = -1;
292 HandlerString = NULL;
293 DeviceString = NULL;
294 StartupString = NULL;
296 len = strlen(*MyDevPtr);
297 if ((*MyDevPtr)[len-1] == ':')
299 /* search for a devicename */
300 DEBUG_MOUNT(KPrintF("Mount: search for devname <%s>\n",
301 (IPTR)*MyDevPtr));
303 strcpy(dirname, *MyDevPtr);
304 dirname[len-1] = '\0';
306 if ((error=CheckDevice(dirname))!=RETURN_OK)
308 DEBUG_MOUNT(KPrintF("Mount: is already mounted..stop\n"));
310 else
312 if (args[1])
314 error=readmountlist(params, dirname, (STRPTR)(args[1]));
315 DEBUG_MOUNT(KPrintF("Mount: readmountlist(%s) returned %ld\n", args[1], error));
317 else
319 char **SearchPtr;
320 ULONG slen;
322 DEBUG_MOUNT(KPrintF("Mount: search device definition <%s>\n",
323 (IPTR)*MyDevPtr));
324 for (SearchPtr=(char**) SearchTable;
325 *SearchPtr;
326 SearchPtr++)
328 if(SetSignal(0L,SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C)
330 error = RETURN_FAIL;
331 SetIoErr(ERROR_BREAK);
332 break;
335 slen = strlen(*SearchPtr);
336 strcpy(dirname, *SearchPtr);
337 dirname[slen] = '\0';
338 strcat(dirname, *MyDevPtr);
339 dirname[slen+len-1] = '\0';
340 DEBUG_MOUNT(KPrintF("Mount: try File <%s>\n", (IPTR)dirname));
342 error=readmountfile(params, dirname);
343 DEBUG_MOUNT(KPrintF("Mount: readmountfile returned %ld\n", error));
344 if (error != ERROR_OBJECT_NOT_FOUND)
345 break;
347 if (error == ERROR_OBJECT_NOT_FOUND)
349 DEBUG_MOUNT(KPrintF("Mount: try from mountlist\n"));
350 dirname[0] = '\0';
351 strcat(dirname, *MyDevPtr);
352 dirname[len-1] = '\0';
353 error=readmountlist(params, dirname, MOUNTLIST);
354 DEBUG_MOUNT(KPrintF("Mount: readmountlist(default) returned %ld\n", error));
359 else
361 /* search for a filename */
363 LONG err;
365 UBYTE stack_ap[sizeof(struct AnchorPath) + 3];
366 struct AnchorPath *MyAp = (struct AnchorPath *) (((IPTR) stack_ap + 3) & ~3);
368 DEBUG_MOUNT(KPrintF("Mount: search for mountfile <%s>\n", *MyDevPtr));
370 memset(MyAp,0,sizeof(struct AnchorPath));
372 dirname[0] = '\0';
373 for (err = MatchFirst(*MyDevPtr,MyAp);
374 err == 0;
375 err = MatchNext(MyAp))
377 if (MyAp->ap_Flags & APF_DirChanged)
379 DEBUG_MOUNT(KPrintF("Mount: Changed directories...\n"));
382 DEBUG_MOUNT(KPrintF("Mount: NameFromLock(0x%p)...\n", MyAp->ap_Current->an_Lock));
383 if (NameFromLock(MyAp->ap_Current->an_Lock,
384 dirname,
385 sizeof(dirname)) == FALSE)
387 ShowFault(IoErr(), "Error on NameFromLock");
388 break;
391 DEBUG_MOUNT(KPrintF("Mount: ...Dir name: %s\n", dirname));
392 if (AddPart(dirname,
393 &(MyAp->ap_Info.fib_FileName[0]),
394 sizeof(dirname)) == FALSE)
396 ShowFault(IoErr(), "Error on AddPart");
397 break;
399 if (MyAp->ap_Info.fib_DirEntryType > 0)
401 if (MyAp->ap_Flags & APF_DIDDIR)
403 DEBUG_MOUNT(KPrintF("Mount: Ascending from directory %s\n",
404 (IPTR)dirname));
406 else
408 DEBUG_MOUNT(KPrintF("Mount: The next dir is ... %s\n", (IPTR)dirname));
410 /* clear the completed directory flag */
411 MyAp->ap_Flags &= ~APF_DIDDIR;
414 else
416 /* Here is code for handling each particular file */
418 DEBUG_MOUNT(KPrintF("Mount: try File <%s>\n",
419 (IPTR)dirname));
421 memset(&flagargs, 0, sizeof(flagargs));
422 IsEHandler = TRUE;
423 IsFilesystem = TRUE;
424 error=readmountfile(params, dirname);
425 DEBUG_MOUNT(KPrintF("Mount: readmount file returned %ld\n", error));
428 /* This absolutely, positively must be called, all of the time. */
429 MatchEnd(MyAp);
431 if (err == ERROR_NO_MORE_ENTRIES)
433 SetIoErr(0);
435 else
437 /* if it was real error promote it - Piru */
438 error = err;
441 FreeVec(params);
443 else
445 error = ERROR_NO_FREE_STORE;
446 break;
448 MyDevPtr++;
451 FreeArgs(rda);
452 } /* if (rda != NULL) */
453 else
455 error = IoErr();
458 if (error && error != ERROR_NO_MORE_ENTRIES && error < ERR_SPECIAL)
460 ShowFault(error, "ERROR");
462 error = RETURN_FAIL;
464 else
466 error = error < ERR_SPECIAL ? RETURN_OK : RETURN_FAIL;
470 else
472 /* wb startup */
473 if (_WBenchMsg->sm_NumArgs >= 2)
475 if ((params = AllocVec(PARAMSLENGTH,
476 MEMF_PUBLIC | MEMF_CLEAR)))
478 int i;
480 for (i = 1; i < _WBenchMsg->sm_NumArgs; i++)
482 BPTR olddir;
484 DEBUG_MOUNT(KPrintF("Mount: try File <%s>\n",
485 (IPTR) _WBenchMsg->sm_ArgList[i].wa_Name));
487 olddir = CurrentDir(_WBenchMsg->sm_ArgList[i].wa_Lock);
489 error=readmountfile(params, _WBenchMsg->sm_ArgList[i].wa_Name);
490 DEBUG_MOUNT(KPrintF("Mount: readmountfile returned %ld\n", error));
491 if (error && error != ERROR_NO_MORE_ENTRIES && error < ERR_SPECIAL)
492 ShowFault(error, "ERROR");
494 (void) CurrentDir(olddir);
497 FreeVec(params);
499 else
501 error = ERROR_NO_FREE_STORE;
505 CloseLibrary((struct Library *)UtilityBase);
507 CloseLibrary((struct Library *)DOSBase);
510 return error;
513 /************************************************************************************************/
514 /************************************************************************************************/
515 ULONG CheckDevice(char *name)
517 struct DosList *dl;
518 ULONG Status;
520 DEBUG_CHECK(KPrintF("CheckDevice: <%s>\n",
521 name));
523 dl = LockDosList(LDF_DEVICES | LDF_VOLUMES | LDF_ASSIGNS | LDF_READ);
524 if ((dl = FindDosEntry(dl,name,LDF_DEVICES | LDF_VOLUMES | LDF_ASSIGNS)))
526 Status = ERROR_OBJECT_EXISTS;
528 else
530 Status = 0;
532 UnLockDosList(LDF_DEVICES | LDF_VOLUMES | LDF_ASSIGNS | LDF_READ);
534 DEBUG_CHECK(KPrintF("CheckDevice: object %s exist\n", Status ? "does" : "doesn't"));
536 return Status;
539 /************************************************************************************************/
540 /************************************************************************************************/
542 void InitParams(IPTR *params)
544 struct DosEnvec *vec;
546 memset(params,0, PARAMSLENGTH);
548 vec = (struct DosEnvec *)&params[4];
550 vec->de_TableSize = DE_BOOTBLOCKS;
551 vec->de_SizeBlock = 512 >> 2;
552 vec->de_Surfaces = 2;
553 vec->de_SectorPerBlock = 1;
554 vec->de_BlocksPerTrack = 11;
555 vec->de_Reserved = 2;
557 /* memset above
558 vec->de_SecOrg = 0;
559 vec->de_BootBlocks = 0;
560 vec->de_BootPri = 0;
561 vec->de_PreAlloc = 0;
562 vec->de_Interleave = 0;
563 vec->de_LowCyl = 0;
566 vec->de_HighCyl = 79;
567 vec->de_NumBuffers = 20; /* On AmigaOS 3.9 it's 5 */
568 vec->de_BufMemType = 3;
569 vec->de_Baud = 1200;
570 vec->de_MaxTransfer = 0x7fffffff;
571 vec->de_Mask = -2; /* 0xfffffffe, sign-extended on 64 bits */
572 vec->de_DosType = ID_DOS_DISK;
574 StackSize = 8192;
575 Priority = 5;
576 GlobalVec = -1;
577 HandlerString = NULL;
578 DeviceString = NULL;
579 StartupString = NULL;
582 void FreeStuff(void)
584 if (UnitString)
586 FreeVec(UnitString);
587 UnitString = NULL;
589 if (FlagsString)
591 FreeVec(FlagsString);
592 FlagsString = NULL;
594 if (ControlString)
596 FreeVec(ControlString);
597 ControlString = NULL;
599 if (HandlerString)
601 FreeVec(HandlerString);
602 HandlerString = NULL;
604 if (DeviceString)
606 FreeVec(DeviceString);
607 DeviceString = NULL;
609 if (StartupString)
611 FreeVec(StartupString);
612 StartupString = NULL;
616 /************************************************************************************************/
617 /************************************************************************************************/
619 static long GetValue(IPTR bufp, char **end)
621 char *buf = (char *)bufp;
622 char *c = buf;
624 if ((c[0]=='-') || (c[0]=='+'))
625 c++;
627 * If it's a hexadecimal number, use strtoul(), otherwise we can lose our 31st bit.
628 * Should be okay since i've never seen any usage of minus sign with hexadecimals.
629 * For decimals we do support sign, because it makes it very convenient to use negative
630 * masks for sign extension on 64 bits.
632 if ((c[0] == '0') && (((c[1])=='x') || (c[1])=='X'))
633 return strtoul(buf, end, 16);
634 else
635 return strtol(buf, end, 10);
638 /************************************************************************************************/
639 /************************************************************************************************/
641 ULONG ReadMountArgs(IPTR *params, struct RDArgs *rda)
643 struct DosEnvec *vec;
644 IPTR args[NUM_ARGS];
645 struct RDArgs *MyRDA;
646 ULONG result = RETURN_OK;
647 int i;
648 char *s = NULL;
650 DEBUG_MOUNT(KPrintF("ReadMountArgs:\n%s\n\n", (IPTR)&rda->RDA_Source.CS_Buffer[rda->RDA_Source.CS_CurChr]));
652 memset(&args, 0, sizeof(args));
654 if (!(MyRDA = ReadArgs((STRPTR)options, &args[0], rda)))
656 DEBUG_MOUNT(KPrintF("ReadMountArgs: ReadArgs failed, error %u\n", IoErr()));
657 return ERR_INVALIDKEYWORD;
660 for (i = 0; i < NUM_ARGS; i++)
662 if (args[i] != 0)
663 flagargs[i] = TRUE;
666 if (args[ARG_HANDLER] != 0)
668 s = (STRPTR)args[ARG_HANDLER];
669 IsEHandler = FALSE;
670 IsFilesystem = FALSE;
672 else if (args[ARG_EHANDLER] != 0)
674 s = (STRPTR)args[ARG_EHANDLER];
675 IsEHandler = TRUE;
676 IsFilesystem = FALSE;
678 else if (args[ARG_FILESYSTEM] != 0)
680 s = (STRPTR)args[ARG_FILESYSTEM];
681 IsEHandler = TRUE;
682 IsFilesystem = TRUE;
683 } else
684 s = NULL;
686 if (s)
688 int len;
690 DEBUG_MOUNT(KPrintF("ReadMountArgs: Handler <%s>\n",s));
691 len = strlen(s);
693 if (HandlerString)
694 FreeVec(HandlerString);
696 if ((HandlerString = AllocVec(len + BSTR_EXTRA, MEMF_PUBLIC|MEMF_CLEAR)))
697 bstrcpy(HandlerString, s, len);
700 if (args[ARG_STACKSIZE] != 0)
701 StackSize = GetValue(args[ARG_STACKSIZE], NULL);
703 if (args[ARG_PRIORITY] != 0)
704 Priority = GetValue(args[ARG_PRIORITY], NULL);
706 if (args[ARG_GLOBVEC] != 0)
707 GlobalVec = GetValue(args[ARG_GLOBVEC], NULL);
709 if (args[ARG_FORCELOAD] != 0)
710 ForceLoad = GetValue(args[ARG_FORCELOAD], NULL);
712 if (args[ARG_ACTIVATE] != 0)
713 Activate = GetValue(args[ARG_ACTIVATE], NULL);
715 if (args[ARG_DEVICE] != 0)
717 int len;
719 DEBUG_MOUNT(KPrintF("ReadMountArgs: Device <%s>\n",(STRPTR)args[ARG_DEVICE]));
721 len = strlen((STRPTR)args[ARG_DEVICE]);
723 if (DeviceString)
724 FreeVec(DeviceString);
726 if ((DeviceString = AllocVec(len+1,MEMF_PUBLIC|MEMF_CLEAR)))
727 strcpy(DeviceString, (STRPTR)args[ARG_DEVICE]);
730 if (args[ARG_UNIT] != 0)
732 if (UnitString)
734 FreeVec(UnitString);
735 UnitString = NULL;
737 params[2] = GetValue(args[ARG_UNIT], &s);
738 if (*s)
740 int len = strlen((STRPTR)args[ARG_UNIT]);
742 DEBUG_MOUNT(KPrintF("ReadMountArgs: len %ld\n",len));
744 if ((UnitString = AllocVec(len + 1, MEMF_PUBLIC|MEMF_CLEAR)))
746 strcpy(UnitString, (STRPTR)args[ARG_UNIT]);
747 params[2] = (IPTR)UnitString;
748 DEBUG_MOUNT(KPrintF("ReadMountArgs: Unit String <%s>\n", (STRPTR)params[2]));
750 else
752 result = ERROR_NO_FREE_STORE;
753 goto error;
756 else
757 DEBUG_MOUNT(KPrintF("ReadMountArgs: Unit Value %ld\n",params[2]));
760 if (args[ARG_FLAGS] != 0)
762 DEBUG_MOUNT(KPrintF("ReadMountArgs: Flags <%s>\n",(STRPTR)args[ARG_FLAGS]));
763 if (FlagsString)
765 FreeVec(FlagsString);
766 FlagsString = NULL;
769 params[3] = GetValue(args[ARG_FLAGS], &s);
770 if (*s)
772 int len = strlen((STRPTR)args[ARG_FLAGS]);
774 DEBUG_MOUNT(KPrintF("ReadMountArgs: len %ld\n",len));
776 if ((FlagsString = AllocVec(len + 1, MEMF_PUBLIC|MEMF_CLEAR)))
778 strcpy(FlagsString, (STRPTR)args[ARG_FLAGS]);
779 params[3] = (IPTR) FlagsString;
780 DEBUG_MOUNT(KPrintF("ReadMountArgs: Flags String <%s>\n",(STRPTR)params[3]));
782 else
784 result = ERROR_NO_FREE_STORE;
785 goto error;
788 else
789 DEBUG_MOUNT(KPrintF("ReadMountArgs: Flag Value %ld\n",params[3]));
792 vec = (struct DosEnvec *)&params[4];
794 if (args[ARG_BLOCKSIZE] != 0)
795 vec->de_SizeBlock = GetValue(args[ARG_BLOCKSIZE], NULL) >> 2;
797 if (args[ARG_SURFACES] != 0)
798 vec->de_Surfaces = GetValue(args[ARG_SURFACES], NULL);
800 if (args[ARG_SECTORSPERBLOCK] != 0)
801 vec->de_SectorPerBlock = GetValue(args[ARG_SECTORSPERBLOCK], NULL);
803 if (args[ARG_BLOCKSPERTRACK] != 0)
804 vec->de_BlocksPerTrack = GetValue(args[ARG_BLOCKSPERTRACK], NULL);
806 if (args[ARG_RESERVED] != 0)
807 vec->de_Reserved = GetValue(args[ARG_RESERVED], NULL);
809 if (args[ARG_PREALLOC] != 0)
810 vec->de_PreAlloc = GetValue(args[ARG_PREALLOC], NULL);
812 if (args[ARG_INTERLEAVE] != 0)
813 vec->de_Interleave = GetValue(args[ARG_INTERLEAVE], NULL);
815 if (args[ARG_LOWCYL] != 0)
816 vec->de_LowCyl = GetValue(args[ARG_LOWCYL], NULL);
818 if (args[ARG_HIGHCYL] != 0)
819 vec->de_HighCyl = GetValue(args[ARG_HIGHCYL], NULL);
821 if (args[ARG_BUFFERS] != 0)
822 vec->de_NumBuffers = GetValue(args[ARG_BUFFERS], NULL);
824 if (args[ARG_BUFMEMTYPE] != 0)
825 vec->de_BufMemType = GetValue(args[ARG_BUFMEMTYPE], NULL);
827 if (args[ARG_BOOTPRI] != 0)
828 vec->de_BootPri = GetValue(args[ARG_BOOTPRI], NULL);
830 if (args[ARG_BAUD] != 0)
831 vec->de_Baud = GetValue(args[ARG_BAUD], NULL);
833 if (args[ARG_MAXTRANSFER] != 0)
834 vec->de_MaxTransfer = GetValue(args[ARG_MAXTRANSFER], NULL);
836 if (args[ARG_MASK] != 0)
837 vec->de_Mask = GetValue(args[ARG_MASK], NULL);
839 if (args[ARG_DOSTYPE] != 0)
840 vec->de_DosType = (IPTR)GetValue(args[ARG_DOSTYPE], NULL);
842 if (args[ARG_CONTROL] != 0)
844 int len;
846 DEBUG_MOUNT(KPrintF("ReadMountArgs: Control <%s>\n",args[ARG_CONTROL]));
847 if (ControlString)
849 FreeVec(ControlString);
850 ControlString = NULL;
853 len = strlen((STRPTR)args[ARG_CONTROL]);
854 if (len < 0x100)
856 if ((ControlString=AllocVec(len + BSTR_EXTRA, MEMF_PUBLIC|MEMF_CLEAR)))
858 bstrcpy(ControlString, (STRPTR)args[ARG_CONTROL], len);
859 vec->de_Control = (IPTR)MKBADDR(ControlString);
861 else
863 result = ERROR_NO_FREE_STORE;
864 goto error;
867 else
869 result = ERROR_LINE_TOO_LONG;
870 SetIoErr(result);
871 goto error;
875 if (args[ARG_STARTUP] != 0)
877 DEBUG_MOUNT(KPrintF("ReadMountArgs: Startup <%s>\n",args[ARG_STARTUP]));
878 if (StartupString)
880 FreeVec(StartupString);
881 StartupString = NULL;
884 StartupValue = GetValue(args[ARG_STARTUP], &s);
885 if (*s)
887 int len = strlen((STRPTR)args[ARG_STARTUP]);
889 DEBUG_MOUNT(KPrintF("ReadMountArgs: len %ld\n",len));
891 if ((StartupString = AllocVec(len + 1, MEMF_PUBLIC|MEMF_CLEAR)))
892 strcpy(StartupString,(STRPTR)args[ARG_STARTUP]);
893 else
895 result = ERROR_NO_FREE_STORE;
896 goto error;
901 error:
902 FreeArgs(MyRDA);
903 return result;
906 /************************************************************************************************/
907 /************************************************************************************************/
909 ULONG readmountlist(IPTR *params,
910 STRPTR name,
911 char *mountlist)
913 STRPTR MountListBuf;
914 LONG MountListBufSize;
915 ULONG error;
917 DEBUG_MOUNT(KPrintF("ReadMountList: find <%s> in mountlist <%s>\n",
918 name,
919 mountlist));
921 error = readfile(mountlist,
922 &MountListBuf,
923 &MountListBufSize);
924 if (error==RETURN_OK)
926 preparefile(MountListBuf,
927 MountListBufSize);
930 InitParams(params);
932 if ((error=parsemountlist(params,
933 name,
934 MountListBuf,
935 MountListBufSize))==RETURN_OK)
937 if ((error = mount(params,name))!=RETURN_OK)
939 DEBUG_MOUNT(KPrintF("ReadMountList: mount failed error %ld\n",
940 error));
943 else
945 switch (error)
947 case ERR_DEVICENOTFOUND:
948 case ERR_INVALIDKEYWORD:
949 ShowError(name, "Device not found in file '%s'", name, mountlist);
950 break;
954 FreeStuff();
955 FreeVec(MountListBuf);
957 return error;
960 /************************************************************************************************/
961 /************************************************************************************************/
963 ULONG readmountfile(IPTR *params, STRPTR filename)
965 struct Library *IconBase;
966 struct DiskObject *diskobj;
967 char **myargv;
968 STRPTR MountListBuf;
969 LONG MountListBufSize;
970 struct RDArgs rda;
971 ULONG error = RETURN_FAIL;
972 UBYTE *nameptr;
973 int toollen;
974 BOOL mountinfo=FALSE;
975 char name[256+1];
977 DEBUG_MOUNT(KPrintF("ReadMountFile: <%s>\n", (IPTR)filename));
980 struct Process *me = (APTR) FindTask(NULL);
981 APTR oldwinptr;
982 BPTR lock;
984 name[0] = '\0';
986 oldwinptr = me->pr_WindowPtr;
987 me->pr_WindowPtr = (APTR) -1;
988 lock = Lock(filename, SHARED_LOCK);
989 if (lock)
991 struct FileInfoBlock *fib = (struct FileInfoBlock*)AllocDosObject(DOS_FIB, NULL);
992 if (fib)
994 if (Examine(lock, fib))
996 nameptr = fib->fib_FileName;
997 memmove(name, nameptr, strlen(nameptr) + 1);
999 FreeDosObject(DOS_FIB, fib);
1001 UnLock(lock);
1003 me->pr_WindowPtr = oldwinptr;
1005 if (name[0] == '\0')
1007 nameptr = FilePart(filename);
1008 strcpy(name,
1009 nameptr);
1013 DEBUG_MOUNT(KPrintF("ReadMountFile: mount <%s>\n", (IPTR)name));
1015 if ((error=CheckDevice(name))!=RETURN_OK)
1017 return error;
1020 InitParams(params);
1022 DEBUG_MOUNT(KPrintF("ReadMountFile: readfile\n"));
1024 error = readfile(filename,
1025 &MountListBuf,
1026 &MountListBufSize);
1027 if (error==RETURN_OK)
1029 DEBUG_MOUNT(KPrintF("ReadMountFile: preparsefile\n"));
1030 preparefile(MountListBuf, MountListBufSize);
1033 DEBUG_MOUNT(KPrintF("ReadMountFile: parsemountfile\n"));
1034 if ((error = parsemountfile(params, MountListBuf, MountListBufSize))!=RETURN_OK)
1036 DEBUG_MOUNT(KPrintF("ReadMountFile: parsemountfile error %ld\n", error));
1037 ShowFault(IoErr(), "Mountfile '%s' is invalid", filename);
1039 else
1041 mountinfo = TRUE;
1043 FreeVec(MountListBuf);
1045 else
1047 DEBUG_MOUNT(KPrintF("ReadMountFile: mountfile not found..search for <%s.info>\n",
1048 filename));
1051 if ((error==RETURN_OK) ||
1052 (error==ERROR_OBJECT_NOT_FOUND))
1054 DEBUG_MOUNT(KPrintF("ReadMountFile: look for icon '%s'\n", filename));
1056 if ((IconBase = OpenLibrary("icon.library", 37)))
1058 if ((diskobj = GetDiskObject(filename)))
1060 myargv =(char**) diskobj->do_ToolTypes;
1061 if (myargv)
1063 while (*myargv)
1065 char *ToolPtr;
1066 ToolPtr = *myargv;
1067 DEBUG_MOUNT(KPrintF("ReadMountFile: ToolType <%s>\n",
1068 ToolPtr));
1069 if ((ToolPtr[0] != '(') && (ToolPtr[0] != '*') &&
1070 !((ToolPtr[0] == 'I') && (ToolPtr[1] == 'M') && (ToolPtr[3] == '=')))
1072 char *ToolString;
1073 toollen = strlen(ToolPtr);
1074 if ((ToolString = AllocVec(toollen + 2,MEMF_ANY)))
1076 memcpy(ToolString,ToolPtr,toollen);
1077 ToolString[toollen] = '\n';
1078 ToolString[toollen+1] = '\0';
1079 memset(&rda,0,sizeof(struct RDArgs));
1080 rda.RDA_Source.CS_Buffer = ToolString;
1081 rda.RDA_Source.CS_Length = toollen+1;
1082 rda.RDA_Source.CS_CurChr = 0;
1083 rda.RDA_Flags = RDAF_NOPROMPT;
1084 if ((ReadMountArgs(params, &rda)==RETURN_OK))
1086 mountinfo = TRUE;
1088 else
1090 DEBUG_MOUNT(KPrintF("ReadMountFile: ReadArgs failed error %ld\n",
1091 error));
1093 FreeVec(ToolString);
1095 else
1097 error = ERROR_NO_FREE_STORE;
1098 break;
1101 else
1103 DEBUG_MOUNT(KPrintF("ReadMountFile: skipped\n"));
1105 myargv++;
1108 FreeDiskObject(diskobj);
1110 else
1113 CloseLibrary(IconBase);
1117 if (mountinfo)
1119 DEBUG_MOUNT(KPrintF("ReadMountFile: mount information exists\n"));
1121 if ((error = mount(params,name)) != RETURN_OK)
1123 DEBUG_MOUNT(KPrintF("ReadMountFile: mount failed error %ld\n",
1124 error));
1128 FreeStuff();
1130 return error;
1133 /************************************************************************************************/
1134 /************************************************************************************************/
1137 LONG readfile(STRPTR name, STRPTR *mem, LONG *size)
1139 BPTR ml;
1140 ULONG rest,sub;
1141 STRPTR buf;
1142 struct Process *me = (struct Process *) FindTask(NULL);
1143 APTR oldwinptr;
1145 oldwinptr = me->pr_WindowPtr;
1146 me->pr_WindowPtr = (APTR) -1;
1147 ml = Open(name, MODE_OLDFILE);
1148 me->pr_WindowPtr = oldwinptr;
1150 DEBUG_MOUNT(KPrintF("ReadFile: <%s>\n", (IPTR) name));
1152 if (ml)
1154 if (Seek(ml, 0, OFFSET_END) != -1)
1156 *size = Seek(ml, 0, OFFSET_BEGINNING);
1158 if (*size != -1)
1160 *mem = (STRPTR)AllocVec(*size+2, MEMF_ANY);
1162 if (*mem)
1164 rest = *size;
1165 buf = *mem;
1167 for (;;)
1169 if (!rest)
1171 Close(ml);
1173 *buf++ = '\n';
1174 *buf = '\0';
1176 return 0;
1179 sub = Read(ml, buf, rest);
1181 if (sub == -1)
1183 break;
1186 rest -= sub;
1187 buf += sub;
1190 FreeVec(*mem);
1192 else
1194 SetIoErr(ERROR_NO_FREE_STORE);
1199 Close(ml);
1202 DEBUG_MOUNT(KPrintF("ReadFile: error %ld\n", IoErr()));
1203 return IoErr();
1206 /************************************************************************************************/
1207 /************************************************************************************************/
1210 void preparefile(STRPTR buf, LONG size)
1212 STRPTR end = buf + size;
1214 while (buf < end)
1216 /* Convert comments to spaces */
1217 if (buf + 1 < end && *buf == '/' && buf[1] == '*')
1219 *buf++ = ' ';
1220 *buf++ = ' ';
1222 while (buf < end)
1224 if (*buf == '*')
1226 *buf++ = ' ';
1228 if (buf >= end)
1230 break;
1233 if (*buf == '/')
1235 *buf++ = ' ';
1236 break;
1239 else
1241 *buf++=' ';
1245 continue;
1248 /* Skip strings */
1249 if (*buf=='\"')
1252 * skip first
1254 buf++;
1255 while (buf < end && *buf != '\"')
1257 buf++;
1260 * skip last "
1262 buf++;
1263 continue;
1266 /* Convert '\n' and ';' to spaces */
1267 if (*buf == '\n' || *buf == ';')
1269 *buf++ = ' ';
1270 continue;
1273 /* Convert '#' to \n */
1274 if (*buf == '#')
1276 *buf++ = '\n';
1277 continue;
1280 /* Skip all other characters */
1281 buf++;
1285 /************************************************************************************************/
1286 /************************************************************************************************/
1288 struct FileSysEntry *GetFileSysEntry(ULONG DosType)
1291 struct FileSysResource *MyFileSysRes;
1292 struct FileSysEntry *MyFileSysEntry;
1293 struct FileSysEntry *CurrentFileSysEntry;
1294 BOOL Matched;
1296 MyFileSysEntry = NULL;
1297 MyFileSysRes = OpenResource(FSRNAME);
1298 if (MyFileSysRes)
1300 Forbid();
1301 CurrentFileSysEntry = (struct FileSysEntry*) MyFileSysRes->fsr_FileSysEntries.lh_Head;
1302 while (CurrentFileSysEntry->fse_Node.ln_Succ)
1304 if (HandlerString != NULL)
1305 Matched = strcmp(HandlerString + BSTR_OFFSET,
1306 AROS_BSTR_ADDR(CurrentFileSysEntry->fse_Handler)) == 0;
1307 else
1308 Matched = CurrentFileSysEntry->fse_DosType == DosType;
1309 if (Matched)
1311 if (MyFileSysEntry)
1313 if (CurrentFileSysEntry->fse_Version > MyFileSysEntry->fse_Version)
1315 MyFileSysEntry = CurrentFileSysEntry;
1318 else
1320 MyFileSysEntry = CurrentFileSysEntry;
1323 CurrentFileSysEntry =(struct FileSysEntry*) CurrentFileSysEntry->fse_Node.ln_Succ;
1325 Permit();
1327 return MyFileSysEntry;
1330 /************************************************************************************************/
1331 /************************************************************************************************/
1333 #define PATCH_FIELD(f, name) \
1334 if (MyFileSysEntry->fse_PatchFlags & f) \
1335 MyDeviceNode->dn_ ## name = (typeof(MyDeviceNode->dn_ ## name))MyFileSysEntry->fse_ ## name
1337 void PatchDosNode(struct DeviceNode *MyDeviceNode, ULONG DosType)
1339 struct FileSysEntry *MyFileSysEntry;
1341 DEBUG_PATCHDOSNODE(Printf("MakeDosNode: DeviceNode 0x%P\n", MyDeviceNode));
1343 if ((MyFileSysEntry=GetFileSysEntry(DosType)))
1345 DEBUG_PATCHDOSNODE(Printf("PatchDosNode: FileSysEntry 0x%P PatchFlags 0x%08lx\n", MyFileSysEntry, MyFileSysEntry->fse_PatchFlags));
1347 PATCH_FIELD(0x0001, Type);
1348 PATCH_FIELD(0x0002, Task);
1349 PATCH_FIELD(0x0004, Lock);
1350 PATCH_FIELD(0x0008, Handler);
1351 PATCH_FIELD(0x0010, StackSize);
1352 PATCH_FIELD(0x0020, Priority);
1353 PATCH_FIELD(0x0040, Startup);
1354 PATCH_FIELD(0x0080, SegList);
1355 PATCH_FIELD(0x0100, GlobalVec);
1357 DEBUG_PATCHDOSNODE(else Printf("PatchDosNode: Can't get FileSysEntry..no bootnode\n"));
1361 /************************************************************************************************/
1362 /************************************************************************************************/
1366 #define DOSNAME_INDEX 0
1367 #define EXECNAME_INDEX 1
1368 #define UNIT_INDEX 2
1369 #define FLAGS_INDEX 3
1370 #define ENVIROMENT_INDEX 4
1372 struct DeviceNode *MyMakeDosNode(char *DosName, IPTR *ParameterPkt, char *StartupName)
1374 int DosNameSize;
1375 int ExecNameSize;
1376 int MyEnvSize = 0;
1377 struct DeviceNode *MyDeviceNode = NULL;
1378 struct FileSysStartupMsg *MyFileSysStartupMsg = NULL;
1379 struct DosEnvec *MyDosEnvec = NULL;
1380 char *MyString = NULL;
1381 ULONG Status = FALSE;
1382 DEBUG_MAKEDOSNODE(Printf("MakeDosNode: Pkt 0x%lx\n",(IPTR)ParameterPkt));
1384 if (ParameterPkt)
1386 DEBUG_MAKEDOSNODE(Printf("MakeDosNode: DosName <%s> DeviceName <%s> Unit ", DosName, ParameterPkt[EXECNAME_INDEX]));
1387 DEBUG_MAKEDOSNODE(if (UnitString)
1388 Printf("<%s>",ParameterPkt[UNIT_INDEX]);
1389 else
1390 Printf("%ld",ParameterPkt[UNIT_INDEX]);)
1391 DEBUG_MAKEDOSNODE(Printf(" Flags 0x%lx DE_TABLESIZE 0x%lx\n", ParameterPkt[FLAGS_INDEX], ParameterPkt[ENVIROMENT_INDEX]));
1393 else
1395 DEBUG_MAKEDOSNODE(Printf("MakeDosNode: DosName <%s> Startup <%s>\n", (IPTR)DosName, (IPTR)StartupName));
1398 DosNameSize = strlen(DosName);
1400 if (ParameterPkt)
1402 if (ParameterPkt[EXECNAME_INDEX])
1404 ExecNameSize = strlen((UBYTE *)ParameterPkt[EXECNAME_INDEX]);
1406 else
1408 ExecNameSize = 0;
1410 MyEnvSize = (ParameterPkt[ENVIROMENT_INDEX] + 1) * sizeof(IPTR);
1412 else
1414 ExecNameSize = StartupName ? strlen(StartupName) : 0;
1417 if ((MyDeviceNode = AllocVec(sizeof(struct DeviceNode), MEMF_PUBLIC | MEMF_CLEAR)))
1419 DEBUG_MAKEDOSNODE(Printf("MakeDosNode: MyDeviceNode 0x%lx\n", (IPTR)MyDeviceNode));
1421 MyDeviceNode->dn_StackSize = 600;
1422 MyDeviceNode->dn_Priority = 10;
1424 if ((MyString=AllocVec(((DosNameSize + BSTR_EXTRA + 4) & ~3) + ((ExecNameSize + BSTR_EXTRA + 4) & ~3), MEMF_PUBLIC | MEMF_CLEAR)))
1426 bstrcpy(MyString, DosName, DosNameSize);
1428 MyDeviceNode->dn_Name = MKBADDR(MyString);
1430 if (ParameterPkt)
1432 if ((MyFileSysStartupMsg = AllocVec(sizeof(struct FileSysStartupMsg), MEMF_PUBLIC | MEMF_CLEAR)))
1434 DEBUG_MAKEDOSNODE(Printf("MakeDosNode: MyFileSysStartupMsg 0x%lx\n", (IPTR)MyFileSysStartupMsg));
1436 if ((MyDosEnvec = AllocVec(MyEnvSize, MEMF_PUBLIC | MEMF_CLEAR)))
1438 char *ExecNamePtr;
1440 DEBUG_MAKEDOSNODE(Printf("MakeDosNode: MyDosEnvec 0x%lx\n", (IPTR)MyDosEnvec));
1441 ExecNamePtr = &MyString[(1 + DosNameSize + BSTR_EXTRA + 3) & ~3];
1443 /* .device name must absolutely **NOT** include the 0 in the
1444 * length!!
1446 * the string *MUST* be 0 terminated, however!
1448 if (ParameterPkt[EXECNAME_INDEX])
1450 bstrcpy(ExecNamePtr, (UBYTE *)ParameterPkt[EXECNAME_INDEX], ExecNameSize);
1452 else
1454 ExecNamePtr[0] = 0;
1455 #ifndef AROS_FAST_BPTR
1456 ExecNamePtr[1] = 0;
1457 #endif
1459 MyFileSysStartupMsg->fssm_Device = MKBADDR(ExecNamePtr);
1460 MyFileSysStartupMsg->fssm_Unit = ParameterPkt[UNIT_INDEX];
1461 MyFileSysStartupMsg->fssm_Flags = ParameterPkt[FLAGS_INDEX];
1462 MyFileSysStartupMsg->fssm_Environ = MKBADDR(MyDosEnvec);
1463 MyDeviceNode->dn_Startup = MKBADDR(MyFileSysStartupMsg);
1465 CopyMem(&ParameterPkt[ENVIROMENT_INDEX], MyDosEnvec, MyEnvSize);
1467 #if __WORDSIZE > 32
1469 * EXPERIMENTAL: Fix up BufMemType on 64 bits.
1470 * Many software (and users) set Mask to 0x7FFFFFFF, assuming 31-bit memory, with BufMemType = PUBLIC.
1471 * This is perfectly true on 32-bit architectures, where addresses from 0x80000000 and up
1472 * belong to MMIO, however on 64 bits we might have memory beyond this address.
1473 * And AllocMem(MEMF_PUBLIC) would prefer to return that memory. This might screw up
1474 * filesystems expecting AllocMem() to return memory fully corresponding to the mask.
1476 if ((MyDosEnvec->de_TableSize >= DE_MASK) && (!(MyDosEnvec->de_Mask & 0x7FFFFFFF)))
1477 MyDosEnvec->de_BufMemType |= MEMF_31BIT;
1478 #endif
1480 Status=TRUE;
1481 DEBUG_MAKEDOSNODE(Printf("MakeDosNode: done\n"));
1485 else
1487 if (StartupName && ExecNameSize)
1489 char *StartupNamePtr;
1491 StartupNamePtr = &MyString[(1 + DosNameSize + BSTR_EXTRA + 3) & ~3];
1492 bstrcpy(StartupNamePtr, StartupName, ExecNameSize);
1493 MyDeviceNode->dn_Startup = MKBADDR(StartupNamePtr);
1495 Status=TRUE;
1499 if (Status)
1501 DEBUG_MAKEDOSNODE(Printf("MakeDosNode: done\n"));
1502 return MyDeviceNode;
1504 else
1506 DEBUG_MAKEDOSNODE(Printf("MakeDosNode: failed\n"));
1507 FreeVec(MyFileSysStartupMsg);
1508 FreeVec(MyDeviceNode);
1509 FreeVec(MyString);
1510 return NULL;
1516 /************************************************************************************************/
1517 /************************************************************************************************/
1520 LONG parsemountfile(IPTR *params, STRPTR buf, LONG size)
1522 STRPTR args[NUM_ARGS];
1523 LONG error;
1524 struct RDArgs rda;
1526 DEBUG_MOUNT(KPrintF("ParseMountFile:\n"));
1528 memset(&args, 0, sizeof(args));
1529 memset(&rda,0,sizeof(struct RDArgs));
1531 rda.RDA_Source.CS_Buffer = buf;
1532 rda.RDA_Source.CS_Length = size;
1533 rda.RDA_Source.CS_CurChr = 0;
1534 rda.RDA_Flags = RDAF_NOPROMPT;
1536 DEBUG_MOUNT(KPrintF("ReadArgs..\n%s\n\n", (IPTR)rda.RDA_Source.CS_Buffer));
1538 if ((error=ReadMountArgs(params,
1539 &rda))!=RETURN_OK)
1541 DEBUG_MOUNT(KPrintF("Parse: ReadArgs failed\n"));
1543 return error;
1546 /************************************************************************************************/
1547 /************************************************************************************************/
1550 LONG parsemountlist(IPTR *params,
1551 STRPTR name,
1552 STRPTR buf,
1553 LONG size)
1555 STRPTR args[NUM_ARGS];
1556 UBYTE buffer[1024];
1557 LONG error=RETURN_OK, res;
1558 STRPTR end = buf + size;
1559 STRPTR s2;
1560 char *ptr;
1561 struct RDArgs rda;
1563 DEBUG_MOUNT(KPrintF("ParseMountList: <%s>\n", (IPTR)name));
1565 memset(&args,0,sizeof(args));
1566 memset(&rda,0,sizeof(struct RDArgs));
1568 rda.RDA_Source.CS_Buffer = buf;
1569 rda.RDA_Source.CS_Length = end - buf;
1570 rda.RDA_Source.CS_CurChr = 0;
1571 rda.RDA_Flags = RDAF_NOPROMPT;
1573 while (rda.RDA_Source.CS_CurChr < rda.RDA_Source.CS_Length)
1575 res = ReadItem(buffer, sizeof(buffer), &rda.RDA_Source);
1577 DEBUG_MOUNT(KPrintF("ParseMountList: buffer <%s>\n", (IPTR)buffer));
1578 DEBUG_MOUNT(KPrintF("ParseMountList: ReadItem res %ld\n",res));
1580 if (res == ITEM_ERROR)
1582 return IoErr();
1585 if (res == ITEM_NOTHING &&
1586 rda.RDA_Source.CS_CurChr == rda.RDA_Source.CS_Length)
1588 return ERR_DEVICENOTFOUND;
1591 if (res != ITEM_QUOTED && res != ITEM_UNQUOTED)
1593 return 1;
1596 s2 = buffer;
1598 while (*s2)
1600 s2++;
1603 if (s2 == buffer || s2[-1] != ':')
1605 DEBUG_MOUNT(KPrintF("ParseMountList: failure\n"));
1606 return ERR_DEVICENOTFOUND;
1609 *--s2 = 0;
1611 if (!Strnicmp(name, buffer, s2 - buffer) &&
1612 (!name[s2 - buffer] || (name[s2 - buffer] == ':' || !name[s2 - buffer + 1])))
1614 DEBUG_MOUNT(KPrintF("ParseMountList: found\n"));
1616 /* Copy the string so we get proper case - Piru */
1617 memcpy(name, buffer, s2 - buffer);
1618 name[s2 - buffer] = '\0';
1620 ptr = name;
1621 while (*ptr)
1623 if (*ptr++ == ':')
1625 ptr[-1] = '\0';
1626 break;
1630 DEBUG_MOUNT(KPrintF("ReadArgs..\n%s\n\n", (IPTR)&rda.RDA_Source.CS_Buffer[rda.RDA_Source.CS_CurChr]));
1632 if ((error=ReadMountArgs(params,
1633 &rda))!=RETURN_OK)
1635 DEBUG_MOUNT(KPrintF("ParseMountList: ReadArgs failed\n"));
1636 //return IoErr();
1639 return error;
1642 while (rda.RDA_Source.CS_CurChr < rda.RDA_Source.CS_Length)
1644 if (rda.RDA_Source.CS_Buffer[rda.RDA_Source.CS_CurChr++] == '\n')
1646 DEBUG_MOUNT(KPrintF("ParseMountList: reach the end of the block\n"));
1647 break;
1652 DEBUG_MOUNT(KPrintF("ParseMountList: mount found nothing\n"));
1653 return ERR_DEVICENOTFOUND;
1656 /************************************************************************************************/
1657 /************************************************************************************************/
1659 static LONG checkmount(STRPTR name, IPTR *params)
1661 struct DosEnvec *vec;
1663 vec = (struct DosEnvec *)&params[4];
1665 params[1] = (IPTR) DeviceString;
1667 if (IsFilesystem && (!flagargs[ARG_DEVICE]
1668 || !flagargs[ARG_SURFACES] || !flagargs[ARG_BLOCKSPERTRACK]
1669 || !flagargs[ARG_LOWCYL] || !flagargs[ARG_HIGHCYL]))
1671 ShowError(name, "Could not find some of the following keywords:\n"
1672 " Surfaces, BlocksPerTrack, LowCyl, HighCyl, Device");
1673 return ERR_INVALIDKEYWORD;
1675 /* bootpri -129 shouldn't be started and not automatic mounted..whatever that means */
1676 if ((vec->de_BootPri < -129) || (vec->de_BootPri > 127))
1678 ShowError(name, "BootPri %ld is not allowed. Legal range is -128..127", vec->de_BootPri);
1679 return ERROR_BAD_NUMBER;
1682 if (flagargs[ARG_GLOBVEC])
1684 if ((GlobalVec != -1) && (GlobalVec != -2))
1686 ShowError(name, "Globvec %ld is not supported. Only -1 and -2 are supported here", GlobalVec);
1687 return ERROR_BAD_NUMBER;
1691 if (flagargs[ARG_STARTUP] && !StartupString)
1693 if (StartupValue >= 0x100)
1695 ShowError(name, "Startup uses too large numeric value %ld", StartupValue);
1696 return ERROR_BAD_NUMBER;
1700 return RETURN_OK;
1703 /************************************************************************************************/
1704 /************************************************************************************************/
1706 LONG mount(IPTR *params, STRPTR name)
1708 struct DosEnvec *vec;
1709 LONG error = RETURN_OK;
1710 struct DeviceNode *dn;
1711 STRPTR cp;
1713 for (cp = name; *cp != 0; cp++)
1714 *cp = ToUpper(*cp);
1716 DEBUG_MOUNT(KPrintF("MountDev: <%s>\n", name));
1718 if ((error=checkmount(name, params))!=RETURN_OK)
1720 DEBUG_MOUNT(KPrintF("MountDev: checkmount failed\n"));
1721 return error;
1724 vec = (struct DosEnvec *)&params[4];
1726 DEBUG_MOUNT(KPrintF("MountDev: DosName <%s>\n", (IPTR)name));
1727 DEBUG_MOUNT(KPrintF("MountDev: Filesystem <%s>\n", (IPTR)HandlerString + BSTR_OFFSET));
1728 DEBUG_MOUNT(KPrintF("MountDev: Device <%s>\n", (IPTR)DeviceString));
1729 DEBUG_MOUNT(KPrintF("MountDev: TableSize %ld\n",vec->de_TableSize));
1730 DEBUG_MOUNT(KPrintF("MountDev: SizeBlock %ld\n",vec->de_SizeBlock));
1731 DEBUG_MOUNT(KPrintF("MountDev: SecOrg %ld\n",vec->de_SecOrg));
1732 DEBUG_MOUNT(KPrintF("MountDev: Surfaces %ld\n",vec->de_Surfaces));
1733 DEBUG_MOUNT(KPrintF("MountDev: SectorsPerBlock %ld\n",vec->de_SectorPerBlock));
1734 DEBUG_MOUNT(KPrintF("MountDev: BlocksPerTrack %ld\n",vec->de_BlocksPerTrack));
1735 DEBUG_MOUNT(KPrintF("MountDev: Reserved %ld\n",vec->de_Reserved));
1736 DEBUG_MOUNT(KPrintF("MountDev: PreAlloc %ld\n",vec->de_PreAlloc));
1737 DEBUG_MOUNT(KPrintF("MountDev: Interleave %ld\n",vec->de_Interleave));
1738 DEBUG_MOUNT(KPrintF("MountDev: LowCyl %ld\n",vec->de_LowCyl));
1739 DEBUG_MOUNT(KPrintF("MountDev: UpperCyl %ld\n",vec->de_HighCyl));
1740 DEBUG_MOUNT(KPrintF("MountDev: NumBuffers %ld\n",vec->de_NumBuffers));
1741 DEBUG_MOUNT(if (vec->de_TableSize >= DE_BUFMEMTYPE))
1742 DEBUG_MOUNT(KPrintF("MountDev: BufMemType 0x%lx\n",vec->de_BufMemType));
1743 DEBUG_MOUNT(KPrintF("MountDev: MaxTransfer 0x%lx\n",vec->de_MaxTransfer));
1744 DEBUG_MOUNT(if (vec->de_TableSize >= DE_MASK))
1745 DEBUG_MOUNT(KPrintF("MountDev: Mask 0x%lx\n",vec->de_Mask));
1746 DEBUG_MOUNT(if (vec->de_TableSize >= DE_BOOTPRI))
1747 DEBUG_MOUNT(KPrintF("MountDev: BootPri %ld\n",vec->de_BootPri));
1748 DEBUG_MOUNT(if (vec->de_TableSize >= DE_DOSTYPE))
1749 DEBUG_MOUNT(KPrintF("MountDev: DosType 0x%lx\n",vec->de_DosType));
1750 DEBUG_MOUNT(if (vec->de_TableSize >= DE_BAUD))
1751 DEBUG_MOUNT(KPrintF("MountDev: Baud %ld\n",vec->de_Baud));
1752 DEBUG_MOUNT(if (vec->de_TableSize >= DE_CONTROL))
1753 DEBUG_MOUNT(KPrintF("MountDev: Control 0x%lx\n",vec->de_Control));
1754 DEBUG_MOUNT(if (vec->de_TableSize >= DE_BOOTBLOCKS))
1755 DEBUG_MOUNT(KPrintF("MountDev: BootBlocks %ld\n",vec->de_BootBlocks));
1757 if ((dn=MyMakeDosNode(name, IsEHandler ? params : NULL, StartupString)))
1759 DEBUG_MOUNT(KPrintF("MountDev: DeviceNode 0x%lx\n", (IPTR)dn));
1761 dn->dn_StackSize = StackSize;
1762 dn->dn_Priority = Priority;
1763 dn->dn_GlobalVec = (BPTR)GlobalVec;
1765 if (!IsEHandler && !StartupString)
1767 dn->dn_Startup = (BPTR)(SIPTR)StartupValue;
1770 if (IsFilesystem && ((ForceLoad==0) || (HandlerString==NULL)))
1772 DEBUG_MOUNT(KPrintF("MountDev: patchdosnode\n"));
1773 PatchDosNode(dn,vec->de_DosType);
1776 if (ForceLoad || dn->dn_SegList==BNULL)
1778 DEBUG_MOUNT(KPrintF("MountDev: Load Handler\n"));
1779 dn->dn_Handler = MKBADDR(HandlerString);
1781 else
1784 * We don't need the HandlerString anymore...free it
1786 if (HandlerString)
1788 FreeVec(HandlerString);
1789 HandlerString = NULL;
1792 DEBUG_MOUNT(KPrintF("MountDev: Name %b\n",dn->dn_Name));
1793 DEBUG_MOUNT(KPrintF("MountDev: Handler 0x%lx <%b>\n",dn->dn_Handler,dn->dn_Handler));
1794 DEBUG_MOUNT(KPrintF("MountDev: SegList 0x%lx\n",dn->dn_SegList));
1795 DEBUG_MOUNT(KPrintF("MountDev: StackSize %ld\n",dn->dn_StackSize));
1796 DEBUG_MOUNT(KPrintF("MountDev: Priority %ld\n",dn->dn_Priority));
1797 DEBUG_MOUNT(KPrintF(!IsEHandler && StartupString ? "MountDev: Startup <%b>\n" : "MountDev: Startup 0x%lx\n", dn->dn_Startup));
1798 DEBUG_MOUNT(KPrintF("MountDev: GlobalVec %ld\n",dn->dn_GlobalVec));
1800 if (dn->dn_SegList || dn->dn_Handler)
1802 if (AddDosEntry((struct DosList *)dn))
1804 DEBUG_MOUNT(KPrintF("MountDev: AddDosEntry worked\n"));
1806 * Don't free these anymore as they belong to the dosnode
1808 HandlerString = NULL;
1809 if (IsEHandler)
1811 UnitString = NULL;
1812 FlagsString = NULL;
1813 ControlString = NULL;
1815 if (Activate)
1817 strcat(name, ":");
1818 DEBUG_MOUNT(KPrintF("Activating \"%s\"\n", (IPTR)name));
1819 DeviceProc(name);
1821 error = 0;
1823 else
1825 DEBUG_MOUNT(KPrintF("MountDev: AddDosEntry failed\n"));
1826 error = ERROR_INVALID_RESIDENT_LIBRARY;
1827 if (HandlerString)
1829 FreeVec(HandlerString);
1833 else
1835 DEBUG_MOUNT(KPrintF("MountDev: no loadseg and no handler specified\n"));
1836 error = ERROR_OBJECT_NOT_FOUND;
1839 else
1841 error = ERROR_NO_FREE_STORE;
1844 return error;
1847 void ShowError(STRPTR name, const char *s, ...)
1849 AROS_SLOWSTACKFORMAT_PRE(s);
1851 NewRawDoFmt("Error mounting '%s'", RAWFMTFUNC_STRING, txtBuf, name);
1853 if (IsCli)
1855 PutStr(txtBuf);
1856 PutStr(": ");
1857 VPrintf(s, AROS_SLOWSTACKFORMAT_ARG(s));
1858 PutStr("\n");
1860 else
1862 struct EasyStruct es =
1864 sizeof(struct EasyStruct),
1866 txtBuf,
1868 "OK"
1871 IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library", 36);
1872 if (IntuitionBase)
1874 EasyRequestArgs(NULL, &es, NULL, AROS_SLOWSTACKFORMAT_ARG(s));
1875 CloseLibrary((struct Library *)IntuitionBase);
1879 AROS_SLOWSTACKFORMAT_POST(s);
1882 void ShowFault(LONG code, const 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);