No empty .Rs/.Re
[netbsd-mini2440.git] / gnu / dist / gettext / gettext-tools / src / urlget.c
blobc30660fdde6177b58e928e24b49e8de0a61cc0b7
1 /* Get the contents of an URL.
2 Copyright (C) 2001-2003, 2005 Free Software Foundation, Inc.
3 Written by Bruno Haible <haible@clisp.cons.org>, 2001.
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2, or (at your option)
8 any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software Foundation,
17 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
20 #ifdef HAVE_CONFIG_H
21 # include "config.h"
22 #endif
24 #include <errno.h>
25 #include <fcntl.h>
26 #include <getopt.h>
27 #include <stdbool.h>
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <locale.h>
32 #ifdef HAVE_UNISTD_H
33 # include <unistd.h>
34 #endif
36 #include "closeout.h"
37 #include "error.h"
38 #include "error-progname.h"
39 #include "progname.h"
40 #include "relocatable.h"
41 #include "basename.h"
42 #include "full-write.h"
43 #include "execute.h"
44 #include "javaexec.h"
45 #include "exit.h"
46 #include "binary-io.h"
47 #include "gettext.h"
49 #define _(str) gettext (str)
51 #ifndef STDOUT_FILENO
52 # define STDOUT_FILENO 1
53 #endif
56 /* Only high-level toolkits, written in languages with exception handling,
57 have an URL datatype and operations to fetch an URL's contents. Such
58 toolkits are Java (class java.net.URL), Qt (classes QUrl and QUrlOperator).
59 We use the Java toolkit.
60 Note that this program doesn't handle redirection pages; programs which
61 wish to process HTML redirection tags need to include a HTML parser,
62 and only full-fledged browsers like w3m, lynx, links have have both
63 an URL fetcher (which covers at least the protocols "http", "ftp", "file")
64 and a HTML parser. */
67 /* Long options. */
68 static const struct option long_options[] =
70 { "help", no_argument, NULL, 'h' },
71 { "version", no_argument, NULL, 'V' },
72 { NULL, 0, NULL, 0 }
76 /* Forward declaration of local functions. */
77 static void usage (int status)
78 #if defined __GNUC__ && ((__GNUC__ == 2 && __GNUC_MINOR__ >= 5) || __GNUC__ > 2)
79 __attribute__ ((noreturn))
80 #endif
82 static void fetch (const char *url, const char *file);
85 int
86 main (int argc, char *argv[])
88 int optchar;
89 bool do_help;
90 bool do_version;
92 /* Set program name for messages. */
93 set_program_name (argv[0]);
94 error_print_progname = maybe_print_progname;
96 #ifdef HAVE_SETLOCALE
97 /* Set locale via LC_ALL. */
98 setlocale (LC_ALL, "");
99 #endif
101 /* Set the text message domain. */
102 bindtextdomain (PACKAGE, relocate (LOCALEDIR));
103 textdomain (PACKAGE);
105 /* Ensure that write errors on stdout are detected. */
106 atexit (close_stdout);
108 /* Set default values for variables. */
109 do_help = false;
110 do_version = false;
112 /* Parse command line options. */
113 while ((optchar = getopt_long (argc, argv, "hV", long_options, NULL)) != EOF)
114 switch (optchar)
116 case '\0': /* Long option. */
117 break;
118 case 'h':
119 do_help = true;
120 break;
121 case 'V':
122 do_version = true;
123 break;
124 default:
125 usage (EXIT_FAILURE);
126 /* NOTREACHED */
129 /* Version information requested. */
130 if (do_version)
132 printf ("%s (GNU %s) %s\n", basename (program_name), PACKAGE, VERSION);
133 /* xgettext: no-wrap */
134 printf (_("Copyright (C) %s Free Software Foundation, Inc.\n\
135 This is free software; see the source for copying conditions. There is NO\n\
136 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\
138 "2001-2003");
139 printf (_("Written by %s.\n"), "Bruno Haible");
140 exit (EXIT_SUCCESS);
143 /* Help is requested. */
144 if (do_help)
145 usage (EXIT_SUCCESS);
147 /* Test argument count. */
148 if (optind + 2 != argc)
149 error (EXIT_FAILURE, 0, _("expected two arguments"));
151 /* Fetch the contents. */
152 fetch (argv[optind], argv[optind + 1]);
154 exit (EXIT_SUCCESS);
157 /* Display usage information and exit. */
158 static void
159 usage (int status)
161 if (status != EXIT_SUCCESS)
162 fprintf (stderr, _("Try `%s --help' for more information.\n"),
163 program_name);
164 else
166 printf (_("\
167 Usage: %s [OPTION] URL FILE\n\
168 "), program_name);
169 printf ("\n");
170 /* xgettext: no-wrap */
171 printf (_("\
172 Fetches and outputs the contents of an URL. If the URL cannot be accessed,\n\
173 the locally accessible FILE is used instead.\n\
174 "));
175 printf ("\n");
176 printf (_("\
177 Informative output:\n"));
178 printf (_("\
179 -h, --help display this help and exit\n"));
180 printf (_("\
181 -V, --version output version information and exit\n"));
182 printf ("\n");
183 fputs (_("Report bugs to <bug-gnu-gettext@gnu.org>.\n"),
184 stdout);
187 exit (status);
190 /* Copy a file's contents to stdout. */
191 static void
192 cat_file (const char *src_filename)
194 int src_fd;
195 char buf[4096];
196 const int buf_size = sizeof (buf);
198 src_fd = open (src_filename, O_RDONLY | O_BINARY);
199 if (src_fd < 0)
200 error (EXIT_FAILURE, errno, _("error while opening \"%s\" for reading"),
201 src_filename);
203 for (;;)
205 ssize_t n_read = read (src_fd, buf, buf_size);
206 if (n_read < 0)
208 #ifdef EINTR
209 if (errno == EINTR)
210 continue;
211 #endif
212 error (EXIT_FAILURE, errno, _("error reading \"%s\""), src_filename);
214 if (n_read == 0)
215 break;
217 if (full_write (STDOUT_FILENO, buf, n_read) < n_read)
218 error (EXIT_FAILURE, errno, _("error writing stdout"));
221 if (close (src_fd) < 0)
222 error (EXIT_FAILURE, errno, _("error after reading \"%s\""), src_filename);
225 static bool
226 execute_it (const char *progname,
227 const char *prog_path, char **prog_argv,
228 void *private_data)
230 (void) private_data;
232 return execute (progname, prog_path, prog_argv, true, true, false, false,
233 true, false)
234 != 0;
237 /* Fetch the URL. Upon error, use the FILE as fallback. */
238 static void
239 fetch (const char *url, const char *file)
241 /* First try: using Java. */
243 const char *class_name = "gnu.gettext.GetURL";
244 const char *gettextjexedir;
245 const char *gettextjar;
246 const char *args[2];
248 #if USEJEXE
249 /* Make it possible to override the executable's location. This is
250 necessary for running the testsuite before "make install". */
251 gettextjexedir = getenv ("GETTEXTJEXEDIR");
252 if (gettextjexedir == NULL || gettextjexedir[0] == '\0')
253 gettextjexedir = relocate (GETTEXTJEXEDIR);
254 #else
255 gettextjexedir = NULL;
256 #endif
258 /* Make it possible to override the gettext.jar location. This is
259 necessary for running the testsuite before "make install". */
260 gettextjar = getenv ("GETTEXTJAR");
261 if (gettextjar == NULL || gettextjar[0] == '\0')
262 gettextjar = relocate (GETTEXTJAR);
264 /* Prepare arguments. */
265 args[0] = url;
266 args[1] = NULL;
268 /* Fetch the URL's contents. */
269 if (execute_java_class (class_name, &gettextjar, 1, true, gettextjexedir,
270 args,
271 false, true,
272 execute_it, NULL) == 0)
273 return;
276 /* Second try: using "wget -q -O - url". */
278 static bool wget_tested;
279 static bool wget_present;
281 if (!wget_tested)
283 /* Test for presence of wget: "wget --version > /dev/null" */
284 char *argv[3];
285 int exitstatus;
287 argv[0] = "wget";
288 argv[1] = "--version";
289 argv[2] = NULL;
290 exitstatus = execute ("wget", "wget", argv, false, false, true, true,
291 true, false);
292 wget_present = (exitstatus == 0);
293 wget_tested = true;
296 if (wget_present)
298 char *argv[8];
299 int exitstatus;
301 argv[0] = "wget";
302 argv[1] = "-q";
303 argv[2] = "-O"; argv[3] = "-";
304 argv[4] = "-T"; argv[5] = "30";
305 argv[6] = (char *) url;
306 argv[7] = NULL;
307 exitstatus = execute ("wget", "wget", argv, true, false, false, false,
308 true, false);
309 if (exitstatus != 127)
311 if (exitstatus != 0)
312 /* Use the file as fallback. */
313 cat_file (file);
314 return;
319 /* Third try: using "lynx -source url". */
321 static bool lynx_tested;
322 static bool lynx_present;
324 if (!lynx_tested)
326 /* Test for presence of lynx: "lynx --version > /dev/null" */
327 char *argv[3];
328 int exitstatus;
330 argv[0] = "lynx";
331 argv[1] = "--version";
332 argv[2] = NULL;
333 exitstatus = execute ("lynx", "lynx", argv, false, false, true, true,
334 true, false);
335 lynx_present = (exitstatus == 0);
336 lynx_tested = true;
339 if (lynx_present)
341 char *argv[4];
342 int exitstatus;
344 argv[0] = "lynx";
345 argv[1] = "-source";
346 argv[2] = (char *) url;
347 argv[3] = NULL;
348 exitstatus = execute ("lynx", "lynx", argv, true, false, false, false,
349 true, false);
350 if (exitstatus != 127)
352 if (exitstatus != 0)
353 /* Use the file as fallback. */
354 cat_file (file);
355 return;
360 /* Fourth try: using "curl --silent url". */
362 static bool curl_tested;
363 static bool curl_present;
365 if (!curl_tested)
367 /* Test for presence of curl: "curl --version > /dev/null" */
368 char *argv[3];
369 int exitstatus;
371 argv[0] = "curl";
372 argv[1] = "--version";
373 argv[2] = NULL;
374 exitstatus = execute ("curl", "curl", argv, false, false, true, true,
375 true, false);
376 curl_present = (exitstatus == 0 || exitstatus == 2);
377 curl_tested = true;
380 if (curl_present)
382 char *argv[4];
383 int exitstatus;
385 argv[0] = "curl";
386 argv[1] = "--silent";
387 argv[2] = (char *) url;
388 argv[3] = NULL;
389 exitstatus = execute ("curl", "curl", argv, true, false, false, false,
390 true, false);
391 if (exitstatus != 127)
393 if (exitstatus != 0)
394 /* Use the file as fallback. */
395 cat_file (file);
396 return;
401 /* Use the file as fallback. */
402 cat_file (file);