Port the SB128 code to AROS.
[AROS.git] / workbench / c / Mount.c
blob01e90c10b440fab128c2e2f168a413ac32fb9737
1 /*
2 (C) 1995-2011 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/semaphores.h>
64 #include <exec/types.h>
65 #include <dos/dosextens.h>
66 #include <dos/exall.h>
67 #include <dos/filehandler.h>
68 #include <dos/rdargs.h>
69 #include <libraries/configvars.h>
70 #include <libraries/expansion.h>
71 #include <workbench/workbench.h>
72 #include <workbench/startup.h>
74 #include <proto/exec.h>
75 #include <proto/dos.h>
76 #include <proto/intuition.h>
77 #include <proto/utility.h>
78 #include <proto/icon.h>
79 #include <proto/expansion.h>
81 #ifdef __SASC
82 typedef unsigned long IPTR;
83 #endif
85 #include <resources/filesysres.h>
86 #include <string.h>
87 #include <stdio.h>
88 #include <stdlib.h>
90 #define DEBUG_PATCHDOSNODE(x)
91 #define DEBUG_MOUNT(x)
92 #define DEBUG_MAKEDOSNODE(x)
93 #define DEBUG_CHECK(x)
95 #define MOUNTLIST "DEVS:MountList"
96 #define DOSDRIVERS "DEVS:DOSDrivers/"
97 #define STORAGEDRIVERS "SYS:Storage/DOSDrivers/"
98 #define PARAMSLENGTH (sizeof(struct DosEnvec) + sizeof(IPTR)*4)
100 enum
102 ERR_SPECIAL = 5000,
103 ERR_DEVICENOTFOUND,
104 ERR_INVALIDKEYWORD
107 const char *SearchTable[]=
110 "DEVS:DOSDrivers/",
111 #ifdef __MORPHOS__
112 "MOSSYS:DEVS/DOSDrivers/",
113 #endif
114 "SYS:Storage/DOSDrivers/",
115 #ifdef __MORPHOS__
116 "MOSSYS:Storage/DOSDrivers/",
117 #endif
118 NULL
122 * startup,control need to be handled differently.
125 enum
127 ARG_HANDLER,
128 ARG_EHANDLER,
129 ARG_FILESYSTEM,
130 ARG_DEVICE,
131 ARG_UNIT,
132 ARG_FLAGS,
133 ARG_BLOCKSIZE,
134 ARG_SURFACES,
135 ARG_BLOCKSPERTRACK,
136 ARG_SECTORSPERBLOCK,
137 ARG_RESERVED,
138 ARG_PREALLOC,
139 ARG_INTERLEAVE,
140 ARG_LOWCYL,
141 ARG_HIGHCYL,
142 ARG_BUFFERS,
143 ARG_BUFMEMTYPE,
144 ARG_MAXTRANSFER,
145 ARG_MASK,
146 ARG_BOOTPRI,
147 ARG_DOSTYPE,
148 ARG_BAUD,
149 ARG_CONTROL,
150 ARG_STACKSIZE,
151 ARG_PRIORITY,
152 ARG_GLOBVEC,
153 ARG_STARTUP,
154 ARG_ACTIVATE,
155 ARG_FORCELOAD,
156 NUM_ARGS
159 const UBYTE options[]=
160 "HANDLER/K,"
161 "EHANDLER/K,"
162 "FILESYSTEM/K,"
163 "DEVICE/K,"
164 "UNIT/K,"
165 "FLAGS/K,"
166 "SECTORSIZE=BLOCKSIZE/K,"
167 "SURFACES/K,"
168 "SECTORSPERTRACK=BLOCKSPERTRACK/K,"
169 "SECTORSPERBLOCK/K,"
170 "RESERVED/K,"
171 "PREALLOC/K,"
172 "INTERLEAVE/K,"
173 "LOWCYL/K,"
174 "HIGHCYL/K,"
175 "BUFFERS/K,"
176 "BUFMEMTYPE/K,"
177 "MAXTRANSFER/K,"
178 "MASK/K,"
179 "BOOTPRI/K,"
180 "DOSTYPE/K,"
181 "BAUD/K,"
182 "CONTROL/K,"
183 "STACKSIZE/K,"
184 "PRIORITY/K,"
185 "GLOBVEC/K,"
186 "STARTUP/K,"
187 "MOUNT=ACTIVATE/K,"
188 "FORCELOAD/K";
190 #ifdef __MORPHOS__
191 #define PROGNAME "Mount unofficial"
192 typedef struct Library *UtilityBase_t;
193 #else
194 #define PROGNAME "Mount"
195 typedef struct UtilityBase *UtilityBase_t;
196 #endif
198 #ifdef __AROS__
199 #define _WBenchMsg WBenchMsg
200 #endif
202 #ifdef AROS_FAST_BPTR
203 #define BSTR_EXTRA 1
204 #define BSTR_OFFSET 0
205 #define bstrcpy(dest, src, len) strcpy(dest, src)
206 #else
207 #define BSTR_EXTRA 2
208 #define BSTR_OFFSET 1
209 #define bstrcpy(dest, src, len) \
210 dest[0] = len; \
211 strcpy(&dest[1], src);
212 #endif
214 static const int __nocommandline;
215 const TEXT version[] = "\0$VER: " PROGNAME " 50.14 (10.1.2008)";
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(char *s, IPTR *ap);
227 void ShowFault(LONG code, char *s, ...);
229 #define ShowError(s, ...) \
231 IPTR __args[] = { AROS_PP_VARIADIC_CAST2IPTR(__VA_ARGS__) }; \
232 ShowErrorArgs(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 extern struct WBStartup *_WBenchMsg;
257 int main(void)
259 IPTR args[2];
260 IPTR *params;
261 LONG error = RETURN_FAIL;
262 struct RDArgs *rda;
263 char dirname[512];
265 if ((DOSBase = (struct DosLibrary *)OpenLibrary("dos.library",37))!=0)
267 if ((UtilityBase = (UtilityBase_t)OpenLibrary("utility.library",37)))
269 memset(&flagargs, 0, sizeof(flagargs));
270 IsEHandler = TRUE;
271 IsFilesystem = TRUE;
272 if (!_WBenchMsg)
274 memset(args,0,sizeof(args));
275 if ((rda = ReadArgs("DEVICE/M,FROM/K", args, NULL)))
277 STRPTR *MyDevPtr;
278 int len;
280 error = 0;
282 MyDevPtr =(STRPTR *)args[0];
283 if (MyDevPtr)
285 while (*MyDevPtr)
287 DEBUG_MOUNT(KPrintF("Mount: Current DevName <%s>\n",
288 (IPTR)*MyDevPtr));
290 if ((params = AllocVec(PARAMSLENGTH, MEMF_PUBLIC | MEMF_CLEAR)))
292 StackSize = 8192;
293 Priority = 5;
294 GlobalVec = -1;
295 HandlerString = NULL;
296 DeviceString = NULL;
297 StartupString = NULL;
299 len = strlen(*MyDevPtr);
300 if ((*MyDevPtr)[len-1] == ':')
302 /* search for a devicename */
303 DEBUG_MOUNT(KPrintF("Mount: search for devname <%s>\n",
304 (IPTR)*MyDevPtr));
306 strcpy(dirname, *MyDevPtr);
307 dirname[len-1] = '\0';
309 if ((error=CheckDevice(dirname))!=RETURN_OK)
311 DEBUG_MOUNT(KPrintF("Mount: is already mounted..stop\n"));
313 else
315 if (args[1])
317 error=readmountlist(params, dirname, (STRPTR)(args[1]));
318 DEBUG_MOUNT(KPrintF("Mount: readmountlist(%s) returned %ld\n", args[1], error));
320 else
322 char **SearchPtr;
323 ULONG slen;
325 DEBUG_MOUNT(KPrintF("Mount: search device definition <%s>\n",
326 (IPTR)*MyDevPtr));
327 for (SearchPtr=(char**) SearchTable;
328 *SearchPtr;
329 SearchPtr++)
331 if(SetSignal(0L,SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C)
333 error = RETURN_FAIL;
334 SetIoErr(ERROR_BREAK);
335 break;
338 slen = strlen(*SearchPtr);
339 strcpy(dirname, *SearchPtr);
340 dirname[slen] = '\0';
341 strcat(dirname, *MyDevPtr);
342 dirname[slen+len-1] = '\0';
343 DEBUG_MOUNT(KPrintF("Mount: try File <%s>\n", (IPTR)dirname));
345 error=readmountfile(params, dirname);
346 DEBUG_MOUNT(KPrintF("Mount: readmountfile returned %ld\n", error));
347 if (error != ERROR_OBJECT_NOT_FOUND)
348 break;
350 if (error == ERROR_OBJECT_NOT_FOUND)
352 DEBUG_MOUNT(KPrintF("Mount: try from mountlist\n"));
353 dirname[0] = '\0';
354 strcat(dirname, *MyDevPtr);
355 dirname[len-1] = '\0';
356 error=readmountlist(params, dirname, MOUNTLIST);
357 DEBUG_MOUNT(KPrintF("Mount: readmountlist(default) returned %ld\n", error));
362 else
364 /* search for a filename */
366 LONG err;
368 UBYTE stack_ap[sizeof(struct AnchorPath) + 3];
369 struct AnchorPath *MyAp = (struct AnchorPath *) (((IPTR) stack_ap + 3) & ~3);
371 DEBUG_MOUNT(KPrintF("Mount: search for mountfile <%s>\n", *MyDevPtr));
373 memset(MyAp,0,sizeof(struct AnchorPath));
375 dirname[0] = '\0';
376 for (err = MatchFirst(*MyDevPtr,MyAp);
377 err == 0;
378 err = MatchNext(MyAp))
380 if (MyAp->ap_Flags & APF_DirChanged)
382 DEBUG_MOUNT(KPrintF("Mount: Changed directories...\n"));
385 DEBUG_MOUNT(KPrintF("Mount: NameFromLock(0x%p)...\n", MyAp->ap_Current->an_Lock));
386 if (NameFromLock(MyAp->ap_Current->an_Lock,
387 dirname,
388 sizeof(dirname)) == FALSE)
390 ShowFault(IoErr(), "Error on NameFromLock");
391 break;
394 DEBUG_MOUNT(KPrintF("Mount: ...Dir name: %s\n", dirname));
395 if (AddPart(dirname,
396 &(MyAp->ap_Info.fib_FileName[0]),
397 sizeof(dirname)) == FALSE)
399 ShowFault(IoErr(), "Error on AddPart");
400 break;
402 if (MyAp->ap_Info.fib_DirEntryType > 0)
404 if (MyAp->ap_Flags & APF_DIDDIR)
406 DEBUG_MOUNT(KPrintF("Mount: Ascending from directory %s\n",
407 (IPTR)dirname));
409 else
411 DEBUG_MOUNT(KPrintF("Mount: The next dir is ... %s\n", (IPTR)dirname));
413 /* clear the completed directory flag */
414 MyAp->ap_Flags &= ~APF_DIDDIR;
417 else
419 /* Here is code for handling each particular file */
421 DEBUG_MOUNT(KPrintF("Mount: try File <%s>\n",
422 (IPTR)dirname));
424 memset(&flagargs, 0, sizeof(flagargs));
425 IsEHandler = TRUE;
426 IsFilesystem = TRUE;
427 error=readmountfile(params, dirname);
428 DEBUG_MOUNT(KPrintF("Mount: readmount file returned %ld\n", error));
431 /* This absolutely, positively must be called, all of the time. */
432 MatchEnd(MyAp);
434 if (err == ERROR_NO_MORE_ENTRIES)
436 SetIoErr(0);
438 else
440 /* if it was real error promote it - Piru */
441 error = err;
444 FreeVec(params);
446 else
448 error = ERROR_NO_FREE_STORE;
449 break;
451 MyDevPtr++;
454 FreeArgs(rda);
455 } /* if (rda != NULL) */
456 else
458 error = IoErr();
461 if (error && error != ERROR_NO_MORE_ENTRIES && error < ERR_SPECIAL)
463 ShowFault(error, "ERROR");
465 error = RETURN_FAIL;
467 else
469 error = error < ERR_SPECIAL ? RETURN_OK : RETURN_FAIL;
473 else
475 /* wb startup */
476 if (_WBenchMsg->sm_NumArgs >= 2)
478 if ((params = AllocVec(PARAMSLENGTH,
479 MEMF_PUBLIC | MEMF_CLEAR)))
481 int i;
483 for (i = 1; i < _WBenchMsg->sm_NumArgs; i++)
485 BPTR olddir;
487 DEBUG_MOUNT(KPrintF("Mount: try File <%s>\n",
488 (IPTR) _WBenchMsg->sm_ArgList[i].wa_Name));
490 olddir = CurrentDir(_WBenchMsg->sm_ArgList[i].wa_Lock);
492 error=readmountfile(params, _WBenchMsg->sm_ArgList[i].wa_Name);
493 DEBUG_MOUNT(KPrintF("Mount: readmountfile returned %ld\n", error));
494 if (error && error != ERROR_NO_MORE_ENTRIES && error < ERR_SPECIAL)
495 ShowFault(error, "ERROR");
497 (void) CurrentDir(olddir);
500 FreeVec(params);
502 else
504 error = ERROR_NO_FREE_STORE;
508 CloseLibrary((struct Library *)UtilityBase);
510 CloseLibrary((struct Library *)DOSBase);
513 return error;
516 /************************************************************************************************/
517 /************************************************************************************************/
518 ULONG CheckDevice(char *name)
520 struct DosList *dl;
521 ULONG Status;
523 DEBUG_CHECK(Printf("CheckDevice: <%s>\n",
524 name));
526 dl = LockDosList(LDF_DEVICES | LDF_VOLUMES | LDF_ASSIGNS | LDF_READ);
527 if ((dl = FindDosEntry(dl,name,LDF_DEVICES | LDF_VOLUMES | LDF_ASSIGNS)))
529 Status = ERROR_OBJECT_EXISTS;
531 else
533 Status = 0;
535 UnLockDosList(LDF_DEVICES | LDF_VOLUMES | LDF_ASSIGNS | LDF_READ);
537 DEBUG_CHECK(Printf("CheckDevice: object %sexist\n", Status ? "does" : "doesn't "));
539 return Status;
542 /************************************************************************************************/
543 /************************************************************************************************/
545 void InitParams(IPTR *params)
547 struct DosEnvec *vec;
549 memset(params,0, PARAMSLENGTH);
551 vec = (struct DosEnvec *)&params[4];
553 vec->de_TableSize = DE_BOOTBLOCKS;
554 vec->de_SizeBlock = 512 >> 2;
555 vec->de_Surfaces = 2;
556 vec->de_SectorPerBlock = 1;
557 vec->de_BlocksPerTrack = 11;
558 vec->de_Reserved = 2;
560 /* memset above
561 vec->de_SecOrg = 0;
562 vec->de_BootBlocks = 0;
563 vec->de_BootPri = 0;
564 vec->de_PreAlloc = 0;
565 vec->de_Interleave = 0;
566 vec->de_LowCyl = 0;
569 vec->de_HighCyl = 79;
570 vec->de_NumBuffers = 20; /* On AmigaOS 3.9 it's 5 */
571 vec->de_BufMemType = 3;
572 vec->de_Baud = 1200;
573 vec->de_MaxTransfer = 0x7fffffff;
574 vec->de_Mask = -2; /* 0xfffffffe, sign-extended on 64 bits */
575 vec->de_DosType = ID_DOS_DISK;
577 StackSize = 8192;
578 Priority = 5;
579 GlobalVec = -1;
580 HandlerString = NULL;
581 DeviceString = NULL;
582 StartupString = NULL;
585 void FreeStuff(void)
587 if (UnitString)
589 FreeVec(UnitString);
590 UnitString = NULL;
592 if (FlagsString)
594 FreeVec(FlagsString);
595 FlagsString = NULL;
597 if (ControlString)
599 FreeVec(ControlString);
600 ControlString = NULL;
602 if (HandlerString)
604 FreeVec(HandlerString);
605 HandlerString = NULL;
607 if (DeviceString)
609 FreeVec(DeviceString);
610 DeviceString = NULL;
612 if (StartupString)
614 FreeVec(StartupString);
615 StartupString = NULL;
619 /************************************************************************************************/
620 /************************************************************************************************/
622 static long GetValue(IPTR bufp, char **end)
624 char *buf = (char *)bufp;
625 int base;
626 char *c = buf;
628 /* I decided to leave this routine in order to prevent reading numbers starting from '0'
629 as octal. Probably this is not needed, or octal support would not do any harm, in this
630 case this routine is not needed at all - Pavel Fedin */
631 if ((c[0]=='-') || (c[1]=='+'))
632 c++;
633 if ((c[0] == '0') && (((c[1])=='x') || (c[1])=='X'))
634 base = 16;
635 else
636 base = 10;
637 return strtol(buf,end,base);
638 /* Left for reference - Pavel Fedin
639 ULONG Value;
640 ULONG Sign;
641 Value = 0;
642 Sign = 1;
643 if (buf[0]=='-')
645 Sign = -1;
646 buf++;
648 else
649 if (buf[0]=='+')
651 buf++;
654 if ((buf[0] == '0') && (((buf[1])=='x') || (buf[1])=='X'))
656 int num;
658 // base = hex
659 buf+=2;
660 while(*buf)
662 Value<<=4;
663 num=*buf++;
665 if((num >= 0x30) && (num <= 0x39))
667 num-=0x30;
668 Value+=num;
670 else
672 num |= 0x20;
674 if((num >= 0x61) && (num <= 0x66))
676 num-=(0x61-10);
677 Value+=num;
682 else
684 // base = dev
685 Value=atoi(buf);
687 return Value * Sign;
691 /************************************************************************************************/
692 /************************************************************************************************/
694 ULONG ReadMountArgs(IPTR *params, struct RDArgs *rda)
696 struct DosEnvec *vec;
697 IPTR args[NUM_ARGS];
698 struct RDArgs *MyRDA;
699 ULONG result = RETURN_OK;
700 int i;
701 char *s = NULL;
703 DEBUG_MOUNT(KPrintF("ReadMountArgs:\n%s\n\n", (IPTR)&rda->RDA_Source.CS_Buffer[rda->RDA_Source.CS_CurChr]));
705 memset(&args, 0, sizeof(args));
707 if (!(MyRDA = ReadArgs((STRPTR)options, &args[0], rda)))
709 DEBUG_MOUNT(KPrintF("ReadMountArgs: ReadArgs failed, error %u\n", IoErr()));
710 //return (ULONG) IoErr();
711 return ERR_INVALIDKEYWORD;
714 for (i = 0; i < NUM_ARGS; i++)
716 if (args[i] != 0)
718 flagargs[i] = TRUE;
722 if (args[ARG_HANDLER] != 0)
724 s = (STRPTR)args[ARG_HANDLER];
725 IsEHandler = FALSE;
726 IsFilesystem = FALSE;
728 else if (args[ARG_EHANDLER] != 0)
730 s = (STRPTR)args[ARG_EHANDLER];
731 IsEHandler = TRUE;
732 IsFilesystem = FALSE;
734 else if (args[ARG_FILESYSTEM] != 0)
736 s = (STRPTR)args[ARG_FILESYSTEM];
737 IsEHandler = TRUE;
738 IsFilesystem = TRUE;
739 } else
740 s = NULL;
741 if (s)
743 int len;
744 DEBUG_MOUNT(KPrintF("ReadMountArgs: Handler <%s>\n",s));
745 len = strlen(s);
746 if (HandlerString)
748 FreeVec(HandlerString);
750 if ((HandlerString = AllocVec(len + BSTR_EXTRA, MEMF_PUBLIC|MEMF_CLEAR)))
752 bstrcpy(HandlerString, s, len);
755 if (args[ARG_STACKSIZE] != 0)
757 StackSize = GetValue(args[ARG_STACKSIZE], NULL);
760 if (args[ARG_PRIORITY] != 0)
762 Priority = GetValue(args[ARG_PRIORITY], NULL);
765 if (args[ARG_GLOBVEC] != 0)
767 GlobalVec = GetValue(args[ARG_GLOBVEC], NULL);
770 if (args[ARG_FORCELOAD] != 0)
772 ForceLoad = GetValue(args[ARG_FORCELOAD], NULL);
775 if (args[ARG_ACTIVATE] != 0)
777 Activate = GetValue(args[ARG_ACTIVATE], NULL);
780 if (args[ARG_DEVICE] != 0)
782 int len;
784 DEBUG_MOUNT(KPrintF("ReadMountArgs: Device <%s>\n",(STRPTR)args[ARG_DEVICE]));
786 len = strlen((STRPTR)args[ARG_DEVICE]);
788 if (DeviceString)
790 FreeVec(DeviceString);
792 if ((DeviceString = AllocVec(len+1,MEMF_PUBLIC|MEMF_CLEAR)))
794 //Printf("copying...\n");
796 strcpy(DeviceString, (STRPTR)args[ARG_DEVICE]);
800 if (args[ARG_UNIT] != 0)
802 if (UnitString)
804 FreeVec(UnitString);
805 UnitString = NULL;
807 params[2] = GetValue(args[ARG_UNIT], &s);
808 if (*s)
810 int len;
812 len = strlen((STRPTR)args[ARG_UNIT]);
814 DEBUG_MOUNT(KPrintF("ReadMountArgs: len %ld\n",len));
816 if ((UnitString = AllocVec(len + 1, MEMF_PUBLIC|MEMF_CLEAR)))
818 strcpy(UnitString, (STRPTR)args[ARG_UNIT]);
819 params[2] = (IPTR)UnitString;
820 DEBUG_MOUNT(KPrintF("ReadMountArgs: Unit String <%s>\n", (STRPTR)params[2]));
822 else
824 result = ERROR_NO_FREE_STORE;
825 goto error;
828 else
829 DEBUG_MOUNT(KPrintF("ReadMountArgs: Unit Value %ld\n",params[2]));
831 if (args[ARG_FLAGS] != 0)
833 // char *String;
835 DEBUG_MOUNT(KPrintF("ReadMountArgs: Flags <%s>\n",(STRPTR)args[ARG_FLAGS]));
836 if (FlagsString)
838 FreeVec(FlagsString);
839 FlagsString = NULL;
842 String = args[ARG_FLAGS];
844 if ((*String >= 0x30) && (*String <= 0x39))
846 params[3] = GetValue(String);
847 DEBUG_MOUNT(KPrintF("ReadMountArgs: Flag Value %ld\n",params[3]));
849 else
851 params[3] = GetValue(args[ARG_FLAGS], &s);
852 if (*s)
854 int len;
856 len = strlen((STRPTR)args[ARG_FLAGS]);
858 DEBUG_MOUNT(KPrintF("ReadMountArgs: len %ld\n",len));
860 if ((FlagsString = AllocVec(len + 1, MEMF_PUBLIC|MEMF_CLEAR)))
862 strcpy(FlagsString, (STRPTR)args[ARG_FLAGS]);
863 params[3] = (IPTR) FlagsString;
864 DEBUG_MOUNT(KPrintF("ReadMountArgs: Flags String <%s>\n",(STRPTR)params[3]));
866 else
868 result = ERROR_NO_FREE_STORE;
869 goto error;
872 else
873 DEBUG_MOUNT(KPrintF("ReadMountArgs: Flag Value %ld\n",params[3]));
876 vec = (struct DosEnvec *)&params[4];
878 if (args[ARG_BLOCKSIZE] != 0)
880 vec->de_SizeBlock = GetValue(args[ARG_BLOCKSIZE], NULL) >> 2;
882 if (args[ARG_SURFACES] != 0)
884 vec->de_Surfaces = GetValue(args[ARG_SURFACES], NULL);
886 if (args[ARG_SECTORSPERBLOCK] != 0)
888 vec->de_SectorPerBlock = GetValue(args[ARG_SECTORSPERBLOCK], NULL);
890 if (args[ARG_BLOCKSPERTRACK] != 0)
892 vec->de_BlocksPerTrack = GetValue(args[ARG_BLOCKSPERTRACK], NULL);
894 if (args[ARG_RESERVED] != 0)
896 vec->de_Reserved = GetValue(args[ARG_RESERVED], NULL);
898 if (args[ARG_PREALLOC] != 0)
900 vec->de_PreAlloc = GetValue(args[ARG_PREALLOC], NULL);
902 if (args[ARG_INTERLEAVE] != 0)
904 vec->de_Interleave = GetValue(args[ARG_INTERLEAVE], NULL);
906 if (args[ARG_LOWCYL] != 0)
908 vec->de_LowCyl = GetValue(args[ARG_LOWCYL], NULL);
910 if (args[ARG_HIGHCYL] != 0)
912 vec->de_HighCyl = GetValue(args[ARG_HIGHCYL], NULL);
914 if (args[ARG_BUFFERS] != 0)
916 vec->de_NumBuffers = GetValue(args[ARG_BUFFERS], NULL);
918 if (args[ARG_BUFMEMTYPE] != 0)
920 vec->de_BufMemType = GetValue(args[ARG_BUFMEMTYPE], NULL);
922 if (args[ARG_BOOTPRI] != 0)
924 vec->de_BootPri = GetValue(args[ARG_BOOTPRI], NULL);
926 if (args[ARG_BAUD] != 0)
928 vec->de_Baud = GetValue(args[ARG_BAUD], NULL);
930 if (args[ARG_MAXTRANSFER] != 0)
932 vec->de_MaxTransfer = GetValue(args[ARG_MAXTRANSFER], NULL);
934 if (args[ARG_MASK] != 0)
936 vec->de_Mask = GetValue(args[ARG_MASK], NULL);
939 if (args[ARG_DOSTYPE] != 0)
941 vec->de_DosType = (IPTR)GetValue(args[ARG_DOSTYPE], NULL);
944 if (args[ARG_CONTROL] != 0)
946 int len;
947 DEBUG_MOUNT(KPrintF("ReadMountArgs: Control <%s>\n",args[ARG_CONTROL]));
948 if (ControlString)
950 FreeVec(ControlString);
951 ControlString = NULL;
953 len = strlen((STRPTR)args[ARG_CONTROL]);
954 if (len < 0x100)
956 if ((ControlString=AllocVec(len + BSTR_EXTRA, MEMF_PUBLIC|MEMF_CLEAR)))
958 bstrcpy(ControlString, (STRPTR)args[ARG_CONTROL], len);
959 vec->de_Control = (IPTR)MKBADDR(ControlString);
961 else
963 ShowError("Unable to allocate Control string");
964 result = ERROR_NO_FREE_STORE;
965 goto error;
968 else
970 result = ERROR_LINE_TOO_LONG;
971 SetIoErr(result);
972 // ShowError("Control string too long");
973 goto error;
977 if (args[ARG_STARTUP] != 0)
979 // char *String;
981 DEBUG_MOUNT(KPrintF("ReadMountArgs: Startup <%s>\n",args[ARG_STARTUP]));
982 if (StartupString)
984 FreeVec(StartupString);
985 StartupString = NULL;
988 String = args[ARG_STARTUP];
989 if ((*String >= 0x30) && (*String <= 0x39))
991 StartupValue = GetValue(String);
993 else
995 StartupValue = GetValue(args[ARG_STARTUP], &s);
996 if (*s)
998 int len;
1000 len = strlen((STRPTR)args[ARG_STARTUP]);
1002 DEBUG_MOUNT(KPrintF("ReadMountArgs: len %ld\n",len));
1004 if ((StartupString = AllocVec(len + 1, MEMF_PUBLIC|MEMF_CLEAR)))
1006 strcpy(StartupString,(STRPTR)args[ARG_STARTUP]);
1008 else
1010 result = ERROR_NO_FREE_STORE;
1011 goto error;
1016 error:
1017 FreeArgs(MyRDA);
1019 return result;
1022 /************************************************************************************************/
1023 /************************************************************************************************/
1025 ULONG readmountlist(IPTR *params,
1026 STRPTR name,
1027 char *mountlist)
1029 STRPTR MountListBuf;
1030 LONG MountListBufSize;
1031 ULONG error;
1033 DEBUG_MOUNT(KPrintF("ReadMountList: find <%s> in mountlist <%s>\n",
1034 name,
1035 mountlist));
1037 error = readfile(mountlist,
1038 &MountListBuf,
1039 &MountListBufSize);
1040 if (error==RETURN_OK)
1042 preparefile(MountListBuf,
1043 MountListBufSize);
1046 InitParams(params);
1048 if ((error=parsemountlist(params,
1049 name,
1050 MountListBuf,
1051 MountListBufSize))==RETURN_OK)
1053 if ((error = mount(params,name))!=RETURN_OK)
1055 DEBUG_MOUNT(KPrintF("ReadMountList: mount failed error %ld\n",
1056 error));
1059 else
1061 switch (error)
1063 case ERR_DEVICENOTFOUND:
1064 case ERR_INVALIDKEYWORD:
1065 ShowError("Device '%s:' not found in file '%s'", name, mountlist);
1066 break;
1070 FreeStuff();
1071 FreeVec(MountListBuf);
1073 return error;
1076 /************************************************************************************************/
1077 /************************************************************************************************/
1079 ULONG readmountfile(IPTR *params, STRPTR filename)
1081 struct Library *IconBase;
1082 struct DiskObject *diskobj;
1083 char **myargv;
1084 STRPTR MountListBuf;
1085 LONG MountListBufSize;
1086 struct RDArgs rda;
1087 ULONG error = RETURN_FAIL;
1088 UBYTE *nameptr;
1089 int toollen;
1090 BOOL mountinfo=FALSE;
1091 char name[256+1];
1093 DEBUG_MOUNT(KPrintF("ReadMountFile: <%s>\n", (IPTR)filename));
1096 struct Process *me = (APTR) FindTask(NULL);
1097 APTR oldwinptr;
1098 BPTR lock;
1100 name[0] = '\0';
1102 oldwinptr = me->pr_WindowPtr;
1103 me->pr_WindowPtr = (APTR) -1;
1104 lock = Lock(filename, SHARED_LOCK);
1105 if (lock)
1107 struct FileInfoBlock *fib = (struct FileInfoBlock*)AllocDosObject(DOS_FIB, NULL);
1108 if (fib)
1110 if (Examine(lock, fib))
1112 nameptr = fib->fib_FileName;
1113 memmove(name, nameptr, strlen(nameptr) + 1);
1115 FreeDosObject(DOS_FIB, fib);
1117 UnLock(lock);
1119 me->pr_WindowPtr = oldwinptr;
1121 if (name[0] == '\0')
1123 nameptr = FilePart(filename);
1124 strcpy(name,
1125 nameptr);
1129 DEBUG_MOUNT(KPrintF("ReadMountFile: mount <%s>\n", (IPTR)name));
1131 if ((error=CheckDevice(name))!=RETURN_OK)
1133 return error;
1136 InitParams(params);
1138 DEBUG_MOUNT(KPrintF("ReadMountFile: readfile\n"));
1140 error = readfile(filename,
1141 &MountListBuf,
1142 &MountListBufSize);
1143 if (error==RETURN_OK)
1145 DEBUG_MOUNT(KPrintF("ReadMountFile: preparsefile\n"));
1146 preparefile(MountListBuf, MountListBufSize);
1149 DEBUG_MOUNT(KPrintF("ReadMountFile: parsemountfile\n"));
1150 if ((error = parsemountfile(params, MountListBuf, MountListBufSize))!=RETURN_OK)
1152 DEBUG_MOUNT(KPrintF("ReadMountFile: parsemountfile error %ld\n", error));
1153 ShowFault(IoErr(), "Mountfile '%s' is invalid", filename);
1155 else
1157 mountinfo = TRUE;
1159 FreeVec(MountListBuf);
1161 else
1163 DEBUG_MOUNT(KPrintF("ReadMountFile: mountfile not found..search for <%s.info>\n",
1164 filename));
1167 if ((error==RETURN_OK) ||
1168 (error==ERROR_OBJECT_NOT_FOUND))
1170 DEBUG_MOUNT(KPrintF("ReadMountFile: look for icon '%s'\n", filename));
1172 if ((IconBase = OpenLibrary("icon.library", 37)))
1174 if ((diskobj = GetDiskObject(filename)))
1176 myargv =(char**) diskobj->do_ToolTypes;
1177 if (myargv)
1179 while (*myargv)
1181 char *ToolPtr;
1182 ToolPtr = *myargv;
1183 DEBUG_MOUNT(KPrintF("ReadMountFile: ToolType <%s>\n",
1184 ToolPtr));
1185 if ((ToolPtr[0] != '(') && (ToolPtr[0] != '*') &&
1186 !((ToolPtr[0] == 'I') && (ToolPtr[1] == 'M') && (ToolPtr[3] == '=')))
1188 char *ToolString;
1189 toollen = strlen(ToolPtr);
1190 if ((ToolString = AllocVec(toollen + 2,MEMF_ANY)))
1192 memcpy(ToolString,ToolPtr,toollen);
1193 ToolString[toollen] = '\n';
1194 ToolString[toollen+1] = '\0';
1195 memset(&rda,0,sizeof(struct RDArgs));
1196 rda.RDA_Source.CS_Buffer = ToolString;
1197 rda.RDA_Source.CS_Length = toollen+1;
1198 rda.RDA_Source.CS_CurChr = 0;
1199 rda.RDA_Flags = RDAF_NOPROMPT;
1200 if ((ReadMountArgs(params, &rda)==RETURN_OK))
1202 mountinfo = TRUE;
1204 else
1206 DEBUG_MOUNT(KPrintF("ReadMountFile: ReadArgs failed error %ld\n",
1207 error));
1209 FreeVec(ToolString);
1211 else
1213 error = ERROR_NO_FREE_STORE;
1214 break;
1217 else
1219 DEBUG_MOUNT(KPrintF("ReadMountFile: skipped\n"));
1221 myargv++;
1224 FreeDiskObject(diskobj);
1226 else
1229 CloseLibrary(IconBase);
1233 if (mountinfo)
1235 DEBUG_MOUNT(KPrintF("ReadMountFile: mount information exists\n"));
1237 if ((error = mount(params,name)) != RETURN_OK)
1239 DEBUG_MOUNT(KPrintF("ReadMountFile: mount failed error %ld\n",
1240 error));
1244 FreeStuff();
1246 return error;
1249 /************************************************************************************************/
1250 /************************************************************************************************/
1253 LONG readfile(STRPTR name, STRPTR *mem, LONG *size)
1255 BPTR ml;
1256 ULONG rest,sub;
1257 STRPTR buf;
1258 struct Process *me = (struct Process *) FindTask(NULL);
1259 APTR oldwinptr;
1261 oldwinptr = me->pr_WindowPtr;
1262 me->pr_WindowPtr = (APTR) -1;
1263 ml = Open(name, MODE_OLDFILE);
1264 me->pr_WindowPtr = oldwinptr;
1266 DEBUG_MOUNT(KPrintF("ReadFile: <%s>\n", (IPTR) name));
1268 if (ml)
1270 if (Seek(ml, 0, OFFSET_END) != -1)
1272 *size = Seek(ml, 0, OFFSET_BEGINNING);
1274 if (*size != -1)
1276 *mem = (STRPTR)AllocVec(*size+2, MEMF_ANY);
1278 if (*mem)
1280 rest = *size;
1281 buf = *mem;
1283 for (;;)
1285 if (!rest)
1287 Close(ml);
1289 *buf++ = '\n';
1290 *buf = '\0';
1292 return 0;
1295 sub = Read(ml, buf, rest);
1297 if (sub == -1)
1299 break;
1302 rest -= sub;
1303 buf += sub;
1306 FreeVec(*mem);
1308 else
1310 SetIoErr(ERROR_NO_FREE_STORE);
1315 Close(ml);
1318 DEBUG_MOUNT(KPrintF("ReadFile: error %ld\n", IoErr()));
1319 return IoErr();
1322 /************************************************************************************************/
1323 /************************************************************************************************/
1326 void preparefile(STRPTR buf, LONG size)
1328 STRPTR end = buf + size;
1330 while (buf < end)
1332 /* Convert comments to spaces */
1333 if (buf + 1 < end && *buf == '/' && buf[1] == '*')
1335 *buf++ = ' ';
1336 *buf++ = ' ';
1338 while (buf < end)
1340 if (*buf == '*')
1342 *buf++ = ' ';
1344 if (buf >= end)
1346 break;
1349 if (*buf == '/')
1351 *buf++ = ' ';
1352 break;
1355 else
1357 *buf++=' ';
1361 continue;
1364 /* Skip strings */
1365 if (*buf=='\"')
1368 * skip first
1370 buf++;
1371 while (buf < end && *buf != '\"')
1373 buf++;
1376 * skip last "
1378 buf++;
1379 continue;
1382 /* Convert '\n' and ';' to spaces */
1383 if (*buf == '\n' || *buf == ';')
1385 *buf++ = ' ';
1386 continue;
1389 /* Convert '#' to \n */
1390 if (*buf == '#')
1392 *buf++ = '\n';
1393 continue;
1396 /* Skip all other characters */
1397 buf++;
1401 /************************************************************************************************/
1402 /************************************************************************************************/
1404 struct FileSysEntry *GetFileSysEntry(ULONG DosType)
1407 struct FileSysResource *MyFileSysRes;
1408 struct FileSysEntry *MyFileSysEntry;
1409 struct FileSysEntry *CurrentFileSysEntry;
1411 MyFileSysEntry = NULL;
1412 MyFileSysRes = OpenResource(FSRNAME);
1413 if (MyFileSysRes)
1415 Forbid();
1416 CurrentFileSysEntry = (struct FileSysEntry*) MyFileSysRes->fsr_FileSysEntries.lh_Head;
1417 while (CurrentFileSysEntry->fse_Node.ln_Succ)
1419 if (CurrentFileSysEntry->fse_DosType == DosType)
1421 if (MyFileSysEntry)
1423 if (CurrentFileSysEntry->fse_Version > MyFileSysEntry->fse_Version)
1425 MyFileSysEntry = CurrentFileSysEntry;
1428 else
1430 MyFileSysEntry = CurrentFileSysEntry;
1433 CurrentFileSysEntry =(struct FileSysEntry*) CurrentFileSysEntry->fse_Node.ln_Succ;
1435 Permit();
1437 return MyFileSysEntry;
1440 /************************************************************************************************/
1441 /************************************************************************************************/
1443 #define PATCH_FIELD(f, name) \
1444 if (MyFileSysEntry->fse_PatchFlags & f) \
1445 MyDeviceNode->dn_ ## name = (typeof(MyDeviceNode->dn_ ## name))MyFileSysEntry->fse_ ## name
1447 void PatchDosNode(struct DeviceNode *MyDeviceNode, ULONG DosType)
1449 struct FileSysEntry *MyFileSysEntry;
1451 DEBUG_PATCHDOSNODE(Printf("MakeDosNode: DeviceNode 0x%P\n", MyDeviceNode));
1453 if ((MyFileSysEntry=GetFileSysEntry(DosType)))
1455 DEBUG_PATCHDOSNODE(Printf("PatchDosNode: FileSysEntry 0x%P PatchFlags 0x%08lx\n", MyFileSysEntry, MyFileSysEntry->fse_PatchFlags));
1457 PATCH_FIELD(0x0001, Type);
1458 PATCH_FIELD(0x0002, Task);
1459 PATCH_FIELD(0x0004, Lock);
1460 PATCH_FIELD(0x0008, Handler);
1461 PATCH_FIELD(0x0010, StackSize);
1462 PATCH_FIELD(0x0020, Priority);
1463 PATCH_FIELD(0x0040, Startup);
1464 PATCH_FIELD(0x0080, SegList);
1465 PATCH_FIELD(0x0100, GlobalVec);
1467 DEBUG_PATCHDOSNODE(else Printf("PatchDosNode: Can't get FileSysEntry..no bootnode\n"));
1471 /************************************************************************************************/
1472 /************************************************************************************************/
1476 #define DOSNAME_INDEX 0
1477 #define EXECNAME_INDEX 1
1478 #define UNIT_INDEX 2
1479 #define FLAGS_INDEX 3
1480 #define ENVIROMENT_INDEX 4
1482 struct DeviceNode *MyMakeDosNode(char *DosName, IPTR *ParameterPkt, char *StartupName)
1484 int DosNameSize;
1485 int ExecNameSize;
1486 int MyEnvSize = 0;
1487 struct DeviceNode *MyDeviceNode = NULL;
1488 struct FileSysStartupMsg *MyFileSysStartupMsg = NULL;
1489 struct DosEnvec *MyDosEnvec = NULL;
1490 char *MyString = NULL;
1491 ULONG Status = FALSE;
1492 DEBUG_MAKEDOSNODE(Printf("MakeDosNode: Pkt 0x%lx\n",(IPTR)ParameterPkt));
1494 if (ParameterPkt)
1496 DEBUG_MAKEDOSNODE(Printf("MakeDosNode: DosName <%s> DeviceName <%s> Unit ", DosName, ParameterPkt[EXECNAME_INDEX]));
1497 DEBUG_MAKEDOSNODE(if (UnitString)
1498 Printf("<%s>",ParameterPkt[UNIT_INDEX]);
1499 else
1500 Printf("%ld",ParameterPkt[UNIT_INDEX]);)
1501 DEBUG_MAKEDOSNODE(Printf(" Flags 0x%lx DE_TABLESIZE 0x%lx\n", ParameterPkt[FLAGS_INDEX], ParameterPkt[ENVIROMENT_INDEX]));
1503 else
1505 DEBUG_MAKEDOSNODE(Printf("MakeDosNode: DosName <%s> Startup <%s>\n", (IPTR)DosName, (IPTR)StartupName));
1508 DosNameSize = strlen(DosName);
1510 if (ParameterPkt)
1512 if (ParameterPkt[EXECNAME_INDEX])
1514 ExecNameSize = strlen((UBYTE *)ParameterPkt[EXECNAME_INDEX]);
1516 else
1518 ExecNameSize = 0;
1520 MyEnvSize = (ParameterPkt[ENVIROMENT_INDEX] + 1) * sizeof(IPTR);
1522 else
1524 ExecNameSize = StartupName ? strlen(StartupName) : 0;
1527 if ((MyDeviceNode = AllocVec(sizeof(struct DeviceNode), MEMF_PUBLIC | MEMF_CLEAR)))
1529 DEBUG_MAKEDOSNODE(Printf("MakeDosNode: MyDeviceNode 0x%lx\n", (IPTR)MyDeviceNode));
1531 MyDeviceNode->dn_StackSize = 600;
1532 MyDeviceNode->dn_Priority = 10;
1534 if ((MyString=AllocVec(((DosNameSize + BSTR_EXTRA + 4) & ~3) + ((ExecNameSize + BSTR_EXTRA + 4) & ~3), MEMF_PUBLIC | MEMF_CLEAR)))
1536 bstrcpy(MyString, DosName, DosNameSize);
1538 MyDeviceNode->dn_Name = MKBADDR(MyString);
1540 if (ParameterPkt)
1542 if ((MyFileSysStartupMsg = AllocVec(sizeof(struct FileSysStartupMsg), MEMF_PUBLIC | MEMF_CLEAR)))
1544 DEBUG_MAKEDOSNODE(Printf("MakeDosNode: MyFileSysStartupMsg 0x%lx\n", (IPTR)MyFileSysStartupMsg));
1546 if ((MyDosEnvec = AllocVec(MyEnvSize, MEMF_PUBLIC | MEMF_CLEAR)))
1548 char *ExecNamePtr;
1550 DEBUG_MAKEDOSNODE(Printf("MakeDosNode: MyDosEnvec 0x%lx\n", (IPTR)MyDosEnvec));
1551 ExecNamePtr = &MyString[(1 + DosNameSize + BSTR_EXTRA + 3) & ~3];
1553 /* .device name must absolutely **NOT** include the 0 in the
1554 * length!!
1556 * the string *MUST* be 0 terminated, however!
1558 if (ParameterPkt[EXECNAME_INDEX])
1560 bstrcpy(ExecNamePtr, (UBYTE *)ParameterPkt[EXECNAME_INDEX], ExecNameSize);
1562 else
1564 ExecNamePtr[0] = 0;
1565 #ifndef AROS_FAST_BPTR
1566 ExecNamePtr[1] = 0;
1567 #endif
1569 MyFileSysStartupMsg->fssm_Device = MKBADDR(ExecNamePtr);
1570 MyFileSysStartupMsg->fssm_Unit = ParameterPkt[UNIT_INDEX];
1571 MyFileSysStartupMsg->fssm_Flags = ParameterPkt[FLAGS_INDEX];
1572 MyFileSysStartupMsg->fssm_Environ = MKBADDR(MyDosEnvec);
1573 MyDeviceNode->dn_Startup = MKBADDR(MyFileSysStartupMsg);
1575 CopyMem(&ParameterPkt[ENVIROMENT_INDEX], MyDosEnvec, MyEnvSize);
1577 #if __WORDSIZE > 32
1579 * EXPERIMENTAL: Fix up BufMemType on 64 bits.
1580 * Many software (and users) set Mask to 0x7FFFFFFF, assuming 31-bit memory, with BufMemType = PUBLIC.
1581 * This is perfectly true on 32-bit architectures, where addresses from 0x80000000 and up
1582 * belong to MMIO, however on 64 bits we might have memory beyond this address.
1583 * And AllocMem(MEMF_PUBLIC) would prefer to return that memory. This might screw up
1584 * filesystems expecting AllocMem() to return memory fully corresponding to the mask.
1586 if ((MyDosEnvec->de_TableSize >= DE_MASK) && (!(MyDosEnvec->de_Mask & 0x7FFFFFFF)))
1587 MyDosEnvec->de_BufMemType |= MEMF_31BIT;
1588 #endif
1590 Status=TRUE;
1591 DEBUG_MAKEDOSNODE(Printf("MakeDosNode: done\n"));
1595 else
1597 if (StartupName && ExecNameSize)
1599 char *StartupNamePtr;
1601 StartupNamePtr = &MyString[(1 + DosNameSize + BSTR_EXTRA + 3) & ~3];
1602 bstrcpy(StartupNamePtr, StartupName, ExecNameSize);
1603 MyDeviceNode->dn_Startup = MKBADDR(StartupNamePtr);
1605 Status=TRUE;
1609 if (Status)
1611 DEBUG_MAKEDOSNODE(Printf("MakeDosNode: done\n"));
1612 return MyDeviceNode;
1614 else
1616 DEBUG_MAKEDOSNODE(Printf("MakeDosNode: failed\n"));
1617 FreeVec(MyFileSysStartupMsg);
1618 FreeVec(MyDeviceNode);
1619 FreeVec(MyString);
1620 return NULL;
1626 /************************************************************************************************/
1627 /************************************************************************************************/
1630 LONG parsemountfile(IPTR *params, STRPTR buf, LONG size)
1632 STRPTR args[NUM_ARGS];
1633 LONG error;
1634 struct RDArgs rda;
1636 DEBUG_MOUNT(KPrintF("ParseMountFile:\n"));
1638 memset(&args, 0, sizeof(args));
1639 memset(&rda,0,sizeof(struct RDArgs));
1641 rda.RDA_Source.CS_Buffer = buf;
1642 rda.RDA_Source.CS_Length = size;
1643 rda.RDA_Source.CS_CurChr = 0;
1644 rda.RDA_Flags = RDAF_NOPROMPT;
1646 DEBUG_MOUNT(KPrintF("ReadArgs..\n%s\n\n", (IPTR)rda.RDA_Source.CS_Buffer));
1648 if ((error=ReadMountArgs(params,
1649 &rda))!=RETURN_OK)
1651 DEBUG_MOUNT(KPrintF("Parse: ReadArgs failed\n"));
1653 return error;
1656 /************************************************************************************************/
1657 /************************************************************************************************/
1660 LONG parsemountlist(IPTR *params,
1661 STRPTR name,
1662 STRPTR buf,
1663 LONG size)
1665 STRPTR args[NUM_ARGS];
1666 UBYTE buffer[1024];
1667 LONG error=RETURN_OK, res;
1668 STRPTR end = buf + size;
1669 STRPTR s2;
1670 char *ptr;
1671 struct RDArgs rda;
1673 DEBUG_MOUNT(KPrintF("ParseMountList: <%s>\n", (IPTR)name));
1675 memset(&args,0,sizeof(args));
1676 memset(&rda,0,sizeof(struct RDArgs));
1678 rda.RDA_Source.CS_Buffer = buf;
1679 rda.RDA_Source.CS_Length = end - buf;
1680 rda.RDA_Source.CS_CurChr = 0;
1681 rda.RDA_Flags = RDAF_NOPROMPT;
1683 while (rda.RDA_Source.CS_CurChr < rda.RDA_Source.CS_Length)
1685 res = ReadItem(buffer, sizeof(buffer), &rda.RDA_Source);
1687 DEBUG_MOUNT(KPrintF("ParseMountList: buffer <%s>\n", (IPTR)buffer));
1688 DEBUG_MOUNT(KPrintF("ParseMountList: ReadItem res %ld\n",res));
1690 if (res == ITEM_ERROR)
1692 return IoErr();
1695 if (res == ITEM_NOTHING &&
1696 rda.RDA_Source.CS_CurChr == rda.RDA_Source.CS_Length)
1698 return 0;
1701 if (res != ITEM_QUOTED && res != ITEM_UNQUOTED)
1703 return 1;
1706 s2 = buffer;
1708 while (*s2)
1710 s2++;
1713 if (s2 == buffer || s2[-1] != ':')
1715 DEBUG_MOUNT(KPrintF("ParseMountList: failure\n"));
1716 return ERR_DEVICENOTFOUND;
1719 *--s2 = 0;
1721 if (!Strnicmp(name, buffer, s2 - buffer) &&
1722 (!name[s2 - buffer] || (name[s2 - buffer] == ':' || !name[s2 - buffer + 1])))
1724 DEBUG_MOUNT(KPrintF("ParseMountList: found\n"));
1726 /* Copy the string so we get proper case - Piru */
1727 memcpy(name, buffer, s2 - buffer);
1728 name[s2 - buffer] = '\0';
1730 ptr = name;
1731 while (*ptr)
1733 if (*ptr++ == ':')
1735 ptr[-1] = '\0';
1736 break;
1740 DEBUG_MOUNT(KPrintF("ReadArgs..\n%s\n\n", (IPTR)&rda.RDA_Source.CS_Buffer[rda.RDA_Source.CS_CurChr]));
1742 if ((error=ReadMountArgs(params,
1743 &rda))!=RETURN_OK)
1745 DEBUG_MOUNT(KPrintF("ParseMountList: ReadArgs failed\n"));
1746 //return IoErr();
1749 return error;
1752 while (rda.RDA_Source.CS_CurChr < rda.RDA_Source.CS_Length)
1754 if (rda.RDA_Source.CS_Buffer[rda.RDA_Source.CS_CurChr++] == '\n')
1756 DEBUG_MOUNT(KPrintF("ParseMountList: reach the end of the block\n"));
1757 break;
1762 DEBUG_MOUNT(KPrintF("ParseMountList: mount found nothing\n"));
1763 return ERR_DEVICENOTFOUND;
1766 /************************************************************************************************/
1767 /************************************************************************************************/
1769 LONG checkmount(IPTR *params)
1771 struct DosEnvec *vec;
1773 vec = (struct DosEnvec *)&params[4];
1775 params[1] = (IPTR) DeviceString;
1777 if (IsFilesystem && (!flagargs[ARG_DEVICE]
1778 || !flagargs[ARG_SURFACES] || !flagargs[ARG_BLOCKSPERTRACK]
1779 || !flagargs[ARG_LOWCYL] || !flagargs[ARG_HIGHCYL]))
1781 ShowError("Could not find some of the following keywords:\n"
1782 " Surfaces, BlocksPerTrack, LowCyl, HighCyl, Device");
1783 return ERR_INVALIDKEYWORD;
1785 /* bootpri -129 shouldn't be started and not automatic mounted..whatever that means */
1786 if ((vec->de_BootPri < -129) || (vec->de_BootPri > 127))
1788 ShowError("BootPri %ld is not allowed. Legal range is -128..127",vec->de_BootPri);
1789 return ERROR_BAD_NUMBER;
1792 if (flagargs[ARG_GLOBVEC])
1794 if ((GlobalVec != -1) && (GlobalVec != -2))
1796 ShowError("Globvec %ld is not supported. Only -1 and -2 are supported here", GlobalVec);
1797 return ERROR_BAD_NUMBER;
1801 if (flagargs[ARG_STARTUP] && !StartupString)
1803 if (StartupValue >= 0x100)
1805 ShowError("Startup uses a too large numerical number %ld",StartupValue);
1806 return ERROR_BAD_NUMBER;
1810 return RETURN_OK;
1813 /************************************************************************************************/
1814 /************************************************************************************************/
1816 LONG mount(IPTR *params, STRPTR name)
1818 struct DosEnvec *vec;
1819 LONG error = RETURN_OK;
1820 struct DeviceNode *dn;
1821 STRPTR cp;
1823 for (cp = name; *cp != 0; cp++)
1824 *cp = ToUpper(*cp);
1826 DEBUG_MOUNT(KPrintF("MountDev: <%s>\n", (IPTR)name));
1828 if ((error=checkmount(params))!=RETURN_OK)
1830 DEBUG_MOUNT(KPrintF("MountDev: checkmount failed\n"));
1831 return error;
1834 vec = (struct DosEnvec *)&params[4];
1836 DEBUG_MOUNT(KPrintF("MountDev: DosName <%s>\n", (IPTR)name));
1837 DEBUG_MOUNT(KPrintF("MountDev: Filesystem <%s>\n", (IPTR)HandlerString + BSTR_OFFSET));
1838 DEBUG_MOUNT(KPrintF("MountDev: Device <%s>\n", (IPTR)DeviceString));
1839 DEBUG_MOUNT(KPrintF("MountDev: TableSize %ld\n",vec->de_TableSize));
1840 DEBUG_MOUNT(KPrintF("MountDev: SizeBlock %ld\n",vec->de_SizeBlock));
1841 DEBUG_MOUNT(KPrintF("MountDev: SecOrg %ld\n",vec->de_SecOrg));
1842 DEBUG_MOUNT(KPrintF("MountDev: Surfaces %ld\n",vec->de_Surfaces));
1843 DEBUG_MOUNT(KPrintF("MountDev: SectorsPerBlock %ld\n",vec->de_SectorPerBlock));
1844 DEBUG_MOUNT(KPrintF("MountDev: BlocksPerTrack %ld\n",vec->de_BlocksPerTrack));
1845 DEBUG_MOUNT(KPrintF("MountDev: Reserved %ld\n",vec->de_Reserved));
1846 DEBUG_MOUNT(KPrintF("MountDev: PreAlloc %ld\n",vec->de_PreAlloc));
1847 DEBUG_MOUNT(KPrintF("MountDev: Interleave %ld\n",vec->de_Interleave));
1848 DEBUG_MOUNT(KPrintF("MountDev: LowCyl %ld\n",vec->de_LowCyl));
1849 DEBUG_MOUNT(KPrintF("MountDev: UpperCyl %ld\n",vec->de_HighCyl));
1850 DEBUG_MOUNT(KPrintF("MountDev: NumBuffers %ld\n",vec->de_NumBuffers));
1851 DEBUG_MOUNT(if (vec->de_TableSize >= DE_BUFMEMTYPE))
1852 DEBUG_MOUNT(KPrintF("MountDev: BufMemType 0x%lx\n",vec->de_BufMemType));
1853 DEBUG_MOUNT(KPrintF("MountDev: MaxTransfer 0x%lx\n",vec->de_MaxTransfer));
1854 DEBUG_MOUNT(if (vec->de_TableSize >= DE_MASK))
1855 DEBUG_MOUNT(KPrintF("MountDev: Mask 0x%lx\n",vec->de_Mask));
1856 DEBUG_MOUNT(if (vec->de_TableSize >= DE_BOOTPRI))
1857 DEBUG_MOUNT(KPrintF("MountDev: BootPri %ld\n",vec->de_BootPri));
1858 DEBUG_MOUNT(if (vec->de_TableSize >= DE_DOSTYPE))
1859 DEBUG_MOUNT(KPrintF("MountDev: DosType 0x%lx\n",vec->de_DosType));
1860 DEBUG_MOUNT(if (vec->de_TableSize >= DE_BAUD))
1861 DEBUG_MOUNT(KPrintF("MountDev: Baud %ld\n",vec->de_Baud));
1862 DEBUG_MOUNT(if (vec->de_TableSize >= DE_CONTROL))
1863 DEBUG_MOUNT(KPrintF("MountDev: Control 0x%lx\n",vec->de_Control));
1864 DEBUG_MOUNT(if (vec->de_TableSize >= DE_BOOTBLOCKS))
1865 DEBUG_MOUNT(KPrintF("MountDev: BootBlocks %ld\n",vec->de_BootBlocks));
1867 if ((dn=MyMakeDosNode(name, IsEHandler ? params : NULL, StartupString)))
1869 DEBUG_MOUNT(KPrintF("MountDev: DeviceNode 0x%lx\n", (IPTR)dn));
1871 dn->dn_StackSize = StackSize;
1872 dn->dn_Priority = Priority;
1873 dn->dn_GlobalVec = (BPTR)GlobalVec;
1875 if (!IsEHandler && !StartupString)
1877 dn->dn_Startup = (BPTR)(SIPTR)StartupValue;
1880 if (IsFilesystem && ((ForceLoad==0) || (HandlerString==NULL)))
1882 DEBUG_MOUNT(KPrintF("MountDev: patchdosnode\n"));
1883 PatchDosNode(dn,vec->de_DosType);
1886 if (ForceLoad || dn->dn_SegList==BNULL)
1888 DEBUG_MOUNT(KPrintF("MountDev: Load Handler\n"));
1889 dn->dn_Handler = MKBADDR(HandlerString);
1891 else
1894 * We don't need the HandlerString anymore...free it
1896 if (HandlerString)
1898 FreeVec(HandlerString);
1899 HandlerString = NULL;
1902 DEBUG_MOUNT(KPrintF("MountDev: Name %b\n",dn->dn_Name));
1903 DEBUG_MOUNT(KPrintF("MountDev: Handler 0x%lx <%b>\n",dn->dn_Handler,dn->dn_Handler));
1904 DEBUG_MOUNT(KPrintF("MountDev: SegList 0x%lx\n",dn->dn_SegList));
1905 DEBUG_MOUNT(KPrintF("MountDev: StackSize %ld\n",dn->dn_StackSize));
1906 DEBUG_MOUNT(KPrintF("MountDev: Priority %ld\n",dn->dn_Priority));
1907 DEBUG_MOUNT(KPrintF(!IsEHandler && StartupString ? "MountDev: Startup <%b>\n" : "MountDev: Startup 0x%lx\n", dn->dn_Startup));
1908 DEBUG_MOUNT(KPrintF("MountDev: GlobalVec %ld\n",dn->dn_GlobalVec));
1910 if (dn->dn_SegList || dn->dn_Handler)
1912 if (AddDosEntry((struct DosList *)dn))
1914 DEBUG_MOUNT(KPrintF("MountDev: AddDosEntry worked\n"));
1916 * Don't free these anymore as they belong to the dosnode
1918 HandlerString = NULL;
1919 if (IsEHandler)
1921 UnitString = NULL;
1922 FlagsString = NULL;
1923 ControlString = NULL;
1925 if (Activate)
1927 strcat(name, ":");
1928 DEBUG_MOUNT(KPrintF("Activating \"%s\"\n", (IPTR)name));
1929 DeviceProc(name);
1931 error = 0;
1933 else
1935 DEBUG_MOUNT(KPrintF("MountDev: AddDosEntry failed\n"));
1936 error = ERROR_INVALID_RESIDENT_LIBRARY;
1937 if (HandlerString)
1939 FreeVec(HandlerString);
1943 else
1945 DEBUG_MOUNT(KPrintF("MountDev: no loadseg and no handler specified\n"));
1946 error = ERROR_OBJECT_NOT_FOUND;
1949 else
1951 error = ERROR_NO_FREE_STORE;
1954 return error;
1957 void ShowErrorArgs(char *s, IPTR *ap)
1959 if (IsCli)
1961 PutStr("ERROR: ");
1962 VPrintf(s, ap);
1963 PutStr("\n");
1965 else
1967 struct EasyStruct es =
1969 sizeof(struct EasyStruct),
1971 "Mount Failure",
1973 "OK"
1976 IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library", 36);
1977 if (IntuitionBase)
1979 EasyRequestArgs(NULL, &es, NULL, ap);
1980 CloseLibrary((struct Library *)IntuitionBase);
1985 void ShowFault(LONG code, char *s, ...)
1987 char buf[256];
1988 va_list ap;
1989 int l;
1991 va_start(ap, s);
1992 l = vsnprintf(buf, sizeof(buf) - 2, s, ap);
1993 va_end(ap);
1994 strcpy(&buf[l], ": ");
1995 l += 2;
1996 Fault(code, NULL, &buf[l], sizeof(buf) - l);
1997 if (IsCli)
1999 PutStr(buf);
2000 PutStr("\n");
2002 else
2004 struct EasyStruct es =
2006 sizeof(struct EasyStruct),
2008 "Mount Failure",
2009 buf,
2010 "OK"
2013 IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library", 36);
2014 if (IntuitionBase)
2016 EasyRequestArgs(NULL, &es, NULL, NULL);
2017 CloseLibrary((struct Library *)IntuitionBase);