1 /* mswindows.c -- Windows-specific support
2 Copyright (C) 1995, 1996, 1997, 1998, 2004
3 Free Software Foundation, Inc.
5 This file is part of GNU Wget.
7 GNU Wget is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 GNU Wget is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with Wget; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 In addition, as a special exception, the Free Software Foundation
22 gives permission to link the code of its release of Wget with the
23 OpenSSL project's "OpenSSL" library (or with modified versions of it
24 that use the same license as the "OpenSSL" library), and distribute
25 the linked executables. You must obey the GNU General Public License
26 in all respects for all of the code used other than "OpenSSL". If you
27 modify this file, you may extend this exception to your version of the
28 file, but you are not obligated to do so. If you do not wish to do
29 so, delete this exception statement from your version. */
40 #ifdef HACK_BCC_UTIME_BUG
46 # ifdef HAVE_SYS_UTIME_H
47 # include <sys/utime.h>
51 #define INHIBIT_WRAP /* avoid wrapping of socket, bind, ... */
57 #ifndef ES_SYSTEM_REQUIRED
58 #define ES_SYSTEM_REQUIRED 0x00000001
62 #define ES_CONTINUOUS 0x80000000
66 /* Defined in log.c. */
67 void log_request_redirect_output (const char *);
69 /* Windows version of xsleep in utils.c. */
72 xsleep (double seconds)
77 /* Explained in utils.c. */
79 seconds -= (long) seconds;
81 usleep (seconds * 1000000L);
82 #else /* not HAVE_USLEEP */
83 SleepEx ((DWORD) (seconds * 1000 + .5), FALSE);
84 #endif /* not HAVE_USLEEP */
87 #if defined(__BORLANDC__) || (defined(_MSC_VER) && _MSC_VER < 1300)
90 char_value (char c, int base)
95 if ('0' <= c && c <= '9')
97 else if ('a' <= c && c <= 'z')
99 else if ('A' <= c && c <= 'Z')
100 value = c - 'A' + 10;
108 /* A fairly simple strtoll replacement for MS VC versions that don't
112 str_to_int64 (const char *nptr, char **endptr, int base)
114 #define INT64_OVERFLOW 9223372036854775807I64
115 #define INT64_UNDERFLOW (-INT64_OVERFLOW - 1)
120 if (base != 0 && (base < 2 || base > 36))
126 while (*nptr == ' ' || *nptr == '\t')
133 else if (*nptr == '+')
141 /* If base is 0, determine the real base based on the beginning on
142 the number; octal numbers begin with "0", hexadecimal with "0x",
143 and the others are considered octal. */
146 if ((base == 0 || base == 16)
148 (*(nptr + 1) == 'x' || *(nptr + 1) == 'X'))
161 /* Parse positive number, checking for overflow. */
163 for (; (val = char_value (*nptr, base)) != -1; ++nptr)
165 __int64 newresult = base * result + val;
166 if (newresult < result)
168 result = INT64_OVERFLOW;
177 /* Parse negative number, checking for underflow. */
179 for (; (val = char_value (*nptr, base)) != -1; ++nptr)
181 __int64 newresult = base * result - val;
182 if (newresult > result)
184 result = INT64_UNDERFLOW;
192 *endptr = (char *) nptr;
196 #else /* !defined(__BORLANDC__) && (!defined(_MSC_VER) || _MSC_VER >= 1300) */
199 str_to_int64 (const char *nptr, char **endptr, int base)
202 return _strtoi64 (nptr, endptr, base);
204 return strtoll (nptr, endptr, base);
208 #endif /* !defined(__BORLANDC__) && (!defined(_MSC_VER) || _MSC_VER >= 1300) */
211 windows_main (int *argc, char **argv, char **exec_name)
215 /* Remove .EXE from filename if it has one. */
216 *exec_name = xstrdup (*exec_name);
217 p = strrchr (*exec_name, '.');
229 ws_hangup (const char *reason)
231 fprintf (stderr, _("Continuing in background.\n"));
232 log_request_redirect_output (reason);
234 /* Detach process from the current console. Under Windows 9x, if we
235 were launched from a 16-bit process (which is usually the case;
236 command.com is 16-bit) the parent process should resume right away.
237 Under NT or if launched from a 32-process under 9x, this is a futile
238 gesture as the parent will wait for us to terminate before resuming. */
242 /* Construct the name for a named section (a.k.a. `file mapping') object.
243 The returned string is dynamically allocated and needs to be xfree()'d. */
245 make_section_name (DWORD pid)
247 return aprintf ("gnu_wget_fake_fork_%lu", pid);
250 /* This structure is used to hold all the data that is exchanged between
252 struct fake_fork_info
255 bool logfile_changed;
256 char lfilename[MAX_PATH + 1];
259 /* Determines if we are the child and if so performs the child logic.
266 fake_fork_child (void)
268 HANDLE section, event;
269 struct fake_fork_info *info;
272 name = make_section_name (GetCurrentProcessId ());
273 section = OpenFileMapping (FILE_MAP_WRITE, FALSE, name);
275 /* It seems that Windows 9x and NT set last-error inconsistently when
276 OpenFileMapping() fails; so we assume it failed because the section
277 object does not exist. */
279 return 0; /* We are the parent. */
281 info = MapViewOfFile (section, FILE_MAP_WRITE, 0, 0, 0);
284 CloseHandle (section);
290 info->logfile_changed = false;
293 /* See utils:fork_to_background for explanation. */
294 FILE *new_log_fp = unique_create (DEFAULT_LOGFILE, false, &opt.lfilename);
297 info->logfile_changed = true;
298 strncpy (info->lfilename, opt.lfilename, sizeof (info->lfilename));
299 info->lfilename[sizeof (info->lfilename) - 1] = '\0';
304 UnmapViewOfFile (info);
305 CloseHandle (section);
307 /* Inform the parent that we've done our part. */
308 if (!SetEvent (event))
312 return 1; /* We are the child. */
315 /* Windows doesn't support the fork() call; so we fake it by invoking
316 another copy of Wget with the same arguments with which we were
317 invoked. The child copy of Wget should perform the same initialization
318 sequence as the parent; so we should have two processes that are
319 essentially identical. We create a specially named section object that
320 allows the child to distinguish itself from the parent and is used to
321 exchange information between the two processes. We use an event object
322 for synchronization. */
326 char exe[MAX_PATH + 1];
328 SECURITY_ATTRIBUTES sa;
329 HANDLE section, event, h[2];
331 PROCESS_INFORMATION pi;
332 struct fake_fork_info *info;
336 section = pi.hProcess = pi.hThread = NULL;
338 /* Get the fully qualified name of our executable. This is more reliable
339 than using argv[0]. */
340 exe_len = GetModuleFileName (GetModuleHandle (NULL), exe, sizeof (exe));
341 if (!exe_len || (exe_len >= sizeof (exe)))
344 sa.nLength = sizeof (sa);
345 sa.lpSecurityDescriptor = NULL;
346 sa.bInheritHandle = TRUE;
348 /* Create an anonymous inheritable event object that starts out
350 event = CreateEvent (&sa, FALSE, FALSE, NULL);
354 /* Create the child process detached form the current console and in a
358 rv = CreateProcess (exe, GetCommandLine (), NULL, NULL, TRUE,
359 CREATE_SUSPENDED | DETACHED_PROCESS,
360 NULL, NULL, &si, &pi);
364 /* Create a named section object with a name based on the process id of
366 name = make_section_name (pi.dwProcessId);
368 CreateFileMapping (INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0,
369 sizeof (struct fake_fork_info), name);
372 /* Fail if the section object already exists (should not happen). */
373 if (!section || (le == ERROR_ALREADY_EXISTS))
379 /* Copy the event handle into the section object. */
380 info = MapViewOfFile (section, FILE_MAP_WRITE, 0, 0, 0);
389 UnmapViewOfFile (info);
391 /* Start the child process. */
392 rv = ResumeThread (pi.hThread);
395 TerminateProcess (pi.hProcess, (DWORD) -1);
399 /* Wait for the child to signal to us that it has done its part. If it
400 terminates before signaling us it's an error. */
404 rv = WAIT_OBJECT_0 == WaitForMultipleObjects (2, h, FALSE, 5 * 60 * 1000);
408 info = MapViewOfFile (section, FILE_MAP_READ, 0, 0, 0);
415 /* Ensure string is properly terminated. */
416 if (info->logfile_changed &&
417 !memchr (info->lfilename, '\0', sizeof (info->lfilename)))
423 printf (_("Continuing in background, pid %lu.\n"), pi.dwProcessId);
424 if (info->logfile_changed)
425 printf (_("Output will be written to `%s'.\n"), info->lfilename);
427 UnmapViewOfFile (info);
434 CloseHandle (section);
436 CloseHandle (pi.hThread);
438 CloseHandle (pi.hProcess);
440 /* We're the parent. If all is well, terminate. */
444 /* We failed, return. */
447 /* This is the corresponding Windows implementation of the
448 fork_to_background() function in utils.c. */
450 fork_to_background (void)
454 rv = fake_fork_child ();
457 fprintf (stderr, "fake_fork_child() failed\n");
462 /* We're the parent. */
464 /* If fake_fork() returns, it failed. */
465 fprintf (stderr, "fake_fork() failed\n");
468 /* If we get here, we're the child. */
472 ws_handler (DWORD dwEvent)
478 ws_hangup ("CTRL+C");
481 #ifdef CTRLBREAK_BACKGND
482 case CTRL_BREAK_EVENT:
483 ws_hangup ("CTRL+Break");
491 static char *title_buf = NULL;
492 static char *curr_url = NULL;
493 static int old_percentage = -1;
495 /* Updates the console title with the URL of the current file being
498 ws_changetitle (const char *url)
500 xfree_null (title_buf);
501 xfree_null (curr_url);
502 title_buf = xmalloc (strlen (url) + 20);
503 curr_url = xstrdup (url);
505 sprintf (title_buf, "Wget %s", curr_url);
506 SetConsoleTitle (title_buf);
509 /* Updates the console title with the percentage of the current file
512 ws_percenttitle (double percentage_float)
516 if (!title_buf || !curr_url)
519 percentage = (int) percentage_float;
521 /* Clamp percentage value. */
524 if (percentage > 100)
527 /* Only update the title when the percentage has changed. */
528 if (percentage == old_percentage)
531 old_percentage = percentage;
533 sprintf (title_buf, "Wget [%d%%] %s", percentage, curr_url);
534 SetConsoleTitle (title_buf);
537 /* Returns a pointer to the fully qualified name of the directory that
538 contains the Wget binary (wget.exe). The returned path does not have a
539 trailing path separator. Returns NULL on failure. */
543 static char *wspathsave = NULL;
547 char buf[MAX_PATH + 1];
551 len = GetModuleFileName (GetModuleHandle (NULL), buf, sizeof (buf));
552 if (!len || (len >= sizeof (buf)))
555 p = strrchr (buf, PATH_SEPARATOR);
560 wspathsave = xstrdup (buf);
566 /* Prevent Windows entering sleep/hibernation-mode while Wget is doing
567 a lengthy transfer. Windows does not, by default, consider network
568 activity in console-programs as activity! Works on Win-98/ME/2K
571 set_sleep_mode (void)
573 typedef DWORD (WINAPI *func_t) (DWORD);
574 func_t set_exec_state;
577 (func_t) GetProcAddress (GetModuleHandle ("KERNEL32.DLL"),
578 "SetThreadExecutionState");
581 set_exec_state (ES_SYSTEM_REQUIRED | ES_CONTINUOUS);
584 /* Perform Windows specific initialization. */
589 WORD requested = MAKEWORD (1, 1);
590 int err = WSAStartup (requested, &data);
593 fprintf (stderr, _("%s: Couldn't find usable socket driver.\n"),
598 if (data.wVersion < requested)
600 fprintf (stderr, _("%s: Couldn't find usable socket driver.\n"),
608 SetConsoleCtrlHandler (ws_handler, TRUE);
611 /* Replacement utime function for buggy Borland C++Builder 5.5 compiler.
612 (The Borland utime function only works on Windows NT.) */
614 #ifdef HACK_BCC_UTIME_BUG
616 borland_utime (const char *path, const struct utimbuf *times)
623 if ((fd = open (path, O_RDWR)) < 0)
626 ptr_tm = localtime (×->modtime);
627 ft.ft_tsec = ptr_tm->tm_sec >> 1;
628 ft.ft_min = ptr_tm->tm_min;
629 ft.ft_hour = ptr_tm->tm_hour;
630 ft.ft_day = ptr_tm->tm_mday;
631 ft.ft_month = ptr_tm->tm_mon + 1;
632 ft.ft_year = ptr_tm->tm_year - 80;
633 res = setftime (fd, &ft);
639 /* run_with_timeout Windows implementation. */
641 /* Stack size 0 uses default thread stack-size (reserve+commit).
642 Determined by what's in the PE header. */
643 #define THREAD_STACK_SIZE 0
647 void (*fun) (void *);
652 /* The callback that runs FUN(ARG) in a separate thread. This
653 function exists for two reasons: a) to not require FUN to be
654 declared WINAPI/__stdcall[1], and b) to retrieve Winsock errors,
655 which are per-thread. The latter is useful when FUN calls Winsock
656 functions, which is how run_with_timeout is used in Wget.
658 [1] MSVC can use __fastcall globally (cl /Gr) and on Watcom this is
659 the default (wcc386 -3r). */
662 thread_helper (void *arg)
664 struct thread_data *td = (struct thread_data *) arg;
666 /* Initialize Winsock error to what it was in the parent. That way
667 the subsequent call to WSAGetLastError will return the same value
668 if td->fun doesn't change Winsock error state. */
669 WSASetLastError (td->ws_error);
673 /* Return Winsock error to the caller, in case FUN ran Winsock
675 td->ws_error = WSAGetLastError ();
679 /* Call FUN(ARG), but don't allow it to run for more than TIMEOUT
680 seconds. Returns true if the function was interrupted with a
681 timeout, false otherwise.
683 This works by running FUN in a separate thread and terminating the
684 thread if it doesn't finish in the specified time. */
687 run_with_timeout (double seconds, void (*fun) (void *), void *arg)
689 static HANDLE thread_hnd = NULL;
690 struct thread_data thread_arg;
694 DEBUGP (("seconds %.2f, ", seconds));
703 /* Should never happen, but test for recursivety anyway. */
704 assert (thread_hnd == NULL);
706 thread_arg.fun = fun;
707 thread_arg.arg = arg;
708 thread_arg.ws_error = WSAGetLastError ();
709 thread_hnd = CreateThread (NULL, THREAD_STACK_SIZE, thread_helper,
710 &thread_arg, 0, &thread_id);
713 DEBUGP (("CreateThread() failed; %s\n", strerror (GetLastError ())));
714 goto blocking_fallback;
717 if (WaitForSingleObject (thread_hnd, (DWORD)(1000 * seconds))
720 /* Propagate error state (which is per-thread) to this thread,
721 so the caller can inspect it. */
722 WSASetLastError (thread_arg.ws_error);
723 DEBUGP (("Winsock error: %d\n", WSAGetLastError ()));
728 TerminateThread (thread_hnd, 1);
732 CloseHandle (thread_hnd); /* Clear-up after TerminateThread(). */
737 /* Wget expects network calls such as connect, recv, send, etc., to set
738 errno on failure. To achieve that, Winsock calls are wrapped with code
739 that, in case of error, sets errno to the value of WSAGetLastError().
740 In addition, we provide a wrapper around strerror, which recognizes
741 Winsock errors and prints the appropriate error message. */
743 /* Define a macro that creates a function definition that wraps FUN into
744 a function that sets errno the way the rest of the code expects. */
746 #define WRAP(fun, decl, call) int wrapped_##fun decl { \
747 int retval = fun call; \
749 errno = WSAGetLastError (); \
753 WRAP (socket, (int domain, int type, int protocol), (domain, type, protocol))
754 WRAP (bind, (int s, struct sockaddr *a, int alen), (s, a, alen))
755 WRAP (connect, (int s, const struct sockaddr *a, int alen), (s, a, alen))
756 WRAP (recv, (int s, void *buf, int len, int flags), (s, buf, len, flags))
757 WRAP (send, (int s, const void *buf, int len, int flags), (s, buf, len, flags))
758 WRAP (select, (int n, fd_set *r, fd_set *w, fd_set *e, const struct timeval *tm),
760 WRAP (getsockname, (int s, struct sockaddr *n, int *nlen), (s, n, nlen))
761 WRAP (getpeername, (int s, struct sockaddr *n, int *nlen), (s, n, nlen))
762 WRAP (setsockopt, (int s, int level, int opt, const void *val, int len),
763 (s, level, opt, val, len))
764 WRAP (closesocket, (int s), (s))
766 /* Return the text of the error message for Winsock error WSERR. */
769 get_winsock_error (int wserr)
772 case WSAEINTR: return "Interrupted system call";
773 case WSAEBADF: return "Bad file number";
774 case WSAEACCES: return "Permission denied";
775 case WSAEFAULT: return "Bad address";
776 case WSAEINVAL: return "Invalid argument";
777 case WSAEMFILE: return "Too many open files";
778 case WSAEWOULDBLOCK: return "Resource temporarily unavailable";
779 case WSAEINPROGRESS: return "Operation now in progress";
780 case WSAEALREADY: return "Operation already in progress";
781 case WSAENOTSOCK: return "Socket operation on nonsocket";
782 case WSAEDESTADDRREQ: return "Destination address required";
783 case WSAEMSGSIZE: return "Message too long";
784 case WSAEPROTOTYPE: return "Protocol wrong type for socket";
785 case WSAENOPROTOOPT: return "Bad protocol option";
786 case WSAEPROTONOSUPPORT: return "Protocol not supported";
787 case WSAESOCKTNOSUPPORT: return "Socket type not supported";
788 case WSAEOPNOTSUPP: return "Operation not supported";
789 case WSAEPFNOSUPPORT: return "Protocol family not supported";
790 case WSAEAFNOSUPPORT: return "Address family not supported by protocol family";
791 case WSAEADDRINUSE: return "Address already in use";
792 case WSAEADDRNOTAVAIL: return "Cannot assign requested address";
793 case WSAENETDOWN: return "Network is down";
794 case WSAENETUNREACH: return "Network is unreachable";
795 case WSAENETRESET: return "Network dropped connection on reset";
796 case WSAECONNABORTED: return "Software caused connection abort";
797 case WSAECONNRESET: return "Connection reset by peer";
798 case WSAENOBUFS: return "No buffer space available";
799 case WSAEISCONN: return "Socket is already connected";
800 case WSAENOTCONN: return "Socket is not connected";
801 case WSAESHUTDOWN: return "Cannot send after socket shutdown";
802 case WSAETOOMANYREFS: return "Too many references";
803 case WSAETIMEDOUT: return "Connection timed out";
804 case WSAECONNREFUSED: return "Connection refused";
805 case WSAELOOP: return "Too many levels of symbolic links";
806 case WSAENAMETOOLONG: return "File name too long";
807 case WSAEHOSTDOWN: return "Host is down";
808 case WSAEHOSTUNREACH: return "No route to host";
809 case WSAENOTEMPTY: return "Not empty";
810 case WSAEPROCLIM: return "Too many processes";
811 case WSAEUSERS: return "Too many users";
812 case WSAEDQUOT: return "Bad quota";
813 case WSAESTALE: return "Something is stale";
814 case WSAEREMOTE: return "Remote error";
815 case WSAEDISCON: return "Disconnected";
817 /* Extended Winsock errors */
818 case WSASYSNOTREADY: return "Winsock library is not ready";
819 case WSANOTINITIALISED: return "Winsock library not initalised";
820 case WSAVERNOTSUPPORTED: return "Winsock version not supported";
822 case WSAHOST_NOT_FOUND: return "Host not found";
823 case WSATRY_AGAIN: return "Host not found, try again";
824 case WSANO_RECOVERY: return "Unrecoverable error in call to nameserver";
825 case WSANO_DATA: return "No data record of requested type";
832 /* Return the error message corresponding to ERR. This is different
833 from Windows libc strerror() in that it handles Winsock errors
837 windows_strerror (int err)
840 if (err >= 0 && err < sys_nerr)
841 return strerror (err);
842 else if ((p = get_winsock_error (err)) != NULL)
847 snprintf (buf, sizeof (buf), "Unknown error %d (%#x)", err, err);