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, ... */
61 #ifndef ES_SYSTEM_REQUIRED
62 #define ES_SYSTEM_REQUIRED 0x00000001
66 #define ES_CONTINUOUS 0x80000000
70 /* Defined in log.c. */
71 void log_request_redirect_output PARAMS ((const char *));
73 /* Windows version of xsleep in utils.c. */
76 xsleep (double seconds)
81 /* Explained in utils.c. */
83 seconds -= (long) seconds;
85 usleep (seconds * 1000000L);
86 #else /* not HAVE_USLEEP */
87 SleepEx ((DWORD) (seconds * 1000 + .5), FALSE);
88 #endif /* not HAVE_USLEEP */
91 #if defined(__BORLANDC__) || (defined(_MSC_VER) && _MSC_VER < 1300)
94 char_value (char c, int base)
99 if ('0' <= c && c <= '9')
101 else if ('a' <= c && c <= 'z')
102 value = c - 'a' + 10;
103 else if ('A' <= c && c <= 'Z')
104 value = c - 'A' + 10;
112 /* A fairly simple strtoll replacement for MS VC versions that don't
116 str_to_int64 (const char *nptr, char **endptr, int base)
118 #define INT64_OVERFLOW 9223372036854775807I64
119 #define INT64_UNDERFLOW (-INT64_OVERFLOW - 1)
124 if (base != 0 && (base < 2 || base > 36))
130 while (*nptr == ' ' || *nptr == '\t')
137 else if (*nptr == '+')
145 /* If base is 0, determine the real base based on the beginning on
146 the number; octal numbers begin with "0", hexadecimal with "0x",
147 and the others are considered octal. */
150 if ((base == 0 || base == 16)
152 (*(nptr + 1) == 'x' || *(nptr + 1) == 'X'))
165 /* Parse positive number, checking for overflow. */
167 for (; (val = char_value (*nptr, base)) != -1; ++nptr)
169 __int64 newresult = base * result + val;
170 if (newresult < result)
172 result = INT64_OVERFLOW;
181 /* Parse negative number, checking for underflow. */
183 for (; (val = char_value (*nptr, base)) != -1; ++nptr)
185 __int64 newresult = base * result - val;
186 if (newresult > result)
188 result = INT64_UNDERFLOW;
196 *endptr = (char *) nptr;
200 #else /* !defined(__BORLANDC__) && (!defined(_MSC_VER) || _MSC_VER >= 1300) */
203 str_to_int64 (const char *nptr, char **endptr, int base)
206 return _strtoi64 (nptr, endptr, base);
208 return strtoll (nptr, endptr, base);
212 #endif /* !defined(__BORLANDC__) && (!defined(_MSC_VER) || _MSC_VER >= 1300) */
215 windows_main (int *argc, char **argv, char **exec_name)
219 /* Remove .EXE from filename if it has one. */
220 *exec_name = xstrdup (*exec_name);
221 p = strrchr (*exec_name, '.');
233 ws_hangup (const char *reason)
235 fprintf (stderr, _("Continuing in background.\n"));
236 log_request_redirect_output (reason);
238 /* Detach process from the current console. Under Windows 9x, if we
239 were launched from a 16-bit process (which is usually the case;
240 command.com is 16-bit) the parent process should resume right away.
241 Under NT or if launched from a 32-process under 9x, this is a futile
242 gesture as the parent will wait for us to terminate before resuming. */
246 /* Construct the name for a named section (a.k.a. `file mapping') object.
247 The returned string is dynamically allocated and needs to be xfree()'d. */
249 make_section_name (DWORD pid)
251 return aprintf ("gnu_wget_fake_fork_%lu", pid);
254 /* This structure is used to hold all the data that is exchanged between
256 struct fake_fork_info
260 char lfilename[MAX_PATH + 1];
263 /* Determines if we are the child and if so performs the child logic.
270 fake_fork_child (void)
272 HANDLE section, event;
273 struct fake_fork_info *info;
276 name = make_section_name (GetCurrentProcessId ());
277 section = OpenFileMapping (FILE_MAP_WRITE, FALSE, name);
279 /* It seems that Windows 9x and NT set last-error inconsistently when
280 OpenFileMapping() fails; so we assume it failed because the section
281 object does not exist. */
283 return 0; /* We are the parent. */
285 info = MapViewOfFile (section, FILE_MAP_WRITE, 0, 0, 0);
288 CloseHandle (section);
294 info->logfile_changed = 0;
297 /* See utils:fork_to_background for explanation. */
298 FILE *new_log_fp = unique_create (DEFAULT_LOGFILE, 0, &opt.lfilename);
301 info->logfile_changed = 1;
302 strncpy (info->lfilename, opt.lfilename, sizeof (info->lfilename));
303 info->lfilename[sizeof (info->lfilename) - 1] = '\0';
308 UnmapViewOfFile (info);
309 CloseHandle (section);
311 /* Inform the parent that we've done our part. */
312 if (!SetEvent (event))
316 return 1; /* We are the child. */
319 /* Windows doesn't support the fork() call; so we fake it by invoking
320 another copy of Wget with the same arguments with which we were
321 invoked. The child copy of Wget should perform the same initialization
322 sequence as the parent; so we should have two processes that are
323 essentially identical. We create a specially named section object that
324 allows the child to distinguish itself from the parent and is used to
325 exchange information between the two processes. We use an event object
326 for synchronization. */
330 char exe[MAX_PATH + 1];
332 SECURITY_ATTRIBUTES sa;
333 HANDLE section, event, h[2];
335 PROCESS_INFORMATION pi;
336 struct fake_fork_info *info;
340 section = pi.hProcess = pi.hThread = NULL;
342 /* Get the fully qualified name of our executable. This is more reliable
343 than using argv[0]. */
344 exe_len = GetModuleFileName (GetModuleHandle (NULL), exe, sizeof (exe));
345 if (!exe_len || (exe_len >= sizeof (exe)))
348 sa.nLength = sizeof (sa);
349 sa.lpSecurityDescriptor = NULL;
350 sa.bInheritHandle = TRUE;
352 /* Create an anonymous inheritable event object that starts out
354 event = CreateEvent (&sa, FALSE, FALSE, NULL);
358 /* Create the child process detached form the current console and in a
362 rv = CreateProcess (exe, GetCommandLine (), NULL, NULL, TRUE,
363 CREATE_SUSPENDED | DETACHED_PROCESS,
364 NULL, NULL, &si, &pi);
368 /* Create a named section object with a name based on the process id of
370 name = make_section_name (pi.dwProcessId);
372 CreateFileMapping (INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0,
373 sizeof (struct fake_fork_info), name);
376 /* Fail if the section object already exists (should not happen). */
377 if (!section || (le == ERROR_ALREADY_EXISTS))
383 /* Copy the event handle into the section object. */
384 info = MapViewOfFile (section, FILE_MAP_WRITE, 0, 0, 0);
393 UnmapViewOfFile (info);
395 /* Start the child process. */
396 rv = ResumeThread (pi.hThread);
399 TerminateProcess (pi.hProcess, (DWORD) -1);
403 /* Wait for the child to signal to us that it has done its part. If it
404 terminates before signaling us it's an error. */
408 rv = WAIT_OBJECT_0 == WaitForMultipleObjects (2, h, FALSE, 5 * 60 * 1000);
412 info = MapViewOfFile (section, FILE_MAP_READ, 0, 0, 0);
419 /* Ensure string is properly terminated. */
420 if (info->logfile_changed &&
421 !memchr (info->lfilename, '\0', sizeof (info->lfilename)))
427 printf (_("Continuing in background, pid %lu.\n"), pi.dwProcessId);
428 if (info->logfile_changed)
429 printf (_("Output will be written to `%s'.\n"), info->lfilename);
431 UnmapViewOfFile (info);
438 CloseHandle (section);
440 CloseHandle (pi.hThread);
442 CloseHandle (pi.hProcess);
444 /* We're the parent. If all is well, terminate. */
448 /* We failed, return. */
451 /* This is the corresponding Windows implementation of the
452 fork_to_background() function in utils.c. */
454 fork_to_background (void)
458 rv = fake_fork_child ();
461 fprintf (stderr, "fake_fork_child() failed\n");
466 /* We're the parent. */
468 /* If fake_fork() returns, it failed. */
469 fprintf (stderr, "fake_fork() failed\n");
472 /* If we get here, we're the child. */
476 ws_handler (DWORD dwEvent)
482 ws_hangup ("CTRL+C");
485 #ifdef CTRLBREAK_BACKGND
486 case CTRL_BREAK_EVENT:
487 ws_hangup ("CTRL+Break");
495 static char *title_buf = NULL;
496 static char *curr_url = NULL;
497 static int old_percentage = -1;
499 /* Updates the console title with the URL of the current file being
502 ws_changetitle (const char *url)
504 xfree_null (title_buf);
505 xfree_null (curr_url);
506 title_buf = (char *)xmalloc (strlen (url) + 20);
507 curr_url = xstrdup (url);
509 sprintf (title_buf, "Wget %s", curr_url);
510 SetConsoleTitle (title_buf);
513 /* Updates the console title with the percentage of the current file
516 ws_percenttitle (double percentage_float)
520 if (!title_buf || !curr_url)
523 percentage = (int) percentage_float;
525 /* Clamp percentage value. */
528 if (percentage > 100)
531 /* Only update the title when the percentage has changed. */
532 if (percentage == old_percentage)
535 old_percentage = percentage;
537 sprintf (title_buf, "Wget [%d%%] %s", percentage, curr_url);
538 SetConsoleTitle (title_buf);
541 /* Returns a pointer to the fully qualified name of the directory that
542 contains the Wget binary (wget.exe). The returned path does not have a
543 trailing path separator. Returns NULL on failure. */
547 static char *wspathsave = NULL;
551 char buf[MAX_PATH + 1];
555 len = GetModuleFileName (GetModuleHandle (NULL), buf, sizeof (buf));
556 if (!len || (len >= sizeof (buf)))
559 p = strrchr (buf, PATH_SEPARATOR);
564 wspathsave = xstrdup (buf);
570 /* Prevent Windows entering sleep/hibernation-mode while Wget is doing
571 a lengthy transfer. Windows does not, by default, consider network
572 activity in console-programs as activity! Works on Win-98/ME/2K
575 set_sleep_mode (void)
577 typedef DWORD (WINAPI *func_t) (DWORD);
578 func_t set_exec_state;
581 (func_t) GetProcAddress (GetModuleHandle ("KERNEL32.DLL"),
582 "SetThreadExecutionState");
585 set_exec_state (ES_SYSTEM_REQUIRED | ES_CONTINUOUS);
588 /* Perform Windows specific initialization. */
593 WORD requested = MAKEWORD (1, 1);
594 int err = WSAStartup (requested, &data);
597 fprintf (stderr, _("%s: Couldn't find usable socket driver.\n"),
602 if (data.wVersion < requested)
604 fprintf (stderr, _("%s: Couldn't find usable socket driver.\n"),
612 SetConsoleCtrlHandler (ws_handler, TRUE);
615 /* Replacement utime function for buggy Borland C++Builder 5.5 compiler.
616 (The Borland utime function only works on Windows NT.) */
618 #ifdef HACK_BCC_UTIME_BUG
620 borland_utime (const char *path, const struct utimbuf *times)
627 if ((fd = open (path, O_RDWR)) < 0)
630 ptr_tm = localtime (×->modtime);
631 ft.ft_tsec = ptr_tm->tm_sec >> 1;
632 ft.ft_min = ptr_tm->tm_min;
633 ft.ft_hour = ptr_tm->tm_hour;
634 ft.ft_day = ptr_tm->tm_mday;
635 ft.ft_month = ptr_tm->tm_mon + 1;
636 ft.ft_year = ptr_tm->tm_year - 80;
637 res = setftime (fd, &ft);
643 /* run_with_timeout Windows implementation. */
645 /* Stack size 0 uses default thread stack-size (reserve+commit).
646 Determined by what's in the PE header. */
647 #define THREAD_STACK_SIZE 0
651 void (*fun) (void *);
656 /* The callback that runs FUN(ARG) in a separate thread. This
657 function exists for two reasons: a) to not require FUN to be
658 declared WINAPI/__stdcall[1], and b) to retrieve Winsock errors,
659 which are per-thread. The latter is useful when FUN calls Winsock
660 functions, which is how run_with_timeout is used in Wget.
662 [1] MSVC can use __fastcall globally (cl /Gr) and on Watcom this is
663 the default (wcc386 -3r). */
666 thread_helper (void *arg)
668 struct thread_data *td = (struct thread_data *) arg;
670 /* Initialize Winsock error to what it was in the parent. That way
671 the subsequent call to WSAGetLastError will return the same value
672 if td->fun doesn't change Winsock error state. */
673 WSASetLastError (td->ws_error);
677 /* Return Winsock error to the caller, in case FUN ran Winsock
679 td->ws_error = WSAGetLastError ();
683 /* Call FUN(ARG), but don't allow it to run for more than TIMEOUT
684 seconds. Returns non-zero if the function was interrupted with a
685 timeout, zero otherwise.
687 This works by running FUN in a separate thread and terminating the
688 thread if it doesn't finish in the specified time. */
691 run_with_timeout (double seconds, void (*fun) (void *), void *arg)
693 static HANDLE thread_hnd = NULL;
694 struct thread_data thread_arg;
698 DEBUGP (("seconds %.2f, ", seconds));
707 /* Should never happen, but test for recursivety anyway. */
708 assert (thread_hnd == NULL);
710 thread_arg.fun = fun;
711 thread_arg.arg = arg;
712 thread_arg.ws_error = WSAGetLastError ();
713 thread_hnd = CreateThread (NULL, THREAD_STACK_SIZE, thread_helper,
714 &thread_arg, 0, &thread_id);
717 DEBUGP (("CreateThread() failed; %s\n", strerror (GetLastError ())));
718 goto blocking_fallback;
721 if (WaitForSingleObject (thread_hnd, (DWORD)(1000 * seconds))
724 /* Propagate error state (which is per-thread) to this thread,
725 so the caller can inspect it. */
726 WSASetLastError (thread_arg.ws_error);
727 DEBUGP (("Winsock error: %d\n", WSAGetLastError ()));
732 TerminateThread (thread_hnd, 1);
736 CloseHandle (thread_hnd); /* Clear-up after TerminateThread(). */
741 /* Wget expects network calls such as connect, recv, send, etc., to set
742 errno on failure. To achieve that, Winsock calls are wrapped with code
743 that, in case of error, sets errno to the value of WSAGetLastError().
744 In addition, we provide a wrapper around strerror, which recognizes
745 Winsock errors and prints the appropriate error message. */
747 /* Define a macro that creates a function definition that wraps FUN into
748 a function that sets errno the way the rest of the code expects. */
750 #define WRAP(fun, decl, call) int wrapped_##fun decl { \
751 int retval = fun call; \
753 errno = WSAGetLastError (); \
757 WRAP (socket, (int domain, int type, int protocol), (domain, type, protocol))
758 WRAP (bind, (int s, struct sockaddr *a, int alen), (s, a, alen))
759 WRAP (connect, (int s, const struct sockaddr *a, int alen), (s, a, alen))
760 WRAP (recv, (int s, void *buf, int len, int flags), (s, buf, len, flags))
761 WRAP (send, (int s, const void *buf, int len, int flags), (s, buf, len, flags))
762 WRAP (select, (int n, fd_set *r, fd_set *w, fd_set *e, const struct timeval *tm),
764 WRAP (getsockname, (int s, struct sockaddr *n, int *nlen), (s, n, nlen))
765 WRAP (getpeername, (int s, struct sockaddr *n, int *nlen), (s, n, nlen))
766 WRAP (setsockopt, (int s, int level, int opt, const void *val, int len),
767 (s, level, opt, val, len))
768 WRAP (closesocket, (int s), (s))
770 /* Return the text of the error message for Winsock error WSERR. */
773 get_winsock_error (int wserr)
776 case WSAEINTR: return "Interrupted system call";
777 case WSAEBADF: return "Bad file number";
778 case WSAEACCES: return "Permission denied";
779 case WSAEFAULT: return "Bad address";
780 case WSAEINVAL: return "Invalid argument";
781 case WSAEMFILE: return "Too many open files";
782 case WSAEWOULDBLOCK: return "Resource temporarily unavailable";
783 case WSAEINPROGRESS: return "Operation now in progress";
784 case WSAEALREADY: return "Operation already in progress";
785 case WSAENOTSOCK: return "Socket operation on nonsocket";
786 case WSAEDESTADDRREQ: return "Destination address required";
787 case WSAEMSGSIZE: return "Message too long";
788 case WSAEPROTOTYPE: return "Protocol wrong type for socket";
789 case WSAENOPROTOOPT: return "Bad protocol option";
790 case WSAEPROTONOSUPPORT: return "Protocol not supported";
791 case WSAESOCKTNOSUPPORT: return "Socket type not supported";
792 case WSAEOPNOTSUPP: return "Operation not supported";
793 case WSAEPFNOSUPPORT: return "Protocol family not supported";
794 case WSAEAFNOSUPPORT: return "Address family not supported by protocol family";
795 case WSAEADDRINUSE: return "Address already in use";
796 case WSAEADDRNOTAVAIL: return "Cannot assign requested address";
797 case WSAENETDOWN: return "Network is down";
798 case WSAENETUNREACH: return "Network is unreachable";
799 case WSAENETRESET: return "Network dropped connection on reset";
800 case WSAECONNABORTED: return "Software caused connection abort";
801 case WSAECONNRESET: return "Connection reset by peer";
802 case WSAENOBUFS: return "No buffer space available";
803 case WSAEISCONN: return "Socket is already connected";
804 case WSAENOTCONN: return "Socket is not connected";
805 case WSAESHUTDOWN: return "Cannot send after socket shutdown";
806 case WSAETOOMANYREFS: return "Too many references";
807 case WSAETIMEDOUT: return "Connection timed out";
808 case WSAECONNREFUSED: return "Connection refused";
809 case WSAELOOP: return "Too many levels of symbolic links";
810 case WSAENAMETOOLONG: return "File name too long";
811 case WSAEHOSTDOWN: return "Host is down";
812 case WSAEHOSTUNREACH: return "No route to host";
813 case WSAENOTEMPTY: return "Not empty";
814 case WSAEPROCLIM: return "Too many processes";
815 case WSAEUSERS: return "Too many users";
816 case WSAEDQUOT: return "Bad quota";
817 case WSAESTALE: return "Something is stale";
818 case WSAEREMOTE: return "Remote error";
819 case WSAEDISCON: return "Disconnected";
821 /* Extended Winsock errors */
822 case WSASYSNOTREADY: return "Winsock library is not ready";
823 case WSANOTINITIALISED: return "Winsock library not initalised";
824 case WSAVERNOTSUPPORTED: return "Winsock version not supported";
826 case WSAHOST_NOT_FOUND: return "Host not found";
827 case WSATRY_AGAIN: return "Host not found, try again";
828 case WSANO_RECOVERY: return "Unrecoverable error in call to nameserver";
829 case WSANO_DATA: return "No data record of requested type";
836 /* Return the error message corresponding to ERR. This is different
837 from Windows libc strerror() in that it handles Winsock errors
841 windows_strerror (int err)
844 if (err >= 0 && err < sys_nerr)
845 return strerror (err);
846 else if ((p = get_winsock_error (err)) != NULL)
851 snprintf (buf, sizeof (buf), "Unknown error %d (%#x)", err, err);