~ubuntu-branches/ubuntu/natty/gettext/natty

« back to all changes in this revision

Viewing changes to .pc/01/gettext-tools/src/urlget.c

  • Committer: Bazaar Package Importer
  • Author(s): Felix Geyer
  • Date: 2010-05-09 10:05:58 UTC
  • mfrom: (2.1.8 sid)
  • Revision ID: james.westby@ubuntu.com-20100509100558-d2n9nzumcpzehn6u
Tags: 0.17-11ubuntu1
* Resynchronise with Debian (LP: #577744). Remaining changes:
  - Build Java components with gcj.
  - Throw away /usr/lib/gettext/gnu.gettext*; we don't need them.
  - gettext-tools/src/write-catalog.c:
    - Add missing "mode" parameter to fix FTBFS.
  - Use autoconf's preferred shell when invoking config.status.
  - Explicitly configure with --disable-csharp.
  - Keep gettext.jar in /usr/share/gettext instead of moving it to
    /usr/share/java.
* Convert Ubuntu direct source changes to quilt patches (u01 and u02).

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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.  */
 
64
static 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.  */
 
73
static void usage (int status)
 
74
#if defined __GNUC__ && ((__GNUC__ == 2 && __GNUC_MINOR__ >= 5) || __GNUC__ > 2)
 
75
     __attribute__ ((noreturn))
 
76
#endif
 
77
;
 
78
static void fetch (const char *url, const char *file);
 
79
 
 
80
 
 
81
int
 
82
main (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\
 
131
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>\n\
 
132
This is free software: you are free to change and redistribute it.\n\
 
133
There 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.  */
 
155
static void
 
156
usage (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 (_("\
 
164
Usage: %s [OPTION] URL FILE\n\
 
165
"), program_name);
 
166
      printf ("\n");
 
167
      /* xgettext: no-wrap */
 
168
      printf (_("\
 
169
Fetches and outputs the contents of an URL.  If the URL cannot be accessed,\n\
 
170
the locally accessible FILE is used instead.\n\
 
171
"));
 
172
      printf ("\n");
 
173
      printf (_("\
 
174
Informative 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.  */
 
192
static void
 
193
cat_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
 
 
226
static bool
 
227
execute_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.  */
 
239
static void
 
240
fetch (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
}