- Don't access list nodes after their memory has been freed.
[AROS.git] / workbench / tools / HDToolBox / prefs.c
blob4b8a86925d18bae0d35c232e108bb0b07b0c05ad
1 /*
2 Copyright © 1995-2011, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #include <dos/dos.h>
7 #include <dos/rdargs.h>
8 #include <exec/lists.h>
9 #include <exec/memory.h>
10 #include <workbench/icon.h>
11 #include <proto/dos.h>
12 #include <proto/exec.h>
13 #include <proto/icon.h>
14 #include <proto/uuid.h>
16 #include <stdio.h>
17 #include <stdlib.h>
18 #include <strings.h>
20 #include "debug.h"
21 #include "prefs.h"
22 #include "devices.h"
23 #include "hdtoolbox_support.h"
24 #include "platform.h"
26 struct List tabletypelist;
28 struct TableTypeNode *findTableTypeNodeName(STRPTR name)
30 struct TableTypeNode *ttn;
32 D(bug("[HDToolBox] findTableTypeNodeName('%s')\n", name));
34 ttn = (struct TableTypeNode *)tabletypelist.lh_Head;
35 while (ttn->ln.ln_Succ)
37 if (strcmp(ttn->pti->pti_Name, name) == 0)
38 return ttn;
39 ttn = (struct TableTypeNode *)ttn->ln.ln_Succ;
41 return NULL;
44 struct TableTypeNode *findTableTypeNode(ULONG tabletype)
46 struct TableTypeNode *ttn;
48 D(bug("[HDToolBox] findTableTypeNode()\n"));
50 ttn = (struct TableTypeNode *)tabletypelist.lh_Head;
51 while (ttn->ln.ln_Succ)
53 if (ttn->pti->pti_Type == tabletype)
54 return ttn;
55 ttn = (struct TableTypeNode *)ttn->ln.ln_Succ;
57 return NULL;
60 struct TypeNode *findPartitionType(struct PartitionType *type, ULONG tabletype)
62 struct TableTypeNode *ttn;
63 struct TypeNode *tn;
65 D(bug("[HDToolBox] findPartitionType()\n"));
67 ttn = findTableTypeNode(tabletype);
68 if (ttn)
70 tn = (struct TypeNode *)ttn->typelist->lh_Head;
71 while (tn->ln.ln_Succ)
73 if (tn->type.id_len == type->id_len)
75 if (memcmp(tn->type.id, type->id, type->id_len) == 0)
76 return tn;
78 tn = (struct TypeNode *)tn->ln.ln_Succ;
81 return NULL;
84 void getTableTypeList(struct List *list)
86 struct TableTypeNode *ttn;
87 int i;
89 D(bug("[HDToolBox] getTableTypeList()\n"));
91 NEWLIST(&tabletypelist);
92 for (i=0;PartitionBase->tables[i];i++)
94 ttn = AllocMem(sizeof(struct TableTypeNode), MEMF_PUBLIC | MEMF_CLEAR);
95 if (ttn)
97 ttn->typelist =
98 AllocMem(sizeof(struct List), MEMF_PUBLIC | MEMF_CLEAR);
99 if (ttn->typelist != NULL)
101 ttn->pti = PartitionBase->tables[i];
102 NEWLIST(ttn->typelist);
103 AddTail(list, &ttn->ln);
105 else
107 FreeMem(ttn, sizeof(struct TableTypeNode));
108 ttn = NULL;
114 static LONG parseType(struct TableTypeNode *ttn, ULONG id_len, char *ident, struct CSource *csrc, WORD line)
116 if (ttn && id_len)
118 LONG res;
119 struct TypeNode *tn = AllocMem(sizeof(struct TypeNode), MEMF_PUBLIC | MEMF_CLEAR);
121 if (tn == NULL)
122 return ERROR_NO_FREE_STORE;
124 tn->type.id_len = id_len;
126 switch (ttn->pti->pti_Type)
128 case PHPTT_GPT:
129 UUID_Parse(ident, (uuid_t *)&tn->type.id);
130 break;
132 default:
133 strcpyESC(tn->type.id, ident);
134 break;
137 res = ReadItem(ident, 256, csrc);
139 switch (res)
141 case ITEM_ERROR:
142 return IoErr();
144 case ITEM_EQUAL:
145 res = ReadItem(ident, 256, csrc);
147 switch (res)
149 case ITEM_ERROR:
150 return IoErr();
152 case ITEM_QUOTED:
153 res = strlen(ident) + 1;
155 tn->ln.ln_Name = AllocVec(res, MEMF_PUBLIC | MEMF_CLEAR);
156 if (tn->ln.ln_Name == NULL)
157 return ERROR_NO_FREE_STORE;
159 CopyMem(ident, tn->ln.ln_Name, res);
161 break;
163 default:
164 printf("LINE %d: Quoted expression expected\n", line);
165 return 0;
167 break;
169 default:
170 printf("LINE %d: Unexpected item after table id\n", line);
171 return 0;
174 AddTail(ttn->typelist, &tn->ln);
176 else
177 printf("LINE %d: Missing partition table type or IDLen\n", line);
179 return 0;
182 enum SectionNum
184 Section_Root,
185 Section_Devices,
186 Section_TableIDs
189 LONG parsePrefs(char *buffer, LONG size)
191 struct TableTypeNode *ttn=NULL;
192 struct CSource csrc = {buffer, size, 0};
193 struct DiskObject *hdtbicon=NULL;
194 char ident[256];
195 LONG res;
196 ULONG id_len = 0;
197 WORD current = Section_Root;
198 WORD line = 1;
200 D(bug("[HDToolBox] parsePrefs()\n"));
202 while (csrc.CS_CurChr < csrc.CS_Length)
204 DB2(bug("[parsePrefs] Cur %d, Length %d\n", csrc.CS_CurChr, csrc.CS_Length));
205 res = ReadItem(ident, 256, &csrc);
207 DB2(bug("[parsePrefs] Got item %d (%s)\n", res, ident));
209 switch (res)
211 case ITEM_ERROR:
212 return IoErr();
213 case ITEM_UNQUOTED:
214 if (strcasecmp(ident, "[Devices]") == 0)
215 current = Section_Devices;
216 else if (strcasecmp(ident, "[TableIDs]") == 0)
218 current = Section_TableIDs;
219 ttn = NULL;
220 id_len = 0;
222 else
224 switch (current)
226 case Section_Devices:
227 addDeviceName(ident);
228 break;
230 case Section_TableIDs:
231 if (strcasecmp(ident, "TableType") == 0)
233 res = ReadItem(ident, 256, &csrc);
235 switch (res)
237 case ITEM_ERROR:
238 return IoErr();
240 case ITEM_EQUAL:
241 res = ReadItem(ident, 256, &csrc);
243 switch (res)
245 case ITEM_ERROR:
246 return IoErr();
248 case ITEM_QUOTED:
249 ttn = findTableTypeNodeName(ident);
250 break;
252 case ITEM_UNQUOTED:
253 ttn = findTableTypeNode(strtoul(ident, NULL, 0));
254 break;
256 default:
257 printf("LINE %d: Unexpected item in TableType\n", line);
258 return 0;
261 if (ttn == 0)
263 printf("LINE %d: Unknown Table %s\n", line, ident);
264 return 0;
266 break;
268 default:
269 printf("LINE %d: Unexpected item after TableType\n", line);
270 return 0;
273 else if (strcasecmp(ident, "IDLen") == 0)
275 res = ReadItem(ident, 256, &csrc);
277 switch (res)
279 case ITEM_ERROR:
280 return IoErr();
282 case ITEM_EQUAL:
283 res = ReadItem(ident, 256, &csrc);
285 switch (res)
287 case ITEM_ERROR:
288 return IoErr();
290 case ITEM_UNQUOTED:
291 id_len = strtoul(ident, NULL, 0);
292 if (id_len == 0)
294 printf("LINE %d: Illegal value of IDLen\n", line);
295 return 0;
297 break;
299 default:
300 printf("LINE %d: Value in IDLen expected\n", line);
301 return 0;
303 break;
305 default:
306 printf("LINE %d: Unexpected item after IDLen\n", line);
307 return 0;
310 else if (strcasecmp(ident, "Default") == 0)
312 if (ttn && id_len)
314 res = ReadItem(ident, 256, &csrc);
316 switch (res)
318 case ITEM_ERROR:
319 return IoErr();
320 break;
322 case ITEM_EQUAL:
323 res = ReadItem(ident, 256, &csrc);
324 switch (res)
326 case ITEM_ERROR:
327 return IoErr();
329 case ITEM_QUOTED:
330 ttn->defaulttype.id_len = id_len;
331 strcpyESC(ttn->defaulttype.id, ident);
332 break;
334 default:
335 printf("LINE %d: Unexpected expression after Default\n", line);
336 return 0;
338 break;
340 default:
341 printf("LINE %d: Unexpected item after IDLen\n", line);
342 return 0;
345 else
347 printf("LINE %d: Unknown option '%s'\n", line, ident);
348 return 0;
351 else
353 res = parseType(ttn, id_len, ident, &csrc, line);
354 if (res)
355 return res;
358 break;
360 default:
361 printf("LINE %d: Unexpected item '%s' in prefs\n", line, ident);
362 return 0;
365 break;
367 case ITEM_QUOTED:
368 res = parseType(ttn, id_len, ident, &csrc, line);
369 if (res)
370 return res;
372 break;
374 case ITEM_NOTHING:
375 line++;
376 break;
380 * Intentional ReadItem() bug workaround.
381 * Ungets '\n' every time, causing an infinite loop without this adjustment.
383 if ((csrc.CS_CurChr < csrc.CS_Length) && (buffer[csrc.CS_CurChr] == '\n'))
384 csrc.CS_CurChr++;
387 hdtbicon = GetIconTags("HDToolBox",
388 ICONGETA_FailIfUnavailable, TRUE,
389 ICONGETA_IsDefaultIcon, FALSE,
390 TAG_DONE);
392 if (hdtbicon != NULL)
394 D(bug("[HDToolBox] Got our Icon..\n"));
395 if (hdtbicon->do_ToolTypes)
397 char *tt = NULL, *devicename;
398 int i = 0;
399 D(bug("[HDToolBox] Icon has tooltypes..\n"));
401 while ((tt = hdtbicon->do_ToolTypes[i]) != NULL)
403 if (strncmp(hdtbicon->do_ToolTypes[i], "DEVICE=", 7) == 0)
405 devicename = hdtbicon->do_ToolTypes[i] + 7;
406 D(bug("[HDToolBox] Adding Device '%s' from ToolType\n", devicename));
407 addDeviceName(devicename);
409 i++;
414 // EBR uses same types as MBR
415 findTableTypeNode(PHPTT_EBR)->typelist =
416 findTableTypeNode(PHPTT_MBR)->typelist;
418 return 0;
421 void LoadPrefs(STRPTR filename)
423 struct FileInfoBlock fib;
424 char *buffer;
425 LONG retval;
426 LONG size;
427 BPTR fh;
429 D(bug("[HDToolBox] LoadPrefs('%s')\n", filename));
431 getTableTypeList(&tabletypelist);
432 fh = Open(filename, MODE_OLDFILE);
433 if (fh)
435 if (ExamineFH(fh, &fib))
437 if (fib.fib_Size>0)
439 buffer = AllocMem(fib.fib_Size, MEMF_PUBLIC | MEMF_CLEAR);
440 if (buffer)
442 size = Read(fh, buffer, fib.fib_Size);
443 if (size == fib.fib_Size)
445 retval = parsePrefs(buffer, size);
446 if (retval)
447 PrintFault(retval, filename);
449 FreeMem(buffer, fib.fib_Size);
451 else
452 PrintFault(ERROR_NO_FREE_STORE, filename);
455 Close(fh);
457 else
458 PrintFault(IoErr(), filename);