Prevent partitions from extending beyond end of container partition.
[AROS.git] / workbench / c / Mount.c
blob3b6c825472d75a62e3be19a8f16b19a845d20ae6
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 <exec/devices.h>
60 #include <exec/io.h>
61 #include <exec/memory.h>
62 #include <exec/semaphores.h>
63 #include <exec/types.h>
64 #include <dos/dosextens.h>
65 #include <dos/exall.h>
66 #include <dos/filehandler.h>
67 #include <dos/rdargs.h>
68 #include <libraries/configvars.h>
69 #include <libraries/expansion.h>
70 #include <workbench/workbench.h>
71 #include <workbench/startup.h>
73 #include <proto/exec.h>
74 #include <proto/dos.h>
75 #include <proto/intuition.h>
76 #include <proto/utility.h>
77 #include <proto/icon.h>
78 #include <proto/expansion.h>
80 #ifndef __SASC
81 #ifdef __AROS__
82 #include <clib/arossupport_protos.h>
83 #else
84 #include <clib/debug_protos.h>
85 #endif
86 #else
87 typedef unsigned long IPTR;
88 #endif
90 #include <resources/filesysres.h>
91 #include <string.h>
92 #include <stdlib.h>
93 #include <stdio.h>
95 #define DEBUG_PATCHDOSNODE(x)
96 #define DEBUG_MOUNT(x)
97 #define DEBUG_MAKEDOSNODE(x)
98 #define DEBUG_CHECK(x)
100 #define MOUNTLIST "DEVS:MountList"
101 #define DOSDRIVERS "DEVS:DOSDrivers/"
102 #define STORAGEDRIVERS "SYS:Storage/DOSDrivers/"
103 #define PARAMSLENGTH (sizeof(struct DosEnvec) + sizeof(IPTR)*4)
105 enum
107 ERR_SPECIAL = 5000,
108 ERR_DEVICENOTFOUND,
109 ERR_INVALIDKEYWORD
112 const char *SearchTable[]=
115 "DEVS:DOSDrivers/",
116 #ifdef __MORPHOS__
117 "MOSSYS:DEVS/DOSDrivers/",
118 #endif
119 "SYS:Storage/DOSDrivers/",
120 #ifdef __MORPHOS__
121 "MOSSYS:Storage/DOSDrivers/",
122 #endif
123 NULL
127 * startup,control need to be handled differently.
130 enum
132 ARG_HANDLER,
133 ARG_EHANDLER,
134 ARG_FILESYSTEM,
135 ARG_DEVICE,
136 ARG_UNIT,
137 ARG_FLAGS,
138 ARG_BLOCKSIZE,
139 ARG_SURFACES,
140 ARG_BLOCKSPERTRACK,
141 ARG_SECTORSPERBLOCK,
142 ARG_RESERVED,
143 ARG_PREALLOC,
144 ARG_INTERLEAVE,
145 ARG_LOWCYL,
146 ARG_HIGHCYL,
147 ARG_BUFFERS,
148 ARG_BUFMEMTYPE,
149 ARG_MAXTRANSFER,
150 ARG_MASK,
151 ARG_BOOTPRI,
152 ARG_DOSTYPE,
153 ARG_BAUD,
154 ARG_CONTROL,
155 ARG_STACKSIZE,
156 ARG_PRIORITY,
157 ARG_GLOBVEC,
158 ARG_STARTUP,
159 ARG_ACTIVATE,
160 ARG_FORCELOAD,
161 NUM_ARGS
164 const UBYTE options[]=
165 "HANDLER/K,"
166 "EHANDLER/K,"
167 "FILESYSTEM/K,"
168 "DEVICE/K,"
169 "UNIT/K,"
170 "FLAGS/K,"
171 "SECTORSIZE=BLOCKSIZE/K,"
172 "SURFACES/K,"
173 "SECTORSPERTRACK=BLOCKSPERTRACK/K,"
174 "SECTORSPERBLOCK/K,"
175 "RESERVED/K,"
176 "PREALLOC/K,"
177 "INTERLEAVE/K,"
178 "LOWCYL/K,"
179 "HIGHCYL/K,"
180 "BUFFERS/K,"
181 "BUFMEMTYPE/K,"
182 "MAXTRANSFER/K,"
183 "MASK/K,"
184 "BOOTPRI/K,"
185 "DOSTYPE/K,"
186 "BAUD/K,"
187 "CONTROL/K,"
188 "STACKSIZE/K,"
189 "PRIORITY/K,"
190 "GLOBVEC/K,"
191 "STARTUP/K,"
192 "MOUNT=ACTIVATE/K,"
193 "FORCELOAD/K";
195 #ifdef __MORPHOS__
196 #define PROGNAME "Mount unofficial"
197 typedef struct Library *UtilityBase_t;
198 #else
199 #define PROGNAME "Mount"
200 typedef struct UtilityBase *UtilityBase_t;
201 #endif
203 #ifdef __AROS__
204 #define _WBenchMsg WBenchMsg
205 #endif
207 #ifdef AROS_FAST_BPTR
208 #define BSTR_EXTRA 1
209 #define BSTR_OFFSET 0
210 #define bstrcpy(dest, src, len) strcpy(dest, src)
211 #else
212 #define BSTR_EXTRA 2
213 #define BSTR_OFFSET 1
214 #define bstrcpy(dest, src, len) \
215 dest[0] = len; \
216 strcpy(&dest[1], src);
217 #endif
219 static const int __nocommandline;
220 const TEXT version[] = "\0$VER: " PROGNAME " 50.14 (10.1.2008)";
222 ULONG CheckDevice(char *name);
223 void InitParams(IPTR *params);
224 LONG readfile(STRPTR name, STRPTR *mem, LONG *size);
225 ULONG readmountlist(IPTR *params, STRPTR name, char *mountlist);
226 ULONG readmountfile(IPTR *params, STRPTR name);
227 void preparefile(STRPTR buf, LONG size);
228 LONG parsemountfile(IPTR *params, STRPTR buf, LONG size);
229 LONG parsemountlist(IPTR *params, STRPTR name, STRPTR buf, LONG size);
230 LONG mount(IPTR *params, STRPTR name);
231 void ShowErrorArgs(char *s, IPTR *ap);
232 void ShowFault(LONG code, char *s, ...);
234 #define ShowError(s, ...) \
236 IPTR __args[] = { AROS_PP_VARIADIC_CAST2IPTR(__VA_ARGS__) }; \
237 ShowErrorArgs(s, __args); \
240 struct DosLibrary *DOSBase;
241 struct IntuitionBase *IntuitionBase;
242 UtilityBase_t UtilityBase;
243 struct Process *MyProcess;
245 ULONG StartupValue;
246 char *StartupString = NULL;
247 char *ControlString = NULL;
248 char *UnitString = NULL;
249 char *FlagsString = NULL;
250 ULONG StackSize;
251 ULONG Priority;
252 ULONG Activate;
253 SIPTR GlobalVec;
254 ULONG ForceLoad;
255 char *HandlerString;
256 char *DeviceString;
257 BOOL IsEHandler, IsFilesystem;
258 BOOL IsCli;
259 BOOL flagargs[NUM_ARGS];
260 extern struct WBStartup *_WBenchMsg;
262 int main(void)
264 IPTR args[2];
265 IPTR *params;
266 LONG error = RETURN_FAIL;
267 struct RDArgs *rda;
268 char dirname[512];
270 if ((DOSBase = (struct DosLibrary *)OpenLibrary("dos.library",37))!=0)
272 if ((UtilityBase = (UtilityBase_t)OpenLibrary("utility.library",37)))
274 memset(&flagargs, 0, sizeof(flagargs));
275 IsEHandler = TRUE;
276 IsFilesystem = TRUE;
277 if (!_WBenchMsg)
279 memset(args,0,sizeof(args));
280 if ((rda = ReadArgs("DEVICE/M,FROM/K", args, NULL)))
282 STRPTR *MyDevPtr;
283 int len;
285 error = 0;
287 MyDevPtr =(STRPTR *)args[0];
288 if (MyDevPtr)
290 while (*MyDevPtr)
292 DEBUG_MOUNT(Printf("Mount: Current DevName <%s>\n",
293 (ULONG)*MyDevPtr));
295 if ((params = AllocVec(PARAMSLENGTH, MEMF_PUBLIC | MEMF_CLEAR)))
297 StackSize = 8192;
298 Priority = 5;
299 GlobalVec = -1;
300 HandlerString = NULL;
301 DeviceString = NULL;
302 StartupString = NULL;
304 len = strlen(*MyDevPtr);
305 if ((*MyDevPtr)[len-1] == ':')
307 /* search for a devicename */
308 DEBUG_MOUNT(Printf("Mount: search for devname <%s>\n",
309 (ULONG)*MyDevPtr));
311 strcpy(dirname, *MyDevPtr);
312 dirname[len-1] = '\0';
314 if ((error=CheckDevice(dirname))!=RETURN_OK)
316 DEBUG_MOUNT(Printf("Mount: is already mounted..stop\n"));
318 else
320 if (args[1])
322 error=readmountlist(params, dirname, (STRPTR)(args[1]));
323 DEBUG_MOUNT(Printf("Mount: readmountlist(%s) returned %ld\n", args[1], error));
325 else
327 char **SearchPtr;
328 ULONG slen;
330 DEBUG_MOUNT(Printf("Mount: search device definition <%s>\n",
331 (ULONG)*MyDevPtr));
332 for (SearchPtr=(char**) SearchTable;
333 *SearchPtr;
334 SearchPtr++)
336 if(SetSignal(0L,SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C)
338 error = RETURN_FAIL;
339 SetIoErr(ERROR_BREAK);
340 break;
343 slen = strlen(*SearchPtr);
344 strcpy(dirname, *SearchPtr);
345 dirname[slen] = '\0';
346 strcat(dirname, *MyDevPtr);
347 dirname[slen+len-1] = '\0';
348 DEBUG_MOUNT(Printf("Mount: try File <%s>\n", (ULONG)dirname));
350 error=readmountfile(params, dirname);
351 DEBUG_MOUNT(Printf("Mount: readmountfile returned %ld\n", error));
352 if (error != ERROR_OBJECT_NOT_FOUND)
353 break;
355 if (error == ERROR_OBJECT_NOT_FOUND)
357 DEBUG_MOUNT(Printf("Mount: try from mountlist\n"));
358 dirname[0] = '\0';
359 strcat(dirname, *MyDevPtr);
360 dirname[len-1] = '\0';
361 error=readmountlist(params, dirname, MOUNTLIST);
362 DEBUG_MOUNT(Printf("Mount: readmountlist(default) returned %ld\n", error));
367 else
369 /* search for a filename */
371 LONG err;
373 UBYTE stack_ap[sizeof(struct AnchorPath) + 3];
374 struct AnchorPath *MyAp = (struct AnchorPath *) (((IPTR) stack_ap + 3) & ~3);
376 DEBUG_MOUNT(Printf("Mount: search for mountfile <%s>\n",
377 (ULONG)*MyDevPtr));
379 memset(MyAp,0,sizeof(struct AnchorPath));
381 dirname[0] = '\0';
382 for (err = MatchFirst(*MyDevPtr,MyAp);
383 err == 0;
384 err = MatchNext(MyAp))
386 if (MyAp->ap_Flags & APF_DirChanged)
388 DEBUG_MOUNT(Printf("Mount: Changed directories...\n"));
391 if (NameFromLock(MyAp->ap_Current->an_Lock,
392 dirname,
393 sizeof(dirname)) == FALSE)
395 ShowFault(IoErr(), "Error on NameFromLock");
396 break;
398 if (AddPart(dirname,
399 &(MyAp->ap_Info.fib_FileName[0]),
400 sizeof(dirname)) == FALSE)
402 ShowFault(IoErr(), "Error on AddPart");
403 break;
405 if (MyAp->ap_Info.fib_DirEntryType > 0)
407 if (MyAp->ap_Flags & APF_DIDDIR)
409 DEBUG_MOUNT(Printf("Mount: Ascending from directory %s\n",
410 (ULONG)dirname));
412 else
414 DEBUG_MOUNT(Printf("Mount: The next dir is ... %s\n", (ULONG)dirname));
416 /* clear the completed directory flag */
417 MyAp->ap_Flags &= ~APF_DIDDIR;
420 else
422 /* Here is code for handling each particular file */
424 DEBUG_MOUNT(Printf("Mount: try File <%s>\n",
425 (ULONG)dirname));
427 memset(&flagargs, 0, sizeof(flagargs));
428 IsEHandler = TRUE;
429 IsFilesystem = TRUE;
430 error=readmountfile(params, dirname);
431 DEBUG_MOUNT(Printf("Mount: readmount file returned %ld\n", error));
434 /* This absolutely, positively must be called, all of the time. */
435 MatchEnd(MyAp);
437 if (err == ERROR_NO_MORE_ENTRIES)
439 SetIoErr(0);
441 else
443 /* if it was real error promote it - Piru */
444 error = err;
447 FreeVec(params);
449 else
451 error = ERROR_NO_FREE_STORE;
452 break;
454 MyDevPtr++;
457 FreeArgs(rda);
458 } /* if (rda != NULL) */
459 else
461 error = IoErr();
464 if (error && error != ERROR_NO_MORE_ENTRIES && error < ERR_SPECIAL)
466 ShowFault(error, "ERROR");
468 error = RETURN_FAIL;
470 else
472 error = error < ERR_SPECIAL ? RETURN_OK : RETURN_FAIL;
476 else
478 /* wb startup */
479 if (_WBenchMsg->sm_NumArgs >= 2)
481 if ((params = AllocVec(PARAMSLENGTH,
482 MEMF_PUBLIC | MEMF_CLEAR)))
484 int i;
486 for (i = 1; i < _WBenchMsg->sm_NumArgs; i++)
488 BPTR olddir;
490 DEBUG_MOUNT(kprintf("Mount: try File <%s>\n",
491 (ULONG) _WBenchMsg->sm_ArgList[i].wa_Name));
493 olddir = CurrentDir(_WBenchMsg->sm_ArgList[i].wa_Lock);
495 error=readmountfile(params, _WBenchMsg->sm_ArgList[i].wa_Name);
496 DEBUG_MOUNT(kprintf("Mount: readmountfile returned %ld\n", error));
497 if (error && error != ERROR_NO_MORE_ENTRIES && error < ERR_SPECIAL)
498 ShowFault(error, "ERROR");
500 (void) CurrentDir(olddir);
503 FreeVec(params);
505 else
507 error = ERROR_NO_FREE_STORE;
511 CloseLibrary((struct Library *)UtilityBase);
513 CloseLibrary((struct Library *)DOSBase);
516 return error;
519 /************************************************************************************************/
520 /************************************************************************************************/
521 ULONG CheckDevice(char *name)
523 struct DosList *dl;
524 ULONG Status;
526 DEBUG_CHECK(Printf("CheckDevice: <%s>\n",
527 name));
529 dl = LockDosList(LDF_DEVICES | LDF_VOLUMES | LDF_ASSIGNS | LDF_READ);
530 if ((dl = FindDosEntry(dl,name,LDF_DEVICES | LDF_VOLUMES | LDF_ASSIGNS)))
532 Status = ERROR_OBJECT_EXISTS;
534 else
536 Status = 0;
538 UnLockDosList(LDF_DEVICES | LDF_VOLUMES | LDF_ASSIGNS | LDF_READ);
540 DEBUG_CHECK(Printf("CheckDevice: object %sexist\n", Status ? "does" : "doesn't "));
542 return Status;
545 /************************************************************************************************/
546 /************************************************************************************************/
548 void InitParams(IPTR *params)
550 struct DosEnvec *vec;
552 memset(params,0, PARAMSLENGTH);
554 vec = (struct DosEnvec *)&params[4];
556 vec->de_TableSize = DE_BOOTBLOCKS;
557 vec->de_SizeBlock = 512 >> 2;
558 vec->de_Surfaces = 2;
559 vec->de_SectorPerBlock = 1;
560 vec->de_BlocksPerTrack = 11;
561 vec->de_Reserved = 2;
563 /* memset above
564 vec->de_SecOrg = 0;
565 vec->de_BootBlocks = 0;
566 vec->de_BootPri = 0;
567 vec->de_PreAlloc = 0;
568 vec->de_Interleave = 0;
569 vec->de_LowCyl = 0;
572 vec->de_HighCyl = 79;
573 vec->de_NumBuffers = 20; /* On AmigaOS 3.9 it's 5 */
574 vec->de_BufMemType = 3;
575 vec->de_Baud = 1200;
576 vec->de_MaxTransfer = 0x7fffffff;
577 vec->de_Mask = -2; /* 0xfffffffe, sign-extended on 64 bits */
578 vec->de_DosType = ID_DOS_DISK;
580 StackSize = 8192;
581 Priority = 5;
582 GlobalVec = -1;
583 HandlerString = NULL;
584 DeviceString = NULL;
585 StartupString = NULL;
588 void FreeStuff(void)
590 if (UnitString)
592 FreeVec(UnitString);
593 UnitString = NULL;
595 if (FlagsString)
597 FreeVec(FlagsString);
598 FlagsString = NULL;
600 if (ControlString)
602 FreeVec(ControlString);
603 ControlString = NULL;
605 if (HandlerString)
607 FreeVec(HandlerString);
608 HandlerString = NULL;
610 if (DeviceString)
612 FreeVec(DeviceString);
613 DeviceString = NULL;
615 if (StartupString)
617 FreeVec(StartupString);
618 StartupString = NULL;
622 /************************************************************************************************/
623 /************************************************************************************************/
625 static long GetValue(IPTR bufp, char **end)
627 char *buf = (char *)bufp;
628 int base;
629 char *c = buf;
631 /* I decided to leave this routine in order to prevent reading numbers starting from '0'
632 as octal. Probably this is not needed, or octal support would not do any harm, in this
633 case this routine is not needed at all - Pavel Fedin */
634 if ((c[0]=='-') || (c[1]=='+'))
635 c++;
636 if ((c[0] == '0') && (((c[1])=='x') || (c[1])=='X'))
637 base = 16;
638 else
639 base = 10;
640 return strtol(buf,end,base);
641 /* Left for reference - Pavel Fedin
642 ULONG Value;
643 ULONG Sign;
644 Value = 0;
645 Sign = 1;
646 if (buf[0]=='-')
648 Sign = -1;
649 buf++;
651 else
652 if (buf[0]=='+')
654 buf++;
657 if ((buf[0] == '0') && (((buf[1])=='x') || (buf[1])=='X'))
659 int num;
661 // base = hex
662 buf+=2;
663 while(*buf)
665 Value<<=4;
666 num=*buf++;
668 if((num >= 0x30) && (num <= 0x39))
670 num-=0x30;
671 Value+=num;
673 else
675 num |= 0x20;
677 if((num >= 0x61) && (num <= 0x66))
679 num-=(0x61-10);
680 Value+=num;
685 else
687 // base = dev
688 Value=atoi(buf);
690 return Value * Sign;
694 /************************************************************************************************/
695 /************************************************************************************************/
697 ULONG ReadMountArgs(IPTR *params, struct RDArgs *rda)
699 struct DosEnvec *vec;
700 IPTR args[NUM_ARGS];
701 struct RDArgs *MyRDA;
702 ULONG result = RETURN_OK;
703 int i;
704 char *s = NULL;
706 DEBUG_MOUNT(Printf("ReadMountArgs:\n%s\n\n",(ULONG)&rda->RDA_Source.CS_Buffer[rda->RDA_Source.CS_CurChr]));
708 memset(&args, 0, sizeof(args));
710 if (!(MyRDA = ReadArgs((STRPTR)options, &args[0], rda)))
712 DEBUG_MOUNT(Printf("ReadMountArgs: ReadArgs failed\n"));
713 DEBUG_MOUNT(PrintFault(IoErr(),"ReadMountArgs"));
714 //return (ULONG) IoErr();
715 return ERR_INVALIDKEYWORD;
718 for (i = 0; i < NUM_ARGS; i++)
720 if (args[i] != 0)
722 flagargs[i] = TRUE;
726 if (args[ARG_HANDLER] != 0)
728 s = (STRPTR)args[ARG_HANDLER];
729 IsEHandler = FALSE;
730 IsFilesystem = FALSE;
732 else if (args[ARG_EHANDLER] != 0)
734 s = (STRPTR)args[ARG_EHANDLER];
735 IsEHandler = TRUE;
736 IsFilesystem = FALSE;
738 else if (args[ARG_FILESYSTEM] != 0)
740 s = (STRPTR)args[ARG_FILESYSTEM];
741 IsEHandler = TRUE;
742 IsFilesystem = TRUE;
743 } else
744 s = NULL;
745 if (s)
747 int len;
748 DEBUG_MOUNT(Printf("ReadMountArgs: Handler <%s>\n",s));
749 len = strlen(s);
750 if (HandlerString)
752 FreeVec(HandlerString);
754 if ((HandlerString = AllocVec(len + BSTR_EXTRA, MEMF_PUBLIC|MEMF_CLEAR)))
756 bstrcpy(HandlerString, s, len);
759 if (args[ARG_STACKSIZE] != 0)
761 StackSize = GetValue(args[ARG_STACKSIZE], NULL);
764 if (args[ARG_PRIORITY] != 0)
766 Priority = GetValue(args[ARG_PRIORITY], NULL);
769 if (args[ARG_GLOBVEC] != 0)
771 GlobalVec = GetValue(args[ARG_GLOBVEC], NULL);
774 if (args[ARG_FORCELOAD] != 0)
776 ForceLoad = GetValue(args[ARG_FORCELOAD], NULL);
779 if (args[ARG_ACTIVATE] != 0)
781 Activate = GetValue(args[ARG_ACTIVATE], NULL);
784 if (args[ARG_DEVICE] != 0)
786 int len;
788 DEBUG_MOUNT(Printf("ReadMountArgs: Device <%s>\n",(STRPTR)args[ARG_DEVICE]));
790 len = strlen((STRPTR)args[ARG_DEVICE]);
792 if (DeviceString)
794 FreeVec(DeviceString);
796 if ((DeviceString = AllocVec(len+1,MEMF_PUBLIC|MEMF_CLEAR)))
798 //Printf("copying...\n");
800 strcpy(DeviceString, (STRPTR)args[ARG_DEVICE]);
804 if (args[ARG_UNIT] != 0)
806 if (UnitString)
808 FreeVec(UnitString);
809 UnitString = NULL;
811 params[2] = GetValue(args[ARG_UNIT], &s);
812 if (*s)
814 int len;
816 len = strlen((STRPTR)args[ARG_UNIT]);
818 DEBUG_MOUNT(Printf("ReadMountArgs: len %ld\n",len));
820 if ((UnitString = AllocVec(len + 1, MEMF_PUBLIC|MEMF_CLEAR)))
822 strcpy(UnitString, (STRPTR)args[ARG_UNIT]);
823 params[2] = (IPTR)UnitString;
824 DEBUG_MOUNT(Printf("ReadMountArgs: Unit String <%s>\n", (STRPTR)params[2]));
826 else
828 result = ERROR_NO_FREE_STORE;
829 goto error;
832 else
833 DEBUG_MOUNT(Printf("ReadMountArgs: Unit Value %ld\n",params[2]));
835 if (args[ARG_FLAGS] != 0)
837 // char *String;
839 DEBUG_MOUNT(Printf("ReadMountArgs: Flags <%s>\n",(STRPTR)args[ARG_FLAGS]));
840 if (FlagsString)
842 FreeVec(FlagsString);
843 FlagsString = NULL;
846 String = args[ARG_FLAGS];
848 if ((*String >= 0x30) && (*String <= 0x39))
850 params[3] = GetValue(String);
851 DEBUG_MOUNT(Printf("ReadMountArgs: Flag Value %ld\n",params[3]));
853 else
855 params[3] = GetValue(args[ARG_FLAGS], &s);
856 if (*s)
858 int len;
860 len = strlen((STRPTR)args[ARG_FLAGS]);
862 DEBUG_MOUNT(Printf("ReadMountArgs: len %ld\n",len));
864 if ((FlagsString = AllocVec(len + 1, MEMF_PUBLIC|MEMF_CLEAR)))
866 strcpy(FlagsString, (STRPTR)args[ARG_FLAGS]);
867 params[3] = (IPTR) FlagsString;
868 DEBUG_MOUNT(Printf("ReadMountArgs: Flags String <%s>\n",(STRPTR)params[3]));
870 else
872 result = ERROR_NO_FREE_STORE;
873 goto error;
876 else
877 DEBUG_MOUNT(Printf("ReadMountArgs: Flag Value %ld\n",params[3]));
880 vec = (struct DosEnvec *)&params[4];
882 if (args[ARG_BLOCKSIZE] != 0)
884 vec->de_SizeBlock = GetValue(args[ARG_BLOCKSIZE], NULL) >> 2;
886 if (args[ARG_SURFACES] != 0)
888 vec->de_Surfaces = GetValue(args[ARG_SURFACES], NULL);
890 if (args[ARG_SECTORSPERBLOCK] != 0)
892 vec->de_SectorPerBlock = GetValue(args[ARG_SECTORSPERBLOCK], NULL);
894 if (args[ARG_BLOCKSPERTRACK] != 0)
896 vec->de_BlocksPerTrack = GetValue(args[ARG_BLOCKSPERTRACK], NULL);
898 if (args[ARG_RESERVED] != 0)
900 vec->de_Reserved = GetValue(args[ARG_RESERVED], NULL);
902 if (args[ARG_PREALLOC] != 0)
904 vec->de_PreAlloc = GetValue(args[ARG_PREALLOC], NULL);
906 if (args[ARG_INTERLEAVE] != 0)
908 vec->de_Interleave = GetValue(args[ARG_INTERLEAVE], NULL);
910 if (args[ARG_LOWCYL] != 0)
912 vec->de_LowCyl = GetValue(args[ARG_LOWCYL], NULL);
914 if (args[ARG_HIGHCYL] != 0)
916 vec->de_HighCyl = GetValue(args[ARG_HIGHCYL], NULL);
918 if (args[ARG_BUFFERS] != 0)
920 vec->de_NumBuffers = GetValue(args[ARG_BUFFERS], NULL);
922 if (args[ARG_BUFMEMTYPE] != 0)
924 vec->de_BufMemType = GetValue(args[ARG_BUFMEMTYPE], NULL);
926 if (args[ARG_BOOTPRI] != 0)
928 vec->de_BootPri = GetValue(args[ARG_BOOTPRI], NULL);
930 if (args[ARG_BAUD] != 0)
932 vec->de_Baud = GetValue(args[ARG_BAUD], NULL);
934 if (args[ARG_MAXTRANSFER] != 0)
936 vec->de_MaxTransfer = GetValue(args[ARG_MAXTRANSFER], NULL);
938 if (args[ARG_MASK] != 0)
940 vec->de_Mask = GetValue(args[ARG_MASK], NULL);
943 if (args[ARG_DOSTYPE] != 0)
945 vec->de_DosType = (IPTR)GetValue(args[ARG_DOSTYPE], NULL);
948 if (args[ARG_CONTROL] != 0)
950 int len;
951 DEBUG_MOUNT(Printf("ReadMountArgs: Control <%s>\n",args[ARG_CONTROL]));
952 if (ControlString)
954 FreeVec(ControlString);
955 ControlString = NULL;
957 len = strlen((STRPTR)args[ARG_CONTROL]);
958 if (len < 0x100)
960 if ((ControlString=AllocVec(len + BSTR_EXTRA, MEMF_PUBLIC|MEMF_CLEAR)))
962 bstrcpy(ControlString, (STRPTR)args[ARG_CONTROL], len);
963 vec->de_Control = (IPTR)MKBADDR(ControlString);
965 else
967 ShowError("Unable to allocate Control string");
968 result = ERROR_NO_FREE_STORE;
969 goto error;
972 else
974 result = ERROR_LINE_TOO_LONG;
975 SetIoErr(result);
976 // ShowError("Control string too long");
977 goto error;
981 if (args[ARG_STARTUP] != 0)
983 // char *String;
985 DEBUG_MOUNT(Printf("ReadMountArgs: Startup <%s>\n",args[ARG_STARTUP]));
986 if (StartupString)
988 FreeVec(StartupString);
989 StartupString = NULL;
992 String = args[ARG_STARTUP];
993 if ((*String >= 0x30) && (*String <= 0x39))
995 StartupValue = GetValue(String);
997 else
999 StartupValue = GetValue(args[ARG_STARTUP], &s);
1000 if (*s)
1002 int len;
1004 len = strlen((STRPTR)args[ARG_STARTUP]);
1006 DEBUG_MOUNT(Printf("ReadMountArgs: len %ld\n",len));
1008 if ((StartupString = AllocVec(len + 1, MEMF_PUBLIC|MEMF_CLEAR)))
1010 strcpy(StartupString,(STRPTR)args[ARG_STARTUP]);
1012 else
1014 result = ERROR_NO_FREE_STORE;
1015 goto error;
1020 error:
1021 FreeArgs(MyRDA);
1023 return result;
1026 /************************************************************************************************/
1027 /************************************************************************************************/
1029 ULONG readmountlist(IPTR *params,
1030 STRPTR name,
1031 char *mountlist)
1033 STRPTR MountListBuf;
1034 LONG MountListBufSize;
1035 ULONG error;
1037 DEBUG_MOUNT(Printf("ReadMountList: find <%s> in mountlist <%s>\n",
1038 name,
1039 mountlist));
1041 error = readfile(mountlist,
1042 &MountListBuf,
1043 &MountListBufSize);
1044 if (error==RETURN_OK)
1046 preparefile(MountListBuf,
1047 MountListBufSize);
1050 InitParams(params);
1052 if ((error=parsemountlist(params,
1053 name,
1054 MountListBuf,
1055 MountListBufSize))==RETURN_OK)
1057 if ((error = mount(params,name))!=RETURN_OK)
1059 DEBUG_MOUNT(Printf("ReadMountList: mount failed error %ld\n",
1060 error));
1063 else
1065 switch (error)
1067 case ERR_DEVICENOTFOUND:
1068 case ERR_INVALIDKEYWORD:
1069 ShowError("Device '%s:' not found in file '%s'", name, mountlist);
1070 break;
1074 FreeStuff();
1075 FreeVec(MountListBuf);
1077 return error;
1080 /************************************************************************************************/
1081 /************************************************************************************************/
1083 ULONG readmountfile(IPTR *params, STRPTR filename)
1085 struct Library *IconBase;
1086 struct DiskObject *diskobj;
1087 char **myargv;
1088 STRPTR MountListBuf;
1089 LONG MountListBufSize;
1090 struct RDArgs rda;
1091 ULONG error = RETURN_FAIL;
1092 UBYTE *nameptr;
1093 int toollen;
1094 BOOL mountinfo=FALSE;
1095 char name[256+1];
1097 DEBUG_MOUNT(Printf("ReadMountFile: <%s>\n", (ULONG)filename));
1100 struct Process *me = (APTR) FindTask(NULL);
1101 APTR oldwinptr;
1102 BPTR lock;
1104 name[0] = '\0';
1106 oldwinptr = me->pr_WindowPtr;
1107 me->pr_WindowPtr = (APTR) -1;
1108 lock = Lock(filename, SHARED_LOCK);
1109 if (lock)
1111 struct FileInfoBlock *fib = (struct FileInfoBlock*)AllocDosObject(DOS_FIB, NULL);
1112 if (fib)
1114 if (Examine(lock, fib))
1116 nameptr = fib->fib_FileName;
1117 memmove(name, nameptr, strlen(nameptr) + 1);
1119 FreeDosObject(DOS_FIB, fib);
1121 UnLock(lock);
1123 me->pr_WindowPtr = oldwinptr;
1125 if (name[0] == '\0')
1127 nameptr = FilePart(filename);
1128 strcpy(name,
1129 nameptr);
1133 DEBUG_MOUNT(Printf("ReadMountFile: mount <%s>\n", (ULONG)name));
1135 if ((error=CheckDevice(name))!=RETURN_OK)
1137 return error;
1140 InitParams(params);
1142 DEBUG_MOUNT(Printf("ReadMountFile: readfile\n"));
1144 error = readfile(filename,
1145 &MountListBuf,
1146 &MountListBufSize);
1147 if (error==RETURN_OK)
1149 DEBUG_MOUNT(Printf("ReadMountFile: preparsefile\n"));
1150 preparefile(MountListBuf, MountListBufSize);
1153 DEBUG_MOUNT(Printf("ReadMountFile: parsemountfile\n"));
1154 if ((error = parsemountfile(params, MountListBuf, MountListBufSize))!=RETURN_OK)
1156 DEBUG_MOUNT(Printf("ReadMountFile: parsemountfile error %ld\n", error));
1157 ShowFault(IoErr(), "Mountfile '%s' is invalid", filename);
1159 else
1161 mountinfo = TRUE;
1163 FreeVec(MountListBuf);
1165 else
1167 DEBUG_MOUNT(Printf("ReadMountFile: mountfile not found..search for <%s.info>\n",
1168 filename));
1171 if ((error==RETURN_OK) ||
1172 (error==ERROR_OBJECT_NOT_FOUND))
1174 DEBUG_MOUNT(Printf("ReadMountFile: look for icon\n"));
1176 if ((IconBase = OpenLibrary("icon.library", 37)))
1178 if ((diskobj = GetDiskObject(filename)))
1180 myargv =(char**) diskobj->do_ToolTypes;
1181 if (myargv)
1183 while (*myargv)
1185 char *ToolPtr;
1186 ToolPtr = *myargv;
1187 DEBUG_MOUNT(Printf("ReadMountFile: ToolType <%s>\n",
1188 ToolPtr));
1189 if ((ToolPtr[0] != '(') && (ToolPtr[0] != '*') &&
1190 !((ToolPtr[0] == 'I') && (ToolPtr[1] == 'M') && (ToolPtr[3] == '=')))
1192 char *ToolString;
1193 toollen = strlen(ToolPtr);
1194 if ((ToolString = AllocVec(toollen + 2,MEMF_ANY)))
1196 memcpy(ToolString,ToolPtr,toollen);
1197 ToolString[toollen] = '\n';
1198 ToolString[toollen+1] = '\0';
1199 memset(&rda,0,sizeof(struct RDArgs));
1200 rda.RDA_Source.CS_Buffer = ToolString;
1201 rda.RDA_Source.CS_Length = toollen+1;
1202 rda.RDA_Source.CS_CurChr = 0;
1203 rda.RDA_Flags = RDAF_NOPROMPT;
1204 if ((ReadMountArgs(params, &rda)==RETURN_OK))
1206 mountinfo = TRUE;
1208 else
1210 DEBUG_MOUNT(Printf("ReadMountFile: ReadArgs failed error %ld\n",
1211 error));
1213 FreeVec(ToolString);
1215 else
1217 error = ERROR_NO_FREE_STORE;
1218 break;
1221 else
1223 DEBUG_MOUNT(Printf("ReadMountFile: skipped\n"));
1225 myargv++;
1228 FreeDiskObject(diskobj);
1230 else
1233 CloseLibrary(IconBase);
1237 if (mountinfo)
1239 DEBUG_MOUNT(Printf("ReadMountFile: mount information exists\n"));
1241 if ((error = mount(params,name)) != RETURN_OK)
1243 DEBUG_MOUNT(Printf("ReadMountFile: mount failed error %ld\n",
1244 error));
1248 FreeStuff();
1250 return error;
1253 /************************************************************************************************/
1254 /************************************************************************************************/
1257 LONG readfile(STRPTR name, STRPTR *mem, LONG *size)
1259 BPTR ml;
1260 ULONG rest,sub;
1261 STRPTR buf;
1262 struct Process *me = (struct Process *) FindTask(NULL);
1263 APTR oldwinptr;
1265 oldwinptr = me->pr_WindowPtr;
1266 me->pr_WindowPtr = (APTR) -1;
1267 ml = Open(name, MODE_OLDFILE);
1268 me->pr_WindowPtr = oldwinptr;
1270 DEBUG_MOUNT(Printf("ReadFile: <%s>\n", (LONG) name));
1272 if (ml)
1274 if (Seek(ml, 0, OFFSET_END) != -1)
1276 *size = Seek(ml, 0, OFFSET_BEGINNING);
1278 if (*size != -1)
1280 *mem = (STRPTR)AllocVec(*size+2, MEMF_ANY);
1282 if (*mem)
1284 rest = *size;
1285 buf = *mem;
1287 for (;;)
1289 if (!rest)
1291 Close(ml);
1293 *buf++ = '\n';
1294 *buf = '\0';
1296 return 0;
1299 sub = Read(ml, buf, rest);
1301 if (sub == -1)
1303 break;
1306 rest -= sub;
1307 buf += sub;
1310 FreeVec(*mem);
1312 else
1314 SetIoErr(ERROR_NO_FREE_STORE);
1319 Close(ml);
1322 DEBUG_MOUNT(Printf("ReadFile: error %ld\n", IoErr()));
1323 return IoErr();
1326 /************************************************************************************************/
1327 /************************************************************************************************/
1330 void preparefile(STRPTR buf, LONG size)
1332 STRPTR end = buf + size;
1334 while (buf < end)
1336 /* Convert comments to spaces */
1337 if (buf + 1 < end && *buf == '/' && buf[1] == '*')
1339 *buf++ = ' ';
1340 *buf++ = ' ';
1342 while (buf < end)
1344 if (*buf == '*')
1346 *buf++ = ' ';
1348 if (buf >= end)
1350 break;
1353 if (*buf == '/')
1355 *buf++ = ' ';
1356 break;
1359 else
1361 *buf++=' ';
1365 continue;
1368 /* Skip strings */
1369 if (*buf=='\"')
1372 * skip first
1374 buf++;
1375 while (buf < end && *buf != '\"')
1377 buf++;
1380 * skip last "
1382 buf++;
1383 continue;
1386 /* Convert '\n' and ';' to spaces */
1387 if (*buf == '\n' || *buf == ';')
1389 *buf++ = ' ';
1390 continue;
1393 /* Convert '#' to \n */
1394 if (*buf == '#')
1396 *buf++ = '\n';
1397 continue;
1400 /* Skip all other characters */
1401 buf++;
1405 /************************************************************************************************/
1406 /************************************************************************************************/
1408 struct FileSysEntry *GetFileSysEntry(ULONG DosType)
1411 struct FileSysResource *MyFileSysRes;
1412 struct FileSysEntry *MyFileSysEntry;
1413 struct FileSysEntry *CurrentFileSysEntry;
1415 MyFileSysEntry = NULL;
1416 MyFileSysRes = OpenResource(FSRNAME);
1417 if (MyFileSysRes)
1419 Forbid();
1420 CurrentFileSysEntry = (struct FileSysEntry*) MyFileSysRes->fsr_FileSysEntries.lh_Head;
1421 while (CurrentFileSysEntry->fse_Node.ln_Succ)
1423 if (CurrentFileSysEntry->fse_DosType == DosType)
1425 if (MyFileSysEntry)
1427 if (CurrentFileSysEntry->fse_Version > MyFileSysEntry->fse_Version)
1429 MyFileSysEntry = CurrentFileSysEntry;
1432 else
1434 MyFileSysEntry = CurrentFileSysEntry;
1437 CurrentFileSysEntry =(struct FileSysEntry*) CurrentFileSysEntry->fse_Node.ln_Succ;
1439 Permit();
1441 return MyFileSysEntry;
1444 /************************************************************************************************/
1445 /************************************************************************************************/
1447 #define PATCH_FIELD(f, name) \
1448 if (MyFileSysEntry->fse_PatchFlags & f) \
1449 MyDeviceNode->dn_ ## name = (typeof(MyDeviceNode->dn_ ## name))MyFileSysEntry->fse_ ## name
1451 void PatchDosNode(struct DeviceNode *MyDeviceNode, ULONG DosType)
1453 struct FileSysEntry *MyFileSysEntry;
1455 DEBUG_PATCHDOSNODE(Printf("MakeDosNode: DeviceNode 0x%P\n", MyDeviceNode));
1457 if ((MyFileSysEntry=GetFileSysEntry(DosType)))
1459 DEBUG_PATCHDOSNODE(Printf("PatchDosNode: FileSysEntry 0x%P PatchFlags 0x%08lx\n", MyFileSysEntry, MyFileSysEntry->fse_PatchFlags));
1461 PATCH_FIELD(0x0001, Type);
1462 PATCH_FIELD(0x0002, Task);
1463 PATCH_FIELD(0x0004, Lock);
1464 PATCH_FIELD(0x0008, Handler);
1465 PATCH_FIELD(0x0010, StackSize);
1466 PATCH_FIELD(0x0020, Priority);
1467 PATCH_FIELD(0x0040, Startup);
1468 PATCH_FIELD(0x0080, SegList);
1469 PATCH_FIELD(0x0100, GlobalVec);
1471 DEBUG_PATCHDOSNODE(else Printf("PatchDosNode: Can't get FileSysEntry..no bootnode\n"));
1475 /************************************************************************************************/
1476 /************************************************************************************************/
1480 #define DOSNAME_INDEX 0
1481 #define EXECNAME_INDEX 1
1482 #define UNIT_INDEX 2
1483 #define FLAGS_INDEX 3
1484 #define ENVIROMENT_INDEX 4
1486 struct DeviceNode *MyMakeDosNode(char *DosName, IPTR *ParameterPkt, char *StartupName)
1488 int DosNameSize;
1489 int ExecNameSize;
1490 int MyEnvSize = 0;
1491 struct DeviceNode *MyDeviceNode = NULL;
1492 struct FileSysStartupMsg *MyFileSysStartupMsg = NULL;
1493 struct DosEnvec *MyDosEnvec = NULL;
1494 char *MyString = NULL;
1495 ULONG Status = FALSE;
1496 DEBUG_MAKEDOSNODE(Printf("MakeDosNode: Pkt 0x%lx\n",(IPTR)ParameterPkt));
1498 if (ParameterPkt)
1500 DEBUG_MAKEDOSNODE(Printf("MakeDosNode: DosName <%s> DeviceName <%s> Unit ", DosName, ParameterPkt[EXECNAME_INDEX]));
1501 DEBUG_MAKEDOSNODE(if (UnitString)
1502 Printf("<%s>",ParameterPkt[UNIT_INDEX]);
1503 else
1504 Printf("%ld",ParameterPkt[UNIT_INDEX]);)
1505 DEBUG_MAKEDOSNODE(Printf(" Flags 0x%lx DE_TABLESIZE 0x%lx\n", ParameterPkt[FLAGS_INDEX], ParameterPkt[ENVIROMENT_INDEX]));
1507 else
1509 DEBUG_MAKEDOSNODE(Printf("MakeDosNode: DosName <%s> Startup <%s>\n", (IPTR)DosName, (IPTR)StartupName));
1512 DosNameSize = strlen(DosName);
1514 if (ParameterPkt)
1516 if (ParameterPkt[EXECNAME_INDEX])
1518 ExecNameSize = strlen((UBYTE *)ParameterPkt[EXECNAME_INDEX]);
1520 else
1522 ExecNameSize = 0;
1524 MyEnvSize = (ParameterPkt[ENVIROMENT_INDEX] + 1) * sizeof(IPTR);
1526 else
1528 ExecNameSize = StartupName ? strlen(StartupName) : 0;
1531 if ((MyDeviceNode = AllocVec(sizeof(struct DeviceNode), MEMF_PUBLIC | MEMF_CLEAR)))
1533 DEBUG_MAKEDOSNODE(Printf("MakeDosNode: MyDeviceNode 0x%lx\n", (ULONG)MyDeviceNode));
1535 MyDeviceNode->dn_StackSize = 600;
1536 MyDeviceNode->dn_Priority = 10;
1538 if ((MyString=AllocVec(((DosNameSize + BSTR_EXTRA + 4) & ~3) + ((ExecNameSize + BSTR_EXTRA + 4) & ~3), MEMF_PUBLIC | MEMF_CLEAR)))
1540 bstrcpy(MyString, DosName, DosNameSize);
1542 MyDeviceNode->dn_Name = MKBADDR(MyString);
1544 if (ParameterPkt)
1546 if ((MyFileSysStartupMsg = AllocVec(sizeof(struct FileSysStartupMsg), MEMF_PUBLIC | MEMF_CLEAR)))
1548 DEBUG_MAKEDOSNODE(Printf("MakeDosNode: MyFileSysStartupMsg 0x%lx\n", (IPTR)MyFileSysStartupMsg));
1550 if ((MyDosEnvec = AllocVec(MyEnvSize, MEMF_PUBLIC | MEMF_CLEAR)))
1552 char *ExecNamePtr;
1554 DEBUG_MAKEDOSNODE(Printf("MakeDosNode: MyDosEnvec 0x%lx\n", (IPTR)MyDosEnvec));
1555 ExecNamePtr = &MyString[(1 + DosNameSize + BSTR_EXTRA + 3) & ~3];
1557 /* .device name must absolutely **NOT** include the 0 in the
1558 * length!!
1560 * the string *MUST* be 0 terminated, however!
1562 if (ParameterPkt[EXECNAME_INDEX])
1564 bstrcpy(ExecNamePtr, (UBYTE *)ParameterPkt[EXECNAME_INDEX], ExecNameSize);
1566 else
1568 ExecNamePtr[0] = 0;
1569 #ifndef AROS_FAST_BPTR
1570 ExecNamePtr[1] = 0;
1571 #endif
1573 MyFileSysStartupMsg->fssm_Device = MKBADDR(ExecNamePtr);
1574 MyFileSysStartupMsg->fssm_Unit = ParameterPkt[UNIT_INDEX];
1575 MyFileSysStartupMsg->fssm_Flags = ParameterPkt[FLAGS_INDEX];
1576 MyFileSysStartupMsg->fssm_Environ = MKBADDR(MyDosEnvec);
1577 MyDeviceNode->dn_Startup = MKBADDR(MyFileSysStartupMsg);
1579 CopyMem(&ParameterPkt[ENVIROMENT_INDEX], MyDosEnvec, MyEnvSize);
1581 Status=TRUE;
1582 DEBUG_MAKEDOSNODE(Printf("MakeDosNode: done\n"));
1586 else
1588 if (StartupName && ExecNameSize)
1590 char *StartupNamePtr;
1592 StartupNamePtr = &MyString[(1 + DosNameSize + BSTR_EXTRA + 3) & ~3];
1593 bstrcpy(StartupNamePtr, StartupName, ExecNameSize);
1594 MyDeviceNode->dn_Startup = MKBADDR(StartupNamePtr);
1596 Status=TRUE;
1600 if (Status)
1602 DEBUG_MAKEDOSNODE(Printf("MakeDosNode: done\n"));
1603 return MyDeviceNode;
1605 else
1607 DEBUG_MAKEDOSNODE(Printf("MakeDosNode: failed\n"));
1608 FreeVec(MyFileSysStartupMsg);
1609 FreeVec(MyDeviceNode);
1610 FreeVec(MyString);
1611 return NULL;
1617 /************************************************************************************************/
1618 /************************************************************************************************/
1621 LONG parsemountfile(IPTR *params, STRPTR buf, LONG size)
1623 STRPTR args[NUM_ARGS];
1624 LONG error;
1625 struct RDArgs rda;
1627 DEBUG_MOUNT(Printf("ParseMountFile:\n"));
1629 memset(&args, 0, sizeof(args));
1630 memset(&rda,0,sizeof(struct RDArgs));
1632 rda.RDA_Source.CS_Buffer = buf;
1633 rda.RDA_Source.CS_Length = size;
1634 rda.RDA_Source.CS_CurChr = 0;
1635 rda.RDA_Flags = RDAF_NOPROMPT;
1637 DEBUG_MOUNT(Printf("ReadArgs..\n%s\n\n",(ULONG)rda.RDA_Source.CS_Buffer));
1639 if ((error=ReadMountArgs(params,
1640 &rda))!=RETURN_OK)
1642 DEBUG_MOUNT(Printf("Parse: ReadArgs failed\n"));
1644 return error;
1647 /************************************************************************************************/
1648 /************************************************************************************************/
1651 LONG parsemountlist(IPTR *params,
1652 STRPTR name,
1653 STRPTR buf,
1654 LONG size)
1656 STRPTR args[NUM_ARGS];
1657 UBYTE buffer[1024];
1658 LONG error=RETURN_OK, res;
1659 STRPTR end = buf + size;
1660 STRPTR s2;
1661 char *ptr;
1662 struct RDArgs rda;
1664 DEBUG_MOUNT(Printf("ParseMountList: <%s>\n",(ULONG)name));
1666 memset(&args,0,sizeof(args));
1667 memset(&rda,0,sizeof(struct RDArgs));
1669 rda.RDA_Source.CS_Buffer = buf;
1670 rda.RDA_Source.CS_Length = end - buf;
1671 rda.RDA_Source.CS_CurChr = 0;
1672 rda.RDA_Flags = RDAF_NOPROMPT;
1674 while (rda.RDA_Source.CS_CurChr < rda.RDA_Source.CS_Length)
1676 res = ReadItem(buffer, sizeof(buffer), &rda.RDA_Source);
1678 DEBUG_MOUNT(Printf("ParseMountList: buffer <%s>\n",(ULONG)buffer));
1679 DEBUG_MOUNT(Printf("ParseMountList: ReadItem res %ld\n",res));
1681 if (res == ITEM_ERROR)
1683 return IoErr();
1686 if (res == ITEM_NOTHING &&
1687 rda.RDA_Source.CS_CurChr == rda.RDA_Source.CS_Length)
1689 return 0;
1692 if (res != ITEM_QUOTED && res != ITEM_UNQUOTED)
1694 return 1;
1697 s2 = buffer;
1699 while (*s2)
1701 s2++;
1704 if (s2 == buffer || s2[-1] != ':')
1706 DEBUG_MOUNT(Printf("ParseMountList: failure\n"));
1707 return ERR_DEVICENOTFOUND;
1710 *--s2 = 0;
1712 if (!Strnicmp(name, buffer, s2 - buffer) &&
1713 (!name[s2 - buffer] || (name[s2 - buffer] == ':' || !name[s2 - buffer + 1])))
1715 DEBUG_MOUNT(Printf("ParseMountList: found\n"));
1717 /* Copy the string so we get proper case - Piru */
1718 memcpy(name, buffer, s2 - buffer);
1719 name[s2 - buffer] = '\0';
1721 ptr = name;
1722 while (*ptr)
1724 if (*ptr++ == ':')
1726 ptr[-1] = '\0';
1727 break;
1731 DEBUG_MOUNT(Printf("ReadArgs..\n%s\n\n",(ULONG)&rda.RDA_Source.CS_Buffer[rda.RDA_Source.CS_CurChr]));
1733 if ((error=ReadMountArgs(params,
1734 &rda))!=RETURN_OK)
1736 DEBUG_MOUNT(Printf("ParseMountList: ReadArgs failed\n"));
1737 //return IoErr();
1740 return error;
1743 while (rda.RDA_Source.CS_CurChr < rda.RDA_Source.CS_Length)
1745 if (rda.RDA_Source.CS_Buffer[rda.RDA_Source.CS_CurChr++] == '\n')
1747 DEBUG_MOUNT(Printf("ParseMountList: reach the end of the block\n"));
1748 break;
1753 DEBUG_MOUNT(Printf("ParseMountList: mount found nothing\n"));
1754 return ERR_DEVICENOTFOUND;
1757 /************************************************************************************************/
1758 /************************************************************************************************/
1760 LONG checkmount(IPTR *params)
1762 struct DosEnvec *vec;
1764 vec = (struct DosEnvec *)&params[4];
1766 params[1] = (IPTR) DeviceString;
1768 if (IsFilesystem && (!flagargs[ARG_DEVICE]
1769 || !flagargs[ARG_SURFACES] || !flagargs[ARG_BLOCKSPERTRACK]
1770 || !flagargs[ARG_LOWCYL] || !flagargs[ARG_HIGHCYL]))
1772 ShowError("Could not find some of the following keywords:\n"
1773 " Surfaces, BlocksPerTrack, LowCyl, HighCyl, Device");
1774 return ERR_INVALIDKEYWORD;
1776 /* bootpri -129 shouldn't be started and not automatic mounted..whatever that means */
1777 if ((vec->de_BootPri < -129) || (vec->de_BootPri > 127))
1779 ShowError("BootPri %ld is not allowed. Legal range is -128..127",vec->de_BootPri);
1780 return ERROR_BAD_NUMBER;
1783 if (flagargs[ARG_GLOBVEC])
1785 if ((GlobalVec != -1) && (GlobalVec != -2))
1787 ShowError("Globvec %ld is not supported. Only -1 and -2 are supported here", GlobalVec);
1788 return ERROR_BAD_NUMBER;
1792 if (flagargs[ARG_STARTUP] && !StartupString)
1794 if (StartupValue >= 0x100)
1796 ShowError("Startup uses a too large numerical number %ld",StartupValue);
1797 return ERROR_BAD_NUMBER;
1801 return RETURN_OK;
1804 /************************************************************************************************/
1805 /************************************************************************************************/
1807 LONG mount(IPTR *params, STRPTR name)
1809 struct DosEnvec *vec;
1810 LONG error = RETURN_OK;
1811 struct DeviceNode *dn;
1813 strupr(name);
1814 DEBUG_MOUNT(Printf("MountDev: <%s>\n",(ULONG)name));
1816 if ((error=checkmount(params))!=RETURN_OK)
1818 DEBUG_MOUNT(Printf("MountDev: checkmount failed\n"));
1819 return error;
1822 vec = (struct DosEnvec *)&params[4];
1824 DEBUG_MOUNT(Printf("MountDev: DosName <%s>\n",(ULONG)name));
1825 DEBUG_MOUNT(Printf("MountDev: Filesystem <%s>\n",(ULONG)HandlerString + BSTR_OFFSET));
1826 DEBUG_MOUNT(Printf("MountDev: Device <%s>\n",(ULONG)DeviceString));
1827 DEBUG_MOUNT(Printf("MountDev: TableSize %ld\n",vec->de_TableSize));
1828 DEBUG_MOUNT(Printf("MountDev: SizeBlock %ld\n",vec->de_SizeBlock));
1829 DEBUG_MOUNT(Printf("MountDev: SecOrg %ld\n",vec->de_SecOrg));
1830 DEBUG_MOUNT(Printf("MountDev: Surfaces %ld\n",vec->de_Surfaces));
1831 DEBUG_MOUNT(Printf("MountDev: SectorsPerBlock %ld\n",vec->de_SectorPerBlock));
1832 DEBUG_MOUNT(Printf("MountDev: BlocksPerTrack %ld\n",vec->de_BlocksPerTrack));
1833 DEBUG_MOUNT(Printf("MountDev: Reserved %ld\n",vec->de_Reserved));
1834 DEBUG_MOUNT(Printf("MountDev: PreAlloc %ld\n",vec->de_PreAlloc));
1835 DEBUG_MOUNT(Printf("MountDev: Interleave %ld\n",vec->de_Interleave));
1836 DEBUG_MOUNT(Printf("MountDev: LowCyl %ld\n",vec->de_LowCyl));
1837 DEBUG_MOUNT(Printf("MountDev: UpperCyl %ld\n",vec->de_HighCyl));
1838 DEBUG_MOUNT(Printf("MountDev: NumBuffers %ld\n",vec->de_NumBuffers));
1839 DEBUG_MOUNT(if (vec->de_TableSize >= DE_BUFMEMTYPE))
1840 DEBUG_MOUNT(Printf("MountDev: BufMemType 0x%lx\n",vec->de_BufMemType));
1841 DEBUG_MOUNT(Printf("MountDev: MaxTransfer 0x%lx\n",vec->de_MaxTransfer));
1842 DEBUG_MOUNT(if (vec->de_TableSize >= DE_MASK))
1843 DEBUG_MOUNT(Printf("MountDev: Mask 0x%lx\n",vec->de_Mask));
1844 DEBUG_MOUNT(if (vec->de_TableSize >= DE_BOOTPRI))
1845 DEBUG_MOUNT(Printf("MountDev: BootPri %ld\n",vec->de_BootPri));
1846 DEBUG_MOUNT(if (vec->de_TableSize >= DE_DOSTYPE))
1847 DEBUG_MOUNT(Printf("MountDev: DosType 0x%lx\n",vec->de_DosType));
1848 DEBUG_MOUNT(if (vec->de_TableSize >= DE_BAUD))
1849 DEBUG_MOUNT(Printf("MountDev: Baud %ld\n",vec->de_Baud));
1850 DEBUG_MOUNT(if (vec->de_TableSize >= DE_CONTROL))
1851 DEBUG_MOUNT(Printf("MountDev: Control 0x%lx\n",vec->de_Control));
1852 DEBUG_MOUNT(if (vec->de_TableSize >= DE_BOOTBLOCKS))
1853 DEBUG_MOUNT(Printf("MountDev: BootBlocks %ld\n",vec->de_BootBlocks));
1855 if ((dn=MyMakeDosNode(name, IsEHandler ? params : NULL, StartupString)))
1857 DEBUG_MOUNT(Printf("MountDev: DeviceNode 0x%lx\n",(ULONG)dn));
1859 dn->dn_StackSize = StackSize;
1860 dn->dn_Priority = Priority;
1861 dn->dn_GlobalVec = (BPTR)GlobalVec;
1863 if (!IsEHandler && !StartupString)
1865 dn->dn_Startup = (BPTR)(SIPTR)StartupValue;
1868 if (IsFilesystem && ((ForceLoad==0) || (HandlerString==NULL)))
1870 DEBUG_MOUNT(Printf("MountDev: patchdosnode\n"));
1871 PatchDosNode(dn,vec->de_DosType);
1874 if (ForceLoad || dn->dn_SegList==BNULL)
1876 DEBUG_MOUNT(Printf("MountDev: Load Handler\n"));
1877 dn->dn_Handler = MKBADDR(HandlerString);
1879 else
1882 * We don't need the HandlerString anymore...free it
1884 if (HandlerString)
1886 FreeVec(HandlerString);
1887 HandlerString = NULL;
1890 DEBUG_MOUNT(Printf("MountDev: Name %b\n",dn->dn_Name));
1891 DEBUG_MOUNT(Printf("MountDev: Handler 0x%lx <%b>\n",dn->dn_Handler,dn->dn_Handler));
1892 DEBUG_MOUNT(Printf("MountDev: SegList 0x%lx\n",dn->dn_SegList));
1893 DEBUG_MOUNT(Printf("MountDev: StackSize %ld\n",dn->dn_StackSize));
1894 DEBUG_MOUNT(Printf("MountDev: Priority %ld\n",dn->dn_Priority));
1895 if (!IsEHandler && StartupString)
1896 DEBUG_MOUNT(Printf("MountDev: Startup <%b>\n", dn->dn_Startup));
1897 else
1898 DEBUG_MOUNT(Printf("MountDev: Startup 0x%lx\n",dn->dn_Startup));
1899 DEBUG_MOUNT(Printf("MountDev: GlobalVec %ld\n",dn->dn_GlobalVec));
1901 if (dn->dn_SegList || dn->dn_Handler)
1903 if (AddDosEntry((struct DosList *)dn))
1905 DEBUG_MOUNT(Printf("MountDev: AddDosEntry worked\n"));
1907 * Don't free these anymore as they belong to the dosnode
1909 HandlerString = NULL;
1910 if (IsEHandler)
1912 UnitString = NULL;
1913 FlagsString = NULL;
1914 ControlString = NULL;
1916 if (Activate)
1918 DEBUG_MOUNT(Printf("Activating\n"));
1919 strcat(name, ":");
1920 DeviceProc(name);
1922 error = 0;
1924 else
1926 DEBUG_MOUNT(Printf("MountDev: AddDosEntry failed\n"));
1927 error = ERROR_INVALID_RESIDENT_LIBRARY;
1928 if (HandlerString)
1930 FreeVec(HandlerString);
1934 else
1936 DEBUG_MOUNT(Printf("MountDev: no loadseg and no handler specified\n"));
1937 error = ERROR_OBJECT_NOT_FOUND;
1940 else
1942 error = ERROR_NO_FREE_STORE;
1945 return error;
1948 void ShowErrorArgs(char *s, IPTR *ap)
1950 if (IsCli)
1952 PutStr("ERROR: ");
1953 VPrintf(s, ap);
1954 PutStr("\n");
1956 else
1958 struct EasyStruct es =
1960 sizeof(struct EasyStruct),
1962 "Mount Failure",
1964 "OK"
1967 IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library", 36);
1968 if (IntuitionBase)
1970 EasyRequestArgs(NULL, &es, NULL, ap);
1971 CloseLibrary((struct Library *)IntuitionBase);
1976 void ShowFault(LONG code, char *s, ...)
1978 char buf[256];
1979 va_list ap;
1980 int l;
1982 va_start(ap, s);
1983 l = vsnprintf(buf, sizeof(buf) - 2, s, ap);
1984 va_end(ap);
1985 strcpy(&buf[l], ": ");
1986 l += 2;
1987 Fault(code, NULL, &buf[l], sizeof(buf) - l);
1988 if (IsCli)
1990 PutStr(buf);
1991 PutStr("\n");
1993 else
1995 struct EasyStruct es =
1997 sizeof(struct EasyStruct),
1999 "Mount Failure",
2000 buf,
2001 "OK"
2004 IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library", 36);
2005 if (IntuitionBase)
2007 EasyRequestArgs(NULL, &es, NULL, NULL);
2008 CloseLibrary((struct Library *)IntuitionBase);