r9263@lvps87-230-33-50: verhaegs | 2008-10-04 23:31:42 +0200
[AROS.git] / workbench / c / Mount.c
bloba280bca318b03791a428f79460f9f80c3797d225
1 /*
2 (C) 1995-2008 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
27 Sys:C
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 #define __stackparm __attribute__((varargs68k))
198 typedef struct Library *UtilityBase_t;
199 #else
200 #define PROGNAME "Mount"
201 typedef struct UtilityBase *UtilityBase_t;
202 #endif
204 #ifdef __PPC__
205 #define ARGS(ap) ap->overflow_arg_area
206 #else
207 #define ARGS(ap) (IPTR *)ap
208 #endif
210 #ifdef __AROS__
211 #define _WBenchMsg WBenchMsg
212 #endif
214 #ifdef AROS_FAST_BPTR
215 #define BSTR_EXTRA 1
216 #define BSTR_OFFSET 0
217 #define bstrcpy(dest, src, len) strcpy(dest, src)
218 #else
219 #define BSTR_EXTRA 2
220 #define BSTR_OFFSET 1
221 #define bstrcpy(dest, src, len) \
222 dest[0] = len; \
223 strcpy(&dest[1], src);
224 #endif
226 static const int __nocommandline;
227 const TEXT version[] = "\0$VER: " PROGNAME " 50.14 (10.1.2008)";
229 ULONG CheckDevice(char *name);
230 void InitParams(IPTR *params);
231 LONG readfile(STRPTR name, STRPTR *mem, LONG *size);
232 ULONG readmountlist(IPTR *params, STRPTR name, char *mountlist);
233 ULONG readmountfile(IPTR *params, STRPTR name);
234 void preparefile(STRPTR buf, LONG size);
235 LONG parsemountfile(IPTR *params, STRPTR buf, LONG size);
236 LONG parsemountlist(IPTR *params, STRPTR name, STRPTR buf, LONG size);
237 LONG mount(IPTR *params, STRPTR name);
238 void __stackparm ShowError(char *s, ...);
239 void ShowFault(LONG code, char *s, ...);
241 struct DosLibrary *DOSBase;
242 struct IntuitionBase *IntuitionBase;
243 UtilityBase_t UtilityBase;
244 struct Process *MyProcess;
246 ULONG StartupValue;
247 char *StartupString = NULL;
248 char *ControlString = NULL;
249 char *UnitString = NULL;
250 char *FlagsString = NULL;
251 ULONG StackSize;
252 ULONG Priority;
253 ULONG Activate;
254 int GlobalVec;
255 ULONG ForceLoad;
256 char *HandlerString;
257 char *DeviceString;
258 BOOL IsEHandler, IsFilesystem;
259 BOOL IsCli;
260 BOOL flagargs[NUM_ARGS];
261 extern struct WBStartup *_WBenchMsg;
263 int main(void)
265 STRPTR args[2];
266 IPTR *params;
267 LONG error = RETURN_FAIL;
268 struct RDArgs *rda;
269 char dirname[512];
271 if ((DOSBase = (struct DosLibrary *)OpenLibrary("dos.library",37))!=0)
273 if ((UtilityBase = (UtilityBase_t)OpenLibrary("utility.library",37)))
275 memset(&flagargs, 0, sizeof(flagargs));
276 IsEHandler = TRUE;
277 IsFilesystem = TRUE;
278 if (!_WBenchMsg)
280 memset(args,0,sizeof(args));
281 if ((rda = ReadArgs("DEVICE/M,FROM/K", (IPTR *)args, NULL)))
283 STRPTR *MyDevPtr;
284 int len;
286 error = 0;
288 MyDevPtr =(STRPTR *)args[0];
289 if (MyDevPtr)
291 while (*MyDevPtr)
293 DEBUG_MOUNT(Printf("Mount: Current DevName <%s>\n",
294 (ULONG)*MyDevPtr));
296 if ((params = AllocVec(PARAMSLENGTH, MEMF_PUBLIC | MEMF_CLEAR)))
298 StackSize = 8192;
299 Priority = 5;
300 GlobalVec = -1;
301 HandlerString = NULL;
302 DeviceString = NULL;
303 StartupString = NULL;
305 len = strlen(*MyDevPtr);
306 if ((*MyDevPtr)[len-1] == ':')
308 /* search for a devicename */
309 DEBUG_MOUNT(Printf("Mount: search for devname <%s>\n",
310 (ULONG)*MyDevPtr));
312 strcpy(dirname, *MyDevPtr);
313 dirname[len-1] = '\0';
315 if ((error=CheckDevice(dirname))!=RETURN_OK)
317 DEBUG_MOUNT(Printf("Mount: is already mounted..stop\n"));
319 else
321 if (args[1])
323 error=readmountlist(params, dirname, args[1]);
324 DEBUG_MOUNT(Printf("Mount: readmountlist(%s) returned %ld\n", args[1], error));
326 else
328 char **SearchPtr;
329 ULONG slen;
331 DEBUG_MOUNT(Printf("Mount: search device definition <%s>\n",
332 (ULONG)*MyDevPtr));
333 for (SearchPtr=(char**) SearchTable;
334 *SearchPtr;
335 SearchPtr++)
337 if(SetSignal(0L,SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C)
339 error = RETURN_FAIL;
340 SetIoErr(ERROR_BREAK);
341 break;
344 slen = strlen(*SearchPtr);
345 strcpy(dirname, *SearchPtr);
346 dirname[slen] = '\0';
347 strcat(dirname, *MyDevPtr);
348 dirname[slen+len-1] = '\0';
349 DEBUG_MOUNT(Printf("Mount: try File <%s>\n", (ULONG)dirname));
351 error=readmountfile(params, dirname);
352 DEBUG_MOUNT(Printf("Mount: readmountfile returned %ld\n", error));
353 if (error != ERROR_OBJECT_NOT_FOUND)
354 break;
356 if (error == ERROR_OBJECT_NOT_FOUND)
358 DEBUG_MOUNT(Printf("Mount: try from mountlist\n"));
359 dirname[0] = '\0';
360 strcat(dirname, *MyDevPtr);
361 dirname[len-1] = '\0';
362 error=readmountlist(params, dirname, MOUNTLIST);
363 DEBUG_MOUNT(Printf("Mount: readmountlist(default) returned %ld\n", error));
368 else
370 /* search for a filename */
372 LONG err;
374 UBYTE stack_ap[sizeof(struct AnchorPath) + 3];
375 struct AnchorPath *MyAp = (struct AnchorPath *) (((ULONG) stack_ap + 3) & ~3);
377 DEBUG_MOUNT(Printf("Mount: search for mountfile <%s>\n",
378 (ULONG)*MyDevPtr));
380 memset(MyAp,0,sizeof(struct AnchorPath));
382 dirname[0] = '\0';
383 for (err = MatchFirst(*MyDevPtr,MyAp);
384 err == 0;
385 err = MatchNext(MyAp))
387 if (MyAp->ap_Flags & APF_DirChanged)
389 DEBUG_MOUNT(Printf("Mount: Changed directories...\n"));
392 if (NameFromLock(MyAp->ap_Current->an_Lock,
393 dirname,
394 sizeof(dirname)) == FALSE)
396 ShowFault(IoErr(), "Error on NameFromLock");
397 break;
399 if (AddPart(dirname,
400 &(MyAp->ap_Info.fib_FileName[0]),
401 sizeof(dirname)) == FALSE)
403 ShowFault(IoErr(), "Error on AddPart");
404 break;
406 if (MyAp->ap_Info.fib_DirEntryType > 0)
408 if (MyAp->ap_Flags & APF_DIDDIR)
410 DEBUG_MOUNT(Printf("Mount: Ascending from directory %s\n",
411 (ULONG)dirname));
413 else
415 DEBUG_MOUNT(Printf("Mount: The next dir is ... %s\n", (ULONG)dirname));
417 /* clear the completed directory flag */
418 MyAp->ap_Flags &= ~APF_DIDDIR;
421 else
423 /* Here is code for handling each particular file */
425 DEBUG_MOUNT(Printf("Mount: try File <%s>\n",
426 (ULONG)dirname));
428 memset(&flagargs, 0, sizeof(flagargs));
429 IsEHandler = TRUE;
430 IsFilesystem = TRUE;
431 error=readmountfile(params, dirname);
432 DEBUG_MOUNT(Printf("Mount: readmount file returned %ld\n", error));
435 /* This absolutely, positively must be called, all of the time. */
436 MatchEnd(MyAp);
438 if (err == ERROR_NO_MORE_ENTRIES)
440 SetIoErr(0);
442 else
444 /* if it was real error promote it - Piru */
445 error = err;
448 FreeVec(params);
450 else
452 error = ERROR_NO_FREE_STORE;
453 break;
455 MyDevPtr++;
458 FreeArgs(rda);
459 } /* if (rda != NULL) */
460 else
462 error = IoErr();
465 if (error && error != ERROR_NO_MORE_ENTRIES && error < ERR_SPECIAL)
467 ShowFault(error, "ERROR");
469 error = RETURN_FAIL;
471 else
473 error = error < ERR_SPECIAL ? RETURN_OK : RETURN_FAIL;
477 else
479 /* wb startup */
480 if (_WBenchMsg->sm_NumArgs >= 2)
482 if ((params = AllocVec(PARAMSLENGTH,
483 MEMF_PUBLIC | MEMF_CLEAR)))
485 int i;
487 for (i = 1; i < _WBenchMsg->sm_NumArgs; i++)
489 BPTR olddir;
491 DEBUG_MOUNT(kprintf("Mount: try File <%s>\n",
492 (ULONG) _WBenchMsg->sm_ArgList[i].wa_Name));
494 olddir = CurrentDir(_WBenchMsg->sm_ArgList[i].wa_Lock);
496 error=readmountfile(params, _WBenchMsg->sm_ArgList[i].wa_Name);
497 DEBUG_MOUNT(kprintf("Mount: readmountfile returned %ld\n", error));
498 if (error && error != ERROR_NO_MORE_ENTRIES && error < ERR_SPECIAL)
499 ShowFault(error, "ERROR");
501 (void) CurrentDir(olddir);
504 FreeVec(params);
506 else
508 error = ERROR_NO_FREE_STORE;
512 CloseLibrary((struct Library *)UtilityBase);
514 CloseLibrary((struct Library *)DOSBase);
517 return error;
520 /************************************************************************************************/
521 /************************************************************************************************/
522 ULONG CheckDevice(char *name)
524 struct DosList *dl;
525 ULONG Status;
527 DEBUG_CHECK(Printf("CheckDevice: <%s>\n",
528 name));
530 dl = LockDosList(LDF_DEVICES | LDF_VOLUMES | LDF_ASSIGNS | LDF_READ);
531 if ((dl = FindDosEntry(dl,name,LDF_DEVICES | LDF_VOLUMES | LDF_ASSIGNS)))
533 Status = ERROR_OBJECT_EXISTS;
535 else
537 Status = 0;
539 UnLockDosList(LDF_DEVICES | LDF_VOLUMES | LDF_ASSIGNS | LDF_READ);
541 DEBUG_CHECK(Printf("CheckDevice: object %sexist\n", Status ? "does" : "doesn't "));
543 return Status;
546 /************************************************************************************************/
547 /************************************************************************************************/
549 void InitParams(IPTR *params)
551 struct DosEnvec *vec;
553 memset(params,0, PARAMSLENGTH);
555 vec = (struct DosEnvec *)&params[4];
557 vec->de_TableSize = DE_BOOTBLOCKS;
558 vec->de_SizeBlock = 512 >> 2;
559 vec->de_Surfaces = 2;
560 vec->de_SectorPerBlock = 1;
561 vec->de_BlocksPerTrack = 11;
562 vec->de_Reserved = 2;
564 /* memset above
565 vec->de_SecOrg = 0;
566 vec->de_BootBlocks = 0;
567 vec->de_BootPri = 0;
568 vec->de_PreAlloc = 0;
569 vec->de_Interleave = 0;
570 vec->de_LowCyl = 0;
573 vec->de_HighCyl = 79;
574 vec->de_NumBuffers = 20; /* On AmigaOS 3.9 it's 5 */
575 vec->de_BufMemType = 3;
576 vec->de_Baud = 1200;
577 vec->de_MaxTransfer = 0x7fffffff;
578 vec->de_Mask = 0xfffffffe;
579 vec->de_DosType = ID_DOS_DISK;
581 StackSize = 8192;
582 Priority = 5;
583 GlobalVec = -1;
584 HandlerString = NULL;
585 DeviceString = NULL;
586 StartupString = NULL;
589 void FreeStuff(void)
591 if (UnitString)
593 FreeVec(UnitString);
594 UnitString = NULL;
596 if (FlagsString)
598 FreeVec(FlagsString);
599 FlagsString = NULL;
601 if (ControlString)
603 FreeVec(ControlString);
604 ControlString = NULL;
606 if (HandlerString)
608 FreeVec(HandlerString);
609 HandlerString = NULL;
611 if (DeviceString)
613 FreeVec(DeviceString);
614 DeviceString = NULL;
616 if (StartupString)
618 FreeVec(StartupString);
619 StartupString = NULL;
623 /************************************************************************************************/
624 /************************************************************************************************/
626 ULONG GetValue(char *buf, char **end)
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 STRPTR 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, (IPTR *)args, 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] != NULL)
722 flagargs[i] = TRUE;
726 if (args[ARG_HANDLER] != NULL)
728 s = (STRPTR)args[ARG_HANDLER];
729 IsEHandler = FALSE;
730 IsFilesystem = FALSE;
732 else if (args[ARG_EHANDLER] != NULL)
734 s = (STRPTR)args[ARG_EHANDLER];
735 IsEHandler = TRUE;
736 IsFilesystem = FALSE;
738 else if (args[ARG_FILESYSTEM] != NULL)
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] != NULL)
761 StackSize = GetValue(args[ARG_STACKSIZE], NULL);
764 if (args[ARG_PRIORITY] != NULL)
766 Priority = GetValue(args[ARG_PRIORITY], NULL);
769 if (args[ARG_GLOBVEC] != NULL)
771 GlobalVec = GetValue(args[ARG_GLOBVEC], NULL);
774 if (args[ARG_FORCELOAD] != NULL)
776 ForceLoad = GetValue((STRPTR)args[ARG_FORCELOAD], NULL);
779 if (args[ARG_ACTIVATE] != NULL)
781 Activate = GetValue(args[ARG_ACTIVATE], NULL);
784 if (args[ARG_DEVICE] != NULL)
786 int len;
788 DEBUG_MOUNT(Printf("ReadMountArgs: Device <%s>\n",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, args[ARG_DEVICE]);
804 if (args[ARG_UNIT] != NULL)
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(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, 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] != NULL)
837 // char *String;
839 DEBUG_MOUNT(Printf("ReadMountArgs: Flags <%s>\n",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(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, 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] != NULL)
884 vec->de_SizeBlock = GetValue(args[ARG_BLOCKSIZE], NULL) >> 2;
886 if (args[ARG_SURFACES] != NULL)
888 vec->de_Surfaces = GetValue(args[ARG_SURFACES], NULL);
890 if (args[ARG_SECTORSPERBLOCK] != NULL)
892 vec->de_SectorPerBlock = GetValue(args[ARG_SECTORSPERBLOCK], NULL);
894 if (args[ARG_BLOCKSPERTRACK] != NULL)
896 vec->de_BlocksPerTrack = GetValue(args[ARG_BLOCKSPERTRACK], NULL);
898 if (args[ARG_RESERVED] != NULL)
900 vec->de_Reserved = GetValue(args[ARG_RESERVED], NULL);
902 if (args[ARG_PREALLOC] != NULL)
904 vec->de_PreAlloc = GetValue(args[ARG_PREALLOC], NULL);
906 if (args[ARG_INTERLEAVE] != NULL)
908 vec->de_Interleave = GetValue(args[ARG_INTERLEAVE], NULL);
910 if (args[ARG_LOWCYL] != NULL)
912 vec->de_LowCyl = GetValue(args[ARG_LOWCYL], NULL);
914 if (args[ARG_HIGHCYL] != NULL)
916 vec->de_HighCyl = GetValue(args[ARG_HIGHCYL], NULL);
918 if (args[ARG_BUFFERS] != NULL)
920 vec->de_NumBuffers = GetValue(args[ARG_BUFFERS], NULL);
922 if (args[ARG_BUFMEMTYPE] != NULL)
924 vec->de_BufMemType = GetValue(args[ARG_BUFMEMTYPE], NULL);
926 if (args[ARG_BOOTPRI] != NULL)
928 vec->de_BootPri = GetValue(args[ARG_BOOTPRI], NULL);
930 if (args[ARG_BAUD] != NULL)
932 vec->de_Baud = GetValue(args[ARG_BAUD], NULL);
934 if (args[ARG_MAXTRANSFER] != NULL)
936 vec->de_MaxTransfer = GetValue(args[ARG_MAXTRANSFER], NULL);
938 if (args[ARG_MASK] != NULL)
940 vec->de_Mask = GetValue(args[ARG_MASK], NULL);
943 if (args[ARG_DOSTYPE] != NULL)
945 vec->de_DosType = (IPTR)GetValue(args[ARG_DOSTYPE], NULL);
948 if (args[ARG_CONTROL] != NULL)
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(args[ARG_CONTROL]);
958 if (len < 0x100)
960 if ((ControlString=AllocVec(len + BSTR_EXTRA, MEMF_PUBLIC|MEMF_CLEAR)))
962 bstrcpy(ControlString, args[ARG_CONTROL], len);
963 vec->de_Control = (IPTR)MKBADDR((char*)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] != NULL)
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(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,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;
1112 if (Examine(lock, &fib))
1114 nameptr = fib.fib_FileName;
1115 memmove(name, nameptr, strlen(nameptr) + 1);
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(Printf("ReadMountFile: mount <%s>\n", (ULONG)name));
1131 if ((error=CheckDevice(name))!=RETURN_OK)
1133 return error;
1136 InitParams(params);
1138 DEBUG_MOUNT(Printf("ReadMountFile: readfile\n"));
1140 error = readfile(filename,
1141 &MountListBuf,
1142 &MountListBufSize);
1143 if (error==RETURN_OK)
1145 DEBUG_MOUNT(Printf("ReadMountFile: preparsefile\n"));
1146 preparefile(MountListBuf, MountListBufSize);
1149 DEBUG_MOUNT(Printf("ReadMountFile: parsemountfile\n"));
1150 if ((error = parsemountfile(params, MountListBuf, MountListBufSize))!=RETURN_OK)
1152 DEBUG_MOUNT(Printf("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(Printf("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(Printf("ReadMountFile: look for icon\n"));
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(Printf("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(Printf("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(Printf("ReadMountFile: skipped\n"));
1221 myargv++;
1224 FreeDiskObject(diskobj);
1226 else
1229 CloseLibrary(IconBase);
1233 if (mountinfo)
1235 DEBUG_MOUNT(Printf("ReadMountFile: mount information exists\n"));
1237 if ((error = mount(params,name)) != RETURN_OK)
1239 DEBUG_MOUNT(Printf("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(Printf("ReadFile: <%s>\n", (LONG) 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(Printf("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 /************************************************************************************************/
1444 void PatchDosNode(struct DeviceNode *MyDeviceNode,
1445 ULONG DosType)
1447 struct FileSysEntry *MyFileSysEntry;
1448 ULONG MyPatchFlags;
1450 DEBUG_PATCHDOSNODE(Printf("MakeDosNode: DeviceNode 0x%lx\n",
1451 (ULONG)MyDeviceNode));
1453 if ((MyFileSysEntry=GetFileSysEntry(DosType)))
1455 MyPatchFlags = MyFileSysEntry->fse_PatchFlags;
1457 DEBUG_PATCHDOSNODE(Printf("PatchDosNode: FileSysEntry 0x%lx PatchFlags 0x%lx\n",
1458 (ULONG)MyFileSysEntry,
1459 MyPatchFlags));
1461 if (MyPatchFlags)
1463 ULONG *PatchDeviceNode;
1464 ULONG *PatchDeviceNodeEnd;
1465 ULONG *PatchFileSysEntry;
1467 PatchFileSysEntry =(ULONG*) &MyFileSysEntry->fse_Type;
1468 PatchDeviceNode =(ULONG*) &MyDeviceNode->dn_Type;
1469 PatchDeviceNodeEnd =(ULONG*) ((ULONG) MyDeviceNode + sizeof(struct DeviceNode));
1471 while (MyPatchFlags)
1473 if (MyPatchFlags & 1)
1475 *PatchDeviceNode = *PatchFileSysEntry;
1477 PatchDeviceNode++;
1478 PatchFileSysEntry++;
1480 if (PatchDeviceNode >= PatchDeviceNodeEnd)
1482 /* Savety */
1483 break;
1486 MyPatchFlags >>= 1;
1490 else
1492 /* Mount with no BootNode */
1493 DEBUG_PATCHDOSNODE(Printf("PatchDosNode: Can't get FileSysEntry..no bootnode\n"));
1498 /************************************************************************************************/
1499 /************************************************************************************************/
1503 #define DOSNAME_INDEX 0
1504 #define EXECNAME_INDEX 1
1505 #define UNIT_INDEX 2
1506 #define FLAGS_INDEX 3
1507 #define ENVIROMENT_INDEX 4
1509 struct DeviceNode *MyMakeDosNode(char *DosName, IPTR *ParameterPkt, char *StartupName)
1511 int DosNameSize;
1512 int ExecNameSize;
1513 int MyEnvSize = 0;
1514 struct DeviceNode *MyDeviceNode = NULL;
1515 struct FileSysStartupMsg *MyFileSysStartupMsg = NULL;
1516 struct DosEnvec *MyDosEnvec = NULL;
1517 char *MyString = NULL;
1518 ULONG Status = FALSE;
1519 DEBUG_MAKEDOSNODE(Printf("MakeDosNode: Pkt 0x%lx\n",(IPTR)ParameterPkt));
1521 if (ParameterPkt)
1523 DEBUG_MAKEDOSNODE(Printf("MakeDosNode: DosName <%s> DeviceName <%s> Unit ", DosName, ParameterPkt[EXECNAME_INDEX]));
1524 DEBUG_MAKEDOSNODE(if (UnitString)
1525 Printf("<%s>",ParameterPkt[UNIT_INDEX]);
1526 else
1527 Printf("%ld",ParameterPkt[UNIT_INDEX]);)
1528 DEBUG_MAKEDOSNODE(Printf(" Flags 0x%lx DE_TABLESIZE 0x%lx\n", ParameterPkt[FLAGS_INDEX], ParameterPkt[ENVIROMENT_INDEX]));
1530 else
1532 DEBUG_MAKEDOSNODE(Printf("MakeDosNode: DosName <%s> Startup <%s>\n", (IPTR)DosName, (IPTR)StartupName));
1535 DosNameSize = strlen(DosName);
1537 if (ParameterPkt)
1539 if (ParameterPkt[EXECNAME_INDEX])
1541 ExecNameSize = strlen((UBYTE *)ParameterPkt[EXECNAME_INDEX]);
1543 else
1545 ExecNameSize = 0;
1547 MyEnvSize = (ParameterPkt[ENVIROMENT_INDEX] + 1) * sizeof(IPTR);
1549 else
1551 ExecNameSize = StartupName ? strlen(StartupName) : 0;
1554 if ((MyDeviceNode = AllocVec(sizeof(struct DeviceNode), MEMF_PUBLIC | MEMF_CLEAR)))
1556 DEBUG_MAKEDOSNODE(Printf("MakeDosNode: MyDeviceNode 0x%lx\n", (ULONG)MyDeviceNode));
1558 MyDeviceNode->dn_StackSize = 600;
1559 MyDeviceNode->dn_Priority = 10;
1561 if ((MyString=AllocVec(((DosNameSize + BSTR_EXTRA + 4) & ~3) + ((ExecNameSize + BSTR_EXTRA + 4) & ~3), MEMF_PUBLIC | MEMF_CLEAR)))
1563 bstrcpy(MyString, DosName, DosNameSize);
1565 MyDeviceNode->dn_Name = MKBADDR(MyString);
1567 if (ParameterPkt)
1569 if ((MyFileSysStartupMsg = AllocVec(sizeof(struct FileSysStartupMsg), MEMF_PUBLIC | MEMF_CLEAR)))
1571 DEBUG_MAKEDOSNODE(Printf("MakeDosNode: MyFileSysStartupMsg 0x%lx\n", (IPTR)MyFileSysStartupMsg));
1573 if ((MyDosEnvec = AllocVec(MyEnvSize, MEMF_PUBLIC | MEMF_CLEAR)))
1575 char *ExecNamePtr;
1577 DEBUG_MAKEDOSNODE(Printf("MakeDosNode: MyDosEnvec 0x%lx\n", (IPTR)MyDosEnvec));
1578 ExecNamePtr = &MyString[(1 + DosNameSize + BSTR_EXTRA + 3) & ~3];
1580 /* .device name must absolutely **NOT** include the 0 in the
1581 * length!!
1583 * the string *MUST* be 0 terminated, however!
1585 if (ParameterPkt[EXECNAME_INDEX])
1587 bstrcpy(ExecNamePtr, (UBYTE *)ParameterPkt[EXECNAME_INDEX], ExecNameSize);
1589 else
1591 ExecNamePtr[0] = 0;
1592 #ifndef AROS_FAST_BPTR
1593 ExecNamePtr[1] = 0;
1594 #endif
1596 MyFileSysStartupMsg->fssm_Device = MKBADDR(ExecNamePtr);
1597 MyFileSysStartupMsg->fssm_Unit = ParameterPkt[UNIT_INDEX];
1598 MyFileSysStartupMsg->fssm_Flags = ParameterPkt[FLAGS_INDEX];
1599 MyFileSysStartupMsg->fssm_Environ = MKBADDR(MyDosEnvec);
1600 MyDeviceNode->dn_Startup = MKBADDR(MyFileSysStartupMsg);
1602 CopyMem(&ParameterPkt[ENVIROMENT_INDEX], MyDosEnvec, MyEnvSize);
1604 Status=TRUE;
1605 DEBUG_MAKEDOSNODE(Printf("MakeDosNode: done\n"));
1609 else
1611 if (StartupName && ExecNameSize)
1613 char *StartupNamePtr;
1615 StartupNamePtr = &MyString[(1 + DosNameSize + BSTR_EXTRA + 3) & ~3];
1616 bstrcpy(StartupNamePtr, StartupName, ExecNameSize);
1617 MyDeviceNode->dn_Startup = MKBADDR(StartupNamePtr);
1619 Status=TRUE;
1623 if (Status)
1625 DEBUG_MAKEDOSNODE(Printf("MakeDosNode: done\n"));
1626 return MyDeviceNode;
1628 else
1630 DEBUG_MAKEDOSNODE(Printf("MakeDosNode: failed\n"));
1631 FreeVec(MyFileSysStartupMsg);
1632 FreeVec(MyDeviceNode);
1633 FreeVec(MyString);
1634 return NULL;
1640 /************************************************************************************************/
1641 /************************************************************************************************/
1644 LONG parsemountfile(IPTR *params, STRPTR buf, LONG size)
1646 STRPTR args[NUM_ARGS];
1647 LONG error;
1648 struct RDArgs rda;
1650 DEBUG_MOUNT(Printf("ParseMountFile:\n"));
1652 memset(&args, 0, sizeof(args));
1653 memset(&rda,0,sizeof(struct RDArgs));
1655 rda.RDA_Source.CS_Buffer = buf;
1656 rda.RDA_Source.CS_Length = size;
1657 rda.RDA_Source.CS_CurChr = 0;
1658 rda.RDA_Flags = RDAF_NOPROMPT;
1660 DEBUG_MOUNT(Printf("ReadArgs..\n%s\n\n",(ULONG)rda.RDA_Source.CS_Buffer));
1662 if ((error=ReadMountArgs(params,
1663 &rda))!=RETURN_OK)
1665 DEBUG_MOUNT(Printf("Parse: ReadArgs failed\n"));
1667 return error;
1670 /************************************************************************************************/
1671 /************************************************************************************************/
1674 LONG parsemountlist(IPTR *params,
1675 STRPTR name,
1676 STRPTR buf,
1677 LONG size)
1679 STRPTR args[NUM_ARGS];
1680 UBYTE buffer[1024];
1681 LONG error=RETURN_OK, res;
1682 STRPTR end = buf + size;
1683 STRPTR s2;
1684 char *ptr;
1685 struct RDArgs rda;
1687 DEBUG_MOUNT(Printf("ParseMountList: <%s>\n",(ULONG)name));
1689 memset(&args,0,sizeof(args));
1690 memset(&rda,0,sizeof(struct RDArgs));
1692 rda.RDA_Source.CS_Buffer = buf;
1693 rda.RDA_Source.CS_Length = end - buf;
1694 rda.RDA_Source.CS_CurChr = 0;
1695 rda.RDA_Flags = RDAF_NOPROMPT;
1697 while (rda.RDA_Source.CS_CurChr < rda.RDA_Source.CS_Length)
1699 res = ReadItem(buffer, sizeof(buffer), &rda.RDA_Source);
1701 DEBUG_MOUNT(Printf("ParseMountList: buffer <%s>\n",(ULONG)buffer));
1702 DEBUG_MOUNT(Printf("ParseMountList: ReadItem res %ld\n",res));
1704 if (res == ITEM_ERROR)
1706 return IoErr();
1709 if (res == ITEM_NOTHING &&
1710 rda.RDA_Source.CS_CurChr == rda.RDA_Source.CS_Length)
1712 return 0;
1715 if (res != ITEM_QUOTED && res != ITEM_UNQUOTED)
1717 return 1;
1720 s2 = buffer;
1722 while (*s2)
1724 s2++;
1727 if (s2 == buffer || s2[-1] != ':')
1729 DEBUG_MOUNT(Printf("ParseMountList: failure\n"));
1730 return ERR_DEVICENOTFOUND;
1733 *--s2 = 0;
1735 if (!Strnicmp(name, buffer, s2 - buffer) &&
1736 (!name[s2 - buffer] || (name[s2 - buffer] == ':' || !name[s2 - buffer + 1])))
1738 DEBUG_MOUNT(Printf("ParseMountList: found\n"));
1740 /* Copy the string so we get proper case - Piru */
1741 memcpy(name, buffer, s2 - buffer);
1742 name[s2 - buffer] = '\0';
1744 ptr = name;
1745 while (*ptr)
1747 if (*ptr++ == ':')
1749 ptr[-1] = '\0';
1750 break;
1754 DEBUG_MOUNT(Printf("ReadArgs..\n%s\n\n",(ULONG)&rda.RDA_Source.CS_Buffer[rda.RDA_Source.CS_CurChr]));
1756 if ((error=ReadMountArgs(params,
1757 &rda))!=RETURN_OK)
1759 DEBUG_MOUNT(Printf("ParseMountList: ReadArgs failed\n"));
1760 //return IoErr();
1763 return error;
1766 while (rda.RDA_Source.CS_CurChr < rda.RDA_Source.CS_Length)
1768 if (rda.RDA_Source.CS_Buffer[rda.RDA_Source.CS_CurChr++] == '\n')
1770 DEBUG_MOUNT(Printf("ParseMountList: reach the end of the block\n"));
1771 break;
1776 DEBUG_MOUNT(Printf("ParseMountList: mount found nothing\n"));
1777 return ERR_DEVICENOTFOUND;
1780 /************************************************************************************************/
1781 /************************************************************************************************/
1783 LONG checkmount(IPTR *params)
1785 struct DosEnvec *vec;
1787 vec = (struct DosEnvec *)&params[4];
1789 params[1] = (IPTR) DeviceString;
1791 if (IsFilesystem && (!flagargs[ARG_DEVICE]
1792 || !flagargs[ARG_SURFACES] || !flagargs[ARG_BLOCKSPERTRACK]
1793 || !flagargs[ARG_LOWCYL] || !flagargs[ARG_HIGHCYL]))
1795 ShowError("Could not find some of the following keywords:\n"
1796 " Surfaces, BlocksPerTrack, LowCyl, HighCyl, Device");
1797 return ERR_INVALIDKEYWORD;
1799 /* bootpri -129 shouldn't be started and not automatic mounted..whatever that means */
1800 if ((vec->de_BootPri < -129) || (vec->de_BootPri > 127))
1802 ShowError("BootPri %ld is not allowed. Legal range is -128..127",vec->de_BootPri);
1803 return ERROR_BAD_NUMBER;
1806 if (flagargs[ARG_GLOBVEC])
1808 if ((GlobalVec != -1) && (GlobalVec != -2))
1810 ShowError("Globvec %ld is not supported. Only -1 and -2 are supported here", GlobalVec);
1811 return ERROR_BAD_NUMBER;
1815 if (flagargs[ARG_STARTUP] && !StartupString)
1817 if (StartupValue >= 0x100)
1819 ShowError("Startup uses a too large numerical number %ld",StartupValue);
1820 return ERROR_BAD_NUMBER;
1824 return RETURN_OK;
1827 /************************************************************************************************/
1828 /************************************************************************************************/
1830 LONG mount(IPTR *params, STRPTR name)
1832 struct DosEnvec *vec;
1833 LONG error = RETURN_OK;
1834 struct DeviceNode *dn;
1836 strupr(name);
1837 DEBUG_MOUNT(Printf("MountDev: <%s>\n",(ULONG)name));
1839 if ((error=checkmount(params))!=RETURN_OK)
1841 DEBUG_MOUNT(Printf("MountDev: checkmount failed\n"));
1842 return error;
1845 vec = (struct DosEnvec *)&params[4];
1847 DEBUG_MOUNT(Printf("MountDev: DosName <%s>\n",(ULONG)name));
1848 DEBUG_MOUNT(Printf("MountDev: Filesystem <%s>\n",(ULONG)HandlerString + BSTR_OFFSET));
1849 DEBUG_MOUNT(Printf("MountDev: Device <%s>\n",(ULONG)DeviceString));
1850 DEBUG_MOUNT(Printf("MountDev: TableSize %ld\n",vec->de_TableSize));
1851 DEBUG_MOUNT(Printf("MountDev: SizeBlock %ld\n",vec->de_SizeBlock));
1852 DEBUG_MOUNT(Printf("MountDev: SecOrg %ld\n",vec->de_SecOrg));
1853 DEBUG_MOUNT(Printf("MountDev: Surfaces %ld\n",vec->de_Surfaces));
1854 DEBUG_MOUNT(Printf("MountDev: SectorsPerBlock %ld\n",vec->de_SectorPerBlock));
1855 DEBUG_MOUNT(Printf("MountDev: BlocksPerTrack %ld\n",vec->de_BlocksPerTrack));
1856 DEBUG_MOUNT(Printf("MountDev: Reserved %ld\n",vec->de_Reserved));
1857 DEBUG_MOUNT(Printf("MountDev: PreAlloc %ld\n",vec->de_PreAlloc));
1858 DEBUG_MOUNT(Printf("MountDev: Interleave %ld\n",vec->de_Interleave));
1859 DEBUG_MOUNT(Printf("MountDev: LowCyl %ld\n",vec->de_LowCyl));
1860 DEBUG_MOUNT(Printf("MountDev: UpperCyl %ld\n",vec->de_HighCyl));
1861 DEBUG_MOUNT(Printf("MountDev: NumBuffers %ld\n",vec->de_NumBuffers));
1862 DEBUG_MOUNT(if (vec->de_TableSize >= DE_BUFMEMTYPE))
1863 DEBUG_MOUNT(Printf("MountDev: BufMemType 0x%lx\n",vec->de_BufMemType));
1864 DEBUG_MOUNT(Printf("MountDev: MaxTransfer 0x%lx\n",vec->de_MaxTransfer));
1865 DEBUG_MOUNT(if (vec->de_TableSize >= DE_MASK))
1866 DEBUG_MOUNT(Printf("MountDev: Mask 0x%lx\n",vec->de_Mask));
1867 DEBUG_MOUNT(if (vec->de_TableSize >= DE_BOOTPRI))
1868 DEBUG_MOUNT(Printf("MountDev: BootPri %ld\n",vec->de_BootPri));
1869 DEBUG_MOUNT(if (vec->de_TableSize >= DE_DOSTYPE))
1870 DEBUG_MOUNT(Printf("MountDev: DosType 0x%lx\n",vec->de_DosType));
1871 DEBUG_MOUNT(if (vec->de_TableSize >= DE_BAUD))
1872 DEBUG_MOUNT(Printf("MountDev: Baud %ld\n",vec->de_Baud));
1873 DEBUG_MOUNT(if (vec->de_TableSize >= DE_CONTROL))
1874 DEBUG_MOUNT(Printf("MountDev: Control 0x%lx\n",vec->de_Control));
1875 DEBUG_MOUNT(if (vec->de_TableSize >= DE_BOOTBLOCKS))
1876 DEBUG_MOUNT(Printf("MountDev: BootBlocks %ld\n",vec->de_BootBlocks));
1878 if ((dn=MyMakeDosNode(name, IsEHandler ? params : NULL, StartupString)))
1880 DEBUG_MOUNT(Printf("MountDev: DeviceNode 0x%lx\n",(ULONG)dn));
1882 dn->dn_StackSize = StackSize;
1883 dn->dn_Priority = Priority;
1884 dn->dn_GlobalVec = (BPTR)GlobalVec;
1886 if (!IsEHandler && !StartupString)
1888 dn->dn_Startup = (BPTR)StartupValue;
1891 if (IsFilesystem && ((ForceLoad==0) || (HandlerString==NULL)))
1893 DEBUG_MOUNT(Printf("MountDev: patchdosnode\n"));
1894 PatchDosNode(dn,vec->de_DosType);
1897 if (ForceLoad || dn->dn_SegList==NULL)
1899 DEBUG_MOUNT(Printf("MountDev: Load Handler\n"));
1900 dn->dn_Handler = MKBADDR(HandlerString);
1902 else
1905 * We don't need the HandlerString anymore...free it
1907 if (HandlerString)
1909 FreeVec(HandlerString);
1910 HandlerString = NULL;
1913 DEBUG_MOUNT(Printf("MountDev: Name %b\n",dn->dn_Name));
1914 DEBUG_MOUNT(Printf("MountDev: Handler 0x%lx <%b>\n",dn->dn_Handler,dn->dn_Handler));
1915 DEBUG_MOUNT(Printf("MountDev: SegList 0x%lx\n",dn->dn_SegList));
1916 DEBUG_MOUNT(Printf("MountDev: StackSize %ld\n",dn->dn_StackSize));
1917 DEBUG_MOUNT(Printf("MountDev: Priority %ld\n",dn->dn_Priority));
1918 if (!IsEHandler && StartupString)
1919 DEBUG_MOUNT(Printf("MountDev: Startup <%b>\n", dn->dn_Startup));
1920 else
1921 DEBUG_MOUNT(Printf("MountDev: Startup 0x%lx\n",dn->dn_Startup));
1922 DEBUG_MOUNT(Printf("MountDev: GlobalVec %ld\n",dn->dn_GlobalVec));
1924 if (dn->dn_SegList || dn->dn_Handler)
1926 if (AddDosEntry((struct DosList *)dn))
1928 DEBUG_MOUNT(Printf("MountDev: AddDosEntry worked\n"));
1930 * Don't free these anymore as they belong to the dosnode
1932 HandlerString = NULL;
1933 if (IsEHandler)
1935 UnitString = NULL;
1936 FlagsString = NULL;
1937 ControlString = NULL;
1939 if (Activate)
1941 DEBUG_MOUNT(Printf("Activating\n"));
1942 strcat(name, ":");
1943 DeviceProc(name);
1945 error = 0;
1947 else
1949 DEBUG_MOUNT(Printf("MountDev: AddDosEntry failed\n"));
1950 error = ERROR_INVALID_RESIDENT_LIBRARY;
1951 if (HandlerString)
1953 FreeVec(HandlerString);
1957 else
1959 DEBUG_MOUNT(Printf("MountDev: no loadseg and no handler specified\n"));
1960 error = ERROR_OBJECT_NOT_FOUND;
1963 else
1965 error = ERROR_NO_FREE_STORE;
1968 return error;
1971 void ShowError(char *s, ...)
1973 va_list ap;
1975 va_start(ap, s);
1976 if (IsCli)
1978 PutStr("ERROR: ");
1979 VPrintf(s, ARGS(ap));
1980 PutStr("\n");
1982 else
1984 struct EasyStruct es =
1986 sizeof(struct EasyStruct),
1988 "Mount Failure",
1990 "OK"
1993 IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library", 36);
1994 if (IntuitionBase)
1996 EasyRequestArgs(NULL, &es, NULL, ARGS(ap));
1997 CloseLibrary((struct Library *)IntuitionBase);
2000 va_end(ap);
2003 void ShowFault(LONG code, char *s, ...)
2005 char buf[256];
2006 va_list ap;
2007 int l;
2009 va_start(ap, s);
2010 l = vsnprintf(buf, sizeof(buf) - 2, s, ap);
2011 va_end(ap);
2012 strcpy(&buf[l], ": ");
2013 l += 2;
2014 Fault(code, NULL, &buf[l], sizeof(buf) - l);
2015 if (IsCli)
2017 PutStr(buf);
2018 PutStr("\n");
2020 else
2022 struct EasyStruct es =
2024 sizeof(struct EasyStruct),
2026 "Mount Failure",
2027 buf,
2028 "OK"
2031 IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library", 36);
2032 if (IntuitionBase)
2034 EasyRequestArgs(NULL, &es, NULL, NULL);
2035 CloseLibrary((struct Library *)IntuitionBase);