]> cygwin.com Git - cygwin-apps/setup.git/blob - ini.cc
* site.cc (do_download_site_info_thread): Correct spelling error.
[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 "IniParseFindVisitor.h"
47 #include "IniParseFeedback.h"
48 //#include "filemanip.h"
49
50 #include "io_stream.h"
51
52 #include "threebar.h"
53
54 #include "rfc1738.h"
55
56 #include "IniDBBuilderPackage.h"
57 #include "compress.h"
58
59 extern ThreeBarProgressPage Progress;
60
61 unsigned int setup_timestamp = 0;
62 String setup_version;
63
64 extern int yyparse ();
65 /*extern int yydebug;*/
66
67 static char *error_buf = 0;
68 static int error_count = 0;
69
70 static const char *ini_filename;
71
72 class GuiParseFeedback : public IniParseFeedback
73 {
74 public:
75 GuiParseFeedback () : lastpct (0)
76 {
77 Progress.SetText2 ("");
78 Progress.SetText3 ("");
79 Progress.SetText4 ("Progress:");
80 }
81 virtual void progress(unsigned long const pos, unsigned long const max)
82 {
83 if (!max)
84 /* length not known or eof */
85 return;
86 if (lastpct == 100)
87 /* rounding down should mean this only ever fires once */
88 lastpct = 0;
89 if (pos * 100 / max > lastpct)
90 {
91 lastpct = pos * 100 / max;
92 log (LOG_BABBLE, String (lastpct) + "% (" + String (pos) + " of " + String (max) + " bytes of ini file read");
93 }
94 Progress.SetBar1(pos, max);
95 }
96 virtual void iniName (String const &name)
97 {
98 Progress.SetText1 ((String ("Parsing ini file \"") + name + "\"").cstr_oneuse());
99 }
100 virtual void babble(String const &message)const
101 {
102 log (LOG_BABBLE, message);
103 }
104 virtual void warning (String const &message)const
105 {
106 MessageBox (0, message.cstr_oneuse(), "Warning", 0);
107 }
108 virtual void error(String const &message)const
109 {
110 MessageBox (0, message.cstr_oneuse(), "Error parsing", 0);
111 }
112 virtual ~ GuiParseFeedback ()
113 {
114 Progress.SetText4("Package:");
115 }
116 private:
117 unsigned char lastpct;
118 };
119
120 static int
121 do_local_ini (HWND owner)
122 {
123 GuiParseFeedback myFeedback;
124 IniDBBuilderPackage findBuilder(myFeedback);
125 IniParseFindVisitor myVisitor (findBuilder, local_dir, myFeedback);
126 Find (local_dir).accept(myVisitor);
127 setup_timestamp = myVisitor.timeStamp();
128 setup_version = myVisitor.version();
129 return myVisitor.iniCount();
130 }
131
132 static int
133 do_remote_ini (HWND owner)
134 {
135 size_t ini_count = 0;
136 GuiParseFeedback myFeedback;
137 IniDBBuilderPackage aBuilder(myFeedback);
138
139 for (SiteList::const_iterator n = site_list.begin();
140 n != site_list.end(); ++n)
141 {
142 io_stream *compressed_ini_file =
143 get_url_to_membuf (n->url + "/setup.bz2", owner);
144 io_stream *ini_file = 0;
145 if (!compressed_ini_file)
146 ini_file = get_url_to_membuf (n->url + "/setup.ini", owner);
147 else
148 {
149 ini_file = compress::decompress (compressed_ini_file);
150 }
151
152 if (!ini_file)
153 {
154 note (owner, IDS_SETUPINI_MISSING, n->url.cstr_oneuse());
155 continue;
156 }
157
158 if (compressed_ini_file)
159 myFeedback.iniName (n->url + "/setup.bz2");
160 else
161 myFeedback.iniName (n->url + "/setup.ini");
162
163 aBuilder.parse_mirror = n->url;
164 ini_init (ini_file, &aBuilder, myFeedback);
165
166 /*yydebug = 1; */
167
168 if (yyparse () || error_count > 0)
169 MessageBox (0, error_buf,
170 error_count == 1 ? "Parse Error" : "Parse Errors", 0);
171 else
172 {
173 /* save known-good setup.ini locally */
174 String const fp = String ("file://") + local_dir + "/" +
175 rfc1738_escape_part (n->url) +
176 "/setup.ini";
177 io_stream::mkpath_p (PATH_TO_FILE, fp);
178 io_stream *inistream = io_stream::open (fp, "wb");
179 if (inistream)
180 {
181 if (compressed_ini_file)
182 {
183 delete ini_file;
184 compressed_ini_file->seek (0, IO_SEEK_SET);
185 ini_file = compress::decompress (compressed_ini_file);
186 }
187 else
188 ini_file->seek (0, IO_SEEK_SET);
189 if (io_stream::copy (ini_file, inistream))
190 io_stream::remove (fp);
191 delete inistream;
192 }
193 ++ini_count;
194 }
195 if (aBuilder.timestamp > setup_timestamp)
196 {
197 setup_timestamp = aBuilder.timestamp;
198 setup_version = aBuilder.version;
199 }
200 delete ini_file;
201 delete compressed_ini_file;
202 }
203 return ini_count;
204 }
205
206 static void
207 do_ini_thread (HINSTANCE h, HWND owner)
208 {
209 size_t ini_count = 0;
210 if (source == IDC_SOURCE_CWD)
211 ini_count = do_local_ini (owner);
212 else
213 ini_count = do_remote_ini (owner);
214
215 if (ini_count == 0)
216 {
217 next_dialog = source == IDC_SOURCE_CWD ? IDD_S_FROM_CWD : IDD_SITE;
218 return;
219 }
220
221 if (get_root_dir ().cstr_oneuse())
222 {
223 io_stream::mkpath_p (PATH_TO_DIR, "cygfile:///etc/setup");
224
225 unsigned int old_timestamp = 0;
226 io_stream *ots =
227 io_stream::open ("cygfile:///etc/setup/timestamp", "rt");
228 if (ots)
229 {
230 char temp[20];
231 memset (temp, '\0', 20);
232 if (ots->read (temp, 19))
233 sscanf (temp, "%u", &old_timestamp);
234 delete ots;
235 if (old_timestamp && setup_timestamp
236 && (old_timestamp > setup_timestamp))
237 {
238 int yn = yesno (owner, IDS_OLD_SETUPINI);
239 if (yn == IDNO)
240 LogSingleton::GetInstance().exit (1);
241 }
242 }
243 if (setup_timestamp)
244 {
245 io_stream *nts =
246 io_stream::open ("cygfile:///etc/setup/timestamp", "wt");
247 if (nts)
248 {
249 char temp[20];
250 sprintf (temp, "%u", setup_timestamp);
251 nts->write (temp, strlen (temp));
252 delete nts;
253 }
254 }
255 }
256
257 msg ("setup_version is %s, our_version is %s", setup_version.size() ?
258 setup_version.cstr_oneuse() : "(null)",
259 version);
260 if (setup_version.size())
261 {
262 String ini_version = canonicalize_version (setup_version);
263 String our_version = canonicalize_version (version);
264 // XXX useversion < operator
265 if (our_version.compare (ini_version) < 0)
266 note (owner, IDS_OLD_SETUP_VERSION, version, setup_version.cstr_oneuse());
267 }
268
269 next_dialog = IDD_CHOOSE;
270 }
271
272 static DWORD WINAPI
273 do_ini_thread_reflector(void* p)
274 {
275 HANDLE *context;
276 context = (HANDLE*)p;
277
278 do_ini_thread((HINSTANCE)context[0], (HWND)context[1]);
279
280 // Tell the progress page that we're done downloading
281 Progress.PostMessage(WM_APP_SETUP_INI_DOWNLOAD_COMPLETE, 0, next_dialog);
282
283 ExitThread(0);
284 }
285
286 static HANDLE context[2];
287
288 void
289 do_ini (HINSTANCE h, HWND owner)
290 {
291 context[0] = h;
292 context[1] = owner;
293
294 DWORD threadID;
295 CreateThread (NULL, 0, do_ini_thread_reflector, context, 0, &threadID);
296 }
297
298
299 extern int yylineno;
300 extern int yybol ();
301
302 extern int
303 yyerror (String const &s)
304 {
305 char buf[MAX_PATH + 1000];
306 int len;
307 sprintf (buf, "%s line %d: ", ini_filename, yylineno - yybol ());
308 sprintf (buf + strlen (buf), s.cstr_oneuse());
309 OutputDebugString (buf);
310 if (error_buf)
311 {
312 strcat (error_buf, "\n");
313 len = strlen (error_buf) + strlen (buf) + 5;
314 error_buf = (char *) realloc (error_buf, len);
315 strcat (error_buf, buf);
316 }
317 else
318 {
319 len = strlen (buf) + 5;
320 error_buf = (char *) malloc (len);
321 strcpy (error_buf, buf);
322 }
323 error_count++;
324 /* TODO: is return 0 correct? */
325 return 0;
326 }
327
328 extern "C" int fprintf (FILE * f, const char *s, ...);
329
330 static char stderrbuf[1000];
331
332 int
333 fprintf (FILE * f, const char *fmt, ...)
334 {
335 char buf[1000];
336 int rv;
337 va_list args;
338 va_start (args, fmt);
339 if (f == stderr)
340 {
341 rv = vsnprintf (buf, 1000, fmt, args);
342 /* todo check here for overflows too */
343 strcat (stderrbuf, buf);
344 if (char *nl = strchr (stderrbuf, '\n'))
345 {
346 *nl = 0;
347 /*OutputDebugString (stderrbuf); */
348 MessageBox (0, buf, "Cygwin Setup", 0);
349 stderrbuf[0] = 0;
350 }
351
352 }
353 else
354 {
355 rv = vfprintf (f, fmt, args);
356 }
357 return rv;
358 }
This page took 0.049716 seconds and 5 git commands to generate.