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