1 /* mswindows.c -- Windows-specific support
2 Copyright (C) 1996-2005 Free Software Foundation, Inc.
4 This file is part of GNU Wget.
6 GNU Wget 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.
11 GNU Wget 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.
16 You should have received a copy of the GNU General Public License
17 along with Wget; if not, write to the Free Software Foundation, Inc.,
18 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 In addition, as a special exception, the Free Software Foundation
21 gives permission to link the code of its release of Wget with the
22 OpenSSL project's "OpenSSL" library (or with modified versions of it
23 that use the same license as the "OpenSSL" library), and distribute
24 the linked executables. You must obey the GNU General Public License
25 in all respects for all of the code used other than "OpenSSL". If you
26 modify this file, you may extend this exception to your version of the
27 file, but you are not obligated to do so. If you do not wish to do
28 so, delete this exception statement from your version. */
39 #define INHIBIT_WRAP /* avoid wrapping of socket, bind, ... */
45 #ifndef ES_SYSTEM_REQUIRED
46 #define ES_SYSTEM_REQUIRED 0x00000001
50 #define ES_CONTINUOUS 0x80000000
54 /* Defined in log.c. */
55 void log_request_redirect_output (const char *);
57 /* Windows version of xsleep in utils.c. */
60 xsleep (double seconds)
65 /* Explained in utils.c. */
67 seconds -= (long) seconds;
69 usleep (seconds * 1000000);
70 #else /* not HAVE_USLEEP */
71 SleepEx ((DWORD) (seconds * 1000 + .5), FALSE);
72 #endif /* not HAVE_USLEEP */
75 #if defined(__BORLANDC__) || (defined(_MSC_VER) && _MSC_VER < 1300)
78 char_value (char c, int base)
83 if ('0' <= c && c <= '9')
85 else if ('a' <= c && c <= 'z')
87 else if ('A' <= c && c <= 'Z')
96 /* A fairly simple strtoll replacement for MS VC versions that don't
100 str_to_int64 (const char *nptr, char **endptr, int base)
102 #define INT64_OVERFLOW 9223372036854775807I64
103 #define INT64_UNDERFLOW (-INT64_OVERFLOW - 1)
108 if (base != 0 && (base < 2 || base > 36))
114 while (*nptr == ' ' || *nptr == '\t')
121 else if (*nptr == '+')
129 /* If base is 0, determine the real base based on the beginning on
130 the number; octal numbers begin with "0", hexadecimal with "0x",
131 and the others are considered octal. */
134 if ((base == 0 || base == 16)
136 (*(nptr + 1) == 'x' || *(nptr + 1) == 'X'))
149 /* Parse positive number, checking for overflow. */
151 for (; (val = char_value (*nptr, base)) != -1; ++nptr)
153 __int64 newresult = base * result + val;
154 if (newresult < result)
156 result = INT64_OVERFLOW;
165 /* Parse negative number, checking for underflow. */
167 for (; (val = char_value (*nptr, base)) != -1; ++nptr)
169 __int64 newresult = base * result - val;
170 if (newresult > result)
172 result = INT64_UNDERFLOW;
180 *endptr = (char *) nptr;
184 #else /* !defined(__BORLANDC__) && (!defined(_MSC_VER) || _MSC_VER >= 1300) */
187 str_to_int64 (const char *nptr, char **endptr, int base)
190 return _strtoi64 (nptr, endptr, base);
192 return strtoll (nptr, endptr, base);
196 #endif /* !defined(__BORLANDC__) && (!defined(_MSC_VER) || _MSC_VER >= 1300) */
199 windows_main (int *argc, char **argv, char **exec_name)
203 /* Remove .EXE from filename if it has one. */
204 *exec_name = xstrdup (*exec_name);
205 p = strrchr (*exec_name, '.');
217 ws_hangup (const char *reason)
219 fprintf (stderr, _("Continuing in background.\n"));
220 log_request_redirect_output (reason);
222 /* Detach process from the current console. Under Windows 9x, if we
223 were launched from a 16-bit process (which is usually the case;
224 command.com is 16-bit) the parent process should resume right away.
225 Under NT or if launched from a 32-process under 9x, this is a futile
226 gesture as the parent will wait for us to terminate before resuming. */
230 /* Construct the name for a named section (a.k.a. `file mapping') object.
231 The returned string is dynamically allocated and needs to be xfree()'d. */
233 make_section_name (DWORD pid)
235 return aprintf ("gnu_wget_fake_fork_%lu", pid);
238 /* This structure is used to hold all the data that is exchanged between
240 struct fake_fork_info
243 bool logfile_changed;
244 char lfilename[MAX_PATH + 1];
247 /* Determines if we are the child and if so performs the child logic.
254 fake_fork_child (void)
256 HANDLE section, event;
257 struct fake_fork_info *info;
260 name = make_section_name (GetCurrentProcessId ());
261 section = OpenFileMapping (FILE_MAP_WRITE, FALSE, name);
263 /* It seems that Windows 9x and NT set last-error inconsistently when
264 OpenFileMapping() fails; so we assume it failed because the section
265 object does not exist. */
267 return 0; /* We are the parent. */
269 info = MapViewOfFile (section, FILE_MAP_WRITE, 0, 0, 0);
272 CloseHandle (section);
278 info->logfile_changed = false;
281 /* See utils:fork_to_background for explanation. */
282 FILE *new_log_fp = unique_create (DEFAULT_LOGFILE, false, &opt.lfilename);
285 info->logfile_changed = true;
286 strncpy (info->lfilename, opt.lfilename, sizeof (info->lfilename));
287 info->lfilename[sizeof (info->lfilename) - 1] = '\0';
292 UnmapViewOfFile (info);
293 CloseHandle (section);
295 /* Inform the parent that we've done our part. */
296 if (!SetEvent (event))
300 return 1; /* We are the child. */
303 /* Windows doesn't support the fork() call; so we fake it by invoking
304 another copy of Wget with the same arguments with which we were
305 invoked. The child copy of Wget should perform the same initialization
306 sequence as the parent; so we should have two processes that are
307 essentially identical. We create a specially named section object that
308 allows the child to distinguish itself from the parent and is used to
309 exchange information between the two processes. We use an event object
310 for synchronization. */
314 char exe[MAX_PATH + 1];
316 SECURITY_ATTRIBUTES sa;
317 HANDLE section, event, h[2];
319 PROCESS_INFORMATION pi;
320 struct fake_fork_info *info;
324 section = pi.hProcess = pi.hThread = NULL;
326 /* Get the fully qualified name of our executable. This is more reliable
327 than using argv[0]. */
328 exe_len = GetModuleFileName (GetModuleHandle (NULL), exe, sizeof (exe));
329 if (!exe_len || (exe_len >= sizeof (exe)))
332 sa.nLength = sizeof (sa);
333 sa.lpSecurityDescriptor = NULL;
334 sa.bInheritHandle = TRUE;
336 /* Create an anonymous inheritable event object that starts out
338 event = CreateEvent (&sa, FALSE, FALSE, NULL);
342 /* Create the child process detached form the current console and in a
346 rv = CreateProcess (exe, GetCommandLine (), NULL, NULL, TRUE,
347 CREATE_SUSPENDED | DETACHED_PROCESS,
348 NULL, NULL, &si, &pi);
352 /* Create a named section object with a name based on the process id of
354 name = make_section_name (pi.dwProcessId);
356 CreateFileMapping (INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0,
357 sizeof (struct fake_fork_info), name);
360 /* Fail if the section object already exists (should not happen). */
361 if (!section || (le == ERROR_ALREADY_EXISTS))
367 /* Copy the event handle into the section object. */
368 info = MapViewOfFile (section, FILE_MAP_WRITE, 0, 0, 0);
377 UnmapViewOfFile (info);
379 /* Start the child process. */
380 rv = ResumeThread (pi.hThread);
383 TerminateProcess (pi.hProcess, (DWORD) -1);
387 /* Wait for the child to signal to us that it has done its part. If it
388 terminates before signaling us it's an error. */
392 rv = WAIT_OBJECT_0 == WaitForMultipleObjects (2, h, FALSE, 5 * 60 * 1000);
396 info = MapViewOfFile (section, FILE_MAP_READ, 0, 0, 0);
403 /* Ensure string is properly terminated. */
404 if (info->logfile_changed &&
405 !memchr (info->lfilename, '\0', sizeof (info->lfilename)))
411 printf (_("Continuing in background, pid %lu.\n"), pi.dwProcessId);
412 if (info->logfile_changed)
413 printf (_("Output will be written to `%s'.\n"), info->lfilename);
415 UnmapViewOfFile (info);
422 CloseHandle (section);
424 CloseHandle (pi.hThread);
426 CloseHandle (pi.hProcess);
428 /* We're the parent. If all is well, terminate. */
432 /* We failed, return. */
435 /* This is the corresponding Windows implementation of the
436 fork_to_background() function in utils.c. */
438 fork_to_background (void)
442 rv = fake_fork_child ();
445 fprintf (stderr, "fake_fork_child() failed\n");
450 /* We're the parent. */
452 /* If fake_fork() returns, it failed. */
453 fprintf (stderr, "fake_fork() failed\n");
456 /* If we get here, we're the child. */
460 ws_handler (DWORD dwEvent)
466 ws_hangup ("CTRL+C");
469 #ifdef CTRLBREAK_BACKGND
470 case CTRL_BREAK_EVENT:
471 ws_hangup ("CTRL+Break");
479 static char *title_buf = NULL;
480 static char *curr_url = NULL;
481 static int old_percentage = -1;
483 /* Updates the console title with the URL of the current file being
486 ws_changetitle (const char *url)
488 xfree_null (title_buf);
489 xfree_null (curr_url);
490 title_buf = xmalloc (strlen (url) + 20);
491 curr_url = xstrdup (url);
493 sprintf (title_buf, "Wget %s", curr_url);
494 SetConsoleTitle (title_buf);
497 /* Updates the console title with the percentage of the current file
500 ws_percenttitle (double percentage_float)
504 if (!title_buf || !curr_url)
507 percentage = (int) percentage_float;
509 /* Clamp percentage value. */
512 if (percentage > 100)
515 /* Only update the title when the percentage has changed. */
516 if (percentage == old_percentage)
519 old_percentage = percentage;
521 sprintf (title_buf, "Wget [%d%%] %s", percentage, curr_url);
522 SetConsoleTitle (title_buf);
525 /* Returns a pointer to the fully qualified name of the directory that
526 contains the Wget binary (wget.exe). The returned path does not have a
527 trailing path separator. Returns NULL on failure. */
531 static char *wspathsave = NULL;
535 char buf[MAX_PATH + 1];
539 len = GetModuleFileName (GetModuleHandle (NULL), buf, sizeof (buf));
540 if (!len || (len >= sizeof (buf)))
543 p = strrchr (buf, PATH_SEPARATOR);
548 wspathsave = xstrdup (buf);
554 /* Prevent Windows entering sleep/hibernation-mode while Wget is doing
555 a lengthy transfer. Windows does not, by default, consider network
556 activity in console-programs as activity! Works on Win-98/ME/2K
559 set_sleep_mode (void)
561 typedef DWORD (WINAPI *func_t) (DWORD);
562 func_t set_exec_state;
565 (func_t) GetProcAddress (GetModuleHandle ("KERNEL32.DLL"),
566 "SetThreadExecutionState");
569 set_exec_state (ES_SYSTEM_REQUIRED | ES_CONTINUOUS);
572 /* Perform Windows specific initialization. */
577 WORD requested = MAKEWORD (1, 1);
578 int err = WSAStartup (requested, &data);
581 fprintf (stderr, _("%s: Couldn't find usable socket driver.\n"),
586 if (data.wVersion < requested)
588 fprintf (stderr, _("%s: Couldn't find usable socket driver.\n"),
596 SetConsoleCtrlHandler (ws_handler, TRUE);
599 /* run_with_timeout Windows implementation. */
601 /* Stack size 0 uses default thread stack-size (reserve+commit).
602 Determined by what's in the PE header. */
603 #define THREAD_STACK_SIZE 0
607 void (*fun) (void *);
612 /* The callback that runs FUN(ARG) in a separate thread. This
613 function exists for two reasons: a) to not require FUN to be
614 declared WINAPI/__stdcall[1], and b) to retrieve Winsock errors,
615 which are per-thread. The latter is useful when FUN calls Winsock
616 functions, which is how run_with_timeout is used in Wget.
618 [1] MSVC can use __fastcall globally (cl /Gr) and on Watcom this is
619 the default (wcc386 -3r). */
622 thread_helper (void *arg)
624 struct thread_data *td = (struct thread_data *) arg;
626 /* Initialize Winsock error to what it was in the parent. That way
627 the subsequent call to WSAGetLastError will return the same value
628 if td->fun doesn't change Winsock error state. */
629 WSASetLastError (td->ws_error);
633 /* Return Winsock error to the caller, in case FUN ran Winsock
635 td->ws_error = WSAGetLastError ();
639 /* Call FUN(ARG), but don't allow it to run for more than TIMEOUT
640 seconds. Returns true if the function was interrupted with a
641 timeout, false otherwise.
643 This works by running FUN in a separate thread and terminating the
644 thread if it doesn't finish in the specified time. */
647 run_with_timeout (double seconds, void (*fun) (void *), void *arg)
649 static HANDLE thread_hnd = NULL;
650 struct thread_data thread_arg;
654 DEBUGP (("seconds %.2f, ", seconds));
663 /* Should never happen, but test for recursivety anyway. */
664 assert (thread_hnd == NULL);
666 thread_arg.fun = fun;
667 thread_arg.arg = arg;
668 thread_arg.ws_error = WSAGetLastError ();
669 thread_hnd = CreateThread (NULL, THREAD_STACK_SIZE, thread_helper,
670 &thread_arg, 0, &thread_id);
673 DEBUGP (("CreateThread() failed; [0x%x]\n", GetLastError ()));
674 goto blocking_fallback;
677 if (WaitForSingleObject (thread_hnd, (DWORD)(1000 * seconds))
680 /* Propagate error state (which is per-thread) to this thread,
681 so the caller can inspect it. */
682 WSASetLastError (thread_arg.ws_error);
683 DEBUGP (("Winsock error: %d\n", WSAGetLastError ()));
688 TerminateThread (thread_hnd, 1);
692 CloseHandle (thread_hnd); /* Clear-up after TerminateThread(). */
697 /* Wget expects network calls such as connect, recv, send, etc., to set
698 errno on failure. To achieve that, Winsock calls are wrapped with code
699 that, in case of error, sets errno to the value of WSAGetLastError().
700 In addition, we provide a wrapper around strerror, which recognizes
701 Winsock errors and prints the appropriate error message. */
703 /* Define a macro that creates a function definition that wraps FUN into
704 a function that sets errno the way the rest of the code expects. */
706 #define WRAP(fun, decl, call) int wrapped_##fun decl { \
707 int retval = fun call; \
709 errno = WSAGetLastError (); \
713 WRAP (socket, (int domain, int type, int protocol), (domain, type, protocol))
714 WRAP (bind, (int s, struct sockaddr *a, int alen), (s, a, alen))
715 WRAP (connect, (int s, const struct sockaddr *a, int alen), (s, a, alen))
716 WRAP (listen, (int s, int backlog), (s, backlog))
717 WRAP (accept, (int s, struct sockaddr *a, int *alen), (s, a, alen))
718 WRAP (recv, (int s, void *buf, int len, int flags), (s, buf, len, flags))
719 WRAP (send, (int s, const void *buf, int len, int flags), (s, buf, len, flags))
720 WRAP (select, (int n, fd_set *r, fd_set *w, fd_set *e, const struct timeval *tm),
722 WRAP (getsockname, (int s, struct sockaddr *n, int *nlen), (s, n, nlen))
723 WRAP (getpeername, (int s, struct sockaddr *n, int *nlen), (s, n, nlen))
724 WRAP (setsockopt, (int s, int level, int opt, const void *val, int len),
725 (s, level, opt, val, len))
726 WRAP (closesocket, (int s), (s))
728 /* Return the text of the error message for Winsock error WSERR. */
731 get_winsock_error (int wserr)
734 case WSAEINTR: return "Interrupted system call";
735 case WSAEBADF: return "Bad file number";
736 case WSAEACCES: return "Permission denied";
737 case WSAEFAULT: return "Bad address";
738 case WSAEINVAL: return "Invalid argument";
739 case WSAEMFILE: return "Too many open files";
740 case WSAEWOULDBLOCK: return "Resource temporarily unavailable";
741 case WSAEINPROGRESS: return "Operation now in progress";
742 case WSAEALREADY: return "Operation already in progress";
743 case WSAENOTSOCK: return "Socket operation on nonsocket";
744 case WSAEDESTADDRREQ: return "Destination address required";
745 case WSAEMSGSIZE: return "Message too long";
746 case WSAEPROTOTYPE: return "Protocol wrong type for socket";
747 case WSAENOPROTOOPT: return "Bad protocol option";
748 case WSAEPROTONOSUPPORT: return "Protocol not supported";
749 case WSAESOCKTNOSUPPORT: return "Socket type not supported";
750 case WSAEOPNOTSUPP: return "Operation not supported";
751 case WSAEPFNOSUPPORT: return "Protocol family not supported";
752 case WSAEAFNOSUPPORT: return "Address family not supported by protocol family";
753 case WSAEADDRINUSE: return "Address already in use";
754 case WSAEADDRNOTAVAIL: return "Cannot assign requested address";
755 case WSAENETDOWN: return "Network is down";
756 case WSAENETUNREACH: return "Network is unreachable";
757 case WSAENETRESET: return "Network dropped connection on reset";
758 case WSAECONNABORTED: return "Software caused connection abort";
759 case WSAECONNRESET: return "Connection reset by peer";
760 case WSAENOBUFS: return "No buffer space available";
761 case WSAEISCONN: return "Socket is already connected";
762 case WSAENOTCONN: return "Socket is not connected";
763 case WSAESHUTDOWN: return "Cannot send after socket shutdown";
764 case WSAETOOMANYREFS: return "Too many references";
765 case WSAETIMEDOUT: return "Connection timed out";
766 case WSAECONNREFUSED: return "Connection refused";
767 case WSAELOOP: return "Too many levels of symbolic links";
768 case WSAENAMETOOLONG: return "File name too long";
769 case WSAEHOSTDOWN: return "Host is down";
770 case WSAEHOSTUNREACH: return "No route to host";
771 case WSAENOTEMPTY: return "Not empty";
772 case WSAEPROCLIM: return "Too many processes";
773 case WSAEUSERS: return "Too many users";
774 case WSAEDQUOT: return "Bad quota";
775 case WSAESTALE: return "Something is stale";
776 case WSAEREMOTE: return "Remote error";
777 case WSAEDISCON: return "Disconnected";
779 /* Extended Winsock errors */
780 case WSASYSNOTREADY: return "Winsock library is not ready";
781 case WSANOTINITIALISED: return "Winsock library not initalised";
782 case WSAVERNOTSUPPORTED: return "Winsock version not supported";
784 case WSAHOST_NOT_FOUND: return "Host not found";
785 case WSATRY_AGAIN: return "Host not found, try again";
786 case WSANO_RECOVERY: return "Unrecoverable error in call to nameserver";
787 case WSANO_DATA: return "No data record of requested type";
794 /* Return the error message corresponding to ERR. This is different
795 from Windows libc strerror() in that it handles Winsock errors
799 windows_strerror (int err)
802 if (err >= 0 && err < sys_nerr)
803 return strerror (err);
804 else if ((p = get_winsock_error (err)) != NULL)
809 snprintf (buf, sizeof (buf), "Unknown error %d (%#x)", err, err);
815 /* An IPv6-only inet_ntop that prints with WSAAddressToString. (Wget
816 uses inet_ntoa for IPv4 addresses -- see print_address.) Prototype
817 complies with POSIX 1003.1-2004. */
820 inet_ntop (int af, const void *src, char *dst, socklen_t cnt)
822 struct sockaddr_in6 sin6;
825 assert (af == AF_INET6);
827 sin6.sin6_family = AF_INET6;
828 sin6.sin6_addr = *(struct in6_addr *) src;
829 if (WSAAddressToString ((struct sockaddr *) &sin6, sizeof (sin6),
830 NULL, dst, &dstlen) != 0)
832 errno = WSAGetLastError();
835 return (const char *) dst;