• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /netgear-WNDR4500-V1.0.1.40_1.0.68/ap/gpl/timemachine/gettext-0.17/gettext-tools/src/
1/* Get the contents of an URL.
2   Copyright (C) 2001-2003, 2005-2007 Free Software Foundation, Inc.
3   Written by Bruno Haible <haible@clisp.cons.org>, 2001.
4
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 3 of the License, or
8   (at your option) any later version.
9
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.
14
15   You should have received a copy of the GNU General Public License
16   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
17
18
19#ifdef HAVE_CONFIG_H
20# include "config.h"
21#endif
22
23#include <errno.h>
24#include <fcntl.h>
25#include <getopt.h>
26#include <stdbool.h>
27#include <stdio.h>
28#include <stdlib.h>
29#include <locale.h>
30#include <unistd.h>
31
32#include "closeout.h"
33#include "error.h"
34#include "error-progname.h"
35#include "progname.h"
36#include "relocatable.h"
37#include "basename.h"
38#include "full-write.h"
39#include "execute.h"
40#include "javaexec.h"
41#include "binary-io.h"
42#include "propername.h"
43#include "gettext.h"
44
45#define _(str) gettext (str)
46
47#ifndef STDOUT_FILENO
48# define STDOUT_FILENO 1
49#endif
50
51
52/* Only high-level toolkits, written in languages with exception handling,
53   have an URL datatype and operations to fetch an URL's contents.  Such
54   toolkits are Java (class java.net.URL), Qt (classes QUrl and QUrlOperator).
55   We use the Java toolkit.
56   Note that this program doesn't handle redirection pages; programs which
57   wish to process HTML redirection tags need to include a HTML parser,
58   and only full-fledged browsers like w3m, lynx, links have have both
59   an URL fetcher (which covers at least the protocols "http", "ftp", "file")
60   and a HTML parser.  */
61
62
63/* Long options.  */
64static const struct option long_options[] =
65{
66  { "help", no_argument, NULL, 'h' },
67  { "version", no_argument, NULL, 'V' },
68  { NULL, 0, NULL, 0 }
69};
70
71
72/* Forward declaration of local functions.  */
73static void usage (int status)
74#if defined __GNUC__ && ((__GNUC__ == 2 && __GNUC_MINOR__ >= 5) || __GNUC__ > 2)
75     __attribute__ ((noreturn))
76#endif
77;
78static void fetch (const char *url, const char *file);
79
80
81int
82main (int argc, char *argv[])
83{
84  int optchar;
85  bool do_help;
86  bool do_version;
87
88  /* Set program name for messages.  */
89  set_program_name (argv[0]);
90  error_print_progname = maybe_print_progname;
91
92#ifdef HAVE_SETLOCALE
93  /* Set locale via LC_ALL.  */
94  setlocale (LC_ALL, "");
95#endif
96
97  /* Set the text message domain.  */
98  bindtextdomain (PACKAGE, relocate (LOCALEDIR));
99  textdomain (PACKAGE);
100
101  /* Ensure that write errors on stdout are detected.  */
102  atexit (close_stdout);
103
104  /* Set default values for variables.  */
105  do_help = false;
106  do_version = false;
107
108  /* Parse command line options.  */
109  while ((optchar = getopt_long (argc, argv, "hV", long_options, NULL)) != EOF)
110    switch (optchar)
111    {
112    case '\0':		/* Long option.  */
113      break;
114    case 'h':
115      do_help = true;
116      break;
117    case 'V':
118      do_version = true;
119      break;
120    default:
121      usage (EXIT_FAILURE);
122      /* NOTREACHED */
123    }
124
125  /* Version information requested.  */
126  if (do_version)
127    {
128      printf ("%s (GNU %s) %s\n", basename (program_name), PACKAGE, VERSION);
129      /* xgettext: no-wrap */
130      printf (_("Copyright (C) %s Free Software Foundation, Inc.\n\
131License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>\n\
132This is free software: you are free to change and redistribute it.\n\
133There is NO WARRANTY, to the extent permitted by law.\n\
134"),
135	      "2001-2003, 2005-2007");
136      printf (_("Written by %s.\n"), proper_name ("Bruno Haible"));
137      exit (EXIT_SUCCESS);
138    }
139
140  /* Help is requested.  */
141  if (do_help)
142    usage (EXIT_SUCCESS);
143
144  /* Test argument count.  */
145  if (optind + 2 != argc)
146    error (EXIT_FAILURE, 0, _("expected two arguments"));
147
148  /* Fetch the contents.  */
149  fetch (argv[optind], argv[optind + 1]);
150
151  exit (EXIT_SUCCESS);
152}
153
154/* Display usage information and exit.  */
155static void
156usage (int status)
157{
158  if (status != EXIT_SUCCESS)
159    fprintf (stderr, _("Try `%s --help' for more information.\n"),
160	     program_name);
161  else
162    {
163      printf (_("\
164Usage: %s [OPTION] URL FILE\n\
165"), program_name);
166      printf ("\n");
167      /* xgettext: no-wrap */
168      printf (_("\
169Fetches and outputs the contents of an URL.  If the URL cannot be accessed,\n\
170the locally accessible FILE is used instead.\n\
171"));
172      printf ("\n");
173      printf (_("\
174Informative output:\n"));
175      printf (_("\
176  -h, --help                  display this help and exit\n"));
177      printf (_("\
178  -V, --version               output version information and exit\n"));
179      printf ("\n");
180      /* TRANSLATORS: The placeholder indicates the bug-reporting address
181         for this package.  Please add _another line_ saying
182         "Report translation bugs to <...>\n" with the address for translation
183         bugs (typically your translation team's web or email address).  */
184      fputs (_("Report bugs to <bug-gnu-gettext@gnu.org>.\n"),
185	     stdout);
186    }
187
188  exit (status);
189}
190
191/* Copy a file's contents to stdout.  */
192static void
193cat_file (const char *src_filename)
194{
195  int src_fd;
196  char buf[4096];
197  const int buf_size = sizeof (buf);
198
199  src_fd = open (src_filename, O_RDONLY | O_BINARY);
200  if (src_fd < 0)
201    error (EXIT_FAILURE, errno, _("error while opening \"%s\" for reading"),
202	   src_filename);
203
204  for (;;)
205    {
206      ssize_t n_read = read (src_fd, buf, buf_size);
207      if (n_read < 0)
208	{
209#ifdef EINTR
210	  if (errno == EINTR)
211	    continue;
212#endif
213	  error (EXIT_FAILURE, errno, _("error reading \"%s\""), src_filename);
214	}
215      if (n_read == 0)
216	break;
217
218      if (full_write (STDOUT_FILENO, buf, n_read) < n_read)
219	error (EXIT_FAILURE, errno, _("error writing stdout"));
220    }
221
222  if (close (src_fd) < 0)
223    error (EXIT_FAILURE, errno, _("error after reading \"%s\""), src_filename);
224}
225
226static bool
227execute_it (const char *progname,
228	    const char *prog_path, char **prog_argv,
229	    void *private_data)
230{
231  (void) private_data;
232
233  return execute (progname, prog_path, prog_argv, true, true, false, false,
234		  true, false)
235	 != 0;
236}
237
238/* Fetch the URL.  Upon error, use the FILE as fallback.  */
239static void
240fetch (const char *url, const char *file)
241{
242  /* First try: using Java.  */
243  {
244    const char *class_name = "gnu.gettext.GetURL";
245    const char *gettextjexedir;
246    const char *gettextjar;
247    const char *args[2];
248
249#if USEJEXE
250    /* Make it possible to override the executable's location.  This is
251       necessary for running the testsuite before "make install".  */
252    gettextjexedir = getenv ("GETTEXTJEXEDIR");
253    if (gettextjexedir == NULL || gettextjexedir[0] == '\0')
254      gettextjexedir = relocate (GETTEXTJEXEDIR);
255#else
256    gettextjexedir = NULL;
257#endif
258
259    /* Make it possible to override the gettext.jar location.  This is
260       necessary for running the testsuite before "make install".  */
261    gettextjar = getenv ("GETTEXTJAR");
262    if (gettextjar == NULL || gettextjar[0] == '\0')
263      gettextjar = relocate (GETTEXTJAR);
264
265    /* Prepare arguments.  */
266    args[0] = url;
267    args[1] = NULL;
268
269    /* Fetch the URL's contents.  */
270    if (execute_java_class (class_name, &gettextjar, 1, true, gettextjexedir,
271			    args,
272			    false, true,
273			    execute_it, NULL) == 0)
274      return;
275  }
276
277  /* Second try: using "wget -q -O - url".  */
278  {
279    static bool wget_tested;
280    static bool wget_present;
281
282    if (!wget_tested)
283      {
284	/* Test for presence of wget: "wget --version > /dev/null"  */
285	char *argv[3];
286	int exitstatus;
287
288	argv[0] = "wget";
289	argv[1] = "--version";
290	argv[2] = NULL;
291	exitstatus = execute ("wget", "wget", argv, false, false, true, true,
292			      true, false);
293	wget_present = (exitstatus == 0);
294	wget_tested = true;
295      }
296
297    if (wget_present)
298      {
299	char *argv[8];
300	int exitstatus;
301
302	argv[0] = "wget";
303	argv[1] = "-q";
304	argv[2] = "-O"; argv[3] = "-";
305	argv[4] = "-T"; argv[5] = "30";
306	argv[6] = (char *) url;
307	argv[7] = NULL;
308	exitstatus = execute ("wget", "wget", argv, true, false, false, false,
309			      true, false);
310	if (exitstatus != 127)
311	  {
312	    if (exitstatus != 0)
313	      /* Use the file as fallback.  */
314	      cat_file (file);
315	    return;
316	  }
317      }
318  }
319
320  /* Third try: using "lynx -source url".  */
321  {
322    static bool lynx_tested;
323    static bool lynx_present;
324
325    if (!lynx_tested)
326      {
327	/* Test for presence of lynx: "lynx --version > /dev/null"  */
328	char *argv[3];
329	int exitstatus;
330
331	argv[0] = "lynx";
332	argv[1] = "--version";
333	argv[2] = NULL;
334	exitstatus = execute ("lynx", "lynx", argv, false, false, true, true,
335			      true, false);
336	lynx_present = (exitstatus == 0);
337	lynx_tested = true;
338      }
339
340    if (lynx_present)
341      {
342	char *argv[4];
343	int exitstatus;
344
345	argv[0] = "lynx";
346	argv[1] = "-source";
347	argv[2] = (char *) url;
348	argv[3] = NULL;
349	exitstatus = execute ("lynx", "lynx", argv, true, false, false, false,
350			      true, false);
351	if (exitstatus != 127)
352	  {
353	    if (exitstatus != 0)
354	      /* Use the file as fallback.  */
355	      cat_file (file);
356	    return;
357	  }
358      }
359  }
360
361  /* Fourth try: using "curl --silent url".  */
362  {
363    static bool curl_tested;
364    static bool curl_present;
365
366    if (!curl_tested)
367      {
368	/* Test for presence of curl: "curl --version > /dev/null"  */
369	char *argv[3];
370	int exitstatus;
371
372	argv[0] = "curl";
373	argv[1] = "--version";
374	argv[2] = NULL;
375	exitstatus = execute ("curl", "curl", argv, false, false, true, true,
376			      true, false);
377	curl_present = (exitstatus == 0 || exitstatus == 2);
378	curl_tested = true;
379      }
380
381    if (curl_present)
382      {
383	char *argv[4];
384	int exitstatus;
385
386	argv[0] = "curl";
387	argv[1] = "--silent";
388	argv[2] = (char *) url;
389	argv[3] = NULL;
390	exitstatus = execute ("curl", "curl", argv, true, false, false, false,
391			      true, false);
392	if (exitstatus != 127)
393	  {
394	    if (exitstatus != 0)
395	      /* Use the file as fallback.  */
396	      cat_file (file);
397	    return;
398	  }
399      }
400  }
401
402  /* Use the file as fallback.  */
403  cat_file (file);
404}
405