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 #ifdef HACK_BCC_UTIME_BUG
45 # ifdef HAVE_SYS_UTIME_H
46 # include <sys/utime.h>
50 #define INHIBIT_WRAP /* avoid wrapping of socket, bind, ... */
56 #ifndef ES_SYSTEM_REQUIRED
57 #define ES_SYSTEM_REQUIRED 0x00000001
61 #define ES_CONTINUOUS 0x80000000
65 /* Defined in log.c. */
66 void log_request_redirect_output (const char *);
68 /* Windows version of xsleep in utils.c. */
71 xsleep (double seconds)
76 /* Explained in utils.c. */
78 seconds -= (long) seconds;
80 usleep (seconds * 1000000L);
81 #else /* not HAVE_USLEEP */
82 SleepEx ((DWORD) (seconds * 1000 + .5), FALSE);
83 #endif /* not HAVE_USLEEP */
86 #if defined(__BORLANDC__) || (defined(_MSC_VER) && _MSC_VER < 1300)
89 char_value (char c, int base)
94 if ('0' <= c && c <= '9')
96 else if ('a' <= c && c <= 'z')
98 else if ('A' <= c && c <= 'Z')
107 /* A fairly simple strtoll replacement for MS VC versions that don't
111 str_to_int64 (const char *nptr, char **endptr, int base)
113 #define INT64_OVERFLOW 9223372036854775807I64
114 #define INT64_UNDERFLOW (-INT64_OVERFLOW - 1)
119 if (base != 0 && (base < 2 || base > 36))
125 while (*nptr == ' ' || *nptr == '\t')
132 else if (*nptr == '+')
140 /* If base is 0, determine the real base based on the beginning on
141 the number; octal numbers begin with "0", hexadecimal with "0x",
142 and the others are considered octal. */
145 if ((base == 0 || base == 16)
147 (*(nptr + 1) == 'x' || *(nptr + 1) == 'X'))
160 /* Parse positive number, checking for overflow. */
162 for (; (val = char_value (*nptr, base)) != -1; ++nptr)
164 __int64 newresult = base * result + val;
165 if (newresult < result)
167 result = INT64_OVERFLOW;
176 /* Parse negative number, checking for underflow. */
178 for (; (val = char_value (*nptr, base)) != -1; ++nptr)
180 __int64 newresult = base * result - val;
181 if (newresult > result)
183 result = INT64_UNDERFLOW;
191 *endptr = (char *) nptr;
195 #else /* !defined(__BORLANDC__) && (!defined(_MSC_VER) || _MSC_VER >= 1300) */
198 str_to_int64 (const char *nptr, char **endptr, int base)
201 return _strtoi64 (nptr, endptr, base);
203 return strtoll (nptr, endptr, base);
207 #endif /* !defined(__BORLANDC__) && (!defined(_MSC_VER) || _MSC_VER >= 1300) */
210 windows_main (int *argc, char **argv, char **exec_name)
214 /* Remove .EXE from filename if it has one. */
215 *exec_name = xstrdup (*exec_name);
216 p = strrchr (*exec_name, '.');
228 ws_hangup (const char *reason)
230 fprintf (stderr, _("Continuing in background.\n"));
231 log_request_redirect_output (reason);
233 /* Detach process from the current console. Under Windows 9x, if we
234 were launched from a 16-bit process (which is usually the case;
235 command.com is 16-bit) the parent process should resume right away.
236 Under NT or if launched from a 32-process under 9x, this is a futile
237 gesture as the parent will wait for us to terminate before resuming. */
241 /* Construct the name for a named section (a.k.a. `file mapping') object.
242 The returned string is dynamically allocated and needs to be xfree()'d. */
244 make_section_name (DWORD pid)
246 return aprintf ("gnu_wget_fake_fork_%lu", pid);
249 /* This structure is used to hold all the data that is exchanged between
251 struct fake_fork_info
254 bool logfile_changed;
255 char lfilename[MAX_PATH + 1];
258 /* Determines if we are the child and if so performs the child logic.
265 fake_fork_child (void)
267 HANDLE section, event;
268 struct fake_fork_info *info;
271 name = make_section_name (GetCurrentProcessId ());
272 section = OpenFileMapping (FILE_MAP_WRITE, FALSE, name);
274 /* It seems that Windows 9x and NT set last-error inconsistently when
275 OpenFileMapping() fails; so we assume it failed because the section
276 object does not exist. */
278 return 0; /* We are the parent. */
280 info = MapViewOfFile (section, FILE_MAP_WRITE, 0, 0, 0);
283 CloseHandle (section);
289 info->logfile_changed = false;
292 /* See utils:fork_to_background for explanation. */
293 FILE *new_log_fp = unique_create (DEFAULT_LOGFILE, false, &opt.lfilename);
296 info->logfile_changed = true;
297 strncpy (info->lfilename, opt.lfilename, sizeof (info->lfilename));
298 info->lfilename[sizeof (info->lfilename) - 1] = '\0';
303 UnmapViewOfFile (info);
304 CloseHandle (section);
306 /* Inform the parent that we've done our part. */
307 if (!SetEvent (event))
311 return 1; /* We are the child. */
314 /* Windows doesn't support the fork() call; so we fake it by invoking
315 another copy of Wget with the same arguments with which we were
316 invoked. The child copy of Wget should perform the same initialization
317 sequence as the parent; so we should have two processes that are
318 essentially identical. We create a specially named section object that
319 allows the child to distinguish itself from the parent and is used to
320 exchange information between the two processes. We use an event object
321 for synchronization. */
325 char exe[MAX_PATH + 1];
327 SECURITY_ATTRIBUTES sa;
328 HANDLE section, event, h[2];
330 PROCESS_INFORMATION pi;
331 struct fake_fork_info *info;
335 section = pi.hProcess = pi.hThread = NULL;
337 /* Get the fully qualified name of our executable. This is more reliable
338 than using argv[0]. */
339 exe_len = GetModuleFileName (GetModuleHandle (NULL), exe, sizeof (exe));
340 if (!exe_len || (exe_len >= sizeof (exe)))
343 sa.nLength = sizeof (sa);
344 sa.lpSecurityDescriptor = NULL;
345 sa.bInheritHandle = TRUE;
347 /* Create an anonymous inheritable event object that starts out
349 event = CreateEvent (&sa, FALSE, FALSE, NULL);
353 /* Create the child process detached form the current console and in a
357 rv = CreateProcess (exe, GetCommandLine (), NULL, NULL, TRUE,
358 CREATE_SUSPENDED | DETACHED_PROCESS,
359 NULL, NULL, &si, &pi);
363 /* Create a named section object with a name based on the process id of
365 name = make_section_name (pi.dwProcessId);
367 CreateFileMapping (INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0,
368 sizeof (struct fake_fork_info), name);
371 /* Fail if the section object already exists (should not happen). */
372 if (!section || (le == ERROR_ALREADY_EXISTS))
378 /* Copy the event handle into the section object. */
379 info = MapViewOfFile (section, FILE_MAP_WRITE, 0, 0, 0);
388 UnmapViewOfFile (info);
390 /* Start the child process. */
391 rv = ResumeThread (pi.hThread);
394 TerminateProcess (pi.hProcess, (DWORD) -1);
398 /* Wait for the child to signal to us that it has done its part. If it
399 terminates before signaling us it's an error. */
403 rv = WAIT_OBJECT_0 == WaitForMultipleObjects (2, h, FALSE, 5 * 60 * 1000);
407 info = MapViewOfFile (section, FILE_MAP_READ, 0, 0, 0);
414 /* Ensure string is properly terminated. */
415 if (info->logfile_changed &&
416 !memchr (info->lfilename, '\0', sizeof (info->lfilename)))
422 printf (_("Continuing in background, pid %lu.\n"), pi.dwProcessId);
423 if (info->logfile_changed)
424 printf (_("Output will be written to `%s'.\n"), info->lfilename);
426 UnmapViewOfFile (info);
433 CloseHandle (section);
435 CloseHandle (pi.hThread);
437 CloseHandle (pi.hProcess);
439 /* We're the parent. If all is well, terminate. */
443 /* We failed, return. */
446 /* This is the corresponding Windows implementation of the
447 fork_to_background() function in utils.c. */
449 fork_to_background (void)
453 rv = fake_fork_child ();
456 fprintf (stderr, "fake_fork_child() failed\n");
461 /* We're the parent. */
463 /* If fake_fork() returns, it failed. */
464 fprintf (stderr, "fake_fork() failed\n");
467 /* If we get here, we're the child. */
471 ws_handler (DWORD dwEvent)
477 ws_hangup ("CTRL+C");
480 #ifdef CTRLBREAK_BACKGND
481 case CTRL_BREAK_EVENT:
482 ws_hangup ("CTRL+Break");
490 static char *title_buf = NULL;
491 static char *curr_url = NULL;
492 static int old_percentage = -1;
494 /* Updates the console title with the URL of the current file being
497 ws_changetitle (const char *url)
499 xfree_null (title_buf);
500 xfree_null (curr_url);
501 title_buf = xmalloc (strlen (url) + 20);
502 curr_url = xstrdup (url);
504 sprintf (title_buf, "Wget %s", curr_url);
505 SetConsoleTitle (title_buf);
508 /* Updates the console title with the percentage of the current file
511 ws_percenttitle (double percentage_float)
515 if (!title_buf || !curr_url)
518 percentage = (int) percentage_float;
520 /* Clamp percentage value. */
523 if (percentage > 100)
526 /* Only update the title when the percentage has changed. */
527 if (percentage == old_percentage)
530 old_percentage = percentage;
532 sprintf (title_buf, "Wget [%d%%] %s", percentage, curr_url);
533 SetConsoleTitle (title_buf);
536 /* Returns a pointer to the fully qualified name of the directory that
537 contains the Wget binary (wget.exe). The returned path does not have a
538 trailing path separator. Returns NULL on failure. */
542 static char *wspathsave = NULL;
546 char buf[MAX_PATH + 1];
550 len = GetModuleFileName (GetModuleHandle (NULL), buf, sizeof (buf));
551 if (!len || (len >= sizeof (buf)))
554 p = strrchr (buf, PATH_SEPARATOR);
559 wspathsave = xstrdup (buf);
565 /* Prevent Windows entering sleep/hibernation-mode while Wget is doing
566 a lengthy transfer. Windows does not, by default, consider network
567 activity in console-programs as activity! Works on Win-98/ME/2K
570 set_sleep_mode (void)
572 typedef DWORD (WINAPI *func_t) (DWORD);
573 func_t set_exec_state;
576 (func_t) GetProcAddress (GetModuleHandle ("KERNEL32.DLL"),
577 "SetThreadExecutionState");
580 set_exec_state (ES_SYSTEM_REQUIRED | ES_CONTINUOUS);
583 /* Perform Windows specific initialization. */
588 WORD requested = MAKEWORD (1, 1);
589 int err = WSAStartup (requested, &data);
592 fprintf (stderr, _("%s: Couldn't find usable socket driver.\n"),
597 if (data.wVersion < requested)
599 fprintf (stderr, _("%s: Couldn't find usable socket driver.\n"),
607 SetConsoleCtrlHandler (ws_handler, TRUE);
610 /* Replacement utime function for buggy Borland C++Builder 5.5 compiler.
611 (The Borland utime function only works on Windows NT.) */
613 #ifdef HACK_BCC_UTIME_BUG
615 borland_utime (const char *path, const struct utimbuf *times)
622 if ((fd = open (path, O_RDWR)) < 0)
625 ptr_tm = localtime (×->modtime);
626 ft.ft_tsec = ptr_tm->tm_sec >> 1;
627 ft.ft_min = ptr_tm->tm_min;
628 ft.ft_hour = ptr_tm->tm_hour;
629 ft.ft_day = ptr_tm->tm_mday;
630 ft.ft_month = ptr_tm->tm_mon + 1;
631 ft.ft_year = ptr_tm->tm_year - 80;
632 res = setftime (fd, &ft);
638 /* run_with_timeout Windows implementation. */
640 /* Stack size 0 uses default thread stack-size (reserve+commit).
641 Determined by what's in the PE header. */
642 #define THREAD_STACK_SIZE 0
646 void (*fun) (void *);
651 /* The callback that runs FUN(ARG) in a separate thread. This
652 function exists for two reasons: a) to not require FUN to be
653 declared WINAPI/__stdcall[1], and b) to retrieve Winsock errors,
654 which are per-thread. The latter is useful when FUN calls Winsock
655 functions, which is how run_with_timeout is used in Wget.
657 [1] MSVC can use __fastcall globally (cl /Gr) and on Watcom this is
658 the default (wcc386 -3r). */
661 thread_helper (void *arg)
663 struct thread_data *td = (struct thread_data *) arg;
665 /* Initialize Winsock error to what it was in the parent. That way
666 the subsequent call to WSAGetLastError will return the same value
667 if td->fun doesn't change Winsock error state. */
668 WSASetLastError (td->ws_error);
672 /* Return Winsock error to the caller, in case FUN ran Winsock
674 td->ws_error = WSAGetLastError ();
678 /* Call FUN(ARG), but don't allow it to run for more than TIMEOUT
679 seconds. Returns true if the function was interrupted with a
680 timeout, false otherwise.
682 This works by running FUN in a separate thread and terminating the
683 thread if it doesn't finish in the specified time. */
686 run_with_timeout (double seconds, void (*fun) (void *), void *arg)
688 static HANDLE thread_hnd = NULL;
689 struct thread_data thread_arg;
693 DEBUGP (("seconds %.2f, ", seconds));
702 /* Should never happen, but test for recursivety anyway. */
703 assert (thread_hnd == NULL);
705 thread_arg.fun = fun;
706 thread_arg.arg = arg;
707 thread_arg.ws_error = WSAGetLastError ();
708 thread_hnd = CreateThread (NULL, THREAD_STACK_SIZE, thread_helper,
709 &thread_arg, 0, &thread_id);
712 DEBUGP (("CreateThread() failed; %s\n", strerror (GetLastError ())));
713 goto blocking_fallback;
716 if (WaitForSingleObject (thread_hnd, (DWORD)(1000 * seconds))
719 /* Propagate error state (which is per-thread) to this thread,
720 so the caller can inspect it. */
721 WSASetLastError (thread_arg.ws_error);
722 DEBUGP (("Winsock error: %d\n", WSAGetLastError ()));
727 TerminateThread (thread_hnd, 1);
731 CloseHandle (thread_hnd); /* Clear-up after TerminateThread(). */
736 /* Wget expects network calls such as connect, recv, send, etc., to set
737 errno on failure. To achieve that, Winsock calls are wrapped with code
738 that, in case of error, sets errno to the value of WSAGetLastError().
739 In addition, we provide a wrapper around strerror, which recognizes
740 Winsock errors and prints the appropriate error message. */
742 /* Define a macro that creates a function definition that wraps FUN into
743 a function that sets errno the way the rest of the code expects. */
745 #define WRAP(fun, decl, call) int wrapped_##fun decl { \
746 int retval = fun call; \
748 errno = WSAGetLastError (); \
752 WRAP (socket, (int domain, int type, int protocol), (domain, type, protocol))
753 WRAP (bind, (int s, struct sockaddr *a, int alen), (s, a, alen))
754 WRAP (connect, (int s, const struct sockaddr *a, int alen), (s, a, alen))
755 WRAP (listen, (int s, int backlog), (s, backlog))
756 WRAP (accept, (int s, struct sockaddr *a, int *alen), (s, a, alen))
757 WRAP (recv, (int s, void *buf, int len, int flags), (s, buf, len, flags))
758 WRAP (send, (int s, const void *buf, int len, int flags), (s, buf, len, flags))
759 WRAP (select, (int n, fd_set *r, fd_set *w, fd_set *e, const struct timeval *tm),
761 WRAP (getsockname, (int s, struct sockaddr *n, int *nlen), (s, n, nlen))
762 WRAP (getpeername, (int s, struct sockaddr *n, int *nlen), (s, n, nlen))
763 WRAP (setsockopt, (int s, int level, int opt, const void *val, int len),
764 (s, level, opt, val, len))
765 WRAP (closesocket, (int s), (s))
767 /* Return the text of the error message for Winsock error WSERR. */
770 get_winsock_error (int wserr)
773 case WSAEINTR: return "Interrupted system call";
774 case WSAEBADF: return "Bad file number";
775 case WSAEACCES: return "Permission denied";
776 case WSAEFAULT: return "Bad address";
777 case WSAEINVAL: return "Invalid argument";
778 case WSAEMFILE: return "Too many open files";
779 case WSAEWOULDBLOCK: return "Resource temporarily unavailable";
780 case WSAEINPROGRESS: return "Operation now in progress";
781 case WSAEALREADY: return "Operation already in progress";
782 case WSAENOTSOCK: return "Socket operation on nonsocket";
783 case WSAEDESTADDRREQ: return "Destination address required";
784 case WSAEMSGSIZE: return "Message too long";
785 case WSAEPROTOTYPE: return "Protocol wrong type for socket";
786 case WSAENOPROTOOPT: return "Bad protocol option";
787 case WSAEPROTONOSUPPORT: return "Protocol not supported";
788 case WSAESOCKTNOSUPPORT: return "Socket type not supported";
789 case WSAEOPNOTSUPP: return "Operation not supported";
790 case WSAEPFNOSUPPORT: return "Protocol family not supported";
791 case WSAEAFNOSUPPORT: return "Address family not supported by protocol family";
792 case WSAEADDRINUSE: return "Address already in use";
793 case WSAEADDRNOTAVAIL: return "Cannot assign requested address";
794 case WSAENETDOWN: return "Network is down";
795 case WSAENETUNREACH: return "Network is unreachable";
796 case WSAENETRESET: return "Network dropped connection on reset";
797 case WSAECONNABORTED: return "Software caused connection abort";
798 case WSAECONNRESET: return "Connection reset by peer";
799 case WSAENOBUFS: return "No buffer space available";
800 case WSAEISCONN: return "Socket is already connected";
801 case WSAENOTCONN: return "Socket is not connected";
802 case WSAESHUTDOWN: return "Cannot send after socket shutdown";
803 case WSAETOOMANYREFS: return "Too many references";
804 case WSAETIMEDOUT: return "Connection timed out";
805 case WSAECONNREFUSED: return "Connection refused";
806 case WSAELOOP: return "Too many levels of symbolic links";
807 case WSAENAMETOOLONG: return "File name too long";
808 case WSAEHOSTDOWN: return "Host is down";
809 case WSAEHOSTUNREACH: return "No route to host";
810 case WSAENOTEMPTY: return "Not empty";
811 case WSAEPROCLIM: return "Too many processes";
812 case WSAEUSERS: return "Too many users";
813 case WSAEDQUOT: return "Bad quota";
814 case WSAESTALE: return "Something is stale";
815 case WSAEREMOTE: return "Remote error";
816 case WSAEDISCON: return "Disconnected";
818 /* Extended Winsock errors */
819 case WSASYSNOTREADY: return "Winsock library is not ready";
820 case WSANOTINITIALISED: return "Winsock library not initalised";
821 case WSAVERNOTSUPPORTED: return "Winsock version not supported";
823 case WSAHOST_NOT_FOUND: return "Host not found";
824 case WSATRY_AGAIN: return "Host not found, try again";
825 case WSANO_RECOVERY: return "Unrecoverable error in call to nameserver";
826 case WSANO_DATA: return "No data record of requested type";
833 /* Return the error message corresponding to ERR. This is different
834 from Windows libc strerror() in that it handles Winsock errors
838 windows_strerror (int err)
841 if (err >= 0 && err < sys_nerr)
842 return strerror (err);
843 else if ((p = get_winsock_error (err)) != NULL)
848 snprintf (buf, sizeof (buf), "Unknown error %d (%#x)", err, err);
854 /* An IPv6-only inet_ntop that prints with WSAAddressToString. (Wget
855 uses inet_ntoa for IPv4 addresses -- see print_address.) Prototype
856 complies with POSIX 1003.1-2004. */
859 inet_ntop (int af, const void *src, char *dst, socklen_t cnt)
861 struct sockaddr_in6 sin6;
864 assert (af == AF_INET6);
866 sin6.sin6_family = AF_INET6;
867 sin6.sin6_addr = *(struct in6_addr *) src;
868 if (WSAAddressToString ((struct sockaddr *) &sin6, sizeof (sin6),
869 NULL, dst, &dstlen) != 0)
871 errno = WSAGetLastError();
874 return (const char *) dst;