]> cygwin.com Git - cygwin-apps/setup.git/blob - ini.cc
2002-05-04 Robert Collins <rbtcollins@hotmail.com>
[cygwin-apps/setup.git] / ini.cc
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
21 #if 0
22 static const char *cvsid =
23 "\n%%% $Id$\n";
24 #endif
25
26 #include "win32.h"
27
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <stdarg.h>
31 #include <process.h>
32
33 #include "ini.h"
34 #include "resource.h"
35 #include "String++.h"
36 #include "state.h"
37 #include "geturl.h"
38 #include "dialog.h"
39 #include "msg.h"
40 #include "log.h"
41 #include "version.h"
42 #include "mount.h"
43 #include "site.h"
44 #include "rfc1738.h"
45 #include "find.h"
46
47 #include "io_stream.h"
48
49 #include "threebar.h"
50
51 #include "rfc1738.h"
52
53 #include "IniDBBuilderPackage.h"
54
55 extern ThreeBarProgressPage Progress;
56
57 unsigned int setup_timestamp = 0;
58 String setup_version;
59
60 extern int yyparse ();
61 /*extern int yydebug;*/
62
63 static char *error_buf = 0;
64 static int error_count = 0;
65
66 static int local_ini;
67
68 static IniDBBuilder *findBuilder;
69
70 static void
71 find_routine (char *path, unsigned int fsize)
72 {
73 if (!strstr (path, "setup.ini") )
74 return;
75 io_stream *ini_file = io_stream::open (String ("file://") + local_dir + "/" +
76 path, "rb");
77 if (!ini_file)
78 {
79 note (NULL, IDS_SETUPINI_MISSING, (String ("file://") + local_dir + "/" +
80 path).cstr_oneuse());
81 return;
82 }
83 else
84 log (LOG_BABBLE, String ("Found ini file - file://") + local_dir + "/" + path);
85
86 /* Attempt to unescape the string */
87 path[strlen(path) -10] = '\0';
88 String mirror = rfc1738_unescape_part (path);
89 findBuilder->parse_mirror = mirror;
90 ini_init (ini_file, findBuilder);
91
92 /*yydebug = 1; */
93
94 if (yyparse () || error_count > 0)
95 MessageBox (0, error_buf, error_count == 1 ? "Parse Error" : "Parse Errors", 0);
96 else
97 local_ini++;
98 if (findBuilder->timestamp > setup_timestamp)
99 {
100 setup_timestamp = findBuilder->timestamp;
101 setup_version = findBuilder->version;
102 }
103 }
104
105 static int
106 do_local_ini (HWND owner)
107 {
108 local_ini = 0;
109 findBuilder = new IniDBBuilderPackage;
110 find (local_dir, find_routine);
111 delete findBuilder;
112 findBuilder = 0;
113 return local_ini;
114 }
115
116 static int
117 do_remote_ini (HWND owner)
118 {
119 size_t ini_count = 0;
120 IniDBBuilderPackage *aBuilder = new IniDBBuilderPackage;
121
122 for (size_t n = 1; n <= site_list.number (); n++)
123 {
124 io_stream *ini_file =
125 get_url_to_membuf (site_list[n]->url + "/setup.ini", owner);
126
127 if (!ini_file)
128 {
129 note (owner, IDS_SETUPINI_MISSING, site_list[n]->url.cstr_oneuse());
130 continue;
131 }
132
133 aBuilder->parse_mirror = site_list[n]->url;
134 ini_init (ini_file, aBuilder);
135
136 /*yydebug = 1; */
137
138 if (yyparse () || error_count > 0)
139 MessageBox (0, error_buf,
140 error_count == 1 ? "Parse Error" : "Parse Errors", 0);
141 else
142 {
143 /* save known-good setup.ini locally */
144 String const fp = String ("file://") + local_dir + "/" +
145 rfc1738_escape_part (site_list[n]->url) +
146 "/setup.ini";
147 io_stream::mkpath_p (PATH_TO_FILE, fp);
148 io_stream *inistream = io_stream::open (fp, "wb");
149 if (inistream && !ini_file->seek (0, IO_SEEK_SET))
150 {
151 if (io_stream::copy (ini_file, inistream))
152 io_stream::remove (fp.cstr_oneuse());
153 delete ini_file;
154 delete inistream;
155 }
156 ++ini_count;
157 }
158 if (aBuilder->timestamp > setup_timestamp)
159 {
160 setup_timestamp = aBuilder->timestamp;
161 setup_version = aBuilder->version;
162 }
163 }
164 delete aBuilder;
165 return ini_count;
166 }
167
168 static void
169 do_ini_thread (HINSTANCE h, HWND owner)
170 {
171 size_t ini_count = 0;
172 if (source == IDC_SOURCE_CWD)
173 ini_count = do_local_ini (owner);
174 else
175 ini_count = do_remote_ini (owner);
176
177 if (ini_count == 0)
178 {
179 next_dialog = source == IDC_SOURCE_CWD ? IDD_S_FROM_CWD : IDD_SITE;
180 return;
181 }
182
183 if (get_root_dir ().cstr_oneuse())
184 {
185 io_stream::mkpath_p (PATH_TO_DIR, "cygfile:///etc/setup");
186
187 unsigned int old_timestamp = 0;
188 io_stream *ots =
189 io_stream::open ("cygfile:///etc/setup/timestamp", "rt");
190 if (ots)
191 {
192 char temp[20];
193 memset (temp, '\0', 20);
194 if (ots->read (temp, 19))
195 sscanf (temp, "%u", &old_timestamp);
196 delete ots;
197 if (old_timestamp && setup_timestamp
198 && (old_timestamp > setup_timestamp))
199 {
200 int yn = yesno (owner, IDS_OLD_SETUPINI);
201 if (yn == IDNO)
202 exit_setup (1);
203 }
204 }
205 if (setup_timestamp)
206 {
207 io_stream *nts =
208 io_stream::open ("cygfile:///etc/setup/timestamp", "wt");
209 if (nts)
210 {
211 char temp[20];
212 sprintf (temp, "%u", setup_timestamp);
213 nts->write (temp, strlen (temp));
214 delete nts;
215 }
216 }
217 }
218
219 msg ("setup_version is %s, our_version is %s", setup_version.size() ?
220 setup_version.cstr_oneuse() : "(null)",
221 version);
222 if (setup_version.size())
223 {
224 String ini_version = canonicalize_version (setup_version);
225 String our_version = canonicalize_version (version);
226 // XXX useversion < operator
227 if (our_version.compare (ini_version) < 0)
228 note (owner, IDS_OLD_SETUP_VERSION, version, setup_version.cstr_oneuse());
229 }
230
231 next_dialog = IDD_CHOOSER;
232 }
233
234 static DWORD WINAPI
235 do_ini_thread_reflector(void* p)
236 {
237 HANDLE *context;
238 context = (HANDLE*)p;
239
240 do_ini_thread((HINSTANCE)context[0], (HWND)context[1]);
241
242 // Tell the progress page that we're done downloading
243 Progress.PostMessage(WM_APP_SETUP_INI_DOWNLOAD_COMPLETE, 0, next_dialog);
244
245 ExitThread(0);
246 }
247
248 static HANDLE context[2];
249
250 void
251 do_ini (HINSTANCE h, HWND owner)
252 {
253 context[0] = h;
254 context[1] = owner;
255
256 DWORD threadID;
257 CreateThread (NULL, 0, do_ini_thread_reflector, context, 0, &threadID);
258 }
259
260
261 extern int yylineno;
262
263 extern int
264 yyerror (String const &s)
265 {
266 char buf[1000];
267 int len;
268 sprintf (buf, "setup.ini line %d: ", yylineno);
269 sprintf (buf + strlen (buf), s.cstr_oneuse());
270 OutputDebugString (buf);
271 if (error_buf)
272 {
273 strcat (error_buf, "\n");
274 len = strlen (error_buf) + strlen (buf) + 5;
275 error_buf = (char *) realloc (error_buf, len);
276 strcat (error_buf, buf);
277 }
278 else
279 {
280 len = strlen (buf) + 5;
281 error_buf = (char *) malloc (len);
282 strcpy (error_buf, buf);
283 }
284 error_count++;
285 /* TODO: is return 0 correct? */
286 return 0;
287 }
288
289 extern "C" int fprintf (FILE * f, const char *s, ...);
290
291 static char stderrbuf[1000];
292
293 int
294 fprintf (FILE * f, const char *fmt, ...)
295 {
296 char buf[1000];
297 int rv;
298 va_list args;
299 va_start (args, fmt);
300 if (f == stderr)
301 {
302 rv = vsprintf (buf, fmt, args);
303 strcat (stderrbuf, buf);
304 if (char *nl = strchr (stderrbuf, '\n'))
305 {
306 *nl = 0;
307 /*OutputDebugString (stderrbuf); */
308 MessageBox (0, buf, "Cygwin Setup", 0);
309 stderrbuf[0] = 0;
310 }
311
312 }
313 else
314 {
315 rv = vfprintf (f, fmt, args);
316 }
317 return rv;
318 }
This page took 0.04923 seconds and 5 git commands to generate.