Fixed binary search: no more infinite loops when vendor is unknown.
[tangerine.git] / workbench / libs / openurl / library / prefs.c
blobf48d2d95ed1771ae238fdc99b061d3bc43926242
1 /*
2 ** openurl.library-universal URL display and browser
3 ** launcher library
4 **
5 ** Written by Troels Walsted Hansen <troels@thule.no>
6 ** Placed in the public domain.
7 **
8 ** Developed by:
9 ** -Alfonso Ranieri <alforan@tin.it>
10 ** -Stefan Kost <ensonic@sonicpulse.de>
14 #include "lib.h"
15 #include <prefs/prefhdr.h>
17 /**************************************************************************/
19 #define ID_BRWS MAKE_ID('B','R','W','S')
20 #define ID_MLRS MAKE_ID('M','L','R','S')
21 #define ID_FTPS MAKE_ID('F','T','P','S')
22 #define ID_FLGS MAKE_ID('F','L','G','S')
23 #define ID_DEFS MAKE_ID('D','E','F','S')
25 #define BRWS_SIZE (sizeof(struct URL_BrowserNode)-sizeof(struct MinNode))
26 #define MLRS_SIZE (sizeof(struct URL_MailerNode)-sizeof(struct MinNode))
27 #define FTPS_SIZE (sizeof(struct URL_FTPNode)-sizeof(struct MinNode))
28 #define FLGS_SIZE (sizeof(ULONG))
29 #define DEFS_SIZE (4 * sizeof(ULONG))
31 /**************************************************************************/
33 struct URL_Prefs *
34 copyPrefs(struct URL_Prefs *old)
36 struct URL_Prefs *new;
37 LONG ver;
39 ver = old->up_Version;
40 if (ver!=PREFS_VERSION) return FALSE;
42 if ((new = allocPooled(sizeof(struct URL_Prefs))))
44 ULONG res;
46 new->up_Version = PREFS_VERSION;
47 new->up_Flags = old->up_Flags;
49 NEWLIST(&new->up_BrowserList);
50 NEWLIST(&new->up_MailerList);
51 NEWLIST(&new->up_FTPList);
53 if ((res = copyList((struct List *)&new->up_BrowserList,(struct List *)&old->up_BrowserList,sizeof(struct URL_BrowserNode))))
55 new->up_DefShow = old->up_DefShow;
56 new->up_DefBringToFront = old->up_DefBringToFront;
57 new->up_DefNewWindow = old->up_DefNewWindow;
58 new->up_DefLaunch = old->up_DefLaunch;
60 if ((res = copyList((struct List *)&new->up_MailerList,(struct List *)&old->up_MailerList,sizeof(struct URL_MailerNode))))
61 res = copyList((struct List *)&new->up_FTPList,(struct List *)&old->up_FTPList,sizeof(struct URL_FTPNode));
63 if (res) return new;
66 URL_FreePrefsA(new,NULL);
69 return NULL;
72 /**************************************************************************/
74 void
75 initPrefs(struct URL_Prefs *p)
77 memset(p,0,sizeof(*p));
79 p->up_Version = PREFS_VERSION;
81 QUICKNEWLIST(&p->up_BrowserList);
82 QUICKNEWLIST(&p->up_MailerList);
83 QUICKNEWLIST(&p->up_FTPList);
86 /**************************************************************************/
88 void
89 setDefaultPrefs(struct URL_Prefs *p)
91 struct URL_BrowserNode *bn;
92 struct URL_MailerNode *mn;
94 initPrefs(p);
96 p->up_Flags = DEF_FLAGS;
98 p->up_DefShow = DEF_DefShow;
99 p->up_DefBringToFront = DEF_DefBringToFront;
100 p->up_DefNewWindow = DEF_DefNewWindow;
101 p->up_DefLaunch = DEF_DefLaunch;
103 /* Browsers: IBrowse */
104 if (!(bn = allocPooled(sizeof(struct URL_BrowserNode)))) return;
105 bn->ubn_Flags = UNF_DISABLED;
106 strcpy(bn->ubn_Name,"IBrowse");
107 strcpy(bn->ubn_Path,"IBrowse \"%u\"");
108 strcpy(bn->ubn_Port,"IBROWSE");
109 strcpy(bn->ubn_ShowCmd,"SHOW");
110 strcpy(bn->ubn_ToFrontCmd,"SCREENTOFRONT");
111 strcpy(bn->ubn_OpenURLCmd,"GOTOURL \"%u\"");
112 strcpy(bn->ubn_OpenURLWCmd,"NEWWINDOW \"%u\"");
113 AddTail(LIST(&p->up_BrowserList),NODE(bn));
115 /* Browsers: AWeb */
116 if (!(bn = allocPooled(sizeof(struct URL_BrowserNode)))) return;
117 bn->ubn_Flags = UNF_DISABLED;
118 strcpy(bn->ubn_Name,"AWeb");
119 strcpy(bn->ubn_Path,"AWeb \"%u\"");
120 strcpy(bn->ubn_Port,"AWEB");
121 strcpy(bn->ubn_ShowCmd,"ICONIFY SHOW");
122 strcpy(bn->ubn_ToFrontCmd,"SCREENTOFRONT");
123 strcpy(bn->ubn_OpenURLCmd,"OPEN \"%u\"");
124 strcpy(bn->ubn_OpenURLWCmd,"NEW \"%u\"");
125 AddTail(LIST(&p->up_BrowserList),NODE(bn));
127 /* Browsers: Voyager */
128 if (!(bn = allocPooled(sizeof(struct URL_BrowserNode)))) return;
129 strcpy(bn->ubn_Name,"Voyager");
130 if (GetVar("Vapor/Voyager_LASTUSEDDIR",bn->ubn_Path,PATH_LEN,GVF_GLOBAL_ONLY)>0) AddPart(bn->ubn_Path,"V \"%u\"",PATH_LEN);
131 else
133 strcpy(bn->ubn_Path,"V \"%u\"");
134 bn->ubn_Flags = UNF_DISABLED;
136 strcpy(bn->ubn_Port,"VOYAGER");
137 strcpy(bn->ubn_ShowCmd,"SHOW");
138 strcpy(bn->ubn_ToFrontCmd,"SCREENTOFRONT");
139 strcpy(bn->ubn_OpenURLCmd,"OPENURL \"%u\"");
140 strcpy(bn->ubn_OpenURLWCmd,"OPENURL \"%u\" NEWWIN");
141 AddTail(LIST(&p->up_BrowserList),NODE(bn));
143 /* Mailers: SimpleMail */
144 if (!(mn = allocPooled(sizeof(struct URL_MailerNode)))) return;
145 mn->umn_Flags = UNF_DISABLED;
146 strcpy(mn->umn_Name,"SimpleMail");
147 strcpy(mn->umn_Path,"SimpleMail MAILTO=\"%a\" SUBJECT=\"%s\"");
148 strcpy(mn->umn_Port,"SIMPLEMAIL");
149 strcpy(mn->umn_ShowCmd,"SHOW");
150 strcpy(mn->umn_ToFrontCmd,"SCREENTOFRONT");
151 strcpy(mn->umn_WriteMailCmd,"MAILWRITE MAILTO=\"%a\" SUBJECT=\"%s\"");
152 AddTail(LIST(&p->up_MailerList),NODE(mn));
154 /* Mailers: YAM */
155 if (!(mn = allocPooled(sizeof(struct URL_MailerNode)))) return;
156 mn->umn_Flags = UNF_DISABLED;
157 strcpy(mn->umn_Name,"YAM 2.3");
158 strcpy(mn->umn_Path,"YAM:YAM MAILTO=\"%a\" SUBJECT=\"%s\" LETTER=\"%f\"");
159 strcpy(mn->umn_Port,"YAM");
160 strcpy(mn->umn_ShowCmd,"SHOW");
161 strcpy(mn->umn_ToFrontCmd,"SCREENTOFRONT");
162 strcpy(mn->umn_WriteMailCmd,"MAILWRITE;WRITETO \"%a\";WRITESUBJECT \"%s\";WRITEEDITOR \"CLEAR\";WRITEEDITOR \"TEXT %b\"");
163 //strcpy(mn->umn_WriteMailCmd,"MAILWRITE;WRITETO '%a';WRITESUBJECT '%s';WRITELETTER '%f'\"");
164 AddTail(LIST(&p->up_MailerList),NODE(mn));
166 /* Mailers: MicroDot II */
167 if (!(mn = allocPooled(sizeof(struct URL_MailerNode)))) return;
168 mn->umn_Flags = UNF_DISABLED;
169 strcpy(mn->umn_Name,"MicroDot II");
170 if (GetVar("Vapor/MD2_LASTUSEDDIR",mn->umn_Path,PATH_LEN,GVF_GLOBAL_ONLY)<0)
171 *mn->umn_Path = 0;
172 AddPart(mn->umn_Path,"MicroDot TO=\"%a\" SUBJECT=\"%s\" CONTENTS=\"%f\"",PATH_LEN);
173 strcpy(mn->umn_Port,"MD");
174 strcpy(mn->umn_ShowCmd,"SHOW");
175 strcpy(mn->umn_WriteMailCmd,"NEWMSGWINDOW TO=\"%a\" SUBJECT=\"%s\" CONTENTS=\"%f\"");
176 AddTail(LIST(&p->up_MailerList),NODE(mn));
178 /* Mailers: lola */
179 if (!(mn = allocPooled(sizeof(struct URL_MailerNode)))) return;
180 mn->umn_Flags = UNF_DISABLED;
181 strcpy(mn->umn_Name,"lola");
182 strcpy(mn->umn_Path,"lola TO=\"%a\" SUBJECT=\"%s\" TEXT=\"%b\" CX_POPUP CX_POPKEY=\"control alt l\"");
183 strcpy(mn->umn_Port,"LOLA");
184 strcpy(mn->umn_ShowCmd,"SHOW");
185 strcpy(mn->umn_WriteMailCmd,"FILL TO=\"%a\" SUBJECT=\"%s\" TEXT=\"%b\"");
186 AddTail(LIST(&p->up_MailerList),NODE(mn));
189 /**************************************************************************/
191 ULONG
192 savePrefs(UBYTE *filename,struct URL_Prefs *p)
194 struct IFFHandle *iffh;
195 ULONG res = FALSE;
197 if ((iffh = AllocIFF()))
199 if ((iffh->iff_Stream = Open(filename,MODE_NEWFILE)))
201 InitIFFasDOS(iffh);
203 if (!OpenIFF(iffh,IFFF_WRITE))
205 struct PrefHeader prhd;
206 struct URL_BrowserNode *bn;
207 struct URL_MailerNode *mn;
208 struct URL_FTPNode *fn;
210 if (PushChunk(iffh,ID_PREF,ID_FORM,IFFSIZE_UNKNOWN)) goto fail;
211 if (PushChunk(iffh,ID_PREF,ID_PRHD,sizeof(struct PrefHeader))) goto fail;
213 prhd.ph_Version = p->up_Version;
214 prhd.ph_Type = 0;
215 prhd.ph_Flags = 0;
217 if (WriteChunkBytes(iffh,&prhd,sizeof(struct PrefHeader))!=sizeof(struct PrefHeader))
218 goto fail;
220 if (PopChunk(iffh)) goto fail;
222 /* write browser nodes */
223 for (bn = (struct URL_BrowserNode *)p->up_BrowserList.mlh_Head;
224 bn->ubn_Node.mln_Succ;
225 bn = (struct URL_BrowserNode *)bn->ubn_Node.mln_Succ)
227 if (PushChunk(iffh,ID_PREF,ID_BRWS,BRWS_SIZE)) goto fail;
228 if (WriteChunkBytes(iffh,&bn->ubn_Flags,BRWS_SIZE)!=BRWS_SIZE) goto fail;
229 if (PopChunk(iffh)) goto fail;
232 /* write mailer nodes */
233 for (mn = (struct URL_MailerNode *)p->up_MailerList.mlh_Head;
234 mn->umn_Node.mln_Succ;
235 mn = (struct URL_MailerNode *)mn->umn_Node.mln_Succ)
237 if (PushChunk(iffh,ID_PREF,ID_MLRS,MLRS_SIZE)) goto fail;
238 if (WriteChunkBytes(iffh,&mn->umn_Flags,MLRS_SIZE)!=MLRS_SIZE) goto fail;
239 if (PopChunk(iffh)) goto fail;
242 /* write ftp nodes */
243 for (fn = (struct URL_FTPNode *)p->up_FTPList.mlh_Head;
244 fn->ufn_Node.mln_Succ;
245 fn = (struct URL_FTPNode *)fn->ufn_Node.mln_Succ)
247 if (PushChunk(iffh,ID_PREF,ID_FTPS,FTPS_SIZE)) goto fail;
248 if (WriteChunkBytes(iffh,&fn->ufn_Flags,FTPS_SIZE)!=FTPS_SIZE) goto fail;
249 if (PopChunk(iffh)) goto fail;
252 /* write flags */
253 if (PushChunk(iffh,ID_PREF,ID_FLGS,FLGS_SIZE)) goto fail;
254 if (WriteChunkBytes(iffh,&p->up_Flags,FLGS_SIZE)!=FLGS_SIZE) goto fail;
255 if (PopChunk(iffh)) goto fail;
257 /* write defaults */
258 if (PushChunk(iffh,ID_PREF,ID_DEFS,DEFS_SIZE)) goto fail;
259 if (WriteChunkBytes(iffh,&p->up_DefShow,DEFS_SIZE)!=DEFS_SIZE) goto fail;
260 if (PopChunk(iffh)) goto fail;
262 /* pop the IFF PREF FORM chunk */
263 if (PopChunk(iffh)) goto fail;
265 res = TRUE;
267 fail:
268 CloseIFF(iffh);
271 Close(iffh->iff_Stream);
274 FreeIFF(iffh);
277 if (!res) DeleteFile(filename);
279 return res;
282 /**************************************************************************/
284 ULONG
285 loadPrefs(struct URL_Prefs *p,ULONG mode)
287 struct IFFHandle *iffh;
288 ULONG res = FALSE;
290 initPrefs(p);
292 if ((iffh = AllocIFF()))
294 UBYTE *fileName;
295 BPTR file;
297 fileName = (mode==LOADPREFS_ENV) ? DEF_ENV : DEF_ENVARC;
299 if (!(file = Open(fileName,MODE_OLDFILE)))
300 if (mode==LOADPREFS_ENV) file = Open(DEF_ENVARC,MODE_OLDFILE);
302 if ((iffh->iff_Stream = file))
304 InitIFFasDOS(iffh);
306 if (!OpenIFF(iffh,IFFF_READ))
308 struct PrefHeader prhd;
309 struct ContextNode *cn;
311 if (StopChunk(iffh,ID_PREF,ID_PRHD)) goto fail;
312 if (StopChunk(iffh,ID_PREF,ID_DEFS)) goto fail;
313 if (StopChunk(iffh,ID_PREF,ID_FLGS)) goto fail;
314 if (StopChunk(iffh,ID_PREF,ID_FTPS)) goto fail;
315 if (StopChunk(iffh,ID_PREF,ID_MLRS)) goto fail;
316 if (StopChunk(iffh,ID_PREF,ID_BRWS)) goto fail;
318 if (ParseIFF(iffh,IFFPARSE_SCAN)) goto fail;
320 if (!(cn = CurrentChunk(iffh))) goto fail;
322 if ((cn->cn_Type!=ID_PREF) || (cn->cn_ID!=ID_PRHD) ||
323 (cn->cn_Size!=sizeof(struct PrefHeader))) goto fail;
325 if (ReadChunkBytes(iffh,&prhd,cn->cn_Size)!=cn->cn_Size) goto fail;
326 if (prhd.ph_Version>PREFS_VERSION) goto fail;
328 for (;;)
330 ULONG error;
332 error = ParseIFF(iffh,IFFPARSE_SCAN);
333 if (error==IFFERR_EOF) break;
334 else if (error) goto fail;
336 if (!(cn = CurrentChunk(iffh))) goto fail;
338 if (cn->cn_Type!=ID_PREF) continue;
340 if ((cn->cn_ID==ID_BRWS) && (cn->cn_Size==BRWS_SIZE))
342 struct URL_BrowserNode *bn;
344 if (!(bn = allocPooled(sizeof(struct URL_BrowserNode))))
345 goto fail;
347 if (ReadChunkBytes(iffh,&bn->ubn_Flags,cn->cn_Size)!=cn->cn_Size)
349 freePooled(bn,sizeof(struct URL_BrowserNode));
350 goto fail;
353 AddTail(LIST(&p->up_BrowserList),NODE(bn));
355 continue;
358 if ((cn->cn_ID==ID_MLRS) && (cn->cn_Size==MLRS_SIZE))
360 struct URL_MailerNode *mn;
362 if (!(mn = allocPooled(sizeof(struct URL_MailerNode))))
363 goto fail;
365 if (ReadChunkBytes(iffh,&mn->umn_Flags,cn->cn_Size)!=cn->cn_Size)
367 freePooled(mn,sizeof(struct URL_MailerNode));
368 goto fail;
371 AddTail(LIST(&p->up_MailerList),NODE(mn));
373 continue;
376 if ((cn->cn_ID==ID_FTPS) && (cn->cn_Size==FTPS_SIZE))
378 struct URL_FTPNode *fn;
380 if (!(fn = allocPooled(sizeof(struct URL_FTPNode))))
381 goto fail;
383 if (ReadChunkBytes(iffh,&fn->ufn_Flags,cn->cn_Size)!=cn->cn_Size)
385 freePooled(fn,sizeof(struct URL_FTPNode));
386 goto fail;
389 AddTail(LIST(&p->up_FTPList),NODE(fn));
391 continue;
394 if ((cn->cn_ID==ID_FLGS) && (cn->cn_Size==FLGS_SIZE))
396 if (ReadChunkBytes(iffh,&p->up_Flags,cn->cn_Size)!=cn->cn_Size)
397 goto fail;
399 continue;
402 if ((cn->cn_ID==ID_DEFS) && (cn->cn_Size==DEFS_SIZE))
404 if (ReadChunkBytes(iffh,&p->up_DefShow,cn->cn_Size)!=cn->cn_Size)
405 goto fail;
407 continue;
411 p->up_Flags &= ~UPF_ISDEFAULTS;
413 res = TRUE;
415 fail:
416 CloseIFF(iffh);
419 Close(file);
422 FreeIFF(iffh);
425 return res;
428 /**************************************************************************/
430 struct URL_Prefs *
431 loadPrefsNotFail(void)
433 struct URL_Prefs *p;
435 if ((p = allocPooled(sizeof(struct URL_Prefs))))
437 if (!loadPrefs(p,LOADPREFS_ENV))
438 setDefaultPrefs(p);
441 return p;
444 /**************************************************************************/