NetSurf
url_protocol.c
Go to the documentation of this file.
1/*
2 * Copyright 2003 John M Bell <jmb202@ecs.soton.ac.uk>
3 * Copyright 2003 Rob Jackson <jacko@xms.ms>
4 * Copyright 2004 James Bursa <bursa@users.sourceforge.net>
5 *
6 * This file is part of NetSurf, http://www.netsurf-browser.org/
7 *
8 * NetSurf is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; version 2 of the License.
11 *
12 * NetSurf is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21/**
22 * \file
23 * ANT URL launching protocol implementation.
24 *
25 * See http://www.vigay.com/inet/inet_url.html
26 */
27
28#include "utils/config.h"
29
30#include <ctype.h>
31#include <stdio.h>
32#include <string.h>
33#include <stdlib.h>
34#include <oslib/inetsuite.h>
35#include <oslib/wimp.h>
36
37#include "utils/log.h"
38#include "utils/messages.h"
39#include "utils/nsurl.h"
40#include "utils/config.h"
41#include "content/fetch.h"
43
44#include "riscos/gui.h"
45#include "riscos/uri.h"
46#include "riscos/url_protocol.h"
47
48/**
49 * Handle a Message_InetSuiteOpenURL.
50 */
51
52void ro_url_message_received(wimp_message *message)
53{
54 char *url;
55 int i;
56 inetsuite_message_open_url *url_message =
57 (inetsuite_message_open_url*) &message->data;
58 os_error *error;
59 nsurl *nsurl;
60 nserror errorns;
61
62 /* If the url_message->indirect.tag is non-zero,
63 * then the message data is contained within the message block.
64 */
65 if (url_message->indirect.tag != 0) {
66 url = strndup(url_message->url, 236);
67 if (!url) {
68 ro_warn_user("NoMemory", 0);
69 return;
70 }
71 /* terminate at first control character */
72 for (i = 0; !iscntrl(url[i]); i++)
73 ;
74 url[i] = 0;
75
76 } else {
77 if (!url_message->indirect.url.offset) {
78 NSLOG(netsurf, INFO, "no URL in message");
79 return;
80 }
81 if (28 < message->size &&
82 url_message->indirect.body_file.offset) {
83 NSLOG(netsurf, INFO,
84 "POST for URL message not implemented");
85 return;
86 }
87 if (url_message->indirect.url.offset < 28 ||
88 236 <= url_message->indirect.url.offset) {
89 NSLOG(netsurf, INFO,
90 "external pointers in URL message unimplemented");
91 /* these messages have never been seen in the wild,
92 * and there is the problem of invalid addresses which
93 * would cause an abort */
94 return;
95 }
96
97 url = strndup((char *) url_message +
98 url_message->indirect.url.offset,
99 236 - url_message->indirect.url.offset);
100 if (!url) {
101 ro_warn_user("NoMemory", 0);
102 return;
103 }
104 for (i = 0; !iscntrl(url[i]); i++)
105 ;
106 url[i] = 0;
107 }
108
109 if (nsurl_create(url, &nsurl) != NSERROR_OK) {
110 free(url);
111 return;
112 }
113
114 if (!fetch_can_fetch(nsurl)) {
116 free(url);
117 return;
118 }
119
120 free(url);
121
122 /* send ack */
123 message->your_ref = message->my_ref;
124 error = xwimp_send_message(wimp_USER_MESSAGE_ACKNOWLEDGE, message,
125 message->sender);
126 if (error) {
127 NSLOG(netsurf, INFO, "xwimp_send_message: 0x%x: %s",
128 error->errnum, error->errmess);
129 ro_warn_user("WimpError", error->errmess);
130 }
131
132 /* create new browser window */
134 nsurl,
135 NULL,
136 NULL,
137 NULL);
138
139
141 if (errorns != NSERROR_OK) {
143 }
144}
145
146
147/**
148 * Broadcast an ANT URL message.
149 */
150
151void ro_url_broadcast(const char *url)
152{
153 inetsuite_full_message_open_url_direct message;
154 os_error *error;
155 int len = strlen(url) + 1;
156
157 /* If URL is too long, then forget ANT and try URI, instead */
158 if (236 < len) {
159 ro_uri_launch(url);
160 return;
161 }
162
163 message.size = ((20+len+3) & ~3);
164 message.your_ref = 0;
165 message.action = message_INET_SUITE_OPEN_URL;
166 strncpy(message.url, url, 235);
167 message.url[235] = 0;
168 error = xwimp_send_message(wimp_USER_MESSAGE_RECORDED,
169 (wimp_message *) &message, 0);
170 if (error) {
171 NSLOG(netsurf, INFO, "xwimp_send_message: 0x%x: %s",
172 error->errnum, error->errmess);
173 ro_warn_user("WimpError", error->errmess);
174 }
175}
176
177
178/**
179 * Launch a program to handle an URL, using the ANT protocol
180 * Alias$URLOpen_ system.
181 */
182
183void ro_url_load(const char *url)
184{
185 char *command;
186 char *colon;
187 os_error *error;
188
189 colon = strchr(url, ':');
190 if (!colon) {
191 NSLOG(netsurf, INFO, "invalid url '%s'", url);
192 return;
193 }
194
195 command = malloc(40 + (colon - url) + strlen(url));
196 if (!command) {
197 ro_warn_user("NoMemory", 0);
198 return;
199 }
200
201 sprintf(command, "Alias$URLOpen_%.*s", (int) (colon - url), url);
202 if (!getenv(command)) {
203 free(command);
204 return;
205 }
206
207 sprintf(command, "URLOpen_%.*s %s", (int) (colon - url), url, url);
208
209 error = xwimp_start_task(command, 0);
210 if (error) {
211 NSLOG(netsurf, INFO, "xwimp_start_task: 0x%x: %s",
212 error->errnum, error->errmess);
213 ro_warn_user("WimpError", error->errmess);
214 }
215
216 free(command);
217}
218
219
220/**
221 * Handle a bounced Message_InetSuiteOpenURL.
222 */
223
224void ro_url_bounce(wimp_message *message)
225{
226 inetsuite_message_open_url *url_message =
227 (inetsuite_message_open_url*) &message->data;
228
229 /* ant broadcast bounced -> try uri broadcast / load */
230 ro_uri_launch(url_message->url);
231}
232
Browser window creation and manipulation interface.
nserror browser_window_create(enum browser_window_create_flags flags, struct nsurl *url, struct nsurl *referrer, struct browser_window *existing, struct browser_window **bw)
Create and open a new root browser window with the given page.
@ BW_CREATE_HISTORY
this will form a new history node (don't set for back/reload/etc)
char * strndup(const char *s, size_t n)
Duplicate up to n characters of a string.
Definition: utils.c:332
bool fetch_can_fetch(const nsurl *url)
Check if a URL's scheme can be fetched.
Definition: fetch.c:586
Fetching of data from a URL (interface).
nserror
Enumeration of error codes.
Definition: errors.h:29
@ NSERROR_OK
No error.
Definition: errors.h:30
#define NSLOG(catname, level, logmsg, args...)
Definition: log.h:116
const char * messages_get_errorcode(nserror code)
lookup of a message by errorcode from the standard Messages hash.
Definition: messages.c:248
Localised message support (interface).
NetSurf URL handling (interface).
nserror nsurl_create(const char *const url_s, nsurl **url)
Create a NetSurf URL object from a URL string.
void nsurl_unref(nsurl *url)
Drop a reference to a NetSurf URL object.
struct nsurl nsurl
NetSurf URL object.
Definition: nsurl.h:31
nserror ro_warn_user(const char *warning, const char *detail)
Display a warning for a serious problem (eg memory exhaustion).
Definition: gui.c:2077
Interface to utility string handling.
bool ro_uri_launch(const char *uri)
Definition: uri.c:93
void ro_url_load(const char *url)
Launch a program to handle an URL, using the ANT protocol Alias$URLOpen_ system.
Definition: url_protocol.c:183
void ro_url_broadcast(const char *url)
Broadcast an ANT URL message.
Definition: url_protocol.c:151
void ro_url_message_received(wimp_message *message)
Handle a Message_InetSuiteOpenURL.
Definition: url_protocol.c:52
void ro_url_bounce(wimp_message *message)
Handle a bounced Message_InetSuiteOpenURL.
Definition: url_protocol.c:224
ANT URL launching protocol (interface).