]> sjero.net Git - wget/blob - src/retr.c
[svn] Various url.c-related changes.
[wget] / src / retr.c
1 /* File retrieval.
2    Copyright (C) 1995, 1996, 1997, 1998, 2000, 2001 Free Software Foundation, Inc.
3
4 This file is part of Wget.
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program 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.  See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
19
20 #include <config.h>
21
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <sys/types.h>
25 #ifdef HAVE_UNISTD_H
26 # include <unistd.h>
27 #endif /* HAVE_UNISTD_H */
28 #include <errno.h>
29 #ifdef HAVE_STRING_H
30 # include <string.h>
31 #else
32 # include <strings.h>
33 #endif /* HAVE_STRING_H */
34 #include <assert.h>
35
36 #include "wget.h"
37 #include "utils.h"
38 #include "retr.h"
39 #include "url.h"
40 #include "recur.h"
41 #include "ftp.h"
42 #include "host.h"
43 #include "connect.h"
44 #include "hash.h"
45
46 #ifndef errno
47 extern int errno;
48 #endif
49
50 #ifdef WINDOWS
51 LARGE_INTEGER internal_time;
52 #else
53 /* Internal variables used by the timer.  */
54 static long internal_secs, internal_msecs;
55 #endif
56
57 /* See the comment in gethttp() why this is needed. */
58 int global_download_count;
59
60 void logflush PARAMS ((void));
61
62 /* From http.c.  */
63 uerr_t http_loop PARAMS ((struct urlinfo *, char **, int *));
64 \f
65 /* Flags for show_progress().  */
66 enum spflags { SP_NONE, SP_INIT, SP_FINISH };
67
68 static int show_progress PARAMS ((long, long, enum spflags));
69
70 #define MIN(i, j) ((i) <= (j) ? (i) : (j))
71
72 /* Reads the contents of file descriptor FD, until it is closed, or a
73    read error occurs.  The data is read in 8K chunks, and stored to
74    stream fp, which should have been open for writing.  If BUF is
75    non-NULL and its file descriptor is equal to FD, flush RBUF first.
76    This function will *not* use the rbuf_* functions!
77
78    The EXPECTED argument is passed to show_progress() unchanged, but
79    otherwise ignored.
80
81    If opt.verbose is set, the progress is also shown.  RESTVAL
82    represents a value from which to start downloading (which will be
83    shown accordingly).  If RESTVAL is non-zero, the stream should have
84    been open for appending.
85
86    The function exits and returns codes of 0, -1 and -2 if the
87    connection was closed, there was a read error, or if it could not
88    write to the output stream, respectively.
89
90    IMPORTANT: The function flushes the contents of the buffer in
91    rbuf_flush() before actually reading from fd.  If you wish to read
92    from fd immediately, flush or discard the buffer.  */
93 int
94 get_contents (int fd, FILE *fp, long *len, long restval, long expected,
95               struct rbuf *rbuf, int use_expected)
96 {
97   int res = 0;
98   static char c[8192];
99
100   *len = restval;
101   if (opt.verbose)
102     show_progress (restval, expected, SP_INIT);
103   if (rbuf && RBUF_FD (rbuf) == fd)
104     {
105       while ((res = rbuf_flush (rbuf, c, sizeof (c))) != 0)
106         {
107           if (fwrite (c, sizeof (char), res, fp) < res)
108             return -2;
109           if (opt.verbose)
110             {
111               if (show_progress (res, expected, SP_NONE))
112                 fflush (fp);
113             }
114           *len += res;
115         }
116     }
117   /* Read from fd while there is available data.
118
119      Normally, if expected is 0, it means that it is not known how
120      much data is expected.  However, if use_expected is specified,
121      then expected being zero means exactly that.  */
122   while (!use_expected || (*len < expected))
123     {
124       int amount_to_read = (use_expected
125                             ? MIN (expected - *len, sizeof (c))
126                             : sizeof (c));
127 #ifdef HAVE_SSL
128                 if (rbuf->ssl!=NULL) {
129                   res = ssl_iread (rbuf->ssl, c, amount_to_read);
130                 } else {
131 #endif /* HAVE_SSL */
132                   res = iread (fd, c, amount_to_read);
133 #ifdef HAVE_SSL
134                 }
135 #endif /* HAVE_SSL */
136       if (res > 0)
137         {
138           if (fwrite (c, sizeof (char), res, fp) < res)
139             return -2;
140           if (opt.verbose)
141             {
142               if (show_progress (res, expected, SP_NONE))
143                 fflush (fp);
144             }
145           *len += res;
146         }
147       else
148         break;
149     }
150   if (res < -1)
151     res = -1;
152   if (opt.verbose)
153     show_progress (0, expected, SP_FINISH);
154   return res;
155 }
156
157 static void
158 print_percentage (long bytes, long expected)
159 {
160   int percentage = (int)(100.0 * bytes / expected);
161   logprintf (LOG_VERBOSE, "%3d%%", percentage);
162 }
163
164 /* Show the dotted progress report of file loading.  Called with
165    length and a flag to tell it whether to reset or not.  It keeps the
166    offset information in static local variables.
167
168    Return value: 1 or 0, designating whether any dots have been drawn.
169
170    If the init argument is set, the routine will initialize.
171
172    If the res is non-zero, res/line_bytes lines are skipped
173    (meaning the appropriate number ok kilobytes), and the number of
174    "dots" fitting on the first line are drawn as ','.  */
175 static int
176 show_progress (long res, long expected, enum spflags flags)
177 {
178   static long line_bytes;
179   static long offs, initial_skip;
180   static int ndot, nrow;
181   static long last_timer, time_offset;
182   int any_output = 0;
183
184   if (flags == SP_FINISH)
185     {
186       if (expected)
187         {
188           int dot = ndot;
189           char *tmpstr = (char *)alloca (2 * opt.dots_in_line + 1);
190           char *tmpp = tmpstr;
191           time_offset = elapsed_time () - last_timer;
192           for (; dot < opt.dots_in_line; dot++)
193             {
194               if (!(dot % opt.dot_spacing))
195                 *tmpp++ = ' ';
196               *tmpp++ = ' ';
197             }
198           *tmpp = '\0';
199           logputs (LOG_VERBOSE, tmpstr);
200           print_percentage (nrow * line_bytes + ndot * opt.dot_bytes + offs,
201                             expected);
202           logprintf (LOG_VERBOSE, " @%s",
203                      rate (ndot * opt.dot_bytes
204                            + offs - (initial_skip % line_bytes),
205                            time_offset, 1));
206         }
207       logputs (LOG_VERBOSE, "\n\n");
208       return 0;
209     }
210
211   /* Temporarily disable flushing.  */
212   opt.no_flush = 1;
213   /* init set means initialization.  If res is set, it also means that
214      the retrieval is *not* done from the beginning.  The part that
215      was already retrieved is not shown again.  */
216   if (flags == SP_INIT)
217     {
218       /* Generic initialization of static variables.  */
219       offs = 0L;
220       ndot = nrow = 0;
221       line_bytes = (long)opt.dots_in_line * opt.dot_bytes;
222       last_timer = elapsed_time ();
223       time_offset = 0;
224       initial_skip = res;
225       if (res)
226         {
227           if (res >= line_bytes)
228             {
229               nrow = res / line_bytes;
230               res %= line_bytes;
231               logprintf (LOG_VERBOSE,
232                          _("\n          [ skipping %dK ]"),
233                          (int) ((nrow * line_bytes) / 1024));
234               ndot = 0;
235             }
236         }
237       logprintf (LOG_VERBOSE, "\n%5ldK", nrow * line_bytes / 1024);
238     }
239   /* Offset gets incremented by current value.  */
240   offs += res;
241   /* While offset is >= opt.dot_bytes, print dots, taking care to
242      precede every 50th dot with a status message.  */
243   for (; offs >= opt.dot_bytes; offs -= opt.dot_bytes)
244     {
245       if (!(ndot % opt.dot_spacing))
246         logputs (LOG_VERBOSE, " ");
247       any_output = 1;
248       logputs (LOG_VERBOSE, flags == SP_INIT ? "," : ".");
249       ++ndot;
250       if (ndot == opt.dots_in_line)
251         {
252           time_offset = elapsed_time () - last_timer;
253           last_timer += time_offset;
254
255           ndot = 0;
256           ++nrow;
257           if (expected)
258             {
259               print_percentage (nrow * line_bytes, expected);
260               logprintf (LOG_VERBOSE, " @%s",
261                          rate (line_bytes - (initial_skip % line_bytes),
262                                time_offset, 1));
263             }
264           initial_skip = 0;
265           logprintf (LOG_VERBOSE, "\n%5ldK", nrow * line_bytes / 1024);
266         }
267     }
268   /* Reenable flushing.  */
269   opt.no_flush = 0;
270   if (any_output)
271     /* Force flush.  #### Oh, what a kludge!  */
272     logflush ();
273   return any_output;
274 }
275 \f
276 /* Reset the internal timer.  */
277 void
278 reset_timer (void)
279 {
280 #ifndef WINDOWS
281   /* Under Unix, the preferred way to measure the passage of time is
282      through gettimeofday() because of its granularity.  However, on
283      some old or weird systems, gettimeofday() might not be available.
284      There we use the simple time().  */
285 # ifdef HAVE_GETTIMEOFDAY
286   struct timeval t;
287   gettimeofday (&t, NULL);
288   internal_secs = t.tv_sec;
289   internal_msecs = t.tv_usec / 1000;
290 # else  /* not HAVE_GETTIMEOFDAY */
291   internal_secs = time (NULL);
292   internal_msecs = 0;
293 # endif /* not HAVE_GETTIMEOFDAY */
294 #else  /* WINDOWS */
295   /* Under Windows, use Windows-specific APIs. */
296   FILETIME ft;
297   SYSTEMTIME st;
298   GetSystemTime(&st);
299   SystemTimeToFileTime(&st,&ft);
300   internal_time.HighPart = ft.dwHighDateTime;
301   internal_time.LowPart = ft.dwLowDateTime;
302 #endif /* WINDOWS */
303 }
304
305 /* Return the time elapsed from the last call to reset_timer(), in
306    milliseconds.  */
307 long
308 elapsed_time (void)
309 {
310 #ifndef WINDOWS
311 # ifdef HAVE_GETTIMEOFDAY
312   struct timeval t;
313   gettimeofday (&t, NULL);
314   return ((t.tv_sec - internal_secs) * 1000
315           + (t.tv_usec / 1000 - internal_msecs));
316 # else  /* not HAVE_GETTIMEOFDAY */
317   return 1000 * ((long)time (NULL) - internal_secs);
318 # endif /* not HAVE_GETTIMEOFDAY */
319 #else  /* WINDOWS */
320   FILETIME ft;
321   SYSTEMTIME st;
322   LARGE_INTEGER li;
323   GetSystemTime(&st);
324   SystemTimeToFileTime(&st,&ft);
325   li.HighPart = ft.dwHighDateTime;
326   li.LowPart = ft.dwLowDateTime;
327   return (long) ((li.QuadPart - internal_time.QuadPart) / 1e4);
328 #endif /* WINDOWS */
329 }
330
331 /* Print out the appropriate download rate.  Appropriate means that if
332    rate is > 1024 bytes per second, kilobytes are used, and if rate >
333    1024 * 1024 bps, megabytes are used.
334
335    If PAD is non-zero, strings will be padded to the width of 7
336    characters (xxxx.xx).  */
337 char *
338 rate (long bytes, long msecs, int pad)
339 {
340   static char res[15];
341   double dlrate;
342
343   if (!msecs)
344     ++msecs;
345   dlrate = (double)1000 * bytes / msecs;
346   if (dlrate < 1024.0)
347     sprintf (res, pad ? "%7.2f B/s" : "%.2f B/s", dlrate);
348   else if (dlrate < 1024.0 * 1024.0)
349     sprintf (res, pad ? "%7.2f KB/s" : "%.2f KB/s", dlrate / 1024.0);
350   else
351     sprintf (res, pad ? "%7.2f MB/s" : "%.2f MB/s", dlrate / (1024.0 * 1024.0));
352   return res;
353 }
354 \f
355 #define USE_PROXY_P(u) (opt.use_proxy && getproxy((u)->proto)           \
356                         && no_proxy_match((u)->host,                    \
357                                           (const char **)opt.no_proxy))
358
359 /* Retrieve the given URL.  Decides which loop to call -- HTTP(S), FTP,
360    or simply copy it with file:// (#### the latter not yet
361    implemented!).  */
362 uerr_t
363 retrieve_url (const char *origurl, char **file, char **newloc,
364               const char *refurl, int *dt)
365 {
366   uerr_t result;
367   char *url;
368   int location_changed, dummy;
369   int local_use_proxy;
370   char *mynewloc, *proxy;
371   struct urlinfo *u;
372   struct hash_table *redirections = NULL;
373
374   /* If dt is NULL, just ignore it.  */
375   if (!dt)
376     dt = &dummy;
377   url = xstrdup (origurl);
378   if (newloc)
379     *newloc = NULL;
380   if (file)
381     *file = NULL;
382
383   u = newurl ();
384   /* Parse the URL. */
385   result = parseurl (url, u, 0);
386   if (result != URLOK)
387     {
388       logprintf (LOG_NOTQUIET, "%s: %s.\n", url, uerrmsg (result));
389       freeurl (u, 1);
390       if (redirections)
391         string_set_free (redirections);
392       xfree (url);
393       return result;
394     }
395
396  redirected:
397
398   /* Set the referer.  */
399   if (refurl)
400     u->referer = xstrdup (refurl);
401   else
402     {
403       if (opt.referer)
404         u->referer = xstrdup (opt.referer);
405       else
406         u->referer = NULL;
407     }
408
409   local_use_proxy = USE_PROXY_P (u);
410   if (local_use_proxy)
411     {
412       struct urlinfo *pu = newurl ();
413
414       /* Copy the original URL to new location.  */
415       memcpy (pu, u, sizeof (*u));
416       pu->proxy = NULL; /* A minor correction :) */
417       /* Initialize u to nil.  */
418       memset (u, 0, sizeof (*u));
419       u->proxy = pu;
420       /* Get the appropriate proxy server, appropriate for the
421          current protocol.  */
422       proxy = getproxy (pu->proto);
423       if (!proxy)
424         {
425           logputs (LOG_NOTQUIET, _("Could not find proxy host.\n"));
426           freeurl (u, 1);
427           if (redirections)
428             string_set_free (redirections);
429           xfree (url);
430           return PROXERR;
431         }
432       /* Parse the proxy URL.  */
433       result = parseurl (proxy, u, 0);
434       if (result != URLOK || u->proto != URLHTTP)
435         {
436           if (u->proto == URLHTTP)
437             logprintf (LOG_NOTQUIET, "Proxy %s: %s.\n", proxy, uerrmsg(result));
438           else
439             logprintf (LOG_NOTQUIET, _("Proxy %s: Must be HTTP.\n"), proxy);
440           freeurl (u, 1);
441           if (redirections)
442             string_set_free (redirections);
443           xfree (url);
444           return PROXERR;
445         }
446       u->proto = URLHTTP;
447     }
448
449   assert (u->proto != URLFILE); /* #### Implement me!  */
450   mynewloc = NULL;
451
452   if (u->proto == URLHTTP
453 #ifdef HAVE_SSL
454       || u->proto == URLHTTPS
455 #endif
456       )
457     result = http_loop (u, &mynewloc, dt);
458   else if (u->proto == URLFTP)
459     {
460       /* If this is a redirection, we must not allow recursive FTP
461          retrieval, so we save recursion to oldrec, and restore it
462          later.  */
463       int oldrec = opt.recursive;
464       if (redirections)
465         opt.recursive = 0;
466       result = ftp_loop (u, dt);
467       opt.recursive = oldrec;
468       /* There is a possibility of having HTTP being redirected to
469          FTP.  In these cases we must decide whether the text is HTML
470          according to the suffix.  The HTML suffixes are `.html' and
471          `.htm', case-insensitive.
472
473          #### All of this is, of course, crap.  These types should be
474          determined through mailcap.  */
475       if (redirections && u->local && (u->proto == URLFTP ))
476         {
477           char *suf = suffix (u->local);
478           if (suf && (!strcasecmp (suf, "html") || !strcasecmp (suf, "htm")))
479             *dt |= TEXTHTML;
480           FREE_MAYBE (suf);
481         }
482     }
483   location_changed = (result == NEWLOCATION);
484   if (location_changed)
485     {
486       char *construced_newloc;
487       uerr_t newloc_result;
488       struct urlinfo *newloc_struct;
489
490       assert (mynewloc != NULL);
491
492       /* The HTTP specs only allow absolute URLs to appear in
493          redirects, but a ton of boneheaded webservers and CGIs out
494          there break the rules and use relative URLs, and popular
495          browsers are lenient about this, so wget should be too. */
496       construced_newloc = uri_merge (url, mynewloc);
497       xfree (mynewloc);
498       mynewloc = construced_newloc;
499
500       /* Now, see if this new location makes sense. */
501       newloc_struct = newurl ();
502       newloc_result = parseurl (mynewloc, newloc_struct, 1);
503       if (newloc_result != URLOK)
504         {
505           logprintf (LOG_NOTQUIET, "%s: %s.\n", mynewloc, uerrmsg (newloc_result));
506           freeurl (newloc_struct, 1);
507           freeurl (u, 1);
508           if (redirections)
509             string_set_free (redirections);
510           xfree (url);
511           xfree (mynewloc);
512           return result;
513         }
514
515       /* Now mynewloc will become newloc_struct->url, because if the
516          Location contained relative paths like .././something, we
517          don't want that propagating as url.  */
518       xfree (mynewloc);
519       mynewloc = xstrdup (newloc_struct->url);
520
521       if (!redirections)
522         {
523           redirections = make_string_hash_table (0);
524           /* Add current URL immediately so we can detect it as soon
525              as possible in case of a cycle. */
526           string_set_add (redirections, u->url);
527         }
528
529       /* The new location is OK.  Let's check for redirection cycle by
530          peeking through the history of redirections. */
531       if (string_set_exists (redirections, newloc_struct->url))
532         {
533           logprintf (LOG_NOTQUIET, _("%s: Redirection cycle detected.\n"),
534                      mynewloc);
535           freeurl (newloc_struct, 1);
536           freeurl (u, 1);
537           if (redirections)
538             string_set_free (redirections);
539           xfree (url);
540           xfree (mynewloc);
541           return WRONGCODE;
542         }
543       string_set_add (redirections, newloc_struct->url);
544
545       xfree (url);
546       url = mynewloc;
547       freeurl (u, 1);
548       u = newloc_struct;
549       goto redirected;
550     }
551
552   if (u->local)
553     {
554       if (*dt & RETROKF)
555         {
556           register_download (url, u->local);
557           if (*dt & TEXTHTML)
558             register_html (url, u->local);
559         }
560     }
561
562   if (file)
563     {
564       if (u->local)
565         *file = xstrdup (u->local);
566       else
567         *file = NULL;
568     }
569   freeurl (u, 1);
570   if (redirections)
571     string_set_free (redirections);
572
573   if (newloc)
574     *newloc = url;
575   else
576     xfree (url);
577
578   ++global_download_count;
579
580   return result;
581 }
582
583 /* Find the URLs in the file and call retrieve_url() for each of
584    them.  If HTML is non-zero, treat the file as HTML, and construct
585    the URLs accordingly.
586
587    If opt.recursive is set, call recursive_retrieve() for each file.  */
588 uerr_t
589 retrieve_from_file (const char *file, int html, int *count)
590 {
591   uerr_t status;
592   urlpos *url_list, *cur_url;
593
594   url_list = (html ? get_urls_html (file, NULL, FALSE, NULL)
595               : get_urls_file (file));
596   status = RETROK;             /* Suppose everything is OK.  */
597   *count = 0;                  /* Reset the URL count.  */
598   recursive_reset ();
599   for (cur_url = url_list; cur_url; cur_url = cur_url->next, ++*count)
600     {
601       char *filename, *new_file;
602       int dt;
603
604       if (downloaded_exceeds_quota ())
605         {
606           status = QUOTEXC;
607           break;
608         }
609       status = retrieve_url (cur_url->url, &filename, &new_file, NULL, &dt);
610       if (opt.recursive && status == RETROK && (dt & TEXTHTML))
611         status = recursive_retrieve (filename, new_file ? new_file
612                                                         : cur_url->url);
613
614       if (filename && opt.delete_after && file_exists_p (filename))
615         {
616           DEBUGP (("Removing file due to --delete-after in"
617                    " retrieve_from_file():\n"));
618           logprintf (LOG_VERBOSE, _("Removing %s.\n"), filename);
619           if (unlink (filename))
620             logprintf (LOG_NOTQUIET, "unlink: %s\n", strerror (errno));
621           dt &= ~RETROKF;
622         }
623
624       FREE_MAYBE (new_file);
625       FREE_MAYBE (filename);
626     }
627
628   /* Free the linked list of URL-s.  */
629   free_urlpos (url_list);
630
631   return status;
632 }
633
634 /* Print `giving up', or `retrying', depending on the impending
635    action.  N1 and N2 are the attempt number and the attempt limit.  */
636 void
637 printwhat (int n1, int n2)
638 {
639   logputs (LOG_VERBOSE, (n1 == n2) ? _("Giving up.\n\n") : _("Retrying.\n\n"));
640 }
641
642 /* Increment opt.downloaded by BY_HOW_MUCH.  If an overflow occurs,
643    set opt.downloaded_overflow to 1. */
644 void
645 downloaded_increase (unsigned long by_how_much)
646 {
647   VERY_LONG_TYPE old;
648   if (opt.downloaded_overflow)
649     return;
650   old = opt.downloaded;
651   opt.downloaded += by_how_much;
652   if (opt.downloaded < old)     /* carry flag, where are you when I
653                                    need you? */
654     {
655       /* Overflow. */
656       opt.downloaded_overflow = 1;
657       opt.downloaded = ~((VERY_LONG_TYPE)0);
658     }
659 }
660
661 /* Return non-zero if the downloaded amount of bytes exceeds the
662    desired quota.  If quota is not set or if the amount overflowed, 0
663    is returned. */
664 int
665 downloaded_exceeds_quota (void)
666 {
667   if (!opt.quota)
668     return 0;
669   if (opt.downloaded_overflow)
670     /* We don't really know.  (Wildly) assume not. */
671     return 0;
672
673   return opt.downloaded > opt.quota;
674 }
675
676 /* If opt.wait or opt.waitretry are specified, and if certain
677    conditions are met, sleep the appropriate number of seconds.  See
678    the documentation of --wait and --waitretry for more information.
679
680    COUNT is the count of current retrieval, beginning with 1. */
681
682 void
683 sleep_between_retrievals (int count)
684 {
685   static int first_retrieval = 1;
686
687   if (!first_retrieval && (opt.wait || opt.waitretry))
688     {
689       if (opt.waitretry && count > 1)
690         {
691           /* If opt.waitretry is specified and this is a retry, wait
692              for COUNT-1 number of seconds, or for opt.waitretry
693              seconds.  */
694           if (count <= opt.waitretry)
695             sleep (count - 1);
696           else
697             sleep (opt.waitretry);
698         }
699       else if (opt.wait)
700         /* Otherwise, check if opt.wait is specified.  If so, sleep.  */
701         sleep (opt.wait);
702     }
703   if (first_retrieval)
704     first_retrieval = 0;
705 }