]> cygwin.com Git - cygwin-apps/setup.git/blame - ini.cc
2007-02-20 Brian Dessent <brian@dessent.net>
[cygwin-apps/setup.git] / ini.cc
CommitLineData
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
22static const char *cvsid =
23 "\n%%% $Id$\n";
24#endif
8507f105 25
2b734ec7
MB
26#include "ini.h"
27
946198be 28#include "csu_util/rfc1738.h"
2b734ec7
MB
29#include "csu_util/version_compare.h"
30
31#include "setup_version.h"
23c9e63c 32#include "win32.h"
a77b6167 33#include "LogSingleton.h"
23c9e63c
DD
34
35#include <stdio.h>
b11b49f3 36#include <stdlib.h>
23c9e63c 37#include <stdarg.h>
ab57ceaa 38#include <process.h>
23c9e63c 39
23c9e63c 40#include "resource.h"
23c9e63c
DD
41#include "state.h"
42#include "geturl.h"
43#include "dialog.h"
44#include "msg.h"
a351e48c 45#include "mount.h"
de6a1a64 46#include "site.h"
de6a1a64 47#include "find.h"
b401ef47 48#include "IniParseFindVisitor.h"
67829ce0 49#include "IniParseFeedback.h"
23c9e63c 50
b24c88b3
RC
51#include "io_stream.h"
52
ab57ceaa 53#include "threebar.h"
58ee6135 54
076654e7 55#include "IniDBBuilderPackage.h"
3272d625 56#include "compress.h"
072fb49a 57#include "Exception.h"
b92028a4 58
ab57ceaa
RC
59extern ThreeBarProgressPage Progress;
60
23c9e63c 61unsigned int setup_timestamp = 0;
fd93eff9 62std::string ini_setup_version;
23c9e63c 63
0af2d779 64extern int yyparse ();
b11b49f3
DD
65/*extern int yydebug;*/
66
67static char *error_buf = 0;
68static int error_count = 0;
23c9e63c 69
0d4e0aad
CF
70static const char *ini_filename;
71
67829ce0
RC
72class GuiParseFeedback : public IniParseFeedback
73{
74public:
aa1e3b4d
RC
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;
a77b6167
MB
92 log (LOG_BABBLE) << lastpct << "% (" << pos << " of " << max
93 << " bytes of ini file read)" << endLog;
aa1e3b4d
RC
94 }
95 Progress.SetBar1(pos, max);
96 }
fd93eff9 97 virtual void iniName (const std::string& name)
aa1e3b4d 98 {
fd93eff9 99 Progress.SetText1 (("Parsing ini file \"" + name + "\"").c_str());
aa1e3b4d 100 }
fd93eff9 101 virtual void babble(const std::string& message)const
67829ce0 102 {
a77b6167 103 log (LOG_BABBLE) << message << endLog;
67829ce0 104 }
fd93eff9 105 virtual void warning (const std::string& message)const
67829ce0 106 {
d2a3615c 107 MessageBox (0, message.c_str(), "Warning", 0);
67829ce0 108 }
fd93eff9 109 virtual void error(const std::string& message)const
67829ce0 110 {
d2a3615c 111 MessageBox (0, message.c_str(), "Error parsing", 0);
67829ce0
RC
112 }
113 virtual ~ GuiParseFeedback ()
114 {
aa1e3b4d 115 Progress.SetText4("Package:");
67829ce0 116 }
aa1e3b4d 117private:
b4cf6208 118 unsigned int lastpct;
67829ce0
RC
119};
120
de6a1a64 121static int
ab57ceaa 122do_local_ini (HWND owner)
de6a1a64 123{
67829ce0
RC
124 GuiParseFeedback myFeedback;
125 IniDBBuilderPackage findBuilder(myFeedback);
126 IniParseFindVisitor myVisitor (findBuilder, local_dir, myFeedback);
b401ef47
RC
127 Find (local_dir).accept(myVisitor);
128 setup_timestamp = myVisitor.timeStamp();
2b734ec7 129 ini_setup_version = myVisitor.version();
b401ef47 130 return myVisitor.iniCount();
de6a1a64
RC
131}
132
133static int
ab57ceaa 134do_remote_ini (HWND owner)
de6a1a64
RC
135{
136 size_t ini_count = 0;
67829ce0
RC
137 GuiParseFeedback myFeedback;
138 IniDBBuilderPackage aBuilder(myFeedback);
aa1e3b4d 139
3bac26a1
RC
140 for (SiteList::const_iterator n = site_list.begin();
141 n != site_list.end(); ++n)
dd3f7f9b 142 {
3272d625 143 io_stream *compressed_ini_file =
3bac26a1 144 get_url_to_membuf (n->url + "/setup.bz2", owner);
3272d625
RC
145 io_stream *ini_file = 0;
146 if (!compressed_ini_file)
3bac26a1 147 ini_file = get_url_to_membuf (n->url + "/setup.ini", owner);
3272d625
RC
148 else
149 {
150 ini_file = compress::decompress (compressed_ini_file);
151 }
de6a1a64
RC
152
153 if (!ini_file)
154 {
d2a3615c 155 note (owner, IDS_SETUPINI_MISSING, n->url.c_str());
de6a1a64
RC
156 continue;
157 }
aa1e3b4d
RC
158
159 if (compressed_ini_file)
3bac26a1 160 myFeedback.iniName (n->url + "/setup.bz2");
aa1e3b4d 161 else
3bac26a1 162 myFeedback.iniName (n->url + "/setup.ini");
de6a1a64 163
3bac26a1 164 aBuilder.parse_mirror = n->url;
aa1e3b4d 165 ini_init (ini_file, &aBuilder, myFeedback);
de6a1a64
RC
166
167 /*yydebug = 1; */
168
169 if (yyparse () || error_count > 0)
170 MessageBox (0, error_buf,
171 error_count == 1 ? "Parse Error" : "Parse Errors", 0);
172 else
173 {
174 /* save known-good setup.ini locally */
fd93eff9 175 const std::string fp = "file://" + local_dir + "/" +
3bac26a1 176 rfc1738_escape_part (n->url) +
3c054baf 177 "/setup.ini";
de6a1a64
RC
178 io_stream::mkpath_p (PATH_TO_FILE, fp);
179 io_stream *inistream = io_stream::open (fp, "wb");
ea36e064 180 if (inistream)
de6a1a64 181 {
ea36e064
RC
182 if (compressed_ini_file)
183 {
184 delete ini_file;
185 compressed_ini_file->seek (0, IO_SEEK_SET);
186 ini_file = compress::decompress (compressed_ini_file);
187 }
188 else
189 ini_file->seek (0, IO_SEEK_SET);
de6a1a64 190 if (io_stream::copy (ini_file, inistream))
ea36e064 191 io_stream::remove (fp);
de6a1a64
RC
192 delete inistream;
193 }
5e0464a1 194 ++ini_count;
dd3f7f9b 195 }
67829ce0 196 if (aBuilder.timestamp > setup_timestamp)
b92028a4 197 {
67829ce0 198 setup_timestamp = aBuilder.timestamp;
2b734ec7 199 ini_setup_version = aBuilder.version;
b92028a4 200 }
3272d625
RC
201 delete ini_file;
202 delete compressed_ini_file;
dd3f7f9b 203 }
de6a1a64
RC
204 return ini_count;
205}
206
d9f4a2ba 207static bool
ab57ceaa 208do_ini_thread (HINSTANCE h, HWND owner)
de6a1a64
RC
209{
210 size_t ini_count = 0;
211 if (source == IDC_SOURCE_CWD)
ab57ceaa 212 ini_count = do_local_ini (owner);
de6a1a64 213 else
ab57ceaa 214 ini_count = do_remote_ini (owner);
de6a1a64
RC
215
216 if (ini_count == 0)
d9f4a2ba 217 return false;
23c9e63c 218
d2a3615c 219 if (get_root_dir ().c_str())
23c9e63c 220 {
b24c88b3 221 io_stream::mkpath_p (PATH_TO_DIR, "cygfile:///etc/setup");
04d6e06b
DD
222
223 unsigned int old_timestamp = 0;
b24c88b3
RC
224 io_stream *ots =
225 io_stream::open ("cygfile:///etc/setup/timestamp", "rt");
04d6e06b 226 if (ots)
23c9e63c 227 {
b24c88b3
RC
228 char temp[20];
229 memset (temp, '\0', 20);
230 if (ots->read (temp, 19))
231 sscanf (temp, "%u", &old_timestamp);
232 delete ots;
04d6e06b
DD
233 if (old_timestamp && setup_timestamp
234 && (old_timestamp > setup_timestamp))
235 {
ab57ceaa 236 int yn = yesno (owner, IDS_OLD_SETUPINI);
04d6e06b 237 if (yn == IDNO)
9f4a0c62 238 LogSingleton::GetInstance().exit (1);
04d6e06b 239 }
23c9e63c 240 }
04d6e06b 241 if (setup_timestamp)
23c9e63c 242 {
b24c88b3
RC
243 io_stream *nts =
244 io_stream::open ("cygfile:///etc/setup/timestamp", "wt");
04d6e06b
DD
245 if (nts)
246 {
b24c88b3
RC
247 char temp[20];
248 sprintf (temp, "%u", setup_timestamp);
249 nts->write (temp, strlen (temp));
250 delete nts;
04d6e06b 251 }
23c9e63c
DD
252 }
253 }
254
2b734ec7 255 msg (".ini setup_version is %s, our setup_version is %s", ini_setup_version.size() ?
d2a3615c 256 ini_setup_version.c_str() : "(null)",
2b734ec7
MB
257 setup_version);
258 if (ini_setup_version.size())
13d27274 259 {
2b734ec7
MB
260 if (version_compare(setup_version, ini_setup_version) < 0)
261 note (owner, IDS_OLD_SETUP_VERSION, setup_version,
d2a3615c 262 ini_setup_version.c_str());
13d27274
DD
263 }
264
d9f4a2ba 265 return true;
23c9e63c
DD
266}
267
45e01f23 268static DWORD WINAPI
ab57ceaa
RC
269do_ini_thread_reflector(void* p)
270{
072fb49a
MB
271 HANDLE *context;
272 context = (HANDLE*)p;
ab57ceaa 273
072fb49a
MB
274 try
275 {
276 bool succeeded = do_ini_thread((HINSTANCE)context[0], (HWND)context[1]);
ab57ceaa 277
072fb49a
MB
278 // Tell the progress page that we're done downloading
279 Progress.PostMessage(WM_APP_SETUP_INI_DOWNLOAD_COMPLETE, 0, succeeded);
280 }
281 TOPLEVEL_CATCH("ini");
ab57ceaa 282
072fb49a 283 ExitThread(0);
ab57ceaa
RC
284}
285
286static HANDLE context[2];
287
288void
289do_ini (HINSTANCE h, HWND owner)
290{
45e01f23
RC
291 context[0] = h;
292 context[1] = owner;
293
294 DWORD threadID;
295 CreateThread (NULL, 0, do_ini_thread_reflector, context, 0, &threadID);
ab57ceaa
RC
296}
297
298
b11b49f3 299extern int yylineno;
0d4e0aad 300extern int yybol ();
b11b49f3 301
6391823e 302extern int
fd93eff9 303yyerror (const std::string& s)
23c9e63c 304{
0d4e0aad 305 char buf[MAX_PATH + 1000];
b11b49f3 306 int len;
0d4e0aad 307 sprintf (buf, "%s line %d: ", ini_filename, yylineno - yybol ());
d2a3615c 308 sprintf (buf + strlen (buf), s.c_str());
b11b49f3
DD
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++;
b24c88b3
RC
324 /* TODO: is return 0 correct? */
325 return 0;
23c9e63c
DD
326}
327
b24c88b3 328extern "C" int fprintf (FILE * f, const char *s, ...);
23c9e63c 329
b11b49f3
DD
330static char stderrbuf[1000];
331
23c9e63c 332int
b24c88b3 333fprintf (FILE * f, const char *fmt, ...)
23c9e63c
DD
334{
335 char buf[1000];
336 int rv;
337 va_list args;
338 va_start (args, fmt);
339 if (f == stderr)
340 {
08cd08c3
RC
341 rv = vsnprintf (buf, 1000, fmt, args);
342 /* todo check here for overflows too */
b11b49f3
DD
343 strcat (stderrbuf, buf);
344 if (char *nl = strchr (stderrbuf, '\n'))
345 {
346 *nl = 0;
b24c88b3 347 /*OutputDebugString (stderrbuf); */
b11b49f3
DD
348 MessageBox (0, buf, "Cygwin Setup", 0);
349 stderrbuf[0] = 0;
350 }
42bf5b92 351
23c9e63c
DD
352 }
353 else
354 {
355 rv = vfprintf (f, fmt, args);
356 }
357 return rv;
358}
This page took 0.090315 seconds and 5 git commands to generate.