grub2: bring back build of aros-side grub2 tools
[AROS.git] / workbench / c / Mount.c
blob59d550edd84a74a15d6e83be017908f77dea7a67
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 __attribute__((used));
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 ShowError(STRPTR name, const char *s, ...);
227 void ShowFault(LONG code, const char *s, ...);
229 struct DosLibrary *DOSBase;
230 struct IntuitionBase *IntuitionBase;
231 UtilityBase_t UtilityBase;
232 struct Process *MyProcess;
234 ULONG StartupValue;
235 char *StartupString = NULL;
236 char *ControlString = NULL;
237 char *UnitString = NULL;
238 char *FlagsString = NULL;
239 ULONG StackSize;
240 ULONG Priority;
241 ULONG Activate;
242 SIPTR GlobalVec;
243 ULONG ForceLoad;
244 char *HandlerString;
245 char *DeviceString;
246 BOOL IsEHandler, IsFilesystem;
247 BOOL IsCli;
248 BOOL flagargs[NUM_ARGS];
249 char txtBuf[256];
250 extern struct WBStartup *_WBenchMsg;
252 int main(void)
254 IPTR args[2];
255 IPTR *params;
256 LONG error = RETURN_FAIL;
257 struct RDArgs *rda;
258 char dirname[512];
260 if ((DOSBase = (struct DosLibrary *)OpenLibrary("dos.library",37))!=0)
262 if ((UtilityBase = (UtilityBase_t)OpenLibrary("utility.library",37)))
264 memset(&flagargs, 0, sizeof(flagargs));
265 IsEHandler = TRUE;
266 IsFilesystem = TRUE;
267 if (!_WBenchMsg)
269 memset(args,0,sizeof(args));
270 if ((rda = ReadArgs("DEVICE/M,FROM/K", args, NULL)))
272 STRPTR *MyDevPtr;
273 int len;
275 error = 0;
277 MyDevPtr =(STRPTR *)args[0];
278 if (MyDevPtr)
280 while (*MyDevPtr)
282 DEBUG_MOUNT(KPrintF("Mount: Current DevName <%s>\n",
283 (IPTR)*MyDevPtr));
285 if ((params = AllocVec(PARAMSLENGTH, MEMF_PUBLIC | MEMF_CLEAR)))
287 StackSize = 8192;
288 Priority = 5;
289 GlobalVec = -1;
290 HandlerString = NULL;
291 DeviceString = NULL;
292 StartupString = NULL;
294 len = strlen(*MyDevPtr);
295 if ((*MyDevPtr)[len-1] == ':')
297 /* search for a devicename */
298 DEBUG_MOUNT(KPrintF("Mount: search for devname <%s>\n",
299 (IPTR)*MyDevPtr));
301 strcpy(dirname, *MyDevPtr);
302 dirname[len-1] = '\0';
304 if ((error=CheckDevice(dirname))!=RETURN_OK)
306 DEBUG_MOUNT(KPrintF("Mount: is already mounted..stop\n"));
308 else
310 if (args[1])
312 error=readmountlist(params, dirname, (STRPTR)(args[1]));
313 DEBUG_MOUNT(KPrintF("Mount: readmountlist(%s) returned %ld\n", args[1], error));
315 else
317 char **SearchPtr;
318 ULONG slen;
320 DEBUG_MOUNT(KPrintF("Mount: search device definition <%s>\n",
321 (IPTR)*MyDevPtr));
322 for (SearchPtr=(char**) SearchTable;
323 *SearchPtr;
324 SearchPtr++)
326 if(SetSignal(0L,SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C)
328 error = RETURN_FAIL;
329 SetIoErr(ERROR_BREAK);
330 break;
333 slen = strlen(*SearchPtr);
334 strcpy(dirname, *SearchPtr);
335 dirname[slen] = '\0';
336 strcat(dirname, *MyDevPtr);
337 dirname[slen+len-1] = '\0';
338 DEBUG_MOUNT(KPrintF("Mount: try File <%s>\n", (IPTR)dirname));
340 error=readmountfile(params, dirname);
341 DEBUG_MOUNT(KPrintF("Mount: readmountfile returned %ld\n", error));
342 if (error != ERROR_OBJECT_NOT_FOUND)
343 break;
345 if (error == ERROR_OBJECT_NOT_FOUND)
347 DEBUG_MOUNT(KPrintF("Mount: try from mountlist\n"));
348 dirname[0] = '\0';
349 strcat(dirname, *MyDevPtr);
350 dirname[len-1] = '\0';
351 error=readmountlist(params, dirname, MOUNTLIST);
352 DEBUG_MOUNT(KPrintF("Mount: readmountlist(default) returned %ld\n", error));
357 else
359 /* search for a filename */
361 LONG err;
363 UBYTE stack_ap[sizeof(struct AnchorPath) + 3];
364 struct AnchorPath *MyAp = (struct AnchorPath *) (((IPTR) stack_ap + 3) & ~3);
366 DEBUG_MOUNT(KPrintF("Mount: search for mountfile <%s>\n", *MyDevPtr));
368 memset(MyAp,0,sizeof(struct AnchorPath));
370 dirname[0] = '\0';
371 for (err = MatchFirst(*MyDevPtr,MyAp);
372 err == 0;
373 err = MatchNext(MyAp))
375 if (MyAp->ap_Flags & APF_DirChanged)
377 DEBUG_MOUNT(KPrintF("Mount: Changed directories...\n"));
380 DEBUG_MOUNT(KPrintF("Mount: NameFromLock(0x%p)...\n", MyAp->ap_Current->an_Lock));
381 if (NameFromLock(MyAp->ap_Current->an_Lock,
382 dirname,
383 sizeof(dirname)) == FALSE)
385 ShowFault(IoErr(), "Error on NameFromLock");
386 break;
389 DEBUG_MOUNT(KPrintF("Mount: ...Dir name: %s\n", dirname));
390 if (AddPart(dirname,
391 &(MyAp->ap_Info.fib_FileName[0]),
392 sizeof(dirname)) == FALSE)
394 ShowFault(IoErr(), "Error on AddPart");
395 break;
397 if (MyAp->ap_Info.fib_DirEntryType > 0)
399 if (MyAp->ap_Flags & APF_DIDDIR)
401 DEBUG_MOUNT(KPrintF("Mount: Ascending from directory %s\n",
402 (IPTR)dirname));
404 else
406 DEBUG_MOUNT(KPrintF("Mount: The next dir is ... %s\n", (IPTR)dirname));
408 /* clear the completed directory flag */
409 MyAp->ap_Flags &= ~APF_DIDDIR;
412 else
414 /* Here is code for handling each particular file */
416 DEBUG_MOUNT(KPrintF("Mount: try File <%s>\n",
417 (IPTR)dirname));
419 memset(&flagargs, 0, sizeof(flagargs));
420 IsEHandler = TRUE;
421 IsFilesystem = TRUE;
422 error=readmountfile(params, dirname);
423 DEBUG_MOUNT(KPrintF("Mount: readmount file returned %ld\n", error));
426 /* This absolutely, positively must be called, all of the time. */
427 MatchEnd(MyAp);
429 if (err == ERROR_NO_MORE_ENTRIES)
431 SetIoErr(0);
433 else
435 /* if it was real error promote it - Piru */
436 error = err;
439 FreeVec(params);
441 else
443 error = ERROR_NO_FREE_STORE;
444 break;
446 MyDevPtr++;
449 FreeArgs(rda);
450 } /* if (rda != NULL) */
451 else
453 error = IoErr();
456 if (error && error != ERROR_NO_MORE_ENTRIES && error < ERR_SPECIAL)
458 ShowFault(error, "ERROR");
460 error = RETURN_FAIL;
462 else
464 error = error < ERR_SPECIAL ? RETURN_OK : RETURN_FAIL;
468 else
470 /* wb startup */
471 if (_WBenchMsg->sm_NumArgs >= 2)
473 if ((params = AllocVec(PARAMSLENGTH,
474 MEMF_PUBLIC | MEMF_CLEAR)))
476 int i;
478 for (i = 1; i < _WBenchMsg->sm_NumArgs; i++)
480 BPTR olddir;
482 DEBUG_MOUNT(KPrintF("Mount: try File <%s>\n",
483 (IPTR) _WBenchMsg->sm_ArgList[i].wa_Name));
485 olddir = CurrentDir(_WBenchMsg->sm_ArgList[i].wa_Lock);
487 error=readmountfile(params, _WBenchMsg->sm_ArgList[i].wa_Name);
488 DEBUG_MOUNT(KPrintF("Mount: readmountfile returned %ld\n", error));
489 if (error && error != ERROR_NO_MORE_ENTRIES && error < ERR_SPECIAL)
490 ShowFault(error, "ERROR");
492 (void) CurrentDir(olddir);
495 FreeVec(params);
497 else
499 error = ERROR_NO_FREE_STORE;
503 CloseLibrary((struct Library *)UtilityBase);
505 CloseLibrary((struct Library *)DOSBase);
508 return error;
511 /************************************************************************************************/
512 /************************************************************************************************/
513 ULONG CheckDevice(char *name)
515 struct DosList *dl;
516 ULONG Status;
518 DEBUG_CHECK(KPrintF("CheckDevice: <%s>\n",
519 name));
521 dl = LockDosList(LDF_DEVICES | LDF_VOLUMES | LDF_ASSIGNS | LDF_READ);
522 if ((dl = FindDosEntry(dl,name,LDF_DEVICES | LDF_VOLUMES | LDF_ASSIGNS)))
524 Status = ERROR_OBJECT_EXISTS;
526 else
528 Status = 0;
530 UnLockDosList(LDF_DEVICES | LDF_VOLUMES | LDF_ASSIGNS | LDF_READ);
532 DEBUG_CHECK(KPrintF("CheckDevice: object %s exist\n", Status ? "does" : "doesn't"));
534 return Status;
537 /************************************************************************************************/
538 /************************************************************************************************/
540 void InitParams(IPTR *params)
542 struct DosEnvec *vec;
544 memset(params,0, PARAMSLENGTH);
546 vec = (struct DosEnvec *)&params[4];
548 vec->de_TableSize = DE_BOOTBLOCKS;
549 vec->de_SizeBlock = 512 >> 2;
550 vec->de_Surfaces = 2;
551 vec->de_SectorPerBlock = 1;
552 vec->de_BlocksPerTrack = 11;
553 vec->de_Reserved = 2;
555 /* memset above
556 vec->de_SecOrg = 0;
557 vec->de_BootBlocks = 0;
558 vec->de_BootPri = 0;
559 vec->de_PreAlloc = 0;
560 vec->de_Interleave = 0;
561 vec->de_LowCyl = 0;
564 vec->de_HighCyl = 79;
565 vec->de_NumBuffers = 20; /* On AmigaOS 3.9 it's 5 */
566 vec->de_BufMemType = 3;
567 vec->de_Baud = 1200;
568 vec->de_MaxTransfer = 0x7fffffff;
569 vec->de_Mask = -2; /* 0xfffffffe, sign-extended on 64 bits */
570 vec->de_DosType = ID_DOS_DISK;
572 StackSize = 8192;
573 Priority = 5;
574 GlobalVec = -1;
575 HandlerString = NULL;
576 DeviceString = NULL;
577 StartupString = NULL;
580 void FreeStuff(void)
582 if (UnitString)
584 FreeVec(UnitString);
585 UnitString = NULL;
587 if (FlagsString)
589 FreeVec(FlagsString);
590 FlagsString = NULL;
592 if (ControlString)
594 FreeVec(ControlString);
595 ControlString = NULL;
597 if (HandlerString)
599 FreeVec(HandlerString);
600 HandlerString = NULL;
602 if (DeviceString)
604 FreeVec(DeviceString);
605 DeviceString = NULL;
607 if (StartupString)
609 FreeVec(StartupString);
610 StartupString = NULL;
614 /************************************************************************************************/
615 /************************************************************************************************/
617 static long GetValue(IPTR bufp, char **end)
619 char *buf = (char *)bufp;
620 char *c = buf;
622 if ((c[0]=='-') || (c[0]=='+'))
623 c++;
625 * If it's a hexadecimal number, use strtoul(), otherwise we can lose our 31st bit.
626 * Should be okay since i've never seen any usage of minus sign with hexadecimals.
627 * For decimals we do support sign, because it makes it very convenient to use negative
628 * masks for sign extension on 64 bits.
630 if ((c[0] == '0') && (((c[1])=='x') || (c[1])=='X'))
631 return strtoul(buf, end, 16);
632 else
633 return strtol(buf, end, 10);
636 /************************************************************************************************/
637 /************************************************************************************************/
639 ULONG ReadMountArgs(IPTR *params, struct RDArgs *rda)
641 struct DosEnvec *vec;
642 IPTR args[NUM_ARGS];
643 struct RDArgs *MyRDA;
644 ULONG result = RETURN_OK;
645 int i;
646 char *s = NULL;
648 DEBUG_MOUNT(KPrintF("ReadMountArgs:\n%s\n\n", (IPTR)&rda->RDA_Source.CS_Buffer[rda->RDA_Source.CS_CurChr]));
650 memset(&args, 0, sizeof(args));
652 if (!(MyRDA = ReadArgs((STRPTR)options, &args[0], rda)))
654 DEBUG_MOUNT(KPrintF("ReadMountArgs: ReadArgs failed, error %u\n", IoErr()));
655 return ERR_INVALIDKEYWORD;
658 for (i = 0; i < NUM_ARGS; i++)
660 if (args[i] != 0)
661 flagargs[i] = TRUE;
664 if (args[ARG_HANDLER] != 0)
666 s = (STRPTR)args[ARG_HANDLER];
667 IsEHandler = FALSE;
668 IsFilesystem = FALSE;
670 else if (args[ARG_EHANDLER] != 0)
672 s = (STRPTR)args[ARG_EHANDLER];
673 IsEHandler = TRUE;
674 IsFilesystem = FALSE;
676 else if (args[ARG_FILESYSTEM] != 0)
678 s = (STRPTR)args[ARG_FILESYSTEM];
679 IsEHandler = TRUE;
680 IsFilesystem = TRUE;
681 } else
682 s = NULL;
684 if (s)
686 int len;
688 DEBUG_MOUNT(KPrintF("ReadMountArgs: Handler <%s>\n",s));
689 len = strlen(s);
691 if (HandlerString)
692 FreeVec(HandlerString);
694 if ((HandlerString = AllocVec(len + BSTR_EXTRA, MEMF_PUBLIC|MEMF_CLEAR)))
695 bstrcpy(HandlerString, s, len);
698 if (args[ARG_STACKSIZE] != 0)
699 StackSize = GetValue(args[ARG_STACKSIZE], NULL);
701 if (args[ARG_PRIORITY] != 0)
702 Priority = GetValue(args[ARG_PRIORITY], NULL);
704 if (args[ARG_GLOBVEC] != 0)
705 GlobalVec = GetValue(args[ARG_GLOBVEC], NULL);
707 if (args[ARG_FORCELOAD] != 0)
708 ForceLoad = GetValue(args[ARG_FORCELOAD], NULL);
710 if (args[ARG_ACTIVATE] != 0)
711 Activate = GetValue(args[ARG_ACTIVATE], NULL);
713 if (args[ARG_DEVICE] != 0)
715 int len;
717 DEBUG_MOUNT(KPrintF("ReadMountArgs: Device <%s>\n",(STRPTR)args[ARG_DEVICE]));
719 len = strlen((STRPTR)args[ARG_DEVICE]);
721 if (DeviceString)
722 FreeVec(DeviceString);
724 if ((DeviceString = AllocVec(len+1,MEMF_PUBLIC|MEMF_CLEAR)))
725 strcpy(DeviceString, (STRPTR)args[ARG_DEVICE]);
728 if (args[ARG_UNIT] != 0)
730 if (UnitString)
732 FreeVec(UnitString);
733 UnitString = NULL;
735 params[2] = GetValue(args[ARG_UNIT], &s);
736 if (*s)
738 int len = strlen((STRPTR)args[ARG_UNIT]);
740 DEBUG_MOUNT(KPrintF("ReadMountArgs: len %ld\n",len));
742 if ((UnitString = AllocVec(len + 1, MEMF_PUBLIC|MEMF_CLEAR)))
744 strcpy(UnitString, (STRPTR)args[ARG_UNIT]);
745 params[2] = (IPTR)UnitString;
746 DEBUG_MOUNT(KPrintF("ReadMountArgs: Unit String <%s>\n", (STRPTR)params[2]));
748 else
750 result = ERROR_NO_FREE_STORE;
751 goto error;
754 else
755 DEBUG_MOUNT(KPrintF("ReadMountArgs: Unit Value %ld\n",params[2]));
758 if (args[ARG_FLAGS] != 0)
760 DEBUG_MOUNT(KPrintF("ReadMountArgs: Flags <%s>\n",(STRPTR)args[ARG_FLAGS]));
761 if (FlagsString)
763 FreeVec(FlagsString);
764 FlagsString = NULL;
767 params[3] = GetValue(args[ARG_FLAGS], &s);
768 if (*s)
770 int len = strlen((STRPTR)args[ARG_FLAGS]);
772 DEBUG_MOUNT(KPrintF("ReadMountArgs: len %ld\n",len));
774 if ((FlagsString = AllocVec(len + 1, MEMF_PUBLIC|MEMF_CLEAR)))
776 strcpy(FlagsString, (STRPTR)args[ARG_FLAGS]);
777 params[3] = (IPTR) FlagsString;
778 DEBUG_MOUNT(KPrintF("ReadMountArgs: Flags String <%s>\n",(STRPTR)params[3]));
780 else
782 result = ERROR_NO_FREE_STORE;
783 goto error;
786 else
787 DEBUG_MOUNT(KPrintF("ReadMountArgs: Flag Value %ld\n",params[3]));
790 vec = (struct DosEnvec *)&params[4];
792 if (args[ARG_BLOCKSIZE] != 0)
793 vec->de_SizeBlock = GetValue(args[ARG_BLOCKSIZE], NULL) >> 2;
795 if (args[ARG_SURFACES] != 0)
796 vec->de_Surfaces = GetValue(args[ARG_SURFACES], NULL);
798 if (args[ARG_SECTORSPERBLOCK] != 0)
799 vec->de_SectorPerBlock = GetValue(args[ARG_SECTORSPERBLOCK], NULL);
801 if (args[ARG_BLOCKSPERTRACK] != 0)
802 vec->de_BlocksPerTrack = GetValue(args[ARG_BLOCKSPERTRACK], NULL);
804 if (args[ARG_RESERVED] != 0)
805 vec->de_Reserved = GetValue(args[ARG_RESERVED], NULL);
807 if (args[ARG_PREALLOC] != 0)
808 vec->de_PreAlloc = GetValue(args[ARG_PREALLOC], NULL);
810 if (args[ARG_INTERLEAVE] != 0)
811 vec->de_Interleave = GetValue(args[ARG_INTERLEAVE], NULL);
813 if (args[ARG_LOWCYL] != 0)
814 vec->de_LowCyl = GetValue(args[ARG_LOWCYL], NULL);
816 if (args[ARG_HIGHCYL] != 0)
817 vec->de_HighCyl = GetValue(args[ARG_HIGHCYL], NULL);
819 if (args[ARG_BUFFERS] != 0)
820 vec->de_NumBuffers = GetValue(args[ARG_BUFFERS], NULL);
822 if (args[ARG_BUFMEMTYPE] != 0)
823 vec->de_BufMemType = GetValue(args[ARG_BUFMEMTYPE], NULL);
825 if (args[ARG_BOOTPRI] != 0)
826 vec->de_BootPri = GetValue(args[ARG_BOOTPRI], NULL);
828 if (args[ARG_BAUD] != 0)
829 vec->de_Baud = GetValue(args[ARG_BAUD], NULL);
831 if (args[ARG_MAXTRANSFER] != 0)
832 vec->de_MaxTransfer = GetValue(args[ARG_MAXTRANSFER], NULL);
834 if (args[ARG_MASK] != 0)
835 vec->de_Mask = GetValue(args[ARG_MASK], NULL);
837 if (args[ARG_DOSTYPE] != 0)
838 vec->de_DosType = (IPTR)GetValue(args[ARG_DOSTYPE], NULL);
840 if (args[ARG_CONTROL] != 0)
842 int len;
844 DEBUG_MOUNT(KPrintF("ReadMountArgs: Control <%s>\n",args[ARG_CONTROL]));
845 if (ControlString)
847 FreeVec(ControlString);
848 ControlString = NULL;
851 len = strlen((STRPTR)args[ARG_CONTROL]);
852 if (len < 0x100)
854 if ((ControlString=AllocVec(len + BSTR_EXTRA, MEMF_PUBLIC|MEMF_CLEAR)))
856 bstrcpy(ControlString, (STRPTR)args[ARG_CONTROL], len);
857 vec->de_Control = (IPTR)MKBADDR(ControlString);
859 else
861 result = ERROR_NO_FREE_STORE;
862 goto error;
865 else
867 result = ERROR_LINE_TOO_LONG;
868 SetIoErr(result);
869 goto error;
873 if (args[ARG_STARTUP] != 0)
875 DEBUG_MOUNT(KPrintF("ReadMountArgs: Startup <%s>\n",args[ARG_STARTUP]));
876 if (StartupString)
878 FreeVec(StartupString);
879 StartupString = NULL;
882 StartupValue = GetValue(args[ARG_STARTUP], &s);
883 if (*s)
885 int len = strlen((STRPTR)args[ARG_STARTUP]);
887 DEBUG_MOUNT(KPrintF("ReadMountArgs: len %ld\n",len));
889 if ((StartupString = AllocVec(len + 1, MEMF_PUBLIC|MEMF_CLEAR)))
890 strcpy(StartupString,(STRPTR)args[ARG_STARTUP]);
891 else
893 result = ERROR_NO_FREE_STORE;
894 goto error;
899 error:
900 FreeArgs(MyRDA);
901 return result;
904 /************************************************************************************************/
905 /************************************************************************************************/
907 ULONG readmountlist(IPTR *params,
908 STRPTR name,
909 char *mountlist)
911 STRPTR MountListBuf;
912 LONG MountListBufSize;
913 ULONG error;
915 DEBUG_MOUNT(KPrintF("ReadMountList: find <%s> in mountlist <%s>\n",
916 name,
917 mountlist));
919 error = readfile(mountlist,
920 &MountListBuf,
921 &MountListBufSize);
922 if (error==RETURN_OK)
924 preparefile(MountListBuf,
925 MountListBufSize);
928 InitParams(params);
930 if ((error=parsemountlist(params,
931 name,
932 MountListBuf,
933 MountListBufSize))==RETURN_OK)
935 if ((error = mount(params,name))!=RETURN_OK)
937 DEBUG_MOUNT(KPrintF("ReadMountList: mount failed error %ld\n",
938 error));
941 else
943 switch (error)
945 case ERR_DEVICENOTFOUND:
946 case ERR_INVALIDKEYWORD:
947 ShowError(name, "Device not found in file '%s'", name, mountlist);
948 break;
952 FreeStuff();
953 FreeVec(MountListBuf);
955 return error;
958 /************************************************************************************************/
959 /************************************************************************************************/
961 ULONG readmountfile(IPTR *params, STRPTR filename)
963 struct Library *IconBase;
964 struct DiskObject *diskobj;
965 char **myargv;
966 STRPTR MountListBuf;
967 LONG MountListBufSize;
968 struct RDArgs rda;
969 ULONG error = RETURN_FAIL;
970 UBYTE *nameptr;
971 int toollen;
972 BOOL mountinfo=FALSE;
973 char name[256+1];
975 DEBUG_MOUNT(KPrintF("ReadMountFile: <%s>\n", (IPTR)filename));
978 struct Process *me = (APTR) FindTask(NULL);
979 APTR oldwinptr;
980 BPTR lock;
982 name[0] = '\0';
984 oldwinptr = me->pr_WindowPtr;
985 me->pr_WindowPtr = (APTR) -1;
986 lock = Lock(filename, SHARED_LOCK);
987 if (lock)
989 struct FileInfoBlock *fib = (struct FileInfoBlock*)AllocDosObject(DOS_FIB, NULL);
990 if (fib)
992 if (Examine(lock, fib))
994 nameptr = fib->fib_FileName;
995 memmove(name, nameptr, strlen(nameptr) + 1);
997 FreeDosObject(DOS_FIB, fib);
999 UnLock(lock);
1001 me->pr_WindowPtr = oldwinptr;
1003 if (name[0] == '\0')
1005 nameptr = FilePart(filename);
1006 strcpy(name,
1007 nameptr);
1011 DEBUG_MOUNT(KPrintF("ReadMountFile: mount <%s>\n", (IPTR)name));
1013 if ((error=CheckDevice(name))!=RETURN_OK)
1015 return error;
1018 InitParams(params);
1020 DEBUG_MOUNT(KPrintF("ReadMountFile: readfile\n"));
1022 error = readfile(filename,
1023 &MountListBuf,
1024 &MountListBufSize);
1025 if (error==RETURN_OK)
1027 DEBUG_MOUNT(KPrintF("ReadMountFile: preparsefile\n"));
1028 preparefile(MountListBuf, MountListBufSize);
1031 DEBUG_MOUNT(KPrintF("ReadMountFile: parsemountfile\n"));
1032 if ((error = parsemountfile(params, MountListBuf, MountListBufSize))!=RETURN_OK)
1034 DEBUG_MOUNT(KPrintF("ReadMountFile: parsemountfile error %ld\n", error));
1035 ShowFault(IoErr(), "Mountfile '%s' is invalid", filename);
1037 else
1039 mountinfo = TRUE;
1041 FreeVec(MountListBuf);
1043 else
1045 DEBUG_MOUNT(KPrintF("ReadMountFile: mountfile not found..search for <%s.info>\n",
1046 filename));
1049 if ((error==RETURN_OK) ||
1050 (error==ERROR_OBJECT_NOT_FOUND))
1052 DEBUG_MOUNT(KPrintF("ReadMountFile: look for icon '%s'\n", filename));
1054 if ((IconBase = OpenLibrary("icon.library", 37)))
1056 if ((diskobj = GetDiskObject(filename)))
1058 myargv =(char**) diskobj->do_ToolTypes;
1059 if (myargv)
1061 while (*myargv)
1063 char *ToolPtr;
1064 ToolPtr = *myargv;
1065 DEBUG_MOUNT(KPrintF("ReadMountFile: ToolType <%s>\n",
1066 ToolPtr));
1067 if ((ToolPtr[0] != '(') && (ToolPtr[0] != '*') &&
1068 !((ToolPtr[0] == 'I') && (ToolPtr[1] == 'M') && (ToolPtr[3] == '=')))
1070 char *ToolString;
1071 toollen = strlen(ToolPtr);
1072 if ((ToolString = AllocVec(toollen + 2,MEMF_ANY)))
1074 memcpy(ToolString,ToolPtr,toollen);
1075 ToolString[toollen] = '\n';
1076 ToolString[toollen+1] = '\0';
1077 memset(&rda,0,sizeof(struct RDArgs));
1078 rda.RDA_Source.CS_Buffer = ToolString;
1079 rda.RDA_Source.CS_Length = toollen+1;
1080 rda.RDA_Source.CS_CurChr = 0;
1081 rda.RDA_Flags = RDAF_NOPROMPT;
1082 if ((ReadMountArgs(params, &rda)==RETURN_OK))
1084 mountinfo = TRUE;
1086 else
1088 DEBUG_MOUNT(KPrintF("ReadMountFile: ReadArgs failed error %ld\n",
1089 error));
1091 FreeVec(ToolString);
1093 else
1095 error = ERROR_NO_FREE_STORE;
1096 break;
1099 else
1101 DEBUG_MOUNT(KPrintF("ReadMountFile: skipped\n"));
1103 myargv++;
1106 FreeDiskObject(diskobj);
1108 else
1111 CloseLibrary(IconBase);
1115 if (mountinfo)
1117 DEBUG_MOUNT(KPrintF("ReadMountFile: mount information exists\n"));
1119 if ((error = mount(params,name)) != RETURN_OK)
1121 DEBUG_MOUNT(KPrintF("ReadMountFile: mount failed error %ld\n",
1122 error));
1126 FreeStuff();
1128 return error;
1131 /************************************************************************************************/
1132 /************************************************************************************************/
1135 LONG readfile(STRPTR name, STRPTR *mem, LONG *size)
1137 BPTR ml;
1138 ULONG rest,sub;
1139 STRPTR buf;
1140 struct Process *me = (struct Process *) FindTask(NULL);
1141 APTR oldwinptr;
1143 oldwinptr = me->pr_WindowPtr;
1144 me->pr_WindowPtr = (APTR) -1;
1145 ml = Open(name, MODE_OLDFILE);
1146 me->pr_WindowPtr = oldwinptr;
1148 DEBUG_MOUNT(KPrintF("ReadFile: <%s>\n", (IPTR) name));
1150 if (ml)
1152 if (Seek(ml, 0, OFFSET_END) != -1)
1154 *size = Seek(ml, 0, OFFSET_BEGINNING);
1156 if (*size != -1)
1158 *mem = (STRPTR)AllocVec(*size+2, MEMF_ANY);
1160 if (*mem)
1162 rest = *size;
1163 buf = *mem;
1165 for (;;)
1167 if (!rest)
1169 Close(ml);
1171 *buf++ = '\n';
1172 *buf = '\0';
1174 return 0;
1177 sub = Read(ml, buf, rest);
1179 if (sub == -1)
1181 break;
1184 rest -= sub;
1185 buf += sub;
1188 FreeVec(*mem);
1190 else
1192 SetIoErr(ERROR_NO_FREE_STORE);
1197 Close(ml);
1200 DEBUG_MOUNT(KPrintF("ReadFile: error %ld\n", IoErr()));
1201 return IoErr();
1204 /************************************************************************************************/
1205 /************************************************************************************************/
1208 void preparefile(STRPTR buf, LONG size)
1210 STRPTR end = buf + size;
1212 while (buf < end)
1214 /* Convert comments to spaces */
1215 if (buf + 1 < end && *buf == '/' && buf[1] == '*')
1217 *buf++ = ' ';
1218 *buf++ = ' ';
1220 while (buf < end)
1222 if (*buf == '*')
1224 *buf++ = ' ';
1226 if (buf >= end)
1228 break;
1231 if (*buf == '/')
1233 *buf++ = ' ';
1234 break;
1237 else
1239 *buf++=' ';
1243 continue;
1246 /* Skip strings */
1247 if (*buf=='\"')
1250 * skip first
1252 buf++;
1253 while (buf < end && *buf != '\"')
1255 buf++;
1258 * skip last "
1260 buf++;
1261 continue;
1264 /* Convert '\n' and ';' to spaces */
1265 if (*buf == '\n' || *buf == ';')
1267 *buf++ = ' ';
1268 continue;
1271 /* Convert '#' to \n */
1272 if (*buf == '#')
1274 *buf++ = '\n';
1275 continue;
1278 /* Skip all other characters */
1279 buf++;
1283 /************************************************************************************************/
1284 /************************************************************************************************/
1286 struct FileSysEntry *GetFileSysEntry(ULONG DosType)
1289 struct FileSysResource *MyFileSysRes;
1290 struct FileSysEntry *MyFileSysEntry;
1291 struct FileSysEntry *CurrentFileSysEntry;
1292 BOOL Matched;
1294 MyFileSysEntry = NULL;
1295 MyFileSysRes = OpenResource(FSRNAME);
1296 if (MyFileSysRes)
1298 Forbid();
1299 CurrentFileSysEntry = (struct FileSysEntry*) MyFileSysRes->fsr_FileSysEntries.lh_Head;
1300 while (CurrentFileSysEntry->fse_Node.ln_Succ)
1302 if (HandlerString != NULL)
1303 Matched = strcmp(HandlerString + BSTR_OFFSET,
1304 AROS_BSTR_ADDR(CurrentFileSysEntry->fse_Handler)) == 0;
1305 else
1306 Matched = CurrentFileSysEntry->fse_DosType == DosType;
1307 if (Matched)
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 ShowError(STRPTR name, const char *s, ...)
1847 AROS_SLOWSTACKFORMAT_PRE(s);
1849 NewRawDoFmt("Error mounting '%s'", RAWFMTFUNC_STRING, txtBuf, name);
1851 if (IsCli)
1853 PutStr(txtBuf);
1854 PutStr(": ");
1855 VPrintf(s, AROS_SLOWSTACKFORMAT_ARG(s));
1856 PutStr("\n");
1858 else
1860 struct EasyStruct es =
1862 sizeof(struct EasyStruct),
1864 txtBuf,
1866 "OK"
1869 IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library", 36);
1870 if (IntuitionBase)
1872 EasyRequestArgs(NULL, &es, NULL, AROS_SLOWSTACKFORMAT_ARG(s));
1873 CloseLibrary((struct Library *)IntuitionBase);
1877 AROS_SLOWSTACKFORMAT_POST(s);
1880 void ShowFault(LONG code, const char *s, ...)
1882 char buf[256];
1883 va_list ap;
1884 int l;
1886 va_start(ap, s);
1887 l = vsnprintf(buf, sizeof(buf) - 2, s, ap);
1888 va_end(ap);
1889 strcpy(&buf[l], ": ");
1890 l += 2;
1891 Fault(code, NULL, &buf[l], sizeof(buf) - l);
1892 if (buf[l] == 0)
1893 snprintf(&buf[l], sizeof(buf) - l, "%ld", (long)code);
1894 buf[sizeof(buf)-1] = 0;
1895 if (IsCli)
1897 PutStr(buf);
1898 PutStr("\n");
1900 else
1902 struct EasyStruct es =
1904 sizeof(struct EasyStruct),
1906 "Mount Failure",
1907 buf,
1908 "OK"
1911 IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library", 36);
1912 if (IntuitionBase)
1914 EasyRequestArgs(NULL, &es, NULL, NULL);
1915 CloseLibrary((struct Library *)IntuitionBase);