]> sjero.net Git - wget/blob - src/mswindows.c
[svn] Include <netdb.h> where h_errno is used. Likewise for <errno.h> and errno.
[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 Wget.
5
6 This program 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 This program 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 this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
19
20 /* #### Someone document these functions!  */
21
22 #include <config.h>
23
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <winsock.h>
27 #include <string.h>
28 #include <assert.h>
29 #include <errno.h>
30
31 #include "wget.h"
32 #include "url.h"
33
34 #ifndef errno
35 extern int errno;
36 #endif
37
38 char *argv0;
39
40 /* Defined in log.c.  */
41 void redirect_output (const char *);
42
43 static int windows_nt_p;
44
45
46 /* Emulation of Unix sleep.  */
47 unsigned int
48 sleep (unsigned seconds)
49 {
50   Sleep (1000 * seconds);
51   /* Unix sleep() is interruptible.  To make it semi-usable, it
52      returns a value that says how much it "really" slept, or some
53      junk like that.  Ignore it.  */
54   return 0U;
55 }
56
57 static char *
58 read_registry (HKEY hkey, char *subkey, char *valuename, char *buf, int *len)
59 {
60   HKEY result;
61   DWORD size = *len;
62   DWORD type = REG_SZ;
63   if (RegOpenKeyEx (hkey, subkey, NULL, KEY_READ, &result) != ERROR_SUCCESS)
64     return NULL;
65   if (RegQueryValueEx (result, valuename, NULL, &type, buf, &size) != ERROR_SUCCESS)
66     buf = NULL;
67   *len = size;
68   RegCloseKey (result);
69   return buf;
70 }
71
72 char *
73 pwd_cuserid (char *where)
74 {
75   char buf[32], *ptr;
76   int len = sizeof (buf);
77   if (GetUserName (buf, (LPDWORD) &len) == TRUE)
78     {
79       ;
80     }
81   else if (!!(ptr = getenv ("USERNAME")))
82     {
83       strcpy (buf, ptr);
84     }
85   else if (!read_registry (HKEY_LOCAL_MACHINE, "Network\\Logon",
86                           "username", buf, &len))
87     {
88       return NULL;
89     }
90   if (where)
91     {
92       strncpy (where, buf, len);
93       return where;
94     }
95   return xstrdup (buf);
96 }
97
98 void
99 windows_main_junk (int *argc, char **argv, char **exec_name)
100 {
101   char *p;
102
103   argv0 = argv[0];
104
105   /* Remove .EXE from filename if it has one.  */
106   *exec_name = xstrdup (*exec_name);
107   p = strrchr (*exec_name, '.');
108   if (p)
109     *p = '\0';
110 }
111 \f
112 /* Winsock stuff. */
113
114 static void
115 ws_cleanup (void)
116 {
117   WSACleanup ();
118 }
119
120 static void
121 ws_hangup (void)
122 {
123   redirect_output (_("\n\
124 CTRL+Break received, redirecting output to `%s'.\n\
125 Execution continued in background.\n\
126 You may stop Wget by pressing CTRL+ALT+DELETE.\n"));
127 }
128
129 void
130 fork_to_background (void)
131 {
132   /* Whether we arrange our own version of opt.lfilename here.  */
133   int changedp = 0;
134
135   if (!opt.lfilename)
136     {
137       opt.lfilename = unique_name (DEFAULT_LOGFILE);
138       changedp = 1;
139     }
140   printf (_("Continuing in background.\n"));
141   if (changedp)
142     printf (_("Output will be written to `%s'.\n"), opt.lfilename);
143
144   ws_hangup ();
145   if (!windows_nt_p)
146     FreeConsole ();
147 }
148
149 static BOOL WINAPI
150 ws_handler (DWORD dwEvent)
151 {
152   switch (dwEvent)
153     {
154 #ifdef CTRLC_BACKGND
155     case CTRL_C_EVENT:
156 #endif
157 #ifdef CTRLBREAK_BACKGND
158     case CTRL_BREAK_EVENT:
159 #endif
160       fork_to_background ();
161       break;
162     case CTRL_SHUTDOWN_EVENT:
163     case CTRL_CLOSE_EVENT:
164     case CTRL_LOGOFF_EVENT:
165     default:
166       WSACleanup ();
167       return FALSE;
168     }
169   return TRUE;
170 }
171
172 void
173 ws_changetitle (char *url, int nurl)
174 {
175   char *title_buf;
176   if (!nurl)
177     return;
178
179   title_buf = (char *)xmalloc (strlen (url) + 20);
180   sprintf (title_buf, "Wget %s%s", url, nurl == 1 ? "" : " ...");
181   /* #### What are the semantics of SetConsoleTitle?  Will it free the
182      given memory later?  */
183   SetConsoleTitle (title_buf);
184 }
185
186 char *
187 ws_mypath (void)
188 {
189   static char *wspathsave;
190   char *buffer;
191   int rrr;
192   char *ptr;
193
194   if (wspathsave)
195     {
196       return wspathsave;
197     }
198   ptr = strrchr (argv0, '\\');
199   if (ptr)
200     {
201       *(ptr + 1) = '\0';
202       wspathsave = (char*) xmalloc (strlen(argv0)+1);
203       strcpy (wspathsave, argv0);
204       return wspathsave;
205     }
206   buffer = (char*) xmalloc (256);
207   rrr = SearchPath (NULL, argv0, strchr (argv0, '.') ? NULL : ".EXE",
208                     256, buffer, &ptr);
209   if (rrr && rrr <= 256)
210     {
211       *ptr = '\0';
212       wspathsave = (char*) xmalloc (strlen(buffer)+1);
213       strcpy (wspathsave, buffer);
214       return wspathsave;
215     }
216   xfree (buffer);
217   return NULL;
218 }
219
220 void
221 ws_help (const char *name)
222 {
223   char *mypath = ws_mypath ();
224
225   if (mypath)
226     {
227       struct stat sbuf;
228       char *buf = (char *)alloca (strlen (mypath) + strlen (name) + 4 + 1);
229       sprintf (buf, "%s%s.HLP", mypath, name);
230       if (stat (buf, &sbuf) == 0) 
231         {
232           printf (_("Starting WinHelp %s\n"), buf);
233           WinHelp (NULL, buf, HELP_INDEX, NULL);
234         }
235       else
236         {
237           printf ("%s: %s\n", buf, strerror (errno));
238         }
239     }
240 }
241
242 void
243 ws_startup (void)
244 {
245   WORD requested;
246   WSADATA data;
247   int err;
248   OSVERSIONINFO os;
249
250   if (GetVersionEx (&os) == TRUE
251       && os.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS)
252     windows_nt_p = 1;
253
254   requested = MAKEWORD (1, 1);
255   err = WSAStartup (requested, &data);
256
257   if (err != 0)
258     {
259       fprintf (stderr, _("%s: Couldn't find usable socket driver.\n"),
260                exec_name);
261       exit (1);
262     }
263
264   if (LOBYTE (requested) < 1 || (LOBYTE (requested) == 1 &&
265                                 HIBYTE (requested) < 1))
266     {
267       fprintf (stderr, _("%s: Couldn't find usable socket driver.\n"),
268                exec_name);
269       WSACleanup ();
270       exit (1);
271     }
272   atexit (ws_cleanup);
273   SetConsoleCtrlHandler (ws_handler, TRUE);
274 }