]> sjero.net Git - wget/blob - src/mswindows.c
[svn] Update the license to include the OpenSSL exception.
[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;
78
79    b) You can't rely on usleep's granularity anyway.  If a caller
80    expects usleep to respect every microsecond, he's in for a
81    surprise.  */
82
83 int
84 usleep (unsigned long usec)
85 {
86   SleepEx (usec / 1000, TRUE);
87   return 0;
88 }
89
90 static char *
91 read_registry (HKEY hkey, char *subkey, char *valuename, char *buf, int *len)
92 {
93   HKEY result;
94   DWORD size = *len;
95   DWORD type = REG_SZ;
96   if (RegOpenKeyEx (hkey, subkey, NULL, KEY_READ, &result) != ERROR_SUCCESS)
97     return NULL;
98   if (RegQueryValueEx (result, valuename, NULL, &type, buf, &size) != ERROR_SUCCESS)
99     buf = NULL;
100   *len = size;
101   RegCloseKey (result);
102   return buf;
103 }
104
105 void
106 windows_main_junk (int *argc, char **argv, char **exec_name)
107 {
108   char *p;
109
110   /* Remove .EXE from filename if it has one.  */
111   *exec_name = xstrdup (*exec_name);
112   p = strrchr (*exec_name, '.');
113   if (p)
114     *p = '\0';
115 }
116 \f
117 /* Winsock stuff. */
118
119 static void
120 ws_cleanup (void)
121 {
122   WSACleanup ();
123 }
124
125 static void
126 ws_hangup (void)
127 {
128   log_request_redirect_output ("CTRL+Break");
129 }
130
131 void
132 fork_to_background (void)
133 {
134   /* Whether we arrange our own version of opt.lfilename here.  */
135   int changedp = 0;
136
137   if (!opt.lfilename)
138     {
139       opt.lfilename = unique_name (DEFAULT_LOGFILE);
140       changedp = 1;
141     }
142   printf (_("Continuing in background.\n"));
143   if (changedp)
144     printf (_("Output will be written to `%s'.\n"), opt.lfilename);
145
146   ws_hangup ();
147   if (!windows_nt_p)
148     FreeConsole ();
149 }
150
151 static BOOL WINAPI
152 ws_handler (DWORD dwEvent)
153 {
154   switch (dwEvent)
155     {
156 #ifdef CTRLC_BACKGND
157     case CTRL_C_EVENT:
158 #endif
159 #ifdef CTRLBREAK_BACKGND
160     case CTRL_BREAK_EVENT:
161 #endif
162       fork_to_background ();
163       break;
164     case CTRL_SHUTDOWN_EVENT:
165     case CTRL_CLOSE_EVENT:
166     case CTRL_LOGOFF_EVENT:
167     default:
168       WSACleanup ();
169       return FALSE;
170     }
171   return TRUE;
172 }
173
174 void
175 ws_changetitle (char *url, int nurl)
176 {
177   char *title_buf;
178   if (!nurl)
179     return;
180
181   title_buf = (char *)alloca (strlen (url) + 20);
182   sprintf (title_buf, "Wget %s%s", url, nurl == 1 ? "" : " ...");
183   SetConsoleTitle (title_buf);
184 }
185
186 char *
187 ws_mypath (void)
188 {
189   static char *wspathsave;
190   char buffer[MAX_PATH];
191   char *ptr;
192
193   if (wspathsave)
194     {
195       return wspathsave;
196     }
197
198   GetModuleFileName (NULL, buffer, MAX_PATH);
199
200   ptr = strrchr (buffer, '\\');
201   if (ptr)
202     {
203       *(ptr + 1) = '\0';
204       wspathsave = (char*) xmalloc (strlen (buffer) + 1);
205       strcpy (wspathsave, buffer);
206     }
207   else
208     wspathsave = NULL;
209   return wspathsave;
210 }
211
212 void
213 ws_help (const char *name)
214 {
215   char *mypath = ws_mypath ();
216
217   if (mypath)
218     {
219       struct stat sbuf;
220       char *buf = (char *)alloca (strlen (mypath) + strlen (name) + 4 + 1);
221       sprintf (buf, "%s%s.HLP", mypath, name);
222       if (stat (buf, &sbuf) == 0) 
223         {
224           printf (_("Starting WinHelp %s\n"), buf);
225           WinHelp (NULL, buf, HELP_INDEX, NULL);
226         }
227       else
228         {
229           printf ("%s: %s\n", buf, strerror (errno));
230         }
231     }
232 }
233
234 void
235 ws_startup (void)
236 {
237   WORD requested;
238   WSADATA data;
239   int err;
240   OSVERSIONINFO os;
241
242   if (GetVersionEx (&os) == TRUE
243       && os.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS)
244     windows_nt_p = 1;
245
246   requested = MAKEWORD (1, 1);
247   err = WSAStartup (requested, &data);
248
249   if (err != 0)
250     {
251       fprintf (stderr, _("%s: Couldn't find usable socket driver.\n"),
252                exec_name);
253       exit (1);
254     }
255
256   if (data.wVersion < requested)
257     {
258       fprintf (stderr, _("%s: Couldn't find usable socket driver.\n"),
259                exec_name);
260       WSACleanup ();
261       exit (1);
262     }
263   atexit (ws_cleanup);
264   SetConsoleCtrlHandler (ws_handler, TRUE);
265 }
266
267 /* Replacement utime function for buggy Borland C++Builder 5.5 compiler.
268    (The Borland utime function only works on Windows NT.)  */
269
270 #ifdef HACK_BCC_UTIME_BUG
271 int borland_utime(const char *path, const struct utimbuf *times)
272 {
273   int fd;
274   int res;
275   struct ftime ft;
276   struct tm *ptr_tm;
277
278   if ((fd = open (path, O_RDWR)) < 0)
279     return -1;
280
281   ptr_tm = localtime (&times->modtime);
282   ft.ft_tsec = ptr_tm->tm_sec >> 1;
283   ft.ft_min = ptr_tm->tm_min;
284   ft.ft_hour = ptr_tm->tm_hour;
285   ft.ft_day = ptr_tm->tm_mday;
286   ft.ft_month = ptr_tm->tm_mon + 1;
287   ft.ft_year = ptr_tm->tm_year - 80;
288   res = setftime (fd, &ft);
289   close (fd);
290   return res;
291 }
292 #endif