2 * OpenURL -- A Workbech/CLI frontend for "openurl.library".
4 * Written by Thomas Aglassinger <agi@sbox.tu-graz.ac.at>
5 * Placed in the public domain.
7 * Based on material provided by Troels Walsted Hansen <troels@thule.no>
9 * Ported to OS4 by Alexandre Balaban <alexandre -@- balaban -.- name>
10 * Argument handling fix by Jeff Gilpin
14 #include <proto/exec.h>
15 #include <proto/dos.h>
16 #include <proto/intuition.h>
17 #include <proto/openurl.h>
19 #include <exec/memory.h>
21 #include <libraries/openurl.h>
22 #include <intuition/intuition.h>
26 #include "SmartReadArgs.h"
27 #include "OpenURL_rev.h"
29 static const char __attribute__((used
)) version
[] = VERSTAG
;
31 /**************************************************************************/
33 #define TEMPLATE "URL/A,NOSHOW/S,NOFRONT/S,NEWWIN/S,NOLAUNCH/S,PUBSCREEN/K,FILE/S"
37 A_URL
, A_NOSHOW
, A_NOFRONT
, A_NEWWIN
, A_NOLAUNCH
, A_PUBSCREEN
, A_FILE
, A_MAX
40 /* Maximum length an URL can get according to w3c. Currently, CLI
41 * imposes even a smaller limit of 512.
43 #define MAXIMUM_URL_LENGTH 1024
45 struct Library
*OpenURLBase
;
47 #if defined(__amigaos4__)
48 struct OpenURLIFace
* IOpenURL
= NULL
;
51 #define OPENURL_VERSION 4 /* Minimum version of openurl.library */
52 #define OPENURL_VERSION_STR "4" /* Used by error message */
53 #define MAXIMUM_ERROR_LENGTH 120 /* Size of buffer for error messages */
55 /* Some shit necessary because C standard libraries suck */
56 ULONG
ulong_max(ULONG a
, ULONG b
)
63 * Note that the startup code of SAS/c sets argc=0 when started from
64 * workbench. This fact is used to auto-enable FILE in such a case.
66 int main(int argc
,char **argv
)
68 int return_code
= RETURN_FAIL
;
70 STRPTR error_cause
= NULL
;
71 struct WBStartup
*wb_startup
= NULL
;
72 UBYTE error_buffer
[MAXIMUM_ERROR_LENGTH
] = {NULL
};
74 if ((OpenURLBase
= OpenLibrary("openurl.library",OPENURL_VERSION
)))
76 #if defined(__amigaos4__)
77 if( (IOpenURL
= (struct OpenURLIFace
*)GetInterface(OpenURLBase
,"main",1L,NULL
)) )
80 struct TagItem tags
[8] = {0};
81 struct SmartArgs smart_args
= {NULL
};
82 IPTR args
[A_MAX
] = {0};
83 STRPTR real_url
= NULL
, filename
= NULL
;
85 /* Prepare argument parsing */
86 smart_args
.sa_Template
= TEMPLATE
;
87 smart_args
.sa_Parameter
= args
;
88 smart_args
.sa_FileParameter
= A_URL
;
89 smart_args
.sa_Window
= "CON:////OpenURL/AUTO/CLOSE/WAIT";
91 return_code
= RETURN_ERROR
;
93 /* Auto-enable FILE switch when started from WB */
96 wb_startup
= (struct WBStartup
*)argv
;
100 /* Parse arguments, either from Workbench or CLI */
101 error_code
= SmartReadArgs(wb_startup
,&smart_args
);
103 /* Allocate string buffers. This reduces stack usage and also
104 * makes the string buffers being checked by Mungwall.
106 * Yes, this wastes some memory if FILE is not set, but makes the
107 * error handling easier.
109 * Yes, we could use a 2K buffer with filename = real_url + 1024 to
110 * use only one allocation. This however would reduce the possibilty
111 * for out-of-bounds checks for the end of one/beginning of the
115 /* Allocate string buffers */
116 real_url
= AllocVec(MAXIMUM_URL_LENGTH
,MEMF_ANY
);
117 filename
= AllocVec(MAXIMUM_URL_LENGTH
, MEMF_ANY
);
118 if (!real_url
|| !filename
)
120 /* Not enough memory */
121 SetIoErr(ERROR_NO_FREE_STORE
);
122 error_code
= IoErr();
130 /* Expand the filename to a fully qualified URL */
131 BPTR lock
= Lock((STRPTR
)args
[A_URL
],ACCESS_READ
);
135 if (NameFromLock(lock
,filename
,MAXIMUM_URL_LENGTH
))
137 strcpy(real_url
,"file://localhost/");
138 strncat(real_url
,filename
,MAXIMUM_URL_LENGTH
);
142 error_cause
= "Error obtaining full filename";
143 error_code
= IoErr();
150 error_cause
= "Error opening input file";
151 error_code
= IoErr();
156 /* Simply use the URL passed in arguments, assuming it is
157 * an already fully qualified URL of any protocol. Possible
158 * errors are now treated by the browser. */
159 strncpy(real_url
,(STRPTR
)args
[A_URL
],MAXIMUM_URL_LENGTH
);
162 /* Make sure that the URL gets a trailing zero (just in case
163 * someone passed a too long one). */
164 real_url
[MAXIMUM_URL_LENGTH
-1] = '\0';
169 if ((args
[A_NOSHOW
]) != 0)
171 tags
[i
].ti_Tag
= URL_Show
;
172 tags
[i
].ti_Data
= FALSE
; i
++;
174 if ((args
[A_NOFRONT
]) != 0)
176 tags
[i
].ti_Tag
= URL_BringToFront
;
177 tags
[i
].ti_Data
= FALSE
; i
++;
179 if ((args
[A_NEWWIN
]) != 0)
181 tags
[i
].ti_Tag
= URL_NewWindow
;
182 tags
[i
].ti_Data
= TRUE
; i
++;
184 if ((args
[A_NOLAUNCH
]) != 0)
186 tags
[i
].ti_Tag
= URL_Launch
;
187 tags
[i
].ti_Data
= FALSE
; i
++;
189 if (args
[A_PUBSCREEN
])
191 tags
[i
].ti_Tag
= URL_PubScreenName
;
192 tags
[i
].ti_Data
= args
[A_PUBSCREEN
]; i
++;
194 tags
[i
].ti_Tag
= TAG_DONE
; tags
[i
].ti_Data
= 0;
196 if (URL_OpenA(real_url
, tags
))
198 return_code
= RETURN_OK
;
203 if (args
[A_NOLAUNCH
])
205 error_cause
= "Could not find browser port";
209 error_cause
= "Could not launch browser";
216 error_cause
= "Error in arguments";
219 /* Free extended read args (even in case of error) */
220 SmartFreeArgs(&smart_args
);
222 /* Release all other resources */
223 if (filename
) FreeVec(filename
);
224 if (real_url
) FreeVec(real_url
);
226 #if defined(__amigaos4__)
227 DropInterface((struct Interface
*)IOpenURL
);
232 error_cause
= "Could not obtain \"openurl.library\" interface";
235 CloseLibrary(OpenURLBase
);
240 "Could not find \"openurl.library\", "
241 "version " OPENURL_VERSION_STR
;
244 /* Create error message in error_buffer (if any) */
247 Fault(error_code
,error_cause
,error_buffer
,MAXIMUM_ERROR_LENGTH
);
249 else if (error_cause
!=NULL
)
251 strncpy(error_buffer
,error_cause
,MAXIMUM_ERROR_LENGTH
-1);
254 /* Display error message in CLI or Requester (if any) */
255 if (error_buffer
[0]!='\0')
259 struct EasyStruct error_requester
=
261 sizeof(struct EasyStruct
),
268 EasyRequest(NULL
,&error_requester
,NULL
,error_buffer
);
272 FPuts(Output(),error_buffer
);
273 FPuts(Output(),"\n");
280 /**************************************************************************/