]> sjero.net Git - wget/blobdiff - src/mswindows.c
[svn] Windows fixes by Gisle Vanem.
[wget] / src / mswindows.c
index bf09b095caecd8287eaf4af1aca79b086e75603a..a3a186a8e97fd0bf97cce5d23d8fb1d65428f4ed 100644 (file)
@@ -1,23 +1,33 @@
 /* mswindows.c -- Windows-specific support
    Copyright (C) 1995, 1996, 1997, 1998  Free Software Foundation, Inc.
 
-This file is part of Wget.
+This file is part of GNU Wget.
 
-This program is free software; you can redistribute it and/or modify
+GNU Wget is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 2 of the License, or
 (at your option) any later version.
 
-This program is distributed in the hope that it will be useful,
+GNU Wget is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
+along with Wget; if not, write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
-/* #### Someone document these functions!  */
+In addition, as a special exception, the Free Software Foundation
+gives permission to link the code of its release of Wget with the
+OpenSSL project's "OpenSSL" library (or with modified versions of it
+that use the same license as the "OpenSSL" library), and distribute
+the linked executables.  You must obey the GNU General Public License
+in all respects for all of the code used other than "OpenSSL".  If you
+modify this file, you may extend this exception to your version of the
+file, but you are not obligated to do so.  If you do not wish to do
+so, delete this exception statement from your version.  */
+
+/* #### Someone please document what these functions do!  */
 
 #include <config.h>
 
@@ -26,77 +36,79 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include <winsock.h>
 #include <string.h>
 #include <assert.h>
+#include <errno.h>
+
+#ifdef HACK_BCC_UTIME_BUG
+# include <io.h>
+# include <fcntl.h>
+# ifdef HAVE_UTIME_H
+#  include <utime.h>
+# endif
+# ifdef HAVE_SYS_UTIME_H
+#  include <sys/utime.h>
+# endif
+#endif
 
 #include "wget.h"
+#include "utils.h"
 #include "url.h"
 
-char *argv0;
+#ifndef errno
+extern int errno;
+#endif
+
+#ifndef ES_SYSTEM_REQUIRED
+#define ES_SYSTEM_REQUIRED  0x00000001
+#endif
+
+#ifndef ES_CONTINUOUS
+#define ES_CONTINUOUS       0x80000000
+#endif
+
 
 /* Defined in log.c.  */
-void redirect_output (const char *);
+void log_request_redirect_output PARAMS ((const char *));
+
+static DWORD set_sleep_mode (DWORD mode);
 
+static DWORD pwr_mode = 0;
 static int windows_nt_p;
 
+#ifndef HAVE_SLEEP
 
 /* Emulation of Unix sleep.  */
+
 unsigned int
 sleep (unsigned seconds)
 {
-  Sleep (1000 * seconds);
-  /* Unix sleep() is interruptible.  To make it semi-usable, it
-     returns a value that says how much it "really" slept, or some
-     junk like that.  Ignore it.  */
-  return 0U;
+  return SleepEx (1000 * seconds, TRUE) ? 0U : 1000 * seconds;
 }
+#endif
 
-static char *
-read_registry (HKEY hkey, char *subkey, char *valuename, char *buf, int *len)
-{
-  HKEY result;
-  DWORD size = *len;
-  DWORD type = REG_SZ;
-  if (RegOpenKeyEx (hkey, subkey, NULL, KEY_READ, &result) != ERROR_SUCCESS)
-    return NULL;
-  if (RegQueryValueEx (result, valuename, NULL, &type, buf, &size) != ERROR_SUCCESS)
-    buf = NULL;
-  *len = size;
-  RegCloseKey (result);
-  return buf;
-}
+#ifndef HAVE_USLEEP
+/* Emulation of Unix usleep().  This has a granularity of
+   milliseconds, but that's ok because:
 
-char *
-pwd_cuserid (char *where)
+   a) Wget is only using it with milliseconds [not anymore, but b)
+      still applies];
+
+   b) You can't rely on usleep's granularity anyway.  If a caller
+   expects usleep to respect every microsecond, he's in for a
+   surprise.  */
+
+int
+usleep (unsigned long usec)
 {
-  char buf[32], *ptr;
-  int len = sizeof (buf);
-  if (GetUserName (buf, (LPDWORD) &len) == TRUE)
-    {
-      ;
-    }
-  else if (!!(ptr = getenv ("USERNAME")))
-    {
-      strcpy (buf, ptr);
-    }
-  else if (!read_registry (HKEY_LOCAL_MACHINE, "Network\\Logon",
-                         "username", buf, &len))
-    {
-      return NULL;
-    }
-  if (where)
-    {
-      strncpy (where, buf, len);
-      return where;
-    }
-  return xstrdup (buf);
+  SleepEx (usec / 1000, TRUE);
+  return 0;
 }
+#endif  /* HAVE_USLEEP */
 
 void
 windows_main_junk (int *argc, char **argv, char **exec_name)
 {
   char *p;
 
-  argv0 = argv[0];
-
   /* Remove .EXE from filename if it has one.  */
   *exec_name = xstrdup (*exec_name);
   p = strrchr (*exec_name, '.');
@@ -110,15 +122,15 @@ static void
 ws_cleanup (void)
 {
   WSACleanup ();
+  if (pwr_mode)
+     set_sleep_mode (pwr_mode);
+  pwr_mode = 0;
 }
 
 static void
 ws_hangup (void)
 {
-  redirect_output (_("\n\
-CTRL+Break received, redirecting output to `%s'.\n\
-Execution continued in background.\n\
-You may stop Wget by pressing CTRL+ALT+DELETE.\n"));
+  log_request_redirect_output ("CTRL+Break");
 }
 
 void
@@ -129,7 +141,7 @@ fork_to_background (void)
 
   if (!opt.lfilename)
     {
-      opt.lfilename = unique_name (DEFAULT_LOGFILE);
+      opt.lfilename = unique_name (DEFAULT_LOGFILE, 0);
       changedp = 1;
     }
   printf (_("Continuing in background.\n"));
@@ -158,7 +170,7 @@ ws_handler (DWORD dwEvent)
     case CTRL_CLOSE_EVENT:
     case CTRL_LOGOFF_EVENT:
     default:
-      WSACleanup ();
+      ws_cleanup ();
       return FALSE;
     }
   return TRUE;
@@ -171,10 +183,8 @@ ws_changetitle (char *url, int nurl)
   if (!nurl)
     return;
 
-  title_buf = (char *)xmalloc (strlen (url) + 20);
+  title_buf = (char *)alloca (strlen (url) + 20);
   sprintf (title_buf, "Wget %s%s", url, nurl == 1 ? "" : " ...");
-  /* #### What are the semantics of SetConsoleTitle?  Will it free the
-     given memory later?  */
   SetConsoleTitle (title_buf);
 }
 
@@ -182,34 +192,26 @@ char *
 ws_mypath (void)
 {
   static char *wspathsave;
-  char *buffer;
-  int rrr;
+  char buffer[MAX_PATH];
   char *ptr;
 
   if (wspathsave)
     {
       return wspathsave;
     }
-  ptr = strrchr (argv0, '\\');
+
+  GetModuleFileName (NULL, buffer, MAX_PATH);
+
+  ptr = strrchr (buffer, '\\');
   if (ptr)
     {
       *(ptr + 1) = '\0';
-      wspathsave = (char*) xmalloc (strlen(argv0)+1);
-      strcpy (wspathsave, argv0);
-      return wspathsave;
-    }
-  buffer = (char*) xmalloc (256);
-  rrr = SearchPath (NULL, argv0, strchr (argv0, '.') ? NULL : ".EXE",
-                   256, buffer, &ptr);
-  if (rrr && rrr <= 256)
-    {
-      *ptr = '\0';
-      wspathsave = (char*) xmalloc (strlen(buffer)+1);
+      wspathsave = (char*) xmalloc (strlen (buffer) + 1);
       strcpy (wspathsave, buffer);
-      return wspathsave;
     }
-  xfree (buffer);
-  return NULL;
+  else
+    wspathsave = NULL;
+  return wspathsave;
 }
 
 void
@@ -256,8 +258,7 @@ ws_startup (void)
       exit (1);
     }
 
-  if (LOBYTE (requested) < 1 || (LOBYTE (requested) == 1 &&
-                               HIBYTE (requested) < 1))
+  if (data.wVersion < requested)
     {
       fprintf (stderr, _("%s: Couldn't find usable socket driver.\n"),
               exec_name);
@@ -265,5 +266,61 @@ ws_startup (void)
       exit (1);
     }
   atexit (ws_cleanup);
+  pwr_mode = set_sleep_mode (0);
   SetConsoleCtrlHandler (ws_handler, TRUE);
 }
+
+/* Replacement utime function for buggy Borland C++Builder 5.5 compiler.
+   (The Borland utime function only works on Windows NT.)  */
+
+#ifdef HACK_BCC_UTIME_BUG
+int borland_utime(const char *path, const struct utimbuf *times)
+{
+  int fd;
+  int res;
+  struct ftime ft;
+  struct tm *ptr_tm;
+
+  if ((fd = open (path, O_RDWR)) < 0)
+    return -1;
+
+  ptr_tm = localtime (&times->modtime);
+  ft.ft_tsec = ptr_tm->tm_sec >> 1;
+  ft.ft_min = ptr_tm->tm_min;
+  ft.ft_hour = ptr_tm->tm_hour;
+  ft.ft_day = ptr_tm->tm_mday;
+  ft.ft_month = ptr_tm->tm_mon + 1;
+  ft.ft_year = ptr_tm->tm_year - 80;
+  res = setftime (fd, &ft);
+  close (fd);
+  return res;
+}
+#endif
+
+/*
+ * Prevent Windows entering sleep/hibernation-mode while wget is doing a lengthy transfer.
+ * Windows does by default not consider network activity in console-programs as activity !
+ * Works on Win-98/ME/2K and up.
+ */
+static
+DWORD set_sleep_mode (DWORD mode)
+{
+  HMODULE mod = LoadLibrary ("kernel32.dll");
+  DWORD (*_SetThreadExecutionState) (DWORD) = NULL;
+  DWORD rc = (DWORD)-1;
+
+  if (mod)
+     (void*)_SetThreadExecutionState = GetProcAddress ((HINSTANCE)mod, "SetThreadExecutionState");
+
+  if (_SetThreadExecutionState)
+    {
+      if (mode == 0)  /* first time */
+         mode = (ES_SYSTEM_REQUIRED | ES_CONTINUOUS);
+      rc = (*_SetThreadExecutionState) (mode);
+    }
+  if (mod)
+     FreeLibrary (mod);
+  DEBUGP (("set_sleep_mode(): mode 0x%08lX, rc 0x%08lX\n", mode, rc));
+  return (rc);
+}
+