prism2.device: Compiler delint
[AROS.git] / workbench / c / Automount.c
blob0ef022b1e554329a77848e9c76955d53ae214629
1 /*
2 Copyright © 1995-2011, The AROS Development Team. All rights reserved.
3 $Id: $
4 */
6 #include <aros/debug.h>
7 #include <dos/dos.h>
8 #include <dos/rdargs.h>
9 #include <exec/lists.h>
10 #include <exec/memory.h>
11 #include <libraries/expansion.h>
12 #include <libraries/expansionbase.h>
13 #include <proto/alib.h>
14 #include <proto/arossupport.h>
15 #include <proto/dos.h>
16 #include <proto/exec.h>
17 #include <proto/expansion.h>
19 #include <stdlib.h>
20 #include <string.h>
22 struct HandlerNode
24 struct MinNode n;
25 ULONG id;
26 ULONG mask;
27 char handler[1];
30 struct MinList handlerlist;
31 APTR pool;
33 LONG parsePrefs(char *buffer, LONG size)
35 struct CSource csrc = {buffer, size, 0};
36 char ident[256];
37 LONG res;
38 WORD line = 1;
40 D(bug("[Automount] parsePrefs()\n"));
42 while (csrc.CS_CurChr < csrc.CS_Length)
44 struct HandlerNode *tn;
45 int i;
46 char *p;
47 ULONG id = 0;
48 ULONG mask = 0xFFFFFFFF;
50 DB2(bug("[parsePrefs] Cur %d, Length %d\n", csrc.CS_CurChr, csrc.CS_Length));
52 res = ReadItem(ident, 256, &csrc);
53 switch (res)
55 case ITEM_ERROR:
56 return IoErr();
58 case ITEM_UNQUOTED:
59 if (ident[0] == '#')
61 /* Skip over to the end of line */
62 while ((csrc.CS_CurChr < csrc.CS_Length) && (buffer[csrc.CS_CurChr] != '\n'))
63 csrc.CS_CurChr++;
65 goto next_line;
67 /* Fall through */
68 case ITEM_QUOTED:
69 p = ident;
70 for (i = 0; i < 4; i++)
72 UBYTE c;
74 if (!*p)
76 Printf("LINE %ld: Mailformed filesystem ID\n", line);
77 return -1;
80 c = *p++;
81 switch (c)
83 case '\\':
84 c = strtoul(p, &p, 16);
85 break;
87 case '?':
88 mask &= ~(0xFF000000 >> (i << 3));
89 c = 0;
92 id <<= 8;
93 id |= c;
95 break;
97 default:
98 Printf("LINE %ld: Missing filesystem ID\n", line);
99 return -1;
102 res = ReadItem(ident, 256, &csrc);
103 if (res == ITEM_ERROR)
104 return IoErr();
106 if (res != ITEM_EQUAL)
108 Printf("LINE %ld: Unexpected item after filesystem ID\n", line);
109 return -1;
112 res = ReadItem(ident, 256, &csrc);
113 if (res == ITEM_ERROR)
114 return IoErr();
116 if ((res != ITEM_QUOTED) && (res != ITEM_UNQUOTED))
118 Printf("LINE %ld: Missing handler name\n", line);
119 return -1;
122 res = strlen(ident);
123 tn = AllocPooled(pool, sizeof(struct HandlerNode) + res);
124 if (tn == NULL)
125 return ERROR_NO_FREE_STORE;
127 tn->id = id;
128 tn->mask = mask;
129 CopyMem(ident, tn->handler, res + 1);
131 AddTail((struct List *)&handlerlist, (struct Node *)tn);
133 next_line:
135 * Intentional ReadItem() bug workaround.
136 * Ungets '\n' every time, causing an infinite loop without this adjustment.
138 if ((csrc.CS_CurChr < csrc.CS_Length) && (buffer[csrc.CS_CurChr] == '\n'))
140 line++;
141 csrc.CS_CurChr++;
145 return 0;
148 static LONG LoadPrefs(STRPTR filename)
150 struct FileInfoBlock fib;
151 char *buffer;
152 LONG retval = 0;
153 LONG size;
154 BPTR fh;
156 D(bug("[Automount] LoadPrefs('%s')\n", filename));
158 fh = Open(filename, MODE_OLDFILE);
159 if (fh)
161 if (ExamineFH(fh, &fib))
163 if (fib.fib_Size>0)
165 buffer = AllocMem(fib.fib_Size, MEMF_PUBLIC | MEMF_CLEAR);
166 if (buffer)
168 size = Read(fh, buffer, fib.fib_Size);
169 if (size == fib.fib_Size)
170 retval = parsePrefs(buffer, size);
171 else
172 retval = IoErr();
174 FreeMem(buffer, fib.fib_Size);
176 else
177 retval = ERROR_NO_FREE_STORE;
180 else
181 retval = IoErr();
183 Close(fh);
186 return retval;
189 static struct HandlerNode *FindHandler(ULONG id)
191 struct HandlerNode *n;
193 ForeachNode(&handlerlist, n)
195 if (n->id == (id & n->mask))
196 return n;
199 return NULL;
202 static BOOL IsMounted(struct DeviceNode *dn)
204 BOOL ret = FALSE;
205 struct DosList *dl = LockDosList(LDF_DEVICES|LDF_READ);
207 while ((dl = NextDosEntry(dl, LDF_DEVICES)))
209 if (dl == (struct DosList *)dn)
211 ret = TRUE;
212 break;
216 UnLockDosList(LDF_DEVICES|LDF_READ);
217 return ret;
220 int __nocommandline = 1;
222 int main(void)
224 LONG res;
226 pool = CreatePool(1024, 1024, MEMF_ANY);
227 if (!pool)
229 PrintFault(ERROR_NO_FREE_STORE, "Automount");
230 return RETURN_FAIL;
233 NewList((struct List *)&handlerlist);
234 res = LoadPrefs("L:automount-config");
236 if (res == 0)
238 struct BootNode *n;
240 ForeachNode(&((struct ExpansionBase *)ExpansionBase)->MountList, n)
242 struct DeviceNode *dn = n->bn_DeviceNode;
244 D(bug("[Automount] Checking BootNode %b...\n", dn->dn_Name));
246 if ((!dn->dn_Task) && (!dn->dn_SegList) && (!dn->dn_Handler) && dn->dn_Startup)
248 struct FileSysStartupMsg *fssm = BADDR(dn->dn_Startup);
250 D(bug("[Automount] Not mounted\n"));
252 if (fssm->fssm_Environ)
254 struct DosEnvec *de = BADDR(fssm->fssm_Environ);
256 if (de)
258 struct HandlerNode *hn = FindHandler(de->de_DosType);
260 if (hn)
262 Printf("Mounting %b with %s\n", dn->dn_Name, hn->handler);
264 dn->dn_Handler = CreateBSTR(hn->handler);
265 if (!dn->dn_Handler)
267 res = ERROR_NO_FREE_STORE;
268 break;
271 if (!IsMounted(dn))
273 D(bug("[Automount] Adding DOS entry...\n"));
274 AddDosEntry((struct DosList *)dn);
277 if (n->bn_Flags & ADNF_STARTPROC)
279 char *buf;
281 D(bug("[Automount] Starting up...\n"));
283 res = AROS_BSTR_strlen(dn->dn_Name);
284 buf = AllocMem(res + 2, MEMF_ANY);
285 if (!buf)
287 res = ERROR_NO_FREE_STORE;
288 break;
291 CopyMem(AROS_BSTR_ADDR(dn->dn_Name), buf, res);
292 buf[res++] = ':';
293 buf[res++] = 0;
295 DeviceProc(buf);
296 FreeMem(buf, res);
304 else if (res != -1)
305 PrintFault(res, "Automount");
307 DeletePool(pool);
308 return RETURN_OK;