1 /***************************************************************************
3 openurl.library - universal URL display and browser launcher library
4 Copyright (C) 1998-2005 by Troels Walsted Hansen, et al.
5 Copyright (C) 2005-2013 by openurl.library Open Source Team
7 This library is free software; it has been placed in the public domain
8 and you can freely redistribute it and/or modify it. Please note, however,
9 that some components may be under the LGPL or GPL license.
11 This library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
15 openurl.library project: http://sourceforge.net/projects/openurllib/
19 ***************************************************************************/
21 #include <proto/exec.h>
22 #include <proto/dos.h>
23 #include <proto/intuition.h>
24 #include <proto/openurl.h>
26 #include <exec/memory.h>
28 #include <libraries/openurl.h>
29 #include <intuition/intuition.h>
34 #include "SmartReadArgs.h"
40 static const char USED_VAR version
[] = "$VER: OpenURL " LIB_REV_STRING
" [" SYSTEMSHORT
"/" CPU
"] (" LIB_DATE
") " LIB_COPYRIGHT
;
42 /**************************************************************************/
44 #define TEMPLATE "URL/A,NOSHOW/S,NOFRONT/S,NEWWIN/S,NOLAUNCH/S,PUBSCREEN/K,FILE/S"
48 A_URL
, A_NOSHOW
, A_NOFRONT
, A_NEWWIN
, A_NOLAUNCH
, A_PUBSCREEN
, A_FILE
, A_MAX
51 /* Maximum length an URL can get according to w3c. Currently, CLI
52 * imposes even a smaller limit of 512.
54 #define MAXIMUM_URL_LENGTH 1024
56 #if defined(__amigaos4__)
57 struct Library
*IntuitionBase
;
58 struct Library
*IconBase
;
59 struct Library
*UtilityBase
;
60 struct Library
*OpenURLBase
;
61 struct IntuitionIFace
*IIntuition
= NULL
;
62 struct IconIFace
*IIcon
= NULL
;
63 struct UtilityIFace
*IUtility
= NULL
;
64 struct OpenURLIFace
* IOpenURL
= NULL
;
66 struct IntuitionBase
*IntuitionBase
;
67 struct Library
*IconBase
;
68 struct Library
*UtilityBase
;
69 struct Library
*OpenURLBase
;
72 #define OPENURL_VERSION 4 /* Minimum version of openurl.library */
73 #define OPENURL_VERSION_STR "4" /* Used by error message */
74 #define MAXIMUM_ERROR_LENGTH 120 /* Size of buffer for error messages */
76 #if defined(__amigaos4__)
77 #define AllocVecShared(size, flags) AllocVecTags((size), AVT_Type, MEMF_SHARED, AVT_Lock, FALSE, ((flags)&MEMF_CLEAR) ? AVT_ClearWithValue : TAG_IGNORE, 0, TAG_DONE)
79 #define AllocVecShared(size, flags) AllocVec((size), (flags))
82 /* Some shit necessary because C standard libraries suck */
83 ULONG
ulong_max(ULONG a
, ULONG b
)
90 * Note that the startup code of SAS/c sets argc=0 when started from
91 * workbench. This fact is used to auto-enable FILE in such a case.
93 int main(int argc
,char **argv
)
95 int return_code
= RETURN_FAIL
;
97 CONST_STRPTR error_cause
= NULL
;
98 struct WBStartup
*wb_startup
= NULL
;
99 TEXT error_buffer
[MAXIMUM_ERROR_LENGTH
] = "";
101 // setup the debugging stuff
106 if((IntuitionBase
= (APTR
)OpenLibrary("intuition.library", 37)) != NULL
&&
107 GETINTERFACE(IIntuition
, IntuitionBase
))
109 if((IconBase
= OpenLibrary("icon.library", 37)) != NULL
&&
110 GETINTERFACE(IIcon
, IconBase
))
112 if((UtilityBase
= OpenLibrary("utility.library", 37)) != NULL
&&
113 GETINTERFACE(IUtility
, UtilityBase
))
115 if((OpenURLBase
= OpenLibrary("openurl.library", OPENURL_VERSION
)) != NULL
&&
116 GETINTERFACE(IOpenURL
, OpenURLBase
))
118 struct TagItem tags
[8];
119 struct SmartArgs smart_args
;
121 STRPTR real_url
= NULL
;
122 STRPTR filename
= NULL
;
124 /* Prepare argument parsing */
125 memset(&args
, 0, sizeof(args
));
126 memset(&smart_args
, 0, sizeof(smart_args
));
127 smart_args
.sa_Template
= TEMPLATE
;
128 smart_args
.sa_Parameter
= (IPTR
*)args
;
129 smart_args
.sa_FileParameter
= A_URL
;
130 smart_args
.sa_Window
= (STRPTR
)"CON:////OpenURL/AUTO/CLOSE/WAIT";
132 return_code
= RETURN_ERROR
;
134 /* Auto-enable FILE switch when started from WB */
137 wb_startup
= (struct WBStartup
*)argv
;
141 /* Parse arguments, either from Workbench or CLI */
142 error_code
= SmartReadArgs(wb_startup
,&smart_args
);
144 /* Allocate string buffers. This reduces stack usage and also
145 * makes the string buffers being checked by Mungwall.
147 * Yes, this wastes some memory if FILE is not set, but makes the
148 * error handling easier.
150 * Yes, we could use a 2K buffer with filename = real_url + 1024 to
151 * use only one allocation. This however would reduce the possibilty
152 * for out-of-bounds checks for the end of one/beginning of the
156 /* Allocate string buffers */
157 real_url
= AllocVecShared(MAXIMUM_URL_LENGTH
, MEMF_ANY
);
158 filename
= AllocVecShared(MAXIMUM_URL_LENGTH
, MEMF_ANY
);
159 if (!real_url
|| !filename
)
161 /* Not enough memory */
162 SetIoErr(ERROR_NO_FREE_STORE
);
163 error_code
= IoErr();
171 /* Expand the filename to a fully qualified URL */
172 BPTR lock
= Lock((STRPTR
)args
[A_URL
],ACCESS_READ
);
176 if (NameFromLock(lock
,filename
,MAXIMUM_URL_LENGTH
))
178 strlcpy(real_url
,"file://localhost/",MAXIMUM_URL_LENGTH
);
179 strlcat(real_url
,filename
,MAXIMUM_URL_LENGTH
);
183 error_cause
= "Error obtaining full filename";
184 error_code
= IoErr();
191 error_cause
= "Error opening input file";
192 error_code
= IoErr();
197 /* Simply use the URL passed in arguments, assuming it is
198 * an already fully qualified URL of any protocol. Possible
199 * errors are now treated by the browser. */
200 strlcpy(real_url
,(STRPTR
)args
[A_URL
],MAXIMUM_URL_LENGTH
);
206 if ((args
[A_NOSHOW
]) != 0)
208 tags
[i
].ti_Tag
= URL_Show
;
209 tags
[i
].ti_Data
= FALSE
; i
++;
211 if ((args
[A_NOFRONT
]) != 0)
213 tags
[i
].ti_Tag
= URL_BringToFront
;
214 tags
[i
].ti_Data
= FALSE
; i
++;
216 if ((args
[A_NEWWIN
]) != 0)
218 tags
[i
].ti_Tag
= URL_NewWindow
;
219 tags
[i
].ti_Data
= TRUE
; i
++;
221 if ((args
[A_NOLAUNCH
]) != 0)
223 tags
[i
].ti_Tag
= URL_Launch
;
224 tags
[i
].ti_Data
= FALSE
; i
++;
226 if (args
[A_PUBSCREEN
])
228 tags
[i
].ti_Tag
= URL_PubScreenName
;
229 tags
[i
].ti_Data
= args
[A_PUBSCREEN
]; i
++;
231 tags
[i
].ti_Tag
= TAG_DONE
; tags
[i
].ti_Data
= 0;
233 if (URL_OpenA(real_url
, tags
))
235 return_code
= RETURN_OK
;
240 if (args
[A_NOLAUNCH
])
242 error_cause
= "Could not find browser port";
246 error_cause
= "Could not launch browser";
253 error_cause
= "Error in arguments";
256 /* Free extended read args (even in case of error) */
257 SmartFreeArgs(&smart_args
);
259 /* Release all other resources */
260 if (filename
) FreeVec(filename
);
261 if (real_url
) FreeVec(real_url
);
263 DROPINTERFACE(IOpenURL
);
264 CloseLibrary(OpenURLBase
);
268 error_cause
= "Could not find 'openurl.library', version " OPENURL_VERSION_STR
;
271 DROPINTERFACE(IUtility
);
272 CloseLibrary(UtilityBase
);
278 DROPINTERFACE(IIcon
);
279 CloseLibrary(IconBase
);
285 DROPINTERFACE(IIntuition
);
286 CloseLibrary((struct Library
*)IntuitionBase
);
292 /* Create error message in error_buffer (if any) */
295 Fault(error_code
, (STRPTR
)error_cause
, error_buffer
, MAXIMUM_ERROR_LENGTH
);
297 else if (error_cause
!=NULL
)
299 strncpy(error_buffer
,error_cause
,MAXIMUM_ERROR_LENGTH
-1);
302 /* Display error message in CLI or Requester (if any) */
303 if (error_buffer
[0] != '\0')
307 struct EasyStruct error_requester
;
309 memset(&error_requester
, 0, sizeof(error_requester
));
310 error_requester
.es_StructSize
= sizeof(struct EasyStruct
);
311 error_requester
.es_Title
= (STRPTR
)"OpenURL Error";
312 error_requester
.es_TextFormat
= (STRPTR
)"%s";
313 error_requester
.es_GadgetFormat
= (STRPTR
)"Cancel";
315 EasyRequestArgs(NULL
, &error_requester
, NULL
, (RAWARG
)&error_buffer
);
319 FPuts(Output(),error_buffer
);
320 FPuts(Output(),"\n");
327 /**************************************************************************/