]> cygwin.com Git - cygwin-apps/setup.git/blob - ini.cc
* ini.cc (find_routine): Don't clear buffer it it's NULL.
[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 #include "filemanip.h"
47
48 #include "io_stream.h"
49
50 #include "threebar.h"
51
52 #include "rfc1738.h"
53
54 #include "IniDBBuilderPackage.h"
55 #include "compress.h"
56
57 extern ThreeBarProgressPage Progress;
58
59 unsigned int setup_timestamp = 0;
60 String setup_version;
61
62 extern int yyparse ();
63 /*extern int yydebug;*/
64
65 static char *error_buf = 0;
66 static int error_count = 0;
67
68 static int local_ini;
69
70 static IniDBBuilder *findBuilder;
71
72 static const char *ini_filename;
73
74 static void
75 find_routine (char *path, unsigned int fsize)
76 {
77 const char *setup_ini = trail (path, "\\setup.ini");
78
79 if (setup_ini == NULL)
80 return;
81
82 io_stream *ini_file = io_stream::open (String ("file://") + path, "rb");
83 if (!ini_file)
84 {
85 note (NULL, IDS_SETUPINI_MISSING, (String ("file://") + path).cstr_oneuse());
86 return;
87 }
88 else
89 log (LOG_BABBLE, String ("Found ini file - file://") + local_dir + "/" + path);
90
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);
98
99 /*yydebug = 1; */
100
101 ini_filename = path;
102 if (yyparse () || error_count > 0)
103 MessageBox (0, error_buf, error_count == 1 ? "Parse Error" : "Parse Errors", 0);
104 else
105 local_ini++;
106
107 if (error_buf)
108 *error_buf = '\0';
109 error_count = 0;
110
111 if (findBuilder->timestamp > setup_timestamp)
112 {
113 setup_timestamp = findBuilder->timestamp;
114 setup_version = findBuilder->version;
115 }
116 }
117
118 static int
119 do_local_ini (HWND owner)
120 {
121 local_ini = 0;
122 findBuilder = new IniDBBuilderPackage;
123 find (local_dir, find_routine);
124 delete findBuilder;
125 findBuilder = 0;
126 return local_ini;
127 }
128
129 static int
130 do_remote_ini (HWND owner)
131 {
132 size_t ini_count = 0;
133 IniDBBuilderPackage *aBuilder = new IniDBBuilderPackage;
134
135 for (size_t n = 1; n <= site_list.number (); n++)
136 {
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 }
146
147 if (!ini_file)
148 {
149 note (owner, IDS_SETUPINI_MISSING, site_list[n]->url.cstr_oneuse());
150 continue;
151 }
152
153 aBuilder->parse_mirror = site_list[n]->url;
154 ini_init (ini_file, aBuilder);
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 */
164 String const fp = String ("file://") + local_dir + "/" +
165 rfc1738_escape_part (site_list[n]->url) +
166 "/setup.ini";
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))
172 io_stream::remove (fp.cstr_oneuse());
173 delete inistream;
174 }
175 ++ini_count;
176 }
177 if (aBuilder->timestamp > setup_timestamp)
178 {
179 setup_timestamp = aBuilder->timestamp;
180 setup_version = aBuilder->version;
181 }
182 delete ini_file;
183 delete compressed_ini_file;
184 }
185 delete aBuilder;
186 return ini_count;
187 }
188
189 static void
190 do_ini_thread (HINSTANCE h, HWND owner)
191 {
192 size_t ini_count = 0;
193 if (source == IDC_SOURCE_CWD)
194 ini_count = do_local_ini (owner);
195 else
196 ini_count = do_remote_ini (owner);
197
198 if (ini_count == 0)
199 {
200 next_dialog = source == IDC_SOURCE_CWD ? IDD_S_FROM_CWD : IDD_SITE;
201 return;
202 }
203
204 if (get_root_dir ().cstr_oneuse())
205 {
206 io_stream::mkpath_p (PATH_TO_DIR, "cygfile:///etc/setup");
207
208 unsigned int old_timestamp = 0;
209 io_stream *ots =
210 io_stream::open ("cygfile:///etc/setup/timestamp", "rt");
211 if (ots)
212 {
213 char temp[20];
214 memset (temp, '\0', 20);
215 if (ots->read (temp, 19))
216 sscanf (temp, "%u", &old_timestamp);
217 delete ots;
218 if (old_timestamp && setup_timestamp
219 && (old_timestamp > setup_timestamp))
220 {
221 int yn = yesno (owner, IDS_OLD_SETUPINI);
222 if (yn == IDNO)
223 LogSingleton::GetInstance().exit (1);
224 }
225 }
226 if (setup_timestamp)
227 {
228 io_stream *nts =
229 io_stream::open ("cygfile:///etc/setup/timestamp", "wt");
230 if (nts)
231 {
232 char temp[20];
233 sprintf (temp, "%u", setup_timestamp);
234 nts->write (temp, strlen (temp));
235 delete nts;
236 }
237 }
238 }
239
240 msg ("setup_version is %s, our_version is %s", setup_version.size() ?
241 setup_version.cstr_oneuse() : "(null)",
242 version);
243 if (setup_version.size())
244 {
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)
249 note (owner, IDS_OLD_SETUP_VERSION, version, setup_version.cstr_oneuse());
250 }
251
252 next_dialog = IDD_CHOOSE;
253 }
254
255 static DWORD WINAPI
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
266 ExitThread(0);
267 }
268
269 static HANDLE context[2];
270
271 void
272 do_ini (HINSTANCE h, HWND owner)
273 {
274 context[0] = h;
275 context[1] = owner;
276
277 DWORD threadID;
278 CreateThread (NULL, 0, do_ini_thread_reflector, context, 0, &threadID);
279 }
280
281
282 extern int yylineno;
283 extern int yybol ();
284
285 extern int
286 yyerror (String const &s)
287 {
288 char buf[MAX_PATH + 1000];
289 int len;
290 sprintf (buf, "%s line %d: ", ini_filename, yylineno - yybol ());
291 sprintf (buf + strlen (buf), s.cstr_oneuse());
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++;
307 /* TODO: is return 0 correct? */
308 return 0;
309 }
310
311 extern "C" int fprintf (FILE * f, const char *s, ...);
312
313 static char stderrbuf[1000];
314
315 int
316 fprintf (FILE * f, const char *fmt, ...)
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);
325 strcat (stderrbuf, buf);
326 if (char *nl = strchr (stderrbuf, '\n'))
327 {
328 *nl = 0;
329 /*OutputDebugString (stderrbuf); */
330 MessageBox (0, buf, "Cygwin Setup", 0);
331 stderrbuf[0] = 0;
332 }
333
334 }
335 else
336 {
337 rv = vfprintf (f, fmt, args);
338 }
339 return rv;
340 }
This page took 0.103855 seconds and 5 git commands to generate.