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