1/* mswindows.c -- Windows-specific support
2   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
3   2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
4
5This file is part of GNU Wget.
6
7GNU Wget is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 3 of the License, or
10(at your option) any later version.
11
12GNU Wget is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with Wget.  If not, see <http://www.gnu.org/licenses/>.
19
20Additional permission under GNU GPL version 3 section 7
21
22If you modify this program, or any covered work, by linking or
23combining it with the OpenSSL project's OpenSSL library (or a
24modified version of that library), containing parts covered by the
25terms of the OpenSSL or SSLeay licenses, the Free Software Foundation
26grants you additional permission to convey the resulting work.
27Corresponding Source for a non-source form of such a combination
28shall include the source code for the parts of OpenSSL used as well
29as that of the covered work.  */
30
31#define INHIBIT_WRAP /* avoid wrapping of socket, bind, ... */
32
33#include "wget.h"
34
35#include <stdio.h>
36#include <stdlib.h>
37#include <string.h>
38#include <errno.h>
39#include <math.h>
40
41
42#include "utils.h"
43#include "url.h"
44
45#ifndef ES_SYSTEM_REQUIRED
46#define ES_SYSTEM_REQUIRED  0x00000001
47#endif
48
49#ifndef ES_CONTINUOUS
50#define ES_CONTINUOUS       0x80000000
51#endif
52
53
54/* Defined in log.c.  */
55void log_request_redirect_output (const char *);
56
57/* Windows version of xsleep in utils.c.  */
58
59void
60xsleep (double seconds)
61{
62#ifdef HAVE_USLEEP
63  if (seconds > 1000)
64    {
65      /* Explained in utils.c. */
66      sleep (seconds);
67      seconds -= (long) seconds;
68    }
69  usleep (seconds * 1000000);
70#else  /* not HAVE_USLEEP */
71  SleepEx ((DWORD) (seconds * 1000 + .5), FALSE);
72#endif /* not HAVE_USLEEP */
73}
74
75void
76windows_main (char **exec_name)
77{
78  char *p;
79
80  /* Remove .EXE from filename if it has one.  */
81  *exec_name = xstrdup (*exec_name);
82  p = strrchr (*exec_name, '.');
83  if (p)
84    *p = '\0';
85}
86
87static void
88ws_cleanup (void)
89{
90  xfree ((char*)exec_name);
91  WSACleanup ();
92}
93
94#if defined(CTRLBREAK_BACKGND) || defined(CTRLC_BACKGND)
95static void
96ws_hangup (const char *reason)
97{
98  fprintf (stderr, _("Continuing in background.\n"));
99  log_request_redirect_output (reason);
100
101  /* Detach process from the current console.  Under Windows 9x, if we
102     were launched from a 16-bit process (which is usually the case;
103     command.com is 16-bit) the parent process should resume right away.
104     Under NT or if launched from a 32-process under 9x, this is a futile
105     gesture as the parent will wait for us to terminate before resuming.  */
106  FreeConsole ();
107}
108#endif
109
110/* Construct the name for a named section (a.k.a. `file mapping') object.
111   The returned string is dynamically allocated and needs to be xfree()'d.  */
112static char *
113make_section_name (DWORD pid)
114{
115  return aprintf ("gnu_wget_fake_fork_%lu", pid);
116}
117
118/* This structure is used to hold all the data that is exchanged between
119   parent and child.  */
120struct fake_fork_info
121{
122  HANDLE event;
123  bool logfile_changed;
124  char lfilename[MAX_PATH + 1];
125};
126
127/* Determines if we are the child and if so performs the child logic.
128   Return values:
129     < 0  error
130       0  parent
131     > 0  child
132*/
133static int
134fake_fork_child (void)
135{
136  HANDLE section, event;
137  struct fake_fork_info *info;
138  char *name;
139
140  name = make_section_name (GetCurrentProcessId ());
141  section = OpenFileMapping (FILE_MAP_WRITE, FALSE, name);
142  xfree (name);
143  /* It seems that Windows 9x and NT set last-error inconsistently when
144     OpenFileMapping() fails; so we assume it failed because the section
145     object does not exist.  */
146  if (!section)
147    return 0;                   /* We are the parent.  */
148
149  info = MapViewOfFile (section, FILE_MAP_WRITE, 0, 0, 0);
150  if (!info)
151    {
152      CloseHandle (section);
153      return -1;
154    }
155
156  event = info->event;
157
158  info->logfile_changed = false;
159  if (!opt.lfilename && (!opt.quiet || opt.server_response))
160    {
161      /* See utils:fork_to_background for explanation. */
162      FILE *new_log_fp = unique_create (DEFAULT_LOGFILE, false, &opt.lfilename);
163      if (new_log_fp)
164        {
165          info->logfile_changed = true;
166          strncpy (info->lfilename, opt.lfilename, sizeof (info->lfilename));
167          info->lfilename[sizeof (info->lfilename) - 1] = '\0';
168          fclose (new_log_fp);
169        }
170    }
171
172  UnmapViewOfFile (info);
173  CloseHandle (section);
174
175  /* Inform the parent that we've done our part.  */
176  if (!SetEvent (event))
177    return -1;
178
179  CloseHandle (event);
180  return 1;                     /* We are the child.  */
181}
182
183/* Windows doesn't support the fork() call; so we fake it by invoking
184   another copy of Wget with the same arguments with which we were
185   invoked.  The child copy of Wget should perform the same initialization
186   sequence as the parent; so we should have two processes that are
187   essentially identical.  We create a specially named section object that
188   allows the child to distinguish itself from the parent and is used to
189   exchange information between the two processes.  We use an event object
190   for synchronization.  */
191static void
192fake_fork (void)
193{
194  char exe[MAX_PATH + 1];
195  DWORD exe_len, le;
196  SECURITY_ATTRIBUTES sa;
197  HANDLE section, event, h[2];
198  STARTUPINFO si;
199  PROCESS_INFORMATION pi;
200  struct fake_fork_info *info;
201  char *name;
202  BOOL rv;
203
204  section = pi.hProcess = pi.hThread = NULL;
205
206  /* Get the fully qualified name of our executable.  This is more reliable
207     than using argv[0].  */
208  exe_len = GetModuleFileName (GetModuleHandle (NULL), exe, sizeof (exe));
209  if (!exe_len || (exe_len >= sizeof (exe)))
210    return;
211
212  sa.nLength = sizeof (sa);
213  sa.lpSecurityDescriptor = NULL;
214  sa.bInheritHandle = TRUE;
215
216  /* Create an anonymous inheritable event object that starts out
217     non-signaled.  */
218  event = CreateEvent (&sa, FALSE, FALSE, NULL);
219  if (!event)
220    return;
221
222  /* Create the child process detached form the current console and in a
223     suspended state.  */
224  xzero (si);
225  si.cb = sizeof (si);
226  rv = CreateProcess (exe, GetCommandLine (), NULL, NULL, TRUE,
227                      CREATE_SUSPENDED | DETACHED_PROCESS,
228                      NULL, NULL, &si, &pi);
229  if (!rv)
230    goto cleanup;
231
232  /* Create a named section object with a name based on the process id of
233     the child.  */
234  name = make_section_name (pi.dwProcessId);
235  section =
236      CreateFileMapping (INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0,
237                         sizeof (struct fake_fork_info), name);
238  le = GetLastError();
239  xfree (name);
240  /* Fail if the section object already exists (should not happen).  */
241  if (!section || (le == ERROR_ALREADY_EXISTS))
242    {
243      rv = FALSE;
244      goto cleanup;
245    }
246
247  /* Copy the event handle into the section object.  */
248  info = MapViewOfFile (section, FILE_MAP_WRITE, 0, 0, 0);
249  if (!info)
250    {
251      rv = FALSE;
252      goto cleanup;
253    }
254
255  info->event = event;
256
257  UnmapViewOfFile (info);
258
259  /* Start the child process.  */
260  rv = ResumeThread (pi.hThread);
261  if (!rv)
262    {
263      TerminateProcess (pi.hProcess, (DWORD) -1);
264      goto cleanup;
265    }
266
267  /* Wait for the child to signal to us that it has done its part.  If it
268     terminates before signaling us it's an error.  */
269
270  h[0] = event;
271  h[1] = pi.hProcess;
272  rv = WAIT_OBJECT_0 == WaitForMultipleObjects (2, h, FALSE, 5 * 60 * 1000);
273  if (!rv)
274    goto cleanup;
275
276  info = MapViewOfFile (section, FILE_MAP_READ, 0, 0, 0);
277  if (!info)
278    {
279      rv = FALSE;
280      goto cleanup;
281    }
282
283  /* Ensure string is properly terminated.  */
284  if (info->logfile_changed &&
285      !memchr (info->lfilename, '\0', sizeof (info->lfilename)))
286    {
287      rv = FALSE;
288      goto cleanup;
289    }
290
291  printf (_("Continuing in background, pid %lu.\n"), pi.dwProcessId);
292  if (info->logfile_changed)
293    printf (_("Output will be written to %s.\n"), quote (info->lfilename));
294
295  UnmapViewOfFile (info);
296
297cleanup:
298
299  if (event)
300    CloseHandle (event);
301  if (section)
302    CloseHandle (section);
303  if (pi.hThread)
304    CloseHandle (pi.hThread);
305  if (pi.hProcess)
306    CloseHandle (pi.hProcess);
307
308  /* We're the parent.  If all is well, terminate.  */
309  if (rv)
310    exit (0);
311
312  /* We failed, return.  */
313}
314
315/* This is the corresponding Windows implementation of the
316   fork_to_background() function in utils.c.  */
317void
318fork_to_background (void)
319{
320  int rv;
321
322  rv = fake_fork_child ();
323  if (rv < 0)
324    {
325      fprintf (stderr, "fake_fork_child() failed\n");
326      abort ();
327    }
328  else if (rv == 0)
329    {
330      /* We're the parent.  */
331      fake_fork ();
332      /* If fake_fork() returns, it failed.  */
333      fprintf (stderr, "fake_fork() failed\n");
334      abort ();
335    }
336  /* If we get here, we're the child.  */
337}
338
339static BOOL WINAPI
340ws_handler (DWORD dwEvent)
341{
342  switch (dwEvent)
343    {
344#ifdef CTRLC_BACKGND
345    case CTRL_C_EVENT:
346      ws_hangup ("CTRL+C");
347      return TRUE;
348#endif
349#ifdef CTRLBREAK_BACKGND
350    case CTRL_BREAK_EVENT:
351      ws_hangup ("CTRL+Break");
352      return TRUE;
353#endif
354    default:
355      return FALSE;
356    }
357}
358
359static char *title_buf = NULL;
360static char *curr_url  = NULL;
361static int old_percentage = -1;
362
363/* Updates the console title with the URL of the current file being
364   transferred.  */
365void
366ws_changetitle (const char *url)
367{
368  xfree_null (title_buf);
369  xfree_null (curr_url);
370  title_buf = xmalloc (strlen (url) + 20);
371  curr_url = xstrdup (url);
372  old_percentage = -1;
373  sprintf (title_buf, "Wget %s", curr_url);
374  SetConsoleTitle (title_buf);
375}
376
377/* Updates the console title with the percentage of the current file
378   transferred.  */
379void
380ws_percenttitle (double percentage_float)
381{
382  int percentage;
383
384  if (!title_buf || !curr_url)
385    return;
386
387  percentage = (int) percentage_float;
388
389  /* Clamp percentage value.  */
390  if (percentage < 0)
391    percentage = 0;
392  if (percentage > 100)
393    percentage = 100;
394
395  /* Only update the title when the percentage has changed.  */
396  if (percentage == old_percentage)
397    return;
398
399  old_percentage = percentage;
400
401  sprintf (title_buf, "Wget [%d%%] %s", percentage, curr_url);
402  SetConsoleTitle (title_buf);
403}
404
405/* Returns a pointer to the fully qualified name of the directory that
406   contains the Wget binary (wget.exe).  The returned path does not have a
407   trailing path separator.  Returns NULL on failure.  */
408char *
409ws_mypath (void)
410{
411  static char *wspathsave = NULL;
412
413  if (!wspathsave)
414    {
415      char buf[MAX_PATH + 1];
416      char *p;
417      DWORD len;
418
419      len = GetModuleFileName (GetModuleHandle (NULL), buf, sizeof (buf));
420      if (!len || (len >= sizeof (buf)))
421        return NULL;
422
423      p = strrchr (buf, PATH_SEPARATOR);
424      if (!p)
425        return NULL;
426
427      *p = '\0';
428      wspathsave = xstrdup (buf);
429    }
430
431  return wspathsave;
432}
433
434/* Prevent Windows entering sleep/hibernation-mode while Wget is doing
435   a lengthy transfer.  Windows does not, by default, consider network
436   activity in console-programs as activity!  Works on Win-98/ME/2K
437   and up.  */
438static void
439set_sleep_mode (void)
440{
441  typedef DWORD (WINAPI *func_t) (DWORD);
442  func_t set_exec_state;
443
444  set_exec_state =
445      (func_t) GetProcAddress (GetModuleHandle ("KERNEL32.DLL"),
446                               "SetThreadExecutionState");
447
448  if (set_exec_state)
449    set_exec_state (ES_SYSTEM_REQUIRED | ES_CONTINUOUS);
450}
451
452/* Perform Windows specific initialization.  */
453void
454ws_startup (void)
455{
456  WSADATA data;
457  WORD requested = MAKEWORD (1, 1);
458  int err = WSAStartup (requested, &data);
459  if (err != 0)
460    {
461      fprintf (stderr, _("%s: Couldn't find usable socket driver.\n"),
462               exec_name);
463      exit (1);
464    }
465
466  if (data.wVersion < requested)
467    {
468      fprintf (stderr, _("%s: Couldn't find usable socket driver.\n"),
469               exec_name);
470      WSACleanup ();
471      exit (1);
472    }
473
474  atexit (ws_cleanup);
475  set_sleep_mode ();
476  SetConsoleCtrlHandler (ws_handler, TRUE);
477}
478
479/* run_with_timeout Windows implementation.  */
480
481/* Stack size 0 uses default thread stack-size (reserve+commit).
482   Determined by what's in the PE header.  */
483#define THREAD_STACK_SIZE  0
484
485struct thread_data
486{
487  void (*fun) (void *);
488  void *arg;
489  DWORD ws_error;
490};
491
492/* The callback that runs FUN(ARG) in a separate thread.  This
493   function exists for two reasons: a) to not require FUN to be
494   declared WINAPI/__stdcall[1], and b) to retrieve Winsock errors,
495   which are per-thread.  The latter is useful when FUN calls Winsock
496   functions, which is how run_with_timeout is used in Wget.
497
498   [1] MSVC can use __fastcall globally (cl /Gr) and on Watcom this is
499   the default (wcc386 -3r).  */
500
501static DWORD WINAPI
502thread_helper (void *arg)
503{
504  struct thread_data *td = (struct thread_data *) arg;
505
506  /* Initialize Winsock error to what it was in the parent.  That way
507     the subsequent call to WSAGetLastError will return the same value
508     if td->fun doesn't change Winsock error state.  */
509  WSASetLastError (td->ws_error);
510
511  td->fun (td->arg);
512
513  /* Return Winsock error to the caller, in case FUN ran Winsock
514     code.  */
515  td->ws_error = WSAGetLastError ();
516  return 0;
517}
518
519/* Call FUN(ARG), but don't allow it to run for more than TIMEOUT
520   seconds.  Returns true if the function was interrupted with a
521   timeout, false otherwise.
522
523   This works by running FUN in a separate thread and terminating the
524   thread if it doesn't finish in the specified time.  */
525
526bool
527run_with_timeout (double seconds, void (*fun) (void *), void *arg)
528{
529  HANDLE thread_hnd;
530  struct thread_data thread_arg;
531  DWORD thread_id;
532  bool rc;
533
534  DEBUGP (("seconds %.2f, ", seconds));
535
536  if (seconds == 0)
537    {
538    blocking_fallback:
539      fun (arg);
540      return false;
541    }
542
543  thread_arg.fun = fun;
544  thread_arg.arg = arg;
545  thread_arg.ws_error = WSAGetLastError ();
546  thread_hnd = CreateThread (NULL, THREAD_STACK_SIZE, thread_helper,
547                             &thread_arg, 0, &thread_id);
548  if (!thread_hnd)
549    {
550      DEBUGP (("CreateThread() failed; [%#lx]\n",
551               (unsigned long) GetLastError ()));
552      goto blocking_fallback;
553    }
554
555  if (WaitForSingleObject (thread_hnd, (DWORD)(1000 * seconds))
556      == WAIT_OBJECT_0)
557    {
558      /* Propagate error state (which is per-thread) to this thread,
559         so the caller can inspect it.  */
560      WSASetLastError (thread_arg.ws_error);
561      DEBUGP (("Winsock error: %d\n", WSAGetLastError ()));
562      rc = false;
563    }
564  else
565    {
566      TerminateThread (thread_hnd, 1);
567      rc = true;
568    }
569
570  CloseHandle (thread_hnd);     /* Clear-up after TerminateThread().  */
571  thread_hnd = NULL;
572  return rc;
573}
574
575/* Wget expects network calls such as connect, recv, send, etc., to set
576   errno on failure.  To achieve that, Winsock calls are wrapped with code
577   that, in case of error, sets errno to the value of WSAGetLastError().
578   In addition, we provide a wrapper around strerror, which recognizes
579   Winsock errors and prints the appropriate error message. */
580
581/* Define a macro that creates a function definition that wraps FUN into
582   a function that sets errno the way the rest of the code expects. */
583
584#define WRAP(fun, decl, call) int wrapped_##fun decl {  \
585  int retval = fun call;                                \
586  if (retval < 0)                                       \
587    errno = WSAGetLastError ();                         \
588  return retval;                                        \
589}
590
591WRAP (socket, (int domain, int type, int protocol), (domain, type, protocol))
592WRAP (bind, (int s, struct sockaddr *a, int alen), (s, a, alen))
593WRAP (connect, (int s, const struct sockaddr *a, int alen), (s, a, alen))
594WRAP (listen, (int s, int backlog), (s, backlog))
595WRAP (accept, (int s, struct sockaddr *a, int *alen), (s, a, alen))
596WRAP (recv, (int s, void *buf, int len, int flags), (s, buf, len, flags))
597WRAP (send, (int s, const void *buf, int len, int flags), (s, buf, len, flags))
598WRAP (select, (int n, fd_set *r, fd_set *w, fd_set *e, const struct timeval *tm),
599              (n, r, w, e, tm))
600WRAP (getsockname, (int s, struct sockaddr *n, int *nlen), (s, n, nlen))
601WRAP (getpeername, (int s, struct sockaddr *n, int *nlen), (s, n, nlen))
602WRAP (setsockopt, (int s, int level, int opt, const void *val, int len),
603                  (s, level, opt, val, len))
604WRAP (closesocket, (int s), (s))
605
606/* Return the text of the error message for Winsock error WSERR. */
607
608static const char *
609get_winsock_error (int wserr)
610{
611  switch (wserr) {
612  case WSAEINTR:           return "Interrupted system call";
613  case WSAEBADF:           return "Bad file number";
614  case WSAEACCES:          return "Permission denied";
615  case WSAEFAULT:          return "Bad address";
616  case WSAEINVAL:          return "Invalid argument";
617  case WSAEMFILE:          return "Too many open files";
618  case WSAEWOULDBLOCK:     return "Resource temporarily unavailable";
619  case WSAEINPROGRESS:     return "Operation now in progress";
620  case WSAEALREADY:        return "Operation already in progress";
621  case WSAENOTSOCK:        return "Socket operation on nonsocket";
622  case WSAEDESTADDRREQ:    return "Destination address required";
623  case WSAEMSGSIZE:        return "Message too long";
624  case WSAEPROTOTYPE:      return "Protocol wrong type for socket";
625  case WSAENOPROTOOPT:     return "Bad protocol option";
626  case WSAEPROTONOSUPPORT: return "Protocol not supported";
627  case WSAESOCKTNOSUPPORT: return "Socket type not supported";
628  case WSAEOPNOTSUPP:      return "Operation not supported";
629  case WSAEPFNOSUPPORT:    return "Protocol family not supported";
630  case WSAEAFNOSUPPORT:    return "Address family not supported by protocol family";
631  case WSAEADDRINUSE:      return "Address already in use";
632  case WSAEADDRNOTAVAIL:   return "Cannot assign requested address";
633  case WSAENETDOWN:        return "Network is down";
634  case WSAENETUNREACH:     return "Network is unreachable";
635  case WSAENETRESET:       return "Network dropped connection on reset";
636  case WSAECONNABORTED:    return "Software caused connection abort";
637  case WSAECONNRESET:      return "Connection reset by peer";
638  case WSAENOBUFS:         return "No buffer space available";
639  case WSAEISCONN:         return "Socket is already connected";
640  case WSAENOTCONN:        return "Socket is not connected";
641  case WSAESHUTDOWN:       return "Cannot send after socket shutdown";
642  case WSAETOOMANYREFS:    return "Too many references";
643  case WSAETIMEDOUT:       return "Connection timed out";
644  case WSAECONNREFUSED:    return "Connection refused";
645  case WSAELOOP:           return "Too many levels of symbolic links";
646  case WSAENAMETOOLONG:    return "File name too long";
647  case WSAEHOSTDOWN:       return "Host is down";
648  case WSAEHOSTUNREACH:    return "No route to host";
649  case WSAENOTEMPTY:       return "Not empty";
650  case WSAEPROCLIM:        return "Too many processes";
651  case WSAEUSERS:          return "Too many users";
652  case WSAEDQUOT:          return "Bad quota";
653  case WSAESTALE:          return "Something is stale";
654  case WSAEREMOTE:         return "Remote error";
655  case WSAEDISCON:         return "Disconnected";
656
657  /* Extended Winsock errors */
658  case WSASYSNOTREADY:     return "Winsock library is not ready";
659  case WSANOTINITIALISED:  return "Winsock library not initalised";
660  case WSAVERNOTSUPPORTED: return "Winsock version not supported";
661
662  case WSAHOST_NOT_FOUND: return "Host not found";
663  case WSATRY_AGAIN:      return "Host not found, try again";
664  case WSANO_RECOVERY:    return "Unrecoverable error in call to nameserver";
665  case WSANO_DATA:        return "No data record of requested type";
666
667  default:
668    return NULL;
669  }
670}
671
672/* Return the error message corresponding to ERR.  This is different
673   from Windows libc strerror() in that it handles Winsock errors
674   correctly.  */
675
676const char *
677windows_strerror (int err)
678{
679  const char *p;
680  if (err >= 0 && err < sys_nerr)
681    return strerror (err);
682  else if ((p = get_winsock_error (err)) != NULL)
683    return p;
684  else
685    {
686      static char buf[32];
687      snprintf (buf, sizeof (buf), "Unknown error %d (%#x)", err, err);
688      return buf;
689    }
690}
691
692#ifdef ENABLE_IPV6
693/* An inet_ntop implementation that uses WSAAddressToString.
694   Prototype complies with POSIX 1003.1-2004.  This is only used under
695   IPv6 because Wget prints IPv4 addresses using inet_ntoa.  */
696
697const char *
698inet_ntop (int af, const void *src, char *dst, socklen_t cnt)
699{
700  /* struct sockaddr can't accomodate struct sockaddr_in6. */
701  union {
702    struct sockaddr_in6 sin6;
703    struct sockaddr_in sin;
704  } sa;
705  DWORD dstlen = cnt;
706  size_t srcsize;
707
708  xzero (sa);
709  switch (af)
710    {
711    case AF_INET:
712      sa.sin.sin_family = AF_INET;
713      sa.sin.sin_addr = *(struct in_addr *) src;
714      srcsize = sizeof (sa.sin);
715      break;
716    case AF_INET6:
717      sa.sin6.sin6_family = AF_INET6;
718      sa.sin6.sin6_addr = *(struct in6_addr *) src;
719      srcsize = sizeof (sa.sin6);
720      break;
721    default:
722      abort ();
723    }
724
725  if (WSAAddressToString ((struct sockaddr *) &sa, srcsize, NULL, dst, &dstlen) != 0)
726    {
727      errno = WSAGetLastError();
728      return NULL;
729    }
730  return (const char *) dst;
731}
732#endif
733