]> sjero.net Git - wget/blob - src/mswindows.c
[svn] Allow decimal values for --timeout, --wait, and --waitretry.
[wget] / src / mswindows.c
1 /* mswindows.c -- Windows-specific support
2    Copyright (C) 1995, 1996, 1997, 1998  Free Software Foundation, Inc.
3
4 This file is part of GNU Wget.
5
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.
10
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.
15
16 You should have received a copy of the GNU General Public License
17 along with Wget; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19
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.  */
29
30 /* #### Someone please document what these functions do!  */
31
32 #include <config.h>
33
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <winsock.h>
37 #include <string.h>
38 #include <assert.h>
39 #include <errno.h>
40
41 #ifdef HACK_BCC_UTIME_BUG
42 # include <io.h>
43 # include <fcntl.h>
44 # ifdef HAVE_UTIME_H
45 #  include <utime.h>
46 # endif
47 # ifdef HAVE_SYS_UTIME_H
48 #  include <sys/utime.h>
49 # endif
50 #endif
51
52 #include "wget.h"
53 #include "utils.h"
54 #include "url.h"
55
56 #ifndef errno
57 extern int errno;
58 #endif
59
60 /* Defined in log.c.  */
61 void log_request_redirect_output PARAMS ((const char *));
62
63 static int windows_nt_p;
64
65
66 /* Emulation of Unix sleep.  */
67
68 unsigned int
69 sleep (unsigned seconds)
70 {
71   return SleepEx (1000 * seconds, TRUE) ? 0U : 1000 * seconds;
72 }
73
74 /* Emulation of Unix usleep().  This has a granularity of
75    milliseconds, but that's ok because:
76
77    a) Wget is only using it with milliseconds [not anymore, but b)
78       still applies];
79
80    b) You can't rely on usleep's granularity anyway.  If a caller
81    expects usleep to respect every microsecond, he's in for a
82    surprise.  */
83
84 int
85 usleep (unsigned long usec)
86 {
87   SleepEx (usec / 1000, TRUE);
88   return 0;
89 }
90
91 static char *
92 read_registry (HKEY hkey, char *subkey, char *valuename, char *buf, int *len)
93 {
94   HKEY result;
95   DWORD size = *len;
96   DWORD type = REG_SZ;
97   if (RegOpenKeyEx (hkey, subkey, NULL, KEY_READ, &result) != ERROR_SUCCESS)
98     return NULL;
99   if (RegQueryValueEx (result, valuename, NULL, &type, buf, &size) != ERROR_SUCCESS)
100     buf = NULL;
101   *len = size;
102   RegCloseKey (result);
103   return buf;
104 }
105
106 void
107 windows_main_junk (int *argc, char **argv, char **exec_name)
108 {
109   char *p;
110
111   /* Remove .EXE from filename if it has one.  */
112   *exec_name = xstrdup (*exec_name);
113   p = strrchr (*exec_name, '.');
114   if (p)
115     *p = '\0';
116 }
117 \f
118 /* Winsock stuff. */
119
120 static void
121 ws_cleanup (void)
122 {
123   WSACleanup ();
124 }
125
126 static void
127 ws_hangup (void)
128 {
129   log_request_redirect_output ("CTRL+Break");
130 }
131
132 void
133 fork_to_background (void)
134 {
135   /* Whether we arrange our own version of opt.lfilename here.  */
136   int changedp = 0;
137
138   if (!opt.lfilename)
139     {
140       opt.lfilename = unique_name (DEFAULT_LOGFILE, 0);
141       changedp = 1;
142     }
143   printf (_("Continuing in background.\n"));
144   if (changedp)
145     printf (_("Output will be written to `%s'.\n"), opt.lfilename);
146
147   ws_hangup ();
148   if (!windows_nt_p)
149     FreeConsole ();
150 }
151
152 static BOOL WINAPI
153 ws_handler (DWORD dwEvent)
154 {
155   switch (dwEvent)
156     {
157 #ifdef CTRLC_BACKGND
158     case CTRL_C_EVENT:
159 #endif
160 #ifdef CTRLBREAK_BACKGND
161     case CTRL_BREAK_EVENT:
162 #endif
163       fork_to_background ();
164       break;
165     case CTRL_SHUTDOWN_EVENT:
166     case CTRL_CLOSE_EVENT:
167     case CTRL_LOGOFF_EVENT:
168     default:
169       WSACleanup ();
170       return FALSE;
171     }
172   return TRUE;
173 }
174
175 void
176 ws_changetitle (char *url, int nurl)
177 {
178   char *title_buf;
179   if (!nurl)
180     return;
181
182   title_buf = (char *)alloca (strlen (url) + 20);
183   sprintf (title_buf, "Wget %s%s", url, nurl == 1 ? "" : " ...");
184   SetConsoleTitle (title_buf);
185 }
186
187 char *
188 ws_mypath (void)
189 {
190   static char *wspathsave;
191   char buffer[MAX_PATH];
192   char *ptr;
193
194   if (wspathsave)
195     {
196       return wspathsave;
197     }
198
199   GetModuleFileName (NULL, buffer, MAX_PATH);
200
201   ptr = strrchr (buffer, '\\');
202   if (ptr)
203     {
204       *(ptr + 1) = '\0';
205       wspathsave = (char*) xmalloc (strlen (buffer) + 1);
206       strcpy (wspathsave, buffer);
207     }
208   else
209     wspathsave = NULL;
210   return wspathsave;
211 }
212
213 void
214 ws_help (const char *name)
215 {
216   char *mypath = ws_mypath ();
217
218   if (mypath)
219     {
220       struct stat sbuf;
221       char *buf = (char *)alloca (strlen (mypath) + strlen (name) + 4 + 1);
222       sprintf (buf, "%s%s.HLP", mypath, name);
223       if (stat (buf, &sbuf) == 0) 
224         {
225           printf (_("Starting WinHelp %s\n"), buf);
226           WinHelp (NULL, buf, HELP_INDEX, NULL);
227         }
228       else
229         {
230           printf ("%s: %s\n", buf, strerror (errno));
231         }
232     }
233 }
234
235 void
236 ws_startup (void)
237 {
238   WORD requested;
239   WSADATA data;
240   int err;
241   OSVERSIONINFO os;
242
243   if (GetVersionEx (&os) == TRUE
244       && os.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS)
245     windows_nt_p = 1;
246
247   requested = MAKEWORD (1, 1);
248   err = WSAStartup (requested, &data);
249
250   if (err != 0)
251     {
252       fprintf (stderr, _("%s: Couldn't find usable socket driver.\n"),
253                exec_name);
254       exit (1);
255     }
256
257   if (data.wVersion < requested)
258     {
259       fprintf (stderr, _("%s: Couldn't find usable socket driver.\n"),
260                exec_name);
261       WSACleanup ();
262       exit (1);
263     }
264   atexit (ws_cleanup);
265   SetConsoleCtrlHandler (ws_handler, TRUE);
266 }
267
268 /* Replacement utime function for buggy Borland C++Builder 5.5 compiler.
269    (The Borland utime function only works on Windows NT.)  */
270
271 #ifdef HACK_BCC_UTIME_BUG
272 int borland_utime(const char *path, const struct utimbuf *times)
273 {
274   int fd;
275   int res;
276   struct ftime ft;
277   struct tm *ptr_tm;
278
279   if ((fd = open (path, O_RDWR)) < 0)
280     return -1;
281
282   ptr_tm = localtime (&times->modtime);
283   ft.ft_tsec = ptr_tm->tm_sec >> 1;
284   ft.ft_min = ptr_tm->tm_min;
285   ft.ft_hour = ptr_tm->tm_hour;
286   ft.ft_day = ptr_tm->tm_mday;
287   ft.ft_month = ptr_tm->tm_mon + 1;
288   ft.ft_year = ptr_tm->tm_year - 80;
289   res = setftime (fd, &ft);
290   close (fd);
291   return res;
292 }
293 #endif