Fixed binary search: no more infinite loops when vendor is unknown.
[tangerine.git] / workbench / libs / openurl / library / api.c
bloba590b39bb43e91ad60fc86cb041f6179a45bf58a
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 <dos/dostags.h>
16 #include "openurl.library_rev.h"
17 #include <exec/execbase.h>
19 /**************************************************************************/
21 #ifdef __AROS__
22 AROS_LH2(ULONG, URL_OpenA,
23 AROS_LHA(STRPTR, URL, A0),
24 AROS_LHA(struct TagItem *, attrs, A1),
25 struct Library *, library, 5, Openurl
28 AROS_LIBFUNC_INIT
29 #else
30 ULONG LIBCALL
31 URL_OpenA(REG(a0,UBYTE *URL),REG(a1,struct TagItem *attrs))
33 #endif
34 struct List portList;
35 UBYTE buf[256], *fullURL = NULL, *pubScreenName;
36 ULONG res, show, toFront, newWindow, launch, httpPrepend = FALSE;
38 NEWLIST(&portList);
39 ObtainSemaphore(&lib_prefsSem);
42 /* parse arguments */
43 pubScreenName = (UBYTE *)GetTagData(URL_PubScreenName,(IPTR)"Workbench",attrs);
44 show = GetTagData(URL_Show,lib_prefs->up_DefShow,attrs);
45 toFront = GetTagData(URL_BringToFront,lib_prefs->up_DefBringToFront,attrs);
46 newWindow = GetTagData(URL_NewWindow,lib_prefs->up_DefNewWindow,attrs);
47 launch = GetTagData(URL_Launch,lib_prefs->up_DefLaunch,attrs);
49 /* make a copy of the global list of named ports */
50 Forbid();
51 res = copyList(&portList,&SysBase->PortList,sizeof(struct Node));
52 Permit();
53 if (!res) goto done;
55 /* prepend "http://" if URL has no method */
56 if (lib_prefs->up_Flags & UPF_PREPENDHTTP)
58 UBYTE *colon;
60 colon = strchr(URL,':');
62 if (!colon) httpPrepend = TRUE;
63 else
65 UBYTE *p;
67 for (p = URL; p<colon; p++)
69 if (!isalnum(*p) && (*p!='+') && (*p!='-'))
71 httpPrepend = TRUE;
72 break;
78 if (httpPrepend)
80 ULONG len = strlen(URL)+8;
82 if (len>sizeof(buf))
84 if (!(fullURL = allocVecPooled(strlen(URL)+8))) goto done;
86 else fullURL = buf;
88 msprintf(fullURL,"http://%s",(IPTR)URL);
90 else fullURL = URL;
92 /* Be case insensitive - Piru */
93 if ((lib_prefs->up_Flags & UPF_DOMAILTO) && !Strnicmp(URL,"mailto:",7))
94 res = sendToMailer(fullURL,&portList,show,toFront,launch,pubScreenName);
95 else
96 if ((lib_prefs->up_Flags & UPF_DOFTP) && !Strnicmp(URL,"ftp://",6))
97 res = sendToFTP(fullURL,&portList,show,toFront,newWindow,launch,pubScreenName);
98 else res = sendToBrowser(fullURL,&portList,show,toFront,newWindow,launch,pubScreenName);
100 done:
101 ReleaseSemaphore(&lib_prefsSem);
102 freeList(&portList,sizeof(struct Node));
103 if (httpPrepend && fullURL && fullURL!=buf) freeVecPooled(fullURL);
105 return res;
107 #ifdef __AROS__
108 AROS_LIBFUNC_EXIT
109 #endif
112 /**************************************************************************/
114 #ifdef __AROS__
115 AROS_LH1(struct URL_Prefs *, URL_GetPrefsA,
116 AROS_LHA(struct TagItem *, attrs, A0),
117 struct Library *, library, 12, Openurl
120 AROS_LIBFUNC_INIT
121 #else
122 struct URL_Prefs * LIBCALL
123 URL_GetPrefsA(REG(a0,struct TagItem *attrs))
125 #endif
126 struct URL_Prefs *p;
127 ULONG mode;
129 mode = GetTagData(URL_GetPrefs_Mode,URL_GetPrefs_Mode_Env,attrs);
131 if (mode==URL_GetPrefs_Mode_Default)
133 if (!(p = allocPooled(sizeof(struct URL_Prefs)))) return NULL;
134 setDefaultPrefs(p);
136 return p;
139 if ((mode==URL_GetPrefs_Mode_Env) || (mode==URL_GetPrefs_Mode_Envarc))
141 mode = (mode==URL_GetPrefs_Mode_Env) ? LOADPREFS_ENV : LOADPREFS_ENVARC;
143 if (!(p = allocPooled(sizeof(struct URL_Prefs))))
144 return NULL;
146 if (loadPrefs(p,mode))
147 return p;
149 if (GetTagData(URL_GetPrefs_FallBack,TRUE,attrs))
152 if ((mode==LOADPREFS_ENV) && loadPrefs(p,LOADPREFS_ENVARC))
153 return p;
155 setDefaultPrefs(p);
157 return p;
160 URL_FreePrefsA(p,NULL);
162 return NULL;
165 ObtainSemaphoreShared(&lib_prefsSem);
166 p = copyPrefs(lib_prefs);
167 ReleaseSemaphore(&lib_prefsSem);
169 return p;
170 #ifdef __AROS__
171 AROS_LIBFUNC_EXIT
172 #endif
175 /**************************************************************************/
177 #ifdef __AROS__
178 AROS_LH0(struct URL_Prefs *, URL_OldGetPrefs,
179 struct Library *, library, 6, Openurl
182 AROS_LIBFUNC_INIT
183 #else
184 struct URL_Prefs * LIBCALL
185 URL_OldGetPrefs(void)
187 #endif
188 return URL_GetPrefsA(NULL);
189 #ifdef __AROS__
190 AROS_LIBFUNC_EXIT
191 #endif
194 /**************************************************************************/
196 #ifdef __AROS__
197 AROS_LH2(VOID, URL_FreePrefsA,
198 AROS_LHA(struct URL_Prefs *, p, A0),
199 AROS_LHA(struct TagItem *, attrs, A1),
200 struct Library *, library, 13, Openurl
203 AROS_LIBFUNC_INIT
204 #else
205 void LIBCALL
206 URL_FreePrefsA(REG(a0,struct URL_Prefs *p),REG(a1,struct TagItem *attrs))
208 #endif
209 if (p)
211 freeList((struct List *)&p->up_BrowserList,sizeof(struct URL_BrowserNode));
212 freeList((struct List *)&p->up_MailerList,sizeof(struct URL_MailerNode));
213 freeList((struct List *)&p->up_FTPList,sizeof(struct URL_FTPNode));
214 freePooled(p,sizeof(*p));
216 #ifdef __AROS__
217 AROS_LIBFUNC_EXIT
218 #endif
221 /**************************************************************************/
223 #ifdef __AROS__
224 AROS_LH1(VOID, URL_OldFreePrefs,
225 AROS_LHA(struct URL_Prefs *, p, A0),
226 struct Library *, library, 7, Openurl
229 AROS_LIBFUNC_INIT
230 #else
231 void LIBCALL
232 URL_OldFreePrefs(REG(a0,struct URL_Prefs *p))
234 #endif
235 URL_FreePrefsA(p,NULL);
236 #ifdef __AROS__
237 AROS_LIBFUNC_EXIT
238 #endif
241 /**************************************************************************/
243 #ifdef __AROS__
244 AROS_LH2(ULONG, URL_SetPrefsA,
245 AROS_LHA(struct URL_Prefs *, p, A0),
246 AROS_LHA(struct TagItem *, attrs, A1),
247 struct Library *, library, 14, Openurl
250 AROS_LIBFUNC_INIT
251 #else
252 ULONG LIBCALL
253 URL_SetPrefsA(REG(a0,struct URL_Prefs *p),REG(a1,struct TagItem *attrs))
255 #endif
256 ULONG res = FALSE;
258 if (p->up_Version==PREFS_VERSION)
260 struct URL_Prefs *newp;
262 ObtainSemaphore(&lib_prefsSem);
264 if ((newp = copyPrefs(p)))
266 newp->up_Version = PREFS_VERSION;
267 newp->up_Flags &= ~UPF_ISDEFAULTS;
269 URL_FreePrefsA(lib_prefs,NULL);
270 lib_prefs = newp;
272 if ((res = savePrefs(DEF_ENV,lib_prefs)))
274 if (GetTagData(URL_SetPrefs_Save,FALSE,attrs))
276 res = savePrefs(DEF_ENVARC,lib_prefs);
281 ReleaseSemaphore(&lib_prefsSem);
284 return res;
285 #ifdef __AROS__
286 AROS_LIBFUNC_EXIT
287 #endif
290 /**************************************************************************/
292 #ifdef __AROS__
293 AROS_LH2(ULONG, URL_OldSetPrefs,
294 AROS_LHA(struct URL_Prefs *, p, A0),
295 AROS_LHA(BOOL, save, D0),
296 struct Library *, library, 8, Openurl
299 AROS_LIBFUNC_INIT
300 #else
301 ULONG LIBCALL
302 URL_OldSetPrefs(REG(a0,struct URL_Prefs *p),REG(d0,ULONG save))
304 #endif
305 struct TagItem stags[] = { {URL_SetPrefs_Save,0} , {TAG_DONE} };
307 stags[0].ti_Data = save;
309 return URL_SetPrefsA(p,stags);
310 #ifdef __AROS__
311 AROS_LIBFUNC_EXIT
312 #endif
315 /**************************************************************************/
317 #ifdef __AROS__
318 AROS_LH0(struct URL_Prefs *, URL_OldGetDefaultPrefs,
319 struct Library *, library, 9, Openurl
322 AROS_LIBFUNC_INIT
323 #else
324 struct URL_Prefs * LIBCALL
325 URL_OldGetDefaultPrefs(void)
327 #endif
328 struct TagItem gtags[] = { {URL_GetPrefs_Mode,URL_GetPrefs_Mode_Default} , {TAG_DONE} };
330 return URL_GetPrefsA(gtags);
331 #ifdef __AROS__
332 AROS_LIBFUNC_EXIT
333 #endif
336 /**************************************************************************/
338 #ifdef __AROS__
339 AROS_LH1(ULONG, URL_LaunchPrefsAppA,
340 AROS_LHA(struct TagItem *, tags, A0),
341 struct Library *, library, 15, Openurl
344 AROS_LIBFUNC_INIT
345 #else
346 ULONG LIBCALL
347 URL_LaunchPrefsAppA(REG(a0,struct TagItem *attrs))
349 #endif
350 BPTR in;
352 if ((in = Open("NIL:",MODE_OLDFILE)))
354 BPTR out;
356 if ((out = Open("NIL:",MODE_OLDFILE)))
358 UBYTE name[256];
359 struct TagItem stags[] = {{SYS_Input, 0},
360 {SYS_Output, 0},
361 {NP_StackSize, 16000},
362 {SYS_Asynch, TRUE},
363 #ifdef __MORPHOS__
364 {NP_PPCStackSize, 32000},
365 #endif
366 {TAG_DONE}};
368 if (GetVar("OpenURL_Prefs_Path",name,sizeof(name),GVF_GLOBAL_ONLY)<=0)
369 strcpy(name,"Sys:Prefs/OpenURL");
371 stags[0].ti_Data = (IPTR)in;
372 stags[1].ti_Data = (IPTR)out;
373 SystemTagList(name,stags);
375 return TRUE;
378 Close(in);
381 return FALSE;
382 #ifdef __AROS__
383 AROS_LIBFUNC_EXIT
384 #endif
387 /**************************************************************************/
389 #ifdef __AROS__
390 AROS_LH0(ULONG, URL_OldLaunchPrefsApp,
391 struct Library *, library, 10, Openurl
394 AROS_LIBFUNC_INIT
395 #else
396 ULONG LIBCALL
397 URL_OldLaunchPrefsApp(void)
399 #endif
400 return URL_LaunchPrefsAppA(NULL);
401 #ifdef __AROS__
402 AROS_LIBFUNC_EXIT
403 #endif
406 /**************************************************************************/
408 #ifdef __AROS__
409 AROS_LH2(ULONG, URL_GetAttr,
410 AROS_LHA(ULONG, attr, D0),
411 AROS_LHA(IPTR *, storage, A0),
412 struct Library *, library, 16, Openurl
415 AROS_LIBFUNC_INIT
416 #else
417 ULONG LIBCALL
418 URL_GetAttr(REG(d0,ULONG attr),REG(a0,ULONG *storage))
420 #endif
421 switch (attr)
423 case URL_GetAttr_Version: *storage = VERSION; return TRUE;
424 case URL_GetAttr_Revision: *storage = REVISION; return TRUE;
425 case URL_GetAttr_VerString: *storage = (IPTR)PRGNAME; return TRUE;
427 case URL_GetAttr_PrefsVer: *storage = PREFS_VERSION; return TRUE;
429 case URL_GetAttr_HandlerVersion: *storage = 0; return TRUE;
430 case URL_GetAttr_HandlerRevision: *storage = 0; return TRUE;
431 case URL_GetAttr_HandlerVerString: *storage = (IPTR)""; return TRUE;
433 default: return FALSE;
435 #ifdef __AROS__
436 AROS_LIBFUNC_EXIT
437 #endif
440 /**************************************************************************/
442 #ifndef __AROS__
443 #ifdef __MORPHOS__
444 LONG dispatch(void)
446 struct RexxMsg *msg = (struct RexxMsg *)REG_A0;
447 #else
448 LONG ASM SAVEDS dispatch(REG(a0,struct RexxMsg *msg),REG(a1,UBYTE **resPtr))
450 #endif
452 UBYTE *fun = msg->rm_Args[0];
453 ULONG res, na = msg->rm_Action & RXARGMASK;
455 if (!stricmp(fun,"OPENURL"))
457 if (na<1) return 17;
458 else
460 struct TagItem tags[MAXRMARG+1];
461 UBYTE *url;
462 int i, j;
464 for (i = na, j = 0, url = NULL; i>0; i--)
466 UBYTE *arg = msg->rm_Args[i];
467 Tag tag;
469 if (!arg || !*arg) continue;
471 if (!stricmp(arg,"SHOW") || !stricmp(arg,"NOSHOW")) tag = URL_Show;
472 else if (!stricmp(arg,"TOFRONT") || !stricmp(arg,"NOTOFRONT")) tag = URL_BringToFront;
473 else if (!stricmp(arg,"NEWWIN") || !stricmp(arg,"NONEWWIN")) tag = URL_NewWindow;
474 else if (!stricmp(arg,"LAUNCH") || !stricmp(arg,"NOLAUNCH")) tag = URL_Launch;
475 else
477 url = arg;
478 continue;
481 tags[j].ti_Tag = tag;
482 tags[j++].ti_Data = strnicmp(arg,"NO",2);
485 tags[j].ti_Tag = TAG_END;
487 res = url && URL_OpenA(url,tags);
490 else
492 if (!stricmp(fun,"OPENURLPREFS"))
494 if (na!=0) return 17;
496 res = URL_LaunchPrefsAppA(NULL);
498 else return 1;
501 #ifdef __MORPHOS__
502 return (REG_A0 = (ULONG)CreateArgstring(res ? "1" : "0",1)) ? 0 : 3;
503 #else
504 return (*resPtr = CreateArgstring(res ? "1" : "0",1)) ? 0 : 3;
505 #endif
507 #endif /* !__AROS__ */
509 /**************************************************************************/