make.tmpl: add missing compiler attribute to build_progs
[AROS.git] / external / openurl / cmd / OpenURL.c
blobcebbf41d14f7a192a3d0329ced46480f42682adb
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/
17 $Id$
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>
27 #include <dos/dos.h>
28 #include <libraries/openurl.h>
29 #include <intuition/intuition.h>
31 #include <string.h>
32 #include <stdio.h>
34 #include "SmartReadArgs.h"
35 #include "macros.h"
36 #include "version.h"
38 #include "debug.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"
46 enum
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;
65 #else
66 struct IntuitionBase *IntuitionBase;
67 struct Library *IconBase;
68 struct Library *UtilityBase;
69 struct Library *OpenURLBase;
70 #endif
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)
78 #else
79 #define AllocVecShared(size, flags) AllocVec((size), (flags))
80 #endif
82 /* Some shit necessary because C standard libraries suck */
83 ULONG ulong_max(ULONG a, ULONG b)
85 return a>b ? a : b;
88 /* Main function
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;
96 LONG error_code = 0;
97 CONST_STRPTR error_cause = NULL;
98 struct WBStartup *wb_startup = NULL;
99 TEXT error_buffer[MAXIMUM_ERROR_LENGTH] = "";
101 // setup the debugging stuff
102 #if defined(DEBUG)
103 SetupDebug();
104 #endif
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;
120 IPTR args[A_MAX];
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 */
135 if (argc==0)
137 wb_startup = (struct WBStartup *)argv;
138 args[A_FILE] = 1;
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
153 * other string. */
154 if (error_code==0)
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();
167 if (error_code==0)
169 if (args[A_FILE])
171 /* Expand the filename to a fully qualified URL */
172 BPTR lock = Lock((STRPTR)args[A_URL],ACCESS_READ);
174 if (lock)
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);
181 else
183 error_cause = "Error obtaining full filename";
184 error_code = IoErr();
187 UnLock(lock);
189 else
191 error_cause = "Error opening input file";
192 error_code = IoErr();
195 else
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);
203 if (error_code==0)
205 int i = 0;
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;
237 else
239 error_code = 0;
240 if (args[A_NOLAUNCH])
242 error_cause = "Could not find browser port";
244 else
246 error_cause = "Could not launch browser";
251 else
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);
266 else
268 error_cause = "Could not find 'openurl.library', version " OPENURL_VERSION_STR;
271 DROPINTERFACE(IUtility);
272 CloseLibrary(UtilityBase);
274 else
278 DROPINTERFACE(IIcon);
279 CloseLibrary(IconBase);
281 else
285 DROPINTERFACE(IIntuition);
286 CloseLibrary((struct Library *)IntuitionBase);
288 else
292 /* Create error message in error_buffer (if any) */
293 if (error_code!=0)
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')
305 if (wb_startup)
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);
317 else
319 FPuts(Output(),error_buffer);
320 FPuts(Output(),"\n");
324 return return_code;
327 /**************************************************************************/