]>
Commit | Line | Data |
---|---|---|
23c9e63c DD |
1 | /* |
2 | * Copyright (c) 2000, Red Hat, Inc. | |
3 | * | |
4 | * This program is free software; you can redistribute it and/or modify | |
5 | * it under the terms of the GNU General Public License as published by | |
6 | * the Free Software Foundation; either version 2 of the License, or | |
7 | * (at your option) any later version. | |
8 | * | |
9 | * A copy of the GNU General Public License can be found at | |
10 | * http://www.gnu.org/ | |
11 | * | |
12 | * Written by DJ Delorie <dj@cygnus.com> | |
13 | * | |
14 | */ | |
15 | ||
16 | /* The purpose of this file is to get and parse the setup.ini file | |
17 | from the mirror site. A few support routines for the bison and | |
18 | flex parsers are provided also. We check to see if this setup.ini | |
19 | is older than the one we used last time, and if so, warn the user. */ | |
20 | ||
b24c88b3 RC |
21 | #if 0 |
22 | static const char *cvsid = | |
23 | "\n%%% $Id$\n"; | |
24 | #endif | |
8507f105 | 25 | |
23c9e63c DD |
26 | #include "win32.h" |
27 | ||
28 | #include <stdio.h> | |
b11b49f3 | 29 | #include <stdlib.h> |
23c9e63c | 30 | #include <stdarg.h> |
ab57ceaa | 31 | #include <process.h> |
23c9e63c DD |
32 | |
33 | #include "ini.h" | |
34 | #include "resource.h" | |
3c054baf | 35 | #include "String++.h" |
23c9e63c DD |
36 | #include "state.h" |
37 | #include "geturl.h" | |
38 | #include "dialog.h" | |
39 | #include "msg.h" | |
89b1a15b | 40 | #include "log.h" |
13d27274 | 41 | #include "version.h" |
a351e48c | 42 | #include "mount.h" |
de6a1a64 RC |
43 | #include "site.h" |
44 | #include "rfc1738.h" | |
45 | #include "find.h" | |
0d4e0aad | 46 | #include "filemanip.h" |
23c9e63c | 47 | |
b24c88b3 RC |
48 | #include "io_stream.h" |
49 | ||
ab57ceaa | 50 | #include "threebar.h" |
58ee6135 RC |
51 | |
52 | #include "rfc1738.h" | |
b92028a4 | 53 | |
076654e7 | 54 | #include "IniDBBuilderPackage.h" |
3272d625 | 55 | #include "compress.h" |
b92028a4 | 56 | |
ab57ceaa RC |
57 | extern ThreeBarProgressPage Progress; |
58 | ||
23c9e63c | 59 | unsigned int setup_timestamp = 0; |
b92028a4 | 60 | String setup_version; |
23c9e63c | 61 | |
0af2d779 | 62 | extern int yyparse (); |
b11b49f3 DD |
63 | /*extern int yydebug;*/ |
64 | ||
65 | static char *error_buf = 0; | |
66 | static int error_count = 0; | |
23c9e63c | 67 | |
de6a1a64 | 68 | static int local_ini; |
23c9e63c | 69 | |
076654e7 RC |
70 | static IniDBBuilder *findBuilder; |
71 | ||
0d4e0aad CF |
72 | static const char *ini_filename; |
73 | ||
de6a1a64 RC |
74 | static void |
75 | find_routine (char *path, unsigned int fsize) | |
76 | { | |
0d4e0aad CF |
77 | const char *setup_ini = trail (path, "\\setup.ini"); |
78 | ||
79 | if (setup_ini == NULL) | |
de6a1a64 | 80 | return; |
0d4e0aad CF |
81 | |
82 | io_stream *ini_file = io_stream::open (String ("file://") + path, "rb"); | |
23c9e63c | 83 | if (!ini_file) |
b5b282c4 | 84 | { |
0d4e0aad | 85 | note (NULL, IDS_SETUPINI_MISSING, (String ("file://") + path).cstr_oneuse()); |
de6a1a64 | 86 | return; |
b5b282c4 | 87 | } |
3c054baf RC |
88 | else |
89 | log (LOG_BABBLE, String ("Found ini file - file://") + local_dir + "/" + path); | |
23c9e63c | 90 | |
0d4e0aad CF |
91 | unsigned pathprefix_len = setup_ini - path; |
92 | /* Copy leading part of path to temporary buffer and unescape it */ | |
93 | ||
94 | char path_prefix[pathprefix_len + 1]; | |
95 | strncpy (path_prefix, path, pathprefix_len); | |
96 | path_prefix[pathprefix_len] = '\0'; | |
97 | String mirror = rfc1738_unescape_part (path_prefix); | |
23c9e63c | 98 | |
b24c88b3 | 99 | /*yydebug = 1; */ |
b11b49f3 | 100 | |
0d4e0aad | 101 | ini_filename = path; |
b11b49f3 | 102 | if (yyparse () || error_count > 0) |
341988b9 | 103 | MessageBox (0, error_buf, error_count == 1 ? "Parse Error" : "Parse Errors", 0); |
dd3f7f9b | 104 | else |
de6a1a64 | 105 | local_ini++; |
0d4e0aad CF |
106 | |
107 | if (error_buf) | |
108 | *error_buf = '\0'; | |
109 | error_count = 0; | |
110 | ||
076654e7 | 111 | if (findBuilder->timestamp > setup_timestamp) |
b92028a4 | 112 | { |
076654e7 RC |
113 | setup_timestamp = findBuilder->timestamp; |
114 | setup_version = findBuilder->version; | |
b92028a4 | 115 | } |
de6a1a64 RC |
116 | } |
117 | ||
118 | static int | |
ab57ceaa | 119 | do_local_ini (HWND owner) |
de6a1a64 RC |
120 | { |
121 | local_ini = 0; | |
076654e7 | 122 | findBuilder = new IniDBBuilderPackage; |
de6a1a64 | 123 | find (local_dir, find_routine); |
076654e7 RC |
124 | delete findBuilder; |
125 | findBuilder = 0; | |
de6a1a64 RC |
126 | return local_ini; |
127 | } | |
128 | ||
129 | static int | |
ab57ceaa | 130 | do_remote_ini (HWND owner) |
de6a1a64 RC |
131 | { |
132 | size_t ini_count = 0; | |
076654e7 | 133 | IniDBBuilderPackage *aBuilder = new IniDBBuilderPackage; |
ab57ceaa | 134 | |
de6a1a64 | 135 | for (size_t n = 1; n <= site_list.number (); n++) |
dd3f7f9b | 136 | { |
3272d625 RC |
137 | io_stream *compressed_ini_file = |
138 | get_url_to_membuf (site_list[n]->url + "/setup.bz2", owner); | |
139 | io_stream *ini_file = 0; | |
140 | if (!compressed_ini_file) | |
141 | ini_file = get_url_to_membuf (site_list[n]->url + "/setup.ini", owner); | |
142 | else | |
143 | { | |
144 | ini_file = compress::decompress (compressed_ini_file); | |
145 | } | |
de6a1a64 RC |
146 | |
147 | if (!ini_file) | |
148 | { | |
3c054baf | 149 | note (owner, IDS_SETUPINI_MISSING, site_list[n]->url.cstr_oneuse()); |
de6a1a64 RC |
150 | continue; |
151 | } | |
152 | ||
076654e7 RC |
153 | aBuilder->parse_mirror = site_list[n]->url; |
154 | ini_init (ini_file, aBuilder); | |
de6a1a64 RC |
155 | |
156 | /*yydebug = 1; */ | |
157 | ||
158 | if (yyparse () || error_count > 0) | |
159 | MessageBox (0, error_buf, | |
160 | error_count == 1 ? "Parse Error" : "Parse Errors", 0); | |
161 | else | |
162 | { | |
163 | /* save known-good setup.ini locally */ | |
3c054baf RC |
164 | String const fp = String ("file://") + local_dir + "/" + |
165 | rfc1738_escape_part (site_list[n]->url) + | |
166 | "/setup.ini"; | |
de6a1a64 RC |
167 | io_stream::mkpath_p (PATH_TO_FILE, fp); |
168 | io_stream *inistream = io_stream::open (fp, "wb"); | |
169 | if (inistream && !ini_file->seek (0, IO_SEEK_SET)) | |
170 | { | |
171 | if (io_stream::copy (ini_file, inistream)) | |
3c054baf | 172 | io_stream::remove (fp.cstr_oneuse()); |
de6a1a64 RC |
173 | delete inistream; |
174 | } | |
5e0464a1 | 175 | ++ini_count; |
dd3f7f9b | 176 | } |
076654e7 | 177 | if (aBuilder->timestamp > setup_timestamp) |
b92028a4 | 178 | { |
076654e7 RC |
179 | setup_timestamp = aBuilder->timestamp; |
180 | setup_version = aBuilder->version; | |
b92028a4 | 181 | } |
3272d625 RC |
182 | delete ini_file; |
183 | delete compressed_ini_file; | |
dd3f7f9b | 184 | } |
076654e7 | 185 | delete aBuilder; |
de6a1a64 RC |
186 | return ini_count; |
187 | } | |
188 | ||
ab57ceaa RC |
189 | static void |
190 | do_ini_thread (HINSTANCE h, HWND owner) | |
de6a1a64 RC |
191 | { |
192 | size_t ini_count = 0; | |
193 | if (source == IDC_SOURCE_CWD) | |
ab57ceaa | 194 | ini_count = do_local_ini (owner); |
de6a1a64 | 195 | else |
ab57ceaa | 196 | ini_count = do_remote_ini (owner); |
de6a1a64 RC |
197 | |
198 | if (ini_count == 0) | |
199 | { | |
200 | next_dialog = source == IDC_SOURCE_CWD ? IDD_S_FROM_CWD : IDD_SITE; | |
201 | return; | |
202 | } | |
23c9e63c | 203 | |
3c054baf | 204 | if (get_root_dir ().cstr_oneuse()) |
23c9e63c | 205 | { |
b24c88b3 | 206 | io_stream::mkpath_p (PATH_TO_DIR, "cygfile:///etc/setup"); |
04d6e06b DD |
207 | |
208 | unsigned int old_timestamp = 0; | |
b24c88b3 RC |
209 | io_stream *ots = |
210 | io_stream::open ("cygfile:///etc/setup/timestamp", "rt"); | |
04d6e06b | 211 | if (ots) |
23c9e63c | 212 | { |
b24c88b3 RC |
213 | char temp[20]; |
214 | memset (temp, '\0', 20); | |
215 | if (ots->read (temp, 19)) | |
216 | sscanf (temp, "%u", &old_timestamp); | |
217 | delete ots; | |
04d6e06b DD |
218 | if (old_timestamp && setup_timestamp |
219 | && (old_timestamp > setup_timestamp)) | |
220 | { | |
ab57ceaa | 221 | int yn = yesno (owner, IDS_OLD_SETUPINI); |
04d6e06b | 222 | if (yn == IDNO) |
9f4a0c62 | 223 | LogSingleton::GetInstance().exit (1); |
04d6e06b | 224 | } |
23c9e63c | 225 | } |
04d6e06b | 226 | if (setup_timestamp) |
23c9e63c | 227 | { |
b24c88b3 RC |
228 | io_stream *nts = |
229 | io_stream::open ("cygfile:///etc/setup/timestamp", "wt"); | |
04d6e06b DD |
230 | if (nts) |
231 | { | |
b24c88b3 RC |
232 | char temp[20]; |
233 | sprintf (temp, "%u", setup_timestamp); | |
234 | nts->write (temp, strlen (temp)); | |
235 | delete nts; | |
04d6e06b | 236 | } |
23c9e63c DD |
237 | } |
238 | } | |
239 | ||
b92028a4 RC |
240 | msg ("setup_version is %s, our_version is %s", setup_version.size() ? |
241 | setup_version.cstr_oneuse() : "(null)", | |
b24c88b3 | 242 | version); |
b92028a4 | 243 | if (setup_version.size()) |
13d27274 | 244 | { |
3c054baf RC |
245 | String ini_version = canonicalize_version (setup_version); |
246 | String our_version = canonicalize_version (version); | |
247 | // XXX useversion < operator | |
248 | if (our_version.compare (ini_version) < 0) | |
b92028a4 | 249 | note (owner, IDS_OLD_SETUP_VERSION, version, setup_version.cstr_oneuse()); |
13d27274 DD |
250 | } |
251 | ||
f6a81f69 | 252 | next_dialog = IDD_CHOOSE; |
23c9e63c DD |
253 | } |
254 | ||
45e01f23 | 255 | static DWORD WINAPI |
ab57ceaa RC |
256 | do_ini_thread_reflector(void* p) |
257 | { | |
258 | HANDLE *context; | |
259 | context = (HANDLE*)p; | |
260 | ||
261 | do_ini_thread((HINSTANCE)context[0], (HWND)context[1]); | |
262 | ||
263 | // Tell the progress page that we're done downloading | |
264 | Progress.PostMessage(WM_APP_SETUP_INI_DOWNLOAD_COMPLETE, 0, next_dialog); | |
265 | ||
45e01f23 | 266 | ExitThread(0); |
ab57ceaa RC |
267 | } |
268 | ||
269 | static HANDLE context[2]; | |
270 | ||
271 | void | |
272 | do_ini (HINSTANCE h, HWND owner) | |
273 | { | |
45e01f23 RC |
274 | context[0] = h; |
275 | context[1] = owner; | |
276 | ||
277 | DWORD threadID; | |
278 | CreateThread (NULL, 0, do_ini_thread_reflector, context, 0, &threadID); | |
ab57ceaa RC |
279 | } |
280 | ||
281 | ||
b11b49f3 | 282 | extern int yylineno; |
0d4e0aad | 283 | extern int yybol (); |
b11b49f3 | 284 | |
6391823e RC |
285 | extern int |
286 | yyerror (String const &s) | |
23c9e63c | 287 | { |
0d4e0aad | 288 | char buf[MAX_PATH + 1000]; |
b11b49f3 | 289 | int len; |
0d4e0aad | 290 | sprintf (buf, "%s line %d: ", ini_filename, yylineno - yybol ()); |
6391823e | 291 | sprintf (buf + strlen (buf), s.cstr_oneuse()); |
b11b49f3 DD |
292 | OutputDebugString (buf); |
293 | if (error_buf) | |
294 | { | |
295 | strcat (error_buf, "\n"); | |
296 | len = strlen (error_buf) + strlen (buf) + 5; | |
297 | error_buf = (char *) realloc (error_buf, len); | |
298 | strcat (error_buf, buf); | |
299 | } | |
300 | else | |
301 | { | |
302 | len = strlen (buf) + 5; | |
303 | error_buf = (char *) malloc (len); | |
304 | strcpy (error_buf, buf); | |
305 | } | |
306 | error_count++; | |
b24c88b3 RC |
307 | /* TODO: is return 0 correct? */ |
308 | return 0; | |
23c9e63c DD |
309 | } |
310 | ||
b24c88b3 | 311 | extern "C" int fprintf (FILE * f, const char *s, ...); |
23c9e63c | 312 | |
b11b49f3 DD |
313 | static char stderrbuf[1000]; |
314 | ||
23c9e63c | 315 | int |
b24c88b3 | 316 | fprintf (FILE * f, const char *fmt, ...) |
23c9e63c DD |
317 | { |
318 | char buf[1000]; | |
319 | int rv; | |
320 | va_list args; | |
321 | va_start (args, fmt); | |
322 | if (f == stderr) | |
323 | { | |
324 | rv = vsprintf (buf, fmt, args); | |
b11b49f3 DD |
325 | strcat (stderrbuf, buf); |
326 | if (char *nl = strchr (stderrbuf, '\n')) | |
327 | { | |
328 | *nl = 0; | |
b24c88b3 | 329 | /*OutputDebugString (stderrbuf); */ |
b11b49f3 DD |
330 | MessageBox (0, buf, "Cygwin Setup", 0); |
331 | stderrbuf[0] = 0; | |
332 | } | |
42bf5b92 | 333 | |
23c9e63c DD |
334 | } |
335 | else | |
336 | { | |
337 | rv = vfprintf (f, fmt, args); | |
338 | } | |
339 | return rv; | |
340 | } |