home *** CD-ROM | disk | FTP | other *** search
- /*
- ** openurl.library - universal URL display and browser launcher library
- ** Written by Troels Walsted Hansen <troels@thule.no>
- ** Placed in the public domain.
- **
- ** Modified by Alfonso Ranieri <alforan@tin.it>
- **
- ** Main module for the library with all API functions.
- */
-
- #include "library_common.h"
- #include "library_api.h"
- #include "library_prefs.h"
- #include "library_util.h"
- #include "handler.h"
-
- /**************************************************************************
- *
- * Global variables.
- *
- */
-
- struct DosLibrary *DOSBase = NULL;
- struct Library *UtilityBase = NULL;
- struct IntuitionBase *IntuitionBase = NULL;
- struct Library *IFFParseBase = NULL;
- struct RxsLib *RexxSysBase = NULL;
- struct URL_Prefs *Prefs = NULL;
- struct SignalSemaphore PrefsSemaphore, HandlerSemaphore;
-
- struct Process *HandlerProcess = NULL;
- struct MsgPort *HandlerMsgPort;
-
- /**************************************************************************
- *
- * SAS/C library functions.
- *
- */
-
- LIB int __UserLibInit(REG(a6) struct Library *OpenURLBase)
- {
- int retval = 1;
- BPTR seglist;
- struct MsgPort *mp = NULL;
- struct HandlerMsg hm = {0};
-
- /* run time initialized globals */
-
- SysBase = *(struct ExecBase **)4;
- InitSemaphore(&PrefsSemaphore);
- InitSemaphore(&HandlerSemaphore);
-
- /* open libraries */
-
- if(!(DOSBase = (struct DosLibrary *)OpenLibrary("dos.library", 36)))
- goto done;
-
- if(!(UtilityBase = OpenLibrary("utility.library", 36)))
- goto done;
-
- if(!(IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library", 36)))
- goto done;
-
- if(!(IFFParseBase = OpenLibrary("iffparse.library", 36)))
- goto done;
-
- if(!(RexxSysBase = (struct RxsLib *)OpenLibrary("rexxsyslib.library", 33)))
- goto done;
-
- /* load prefs */
-
- if(!LoadPrefs(PREFS_NAME_USE) && !(Prefs = LIB_URL_GetDefaultPrefs()))
- goto done;
-
- /* load and launch handler */
-
- if(!(mp = CreateMsgPort()))
- goto done;
-
- if(!(seglist = LoadSeg("L:OpenURL-Handler")))
- {
- struct EasyStruct es;
- es.es_StructSize = sizeof(struct EasyStruct);
- es.es_Flags = 0;
- es.es_Title = "OpenURL Error";
- es.es_TextFormat = "openurl.library was unable to load\n"
- "L:OpenURL-Handler into memory.\n"
- "Please reinstall.";
- es.es_GadgetFormat = "Ok";
- EasyRequestArgs(NULL, &es, NULL, NULL);
- goto done;
- }
-
- /*
- * Alfonso:
- * The one and only modification done was adding the tag NP_FreeSeglist, TRUE
- */
- HandlerProcess = CreateNewProcTags(NP_Seglist, seglist,
- NP_FreeSeglist, TRUE,
- NP_Name, "OpenURL ARexx Handler",
- NP_Priority, 0,
- NP_StackSize, 4096,
- NP_Input, NULL,
- NP_Output, NULL,
- NP_CloseInput, FALSE,
- NP_CloseOutput, FALSE,
- NP_CurrentDir, NULL,
- NP_HomeDir, NULL,
- NP_CopyVars, FALSE,
- TAG_DONE);
-
- if(!HandlerProcess)
- {
- UnLoadSeg(seglist);
- goto done;
- }
-
- /* use a startup msg to synchronize with the handler */
-
- hm.hm_Msg.mn_ReplyPort = mp;
- hm.hm_Msg.mn_Length = sizeof(struct HandlerMsg);
- hm.hm_Type = HMT_STARTUP;
- hm.hm_Semaphore = &HandlerSemaphore;
-
- PutMsg(&(HandlerProcess->pr_MsgPort), (struct Message *)&hm);
- WaitPort(mp);
- GetMsg(mp);
-
- /* check that handler initialized its resources correctly */
-
- if(!hm.hm_Success)
- {
- HandlerProcess = NULL;
- goto done;
- }
-
- HandlerMsgPort = hm.hm_MsgPort;
- retval = 0;
-
- done:
- if(mp) DeleteMsgPort(mp);
- if(retval) __UserLibCleanup(OpenURLBase);
- return(retval);
- }
-
- /**************************************************************************/
-
- LIB void __UserLibCleanup(REG(a6) struct Library *OpenURLBase)
- {
- /* shutdown handler process */
-
- if(!AttemptSemaphore(&HandlerSemaphore))
- {
- /* process is still alive, and holding semaphore.
- signal it to terminate */
-
- Signal((struct Task *)HandlerProcess, SIGBREAKF_CTRL_C);
- }
- else ReleaseSemaphore(&HandlerSemaphore);
-
- /* free other resources */
-
- if(Prefs) LIB_URL_FreePrefs(Prefs);
- CloseLibrary((struct Library *)RexxSysBase);
- CloseLibrary(IFFParseBase);
- CloseLibrary((struct Library *)IntuitionBase);
- CloseLibrary(UtilityBase);
- CloseLibrary((struct Library *)DOSBase);
- }
-
- /**************************************************************************
- *
- * Library functions available through API.
- *
- */
-
- LIB BOOL LIB_URL_OpenA(REG(a0) STRPTR url, REG(a1) struct TagItem *tags)
- {
- BOOL retval = FALSE;
- struct List portlist;
- struct MsgPort *mp;
- STRPTR fullurl = NULL;
- BOOL Show, ToFront, NewWindow, Launch;
- BOOL http_prepend = FALSE;
-
- /* some initialization */
-
- NewList(&portlist);
- ObtainSemaphore(&PrefsSemaphore);
-
- if(!(mp = CreateMsgPort()))
- goto done;
-
- /* parse the arguments */
-
- Show = GetTagData(URL_Show, Prefs->up_DefShow, tags);
- ToFront = GetTagData(URL_BringToFront, Prefs->up_DefBringToFront, tags);
- NewWindow = GetTagData(URL_NewWindow, Prefs->up_DefNewWindow, tags);
- Launch = GetTagData(URL_Launch, Prefs->up_DefLaunch, tags);
-
- /* make a copy of the global list of named ports */
-
- Forbid();
- retval = CopyList(&portlist, &SysBase->PortList, sizeof(struct Node));
- Permit();
-
- if(!retval) goto done;
-
- /* prepend "http://" if URL has no method */
-
- if(Prefs->up_Flags & UPF_PREPENDHTTP)
- {
- STRPTR colon;
-
- colon = strchr(url, ':');
-
- if(!colon)
- http_prepend = TRUE;
- else
- {
- STRPTR p;
-
- for(p = url; p < colon; p++)
- {
- if(!isalnum(*p) && (*p != '+') && (*p != '-'))
- {
- http_prepend = TRUE;
- break;
- }
- }
- }
- }
-
- if(http_prepend)
- {
- if(!(fullurl = AllocVec(strlen(url) + 8, MEMF_PUBLIC)))
- goto done;
-
- SPrintf(fullurl, "http://%s", url);
- }
- else fullurl = url;
-
- /* mailto: or generic URL? */
-
- if((Prefs->up_Flags & UPF_DOMAILTO) && !strncmp(url, "mailto:", 7))
- retval = SendToMailer(fullurl, &portlist, mp, Show, ToFront, Launch);
- else
- retval = SendToBrowser(fullurl, &portlist, mp, Show, ToFront, NewWindow, Launch);
-
- done:
- ReleaseSemaphore(&PrefsSemaphore);
- FreeList(&portlist, sizeof(struct Node));
- if(mp) DeleteMsgPort(mp);
- if(http_prepend && fullurl) FreeVec(fullurl);
- return(retval);
- }
-
- /**************************************************************************/
-
- LIB struct URL_Prefs *LIB_URL_GetPrefs(VOID)
- {
- struct URL_Prefs *p;
-
- /* make a copy of the prefs structure and return that */
-
- ObtainSemaphoreShared(&PrefsSemaphore);
- p = CopyPrefs(Prefs);
- ReleaseSemaphore(&PrefsSemaphore);
- return(p);
- }
-
- /**************************************************************************/
-
- LIB VOID LIB_URL_FreePrefs(REG(a0) struct URL_Prefs *up)
- {
- /* free a prefs structure */
- FreeList((struct List *)&up->up_BrowserList, sizeof(struct URL_BrowserNode));
- FreeList((struct List *)&up->up_MailerList, sizeof(struct URL_MailerNode));
- FreeMem(up, sizeof(struct URL_Prefs));
- }
-
- /**************************************************************************/
-
- LIB BOOL LIB_URL_SetPrefs(REG(a0) struct URL_Prefs *p, REG(d0) BOOL permanent)
- {
- BOOL retval = FALSE;
- struct URL_Prefs *new_p;
-
- ObtainSemaphore(&PrefsSemaphore);
-
- /* copy prefs structure */
-
- if(!(new_p = CopyPrefs(p)))
- goto done;
-
- if(new_p->up_Version > PREFS_VERSION)
- goto done;
-
- if(new_p->up_Version < 2)
- SetDefaultPrefsV2(new_p);
-
- if(new_p->up_Version == 2)
- ConvertPrefsV2toV3(Prefs);
-
- if(new_p->up_Version < 3)
- SetDefaultPrefsV3(new_p);
-
- new_p->up_Version = PREFS_VERSION;
- new_p->up_Flags &= ~UPF_ISDEFAULTS;
-
- LIB_URL_FreePrefs(Prefs);
- Prefs = new_p;
-
- /* and save it to disk */
-
- if(!SavePrefs(PREFS_NAME_USE, Prefs)) goto done;
- if(permanent && !SavePrefs(PREFS_NAME_SAVE, Prefs))
- goto done;
-
- retval = TRUE;
- done:
- ReleaseSemaphore(&PrefsSemaphore);
- return(retval);
- }
-
-
- /**************************************************************************/
-
- LIB struct URL_Prefs *LIB_URL_GetDefaultPrefs(VOID)
- {
- struct URL_Prefs *p;
-
- if(!(p = AllocMem(sizeof(struct URL_Prefs), MEMF_CLEAR)))
- return(NULL);
-
- p->up_Version = PREFS_VERSION;
- p->up_Flags |= UPF_ISDEFAULTS;
-
- if(!SetDefaultPrefsV1(p))
- {
- LIB_URL_FreePrefs(p);
- return(NULL);
- }
-
- SetDefaultPrefsV2(p);
-
- if(!SetDefaultPrefsV3(p))
- {
- LIB_URL_FreePrefs(p);
- return(NULL);
- }
-
- return(p);
- }
-
- /**************************************************************************/
-
- LIB BOOL LIB_URL_LaunchPrefsApp(VOID)
- {
- char path[256];
-
- if(GetVar("OpenURL_Prefs_Path", path, sizeof(path), 0) == -1)
- strcpy(path, "SYS:Prefs/OpenURL");
-
- if(SystemTags(path,
- SYS_Asynch, TRUE,
- SYS_Input, Open("NIL:", MODE_NEWFILE),
- SYS_Output, NULL,
- TAG_END) == -1)
- return(FALSE);
- else
- return(TRUE);
- }
-
- /**************************************************************************/
-
- ASM ULONG a0hack(REG(d0) ULONG return1, REG(a0) UBYTE *return2)
- {
- /* lame hack to return an argstring in A0 as arexx expects */
- return(return1);
- }
-
- LIB ULONG LIB_DoFunction(REG(a0) struct RexxMsg *rxmsg)
- {
- UBYTE *argstr;
- STRPTR resstr;
-
- /* check validity of rexx msg */
-
- if(!rxmsg || !IsRexxMsg(rxmsg) || !(rxmsg->rm_Action & RXFUNC) ||
- !rxmsg->rm_Args[0])
- {
- return(ERR10_010); /* invalid message packet */
- }
-
- /* check that we recognise the command */
-
- if(!stricmp(rxmsg->rm_Args[0], "OPENURL"))
- {
- struct TagItem tags[MAXRMARG + 1];
- STRPTR url = NULL;
- int i, j;
-
- /* parse the arguments (ReadArgs would be overkill for this) */
-
- for(i = 1, j = 0; rxmsg->rm_Args[i] && j < MAXRMARG; i++)
- {
- Tag tag;
-
- if(!stricmp(rxmsg->rm_Args[i], "SHOW") || !stricmp(rxmsg->rm_Args[i], "NOSHOW"))
- tag = URL_Show;
- else if(!stricmp(rxmsg->rm_Args[i], "TOFRONT") || !stricmp(rxmsg->rm_Args[i], "NOTOFRONT"))
- tag = URL_BringToFront;
- else if(!stricmp(rxmsg->rm_Args[i], "NEWWIN") || !stricmp(rxmsg->rm_Args[i], "NONEWWIN"))
- tag = URL_NewWindow;
- else if(!stricmp(rxmsg->rm_Args[i], "LAUNCH") || !stricmp(rxmsg->rm_Args[i], "NOLAUNCH"))
- tag = URL_Launch;
- else
- {
- url = rxmsg->rm_Args[i];
- continue;
- }
-
- tags[j].ti_Tag = tag;
- tags[j].ti_Data = strnicmp(rxmsg->rm_Args[i], "NO", 2);
- j++;
- }
-
- tags[j].ti_Tag = TAG_END;
-
- if(url && LIB_URL_OpenA(url, tags))
- resstr = "1";
- else
- resstr = "0";
- }
- else if(!stricmp(rxmsg->rm_Args[0], "OPENURLPREFS"))
- {
- if(LIB_URL_LaunchPrefsApp())
- resstr = "1";
- else
- resstr = "0";
- }
- else
- return(ERR10_001); /* program not found */
-
- if(!(argstr = CreateArgstring(resstr, 1)))
- return(ERR10_003); /* no memory available */
-
- return(a0hack(0, argstr));
- }
-