home *** CD-ROM | disk | FTP | other *** search
/ Chip 2002 February / chip_20022115.iso / amiga / chiputil / openurl31.lha / OpenURL / Developer / Sources / library_api.c
C/C++ Source or Header  |  2001-12-03  |  11KB  |  451 lines

  1. /*
  2. ** openurl.library - universal URL display and browser launcher library
  3. ** Written by Troels Walsted Hansen <troels@thule.no>
  4. ** Placed in the public domain.
  5. **
  6. ** Modified by Alfonso Ranieri <alforan@tin.it>
  7. **
  8. ** Main module for the library with all API functions.
  9. */
  10.  
  11. #include "library_common.h"
  12. #include "library_api.h"
  13. #include "library_prefs.h"
  14. #include "library_util.h"
  15. #include "handler.h"
  16.  
  17. /**************************************************************************
  18. *
  19. * Global variables.
  20. *
  21. */
  22.  
  23. struct DosLibrary *DOSBase = NULL;
  24. struct Library *UtilityBase = NULL;
  25. struct IntuitionBase *IntuitionBase = NULL;
  26. struct Library *IFFParseBase = NULL;
  27. struct RxsLib *RexxSysBase = NULL;
  28. struct URL_Prefs *Prefs = NULL;
  29. struct SignalSemaphore PrefsSemaphore, HandlerSemaphore;
  30.  
  31. struct Process *HandlerProcess = NULL;
  32. struct MsgPort *HandlerMsgPort;
  33.  
  34. /**************************************************************************
  35. *
  36. * SAS/C library functions.
  37. *
  38. */
  39.  
  40. LIB int __UserLibInit(REG(a6) struct Library *OpenURLBase)
  41. {
  42.     int retval = 1;
  43.     BPTR seglist;
  44.     struct MsgPort *mp = NULL;
  45.     struct HandlerMsg hm = {0};
  46.  
  47.     /* run time initialized globals */
  48.  
  49.     SysBase = *(struct ExecBase **)4;
  50.     InitSemaphore(&PrefsSemaphore);
  51.     InitSemaphore(&HandlerSemaphore);
  52.  
  53.     /* open libraries */
  54.  
  55.     if(!(DOSBase = (struct DosLibrary *)OpenLibrary("dos.library", 36)))
  56.         goto done;
  57.  
  58.     if(!(UtilityBase = OpenLibrary("utility.library", 36)))
  59.         goto done;
  60.  
  61.     if(!(IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library", 36)))
  62.         goto done;
  63.  
  64.     if(!(IFFParseBase = OpenLibrary("iffparse.library", 36)))
  65.         goto done;
  66.  
  67.     if(!(RexxSysBase = (struct RxsLib *)OpenLibrary("rexxsyslib.library", 33)))
  68.         goto done;
  69.  
  70.     /* load prefs */
  71.  
  72.     if(!LoadPrefs(PREFS_NAME_USE) && !(Prefs = LIB_URL_GetDefaultPrefs()))
  73.         goto done;
  74.  
  75.     /* load and launch handler */
  76.  
  77.     if(!(mp = CreateMsgPort()))
  78.         goto done;
  79.  
  80.     if(!(seglist = LoadSeg("L:OpenURL-Handler")))
  81.     {
  82.         struct EasyStruct es;
  83.         es.es_StructSize   = sizeof(struct EasyStruct);
  84.         es.es_Flags        = 0;
  85.         es.es_Title        = "OpenURL Error";
  86.         es.es_TextFormat   = "openurl.library was unable to load\n"
  87.                            "L:OpenURL-Handler into memory.\n"
  88.                            "Please reinstall.";
  89.         es.es_GadgetFormat = "Ok";
  90.         EasyRequestArgs(NULL, &es, NULL, NULL);
  91.         goto done;
  92.     }
  93.  
  94.     /*
  95.      * Alfonso:
  96.      * The one and only modification done was adding the tag NP_FreeSeglist, TRUE
  97.      */
  98.     HandlerProcess = CreateNewProcTags(NP_Seglist,     seglist,
  99.                                        NP_FreeSeglist, TRUE,
  100.                                        NP_Name,        "OpenURL ARexx Handler",
  101.                                        NP_Priority,    0,
  102.                                        NP_StackSize,   4096,
  103.                                        NP_Input,       NULL,
  104.                                        NP_Output,      NULL,
  105.                                        NP_CloseInput,  FALSE,
  106.                                        NP_CloseOutput, FALSE,
  107.                                        NP_CurrentDir,  NULL,
  108.                                        NP_HomeDir,     NULL,
  109.                                        NP_CopyVars,    FALSE,
  110.                                        TAG_DONE);
  111.  
  112.     if(!HandlerProcess)
  113.     {
  114.         UnLoadSeg(seglist);
  115.         goto done;
  116.     }
  117.  
  118.     /* use a startup msg to synchronize with the handler */
  119.  
  120.     hm.hm_Msg.mn_ReplyPort = mp;
  121.     hm.hm_Msg.mn_Length    = sizeof(struct HandlerMsg);
  122.     hm.hm_Type             = HMT_STARTUP;
  123.     hm.hm_Semaphore        = &HandlerSemaphore;
  124.  
  125.     PutMsg(&(HandlerProcess->pr_MsgPort), (struct Message *)&hm);
  126.     WaitPort(mp);
  127.     GetMsg(mp);
  128.  
  129.     /* check that handler initialized its resources correctly */
  130.  
  131.     if(!hm.hm_Success)
  132.     {
  133.         HandlerProcess = NULL;
  134.         goto done;
  135.     }
  136.  
  137.     HandlerMsgPort = hm.hm_MsgPort;
  138.     retval         = 0;
  139.  
  140. done:
  141.     if(mp) DeleteMsgPort(mp);
  142.     if(retval) __UserLibCleanup(OpenURLBase);
  143.     return(retval);
  144. }
  145.  
  146. /**************************************************************************/
  147.  
  148. LIB void __UserLibCleanup(REG(a6) struct Library *OpenURLBase)
  149. {
  150.     /* shutdown handler process */
  151.  
  152.     if(!AttemptSemaphore(&HandlerSemaphore))
  153.     {
  154.         /* process is still alive, and holding semaphore.
  155.            signal it to terminate */
  156.  
  157.         Signal((struct Task *)HandlerProcess, SIGBREAKF_CTRL_C);
  158.     }
  159.     else ReleaseSemaphore(&HandlerSemaphore);
  160.  
  161.     /* free other resources */
  162.  
  163.     if(Prefs) LIB_URL_FreePrefs(Prefs);
  164.     CloseLibrary((struct Library *)RexxSysBase);
  165.     CloseLibrary(IFFParseBase);
  166.     CloseLibrary((struct Library *)IntuitionBase);
  167.     CloseLibrary(UtilityBase);
  168.     CloseLibrary((struct Library *)DOSBase);
  169. }
  170.  
  171. /**************************************************************************
  172. *
  173. * Library functions available through API.
  174. *
  175. */
  176.  
  177. LIB BOOL LIB_URL_OpenA(REG(a0) STRPTR url, REG(a1) struct TagItem *tags)
  178. {
  179.     BOOL retval = FALSE;
  180.     struct List portlist;
  181.     struct MsgPort *mp;
  182.     STRPTR fullurl = NULL;
  183.     BOOL Show, ToFront, NewWindow, Launch;
  184.     BOOL http_prepend = FALSE;
  185.  
  186.     /* some initialization */
  187.  
  188.     NewList(&portlist);
  189.     ObtainSemaphore(&PrefsSemaphore);
  190.  
  191.     if(!(mp = CreateMsgPort()))
  192.         goto done;
  193.  
  194.     /* parse the arguments */
  195.  
  196.     Show      = GetTagData(URL_Show,         Prefs->up_DefShow,         tags);
  197.     ToFront   = GetTagData(URL_BringToFront, Prefs->up_DefBringToFront, tags);
  198.     NewWindow = GetTagData(URL_NewWindow,    Prefs->up_DefNewWindow,    tags);
  199.     Launch    = GetTagData(URL_Launch,       Prefs->up_DefLaunch,       tags);
  200.  
  201.     /* make a copy of the global list of named ports */
  202.  
  203.     Forbid();
  204.     retval = CopyList(&portlist, &SysBase->PortList, sizeof(struct Node));
  205.     Permit();
  206.  
  207.     if(!retval) goto done;
  208.  
  209.     /* prepend "http://" if URL has no method */
  210.  
  211.     if(Prefs->up_Flags & UPF_PREPENDHTTP)
  212.     {
  213.         STRPTR colon;
  214.  
  215.         colon = strchr(url, ':');
  216.  
  217.         if(!colon)
  218.             http_prepend = TRUE;
  219.         else
  220.         {
  221.             STRPTR p;
  222.  
  223.             for(p = url; p < colon; p++)
  224.             {
  225.                 if(!isalnum(*p) && (*p != '+') && (*p != '-'))
  226.                 {
  227.                     http_prepend = TRUE;
  228.                     break;
  229.                 }
  230.             }
  231.         }
  232.     }
  233.  
  234.     if(http_prepend)
  235.     {
  236.         if(!(fullurl = AllocVec(strlen(url) + 8, MEMF_PUBLIC)))
  237.             goto done;
  238.  
  239.         SPrintf(fullurl, "http://%s", url);
  240.     }
  241.     else fullurl = url;
  242.  
  243.     /* mailto: or generic URL? */
  244.  
  245.     if((Prefs->up_Flags & UPF_DOMAILTO) && !strncmp(url, "mailto:", 7))
  246.         retval = SendToMailer(fullurl, &portlist, mp, Show, ToFront, Launch);
  247.     else
  248.         retval = SendToBrowser(fullurl, &portlist, mp, Show, ToFront, NewWindow, Launch);
  249.  
  250. done:
  251.     ReleaseSemaphore(&PrefsSemaphore);
  252.     FreeList(&portlist, sizeof(struct Node));
  253.     if(mp) DeleteMsgPort(mp);
  254.     if(http_prepend && fullurl) FreeVec(fullurl);
  255.     return(retval);
  256. }
  257.  
  258. /**************************************************************************/
  259.  
  260. LIB struct URL_Prefs *LIB_URL_GetPrefs(VOID)
  261. {
  262.     struct URL_Prefs *p;
  263.  
  264.     /* make a copy of the prefs structure and return that */
  265.  
  266.     ObtainSemaphoreShared(&PrefsSemaphore);
  267.     p = CopyPrefs(Prefs);
  268.     ReleaseSemaphore(&PrefsSemaphore);
  269.     return(p);
  270. }
  271.  
  272. /**************************************************************************/
  273.  
  274. LIB VOID LIB_URL_FreePrefs(REG(a0) struct URL_Prefs *up)
  275. {
  276.     /* free a prefs structure */
  277.     FreeList((struct List *)&up->up_BrowserList, sizeof(struct URL_BrowserNode));
  278.     FreeList((struct List *)&up->up_MailerList, sizeof(struct URL_MailerNode));
  279.     FreeMem(up, sizeof(struct URL_Prefs));
  280. }
  281.  
  282. /**************************************************************************/
  283.  
  284. LIB BOOL LIB_URL_SetPrefs(REG(a0) struct URL_Prefs *p, REG(d0) BOOL permanent)
  285. {
  286.     BOOL retval = FALSE;
  287.     struct URL_Prefs *new_p;
  288.  
  289.     ObtainSemaphore(&PrefsSemaphore);
  290.  
  291.     /* copy prefs structure */
  292.  
  293.     if(!(new_p = CopyPrefs(p)))
  294.         goto done;
  295.  
  296.     if(new_p->up_Version > PREFS_VERSION)
  297.         goto done;
  298.  
  299.     if(new_p->up_Version < 2)
  300.         SetDefaultPrefsV2(new_p);
  301.  
  302.     if(new_p->up_Version == 2)
  303.         ConvertPrefsV2toV3(Prefs);
  304.  
  305.     if(new_p->up_Version < 3)
  306.         SetDefaultPrefsV3(new_p);
  307.  
  308.     new_p->up_Version = PREFS_VERSION;
  309.     new_p->up_Flags &= ~UPF_ISDEFAULTS;
  310.  
  311.     LIB_URL_FreePrefs(Prefs);
  312.     Prefs = new_p;
  313.  
  314.     /* and save it to disk */
  315.  
  316.     if(!SavePrefs(PREFS_NAME_USE, Prefs)) goto done;
  317.     if(permanent && !SavePrefs(PREFS_NAME_SAVE, Prefs))
  318.         goto done;
  319.  
  320.     retval = TRUE;
  321. done:
  322.     ReleaseSemaphore(&PrefsSemaphore);
  323.     return(retval);
  324. }
  325.  
  326.  
  327. /**************************************************************************/
  328.  
  329. LIB struct URL_Prefs *LIB_URL_GetDefaultPrefs(VOID)
  330. {
  331.     struct URL_Prefs *p;
  332.  
  333.     if(!(p = AllocMem(sizeof(struct URL_Prefs), MEMF_CLEAR)))
  334.         return(NULL);
  335.  
  336.     p->up_Version = PREFS_VERSION;
  337.     p->up_Flags |= UPF_ISDEFAULTS;
  338.  
  339.     if(!SetDefaultPrefsV1(p))
  340.     {
  341.         LIB_URL_FreePrefs(p);
  342.         return(NULL);
  343.     }
  344.  
  345.     SetDefaultPrefsV2(p);
  346.  
  347.     if(!SetDefaultPrefsV3(p))
  348.     {
  349.         LIB_URL_FreePrefs(p);
  350.         return(NULL);
  351.     }
  352.  
  353.     return(p);
  354. }
  355.  
  356. /**************************************************************************/
  357.  
  358. LIB BOOL LIB_URL_LaunchPrefsApp(VOID)
  359. {
  360.     char path[256];
  361.  
  362.     if(GetVar("OpenURL_Prefs_Path", path, sizeof(path), 0) == -1)
  363.         strcpy(path, "SYS:Prefs/OpenURL");
  364.  
  365.     if(SystemTags(path,
  366.                   SYS_Asynch, TRUE,
  367.                   SYS_Input,  Open("NIL:", MODE_NEWFILE),
  368.                   SYS_Output, NULL,
  369.                   TAG_END) == -1)
  370.         return(FALSE);
  371.     else
  372.         return(TRUE);
  373. }
  374.  
  375. /**************************************************************************/
  376.  
  377. ASM ULONG a0hack(REG(d0) ULONG return1, REG(a0) UBYTE *return2)
  378. {
  379.     /* lame hack to return an argstring in A0 as arexx expects */
  380.     return(return1);
  381. }
  382.  
  383. LIB ULONG LIB_DoFunction(REG(a0) struct RexxMsg *rxmsg)
  384. {
  385.     UBYTE *argstr;
  386.     STRPTR resstr;
  387.  
  388.     /* check validity of rexx msg */
  389.  
  390.     if(!rxmsg || !IsRexxMsg(rxmsg) || !(rxmsg->rm_Action & RXFUNC) ||
  391.        !rxmsg->rm_Args[0])
  392.     {
  393.         return(ERR10_010); /*  invalid message packet      */
  394.     }
  395.  
  396.     /* check that we recognise the command */
  397.  
  398.     if(!stricmp(rxmsg->rm_Args[0], "OPENURL"))
  399.     {
  400.         struct TagItem tags[MAXRMARG + 1];
  401.         STRPTR url = NULL;
  402.         int i, j;
  403.  
  404.         /* parse the arguments (ReadArgs would be overkill for this) */
  405.  
  406.         for(i = 1, j = 0; rxmsg->rm_Args[i] && j < MAXRMARG; i++)
  407.         {
  408.             Tag tag;
  409.  
  410.             if(!stricmp(rxmsg->rm_Args[i], "SHOW") || !stricmp(rxmsg->rm_Args[i], "NOSHOW"))
  411.                 tag = URL_Show;
  412.             else if(!stricmp(rxmsg->rm_Args[i], "TOFRONT") || !stricmp(rxmsg->rm_Args[i], "NOTOFRONT"))
  413.                 tag  = URL_BringToFront;
  414.             else if(!stricmp(rxmsg->rm_Args[i], "NEWWIN") || !stricmp(rxmsg->rm_Args[i], "NONEWWIN"))
  415.                 tag = URL_NewWindow;
  416.             else if(!stricmp(rxmsg->rm_Args[i], "LAUNCH") || !stricmp(rxmsg->rm_Args[i], "NOLAUNCH"))
  417.                 tag  = URL_Launch;
  418.             else
  419.             {
  420.                 url = rxmsg->rm_Args[i];
  421.                 continue;
  422.             }
  423.  
  424.             tags[j].ti_Tag  = tag;
  425.             tags[j].ti_Data = strnicmp(rxmsg->rm_Args[i], "NO", 2);
  426.             j++;
  427.         }
  428.  
  429.         tags[j].ti_Tag = TAG_END;
  430.  
  431.         if(url && LIB_URL_OpenA(url, tags))
  432.             resstr = "1";
  433.         else
  434.             resstr = "0";
  435.     }
  436.     else if(!stricmp(rxmsg->rm_Args[0], "OPENURLPREFS"))
  437.     {
  438.         if(LIB_URL_LaunchPrefsApp())
  439.             resstr = "1";
  440.         else
  441.             resstr = "0";
  442.     }
  443.     else
  444.         return(ERR10_001); /*  program not found           */
  445.  
  446.     if(!(argstr = CreateArgstring(resstr, 1)))
  447.         return(ERR10_003); /*  no memory available           */
  448.  
  449.     return(a0hack(0, argstr));
  450. }
  451.