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