]> cygwin.com Git - cygwin-apps/setup.git/blame - ini.cc
2002-07-05 Robert Collins <rbtcollins@hotmail.com>
[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
23c9e63c
DD
26#include "win32.h"
27
28#include <stdio.h>
b11b49f3 29#include <stdlib.h>
23c9e63c 30#include <stdarg.h>
ab57ceaa 31#include <process.h>
23c9e63c
DD
32
33#include "ini.h"
34#include "resource.h"
3c054baf 35#include "String++.h"
23c9e63c
DD
36#include "state.h"
37#include "geturl.h"
38#include "dialog.h"
39#include "msg.h"
89b1a15b 40#include "log.h"
13d27274 41#include "version.h"
a351e48c 42#include "mount.h"
de6a1a64
RC
43#include "site.h"
44#include "rfc1738.h"
45#include "find.h"
b401ef47 46#include "IniParseFindVisitor.h"
67829ce0
RC
47#include "IniParseFeedback.h"
48//#include "filemanip.h"
23c9e63c 49
b24c88b3
RC
50#include "io_stream.h"
51
ab57ceaa 52#include "threebar.h"
58ee6135
RC
53
54#include "rfc1738.h"
b92028a4 55
076654e7 56#include "IniDBBuilderPackage.h"
3272d625 57#include "compress.h"
b92028a4 58
ab57ceaa
RC
59extern ThreeBarProgressPage Progress;
60
23c9e63c 61unsigned int setup_timestamp = 0;
b92028a4 62String 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;
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 }
67829ce0
RC
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 {
aa1e3b4d 114 Progress.SetText4("Package:");
67829ce0 115 }
aa1e3b4d
RC
116private:
117 unsigned char lastpct;
67829ce0
RC
118};
119
de6a1a64 120static int
ab57ceaa 121do_local_ini (HWND owner)
de6a1a64 122{
67829ce0
RC
123 GuiParseFeedback myFeedback;
124 IniDBBuilderPackage findBuilder(myFeedback);
125 IniParseFindVisitor myVisitor (findBuilder, local_dir, myFeedback);
b401ef47
RC
126 Find (local_dir).accept(myVisitor);
127 setup_timestamp = myVisitor.timeStamp();
128 setup_version = myVisitor.version();
129 return myVisitor.iniCount();
de6a1a64
RC
130}
131
132static int
ab57ceaa 133do_remote_ini (HWND owner)
de6a1a64
RC
134{
135 size_t ini_count = 0;
67829ce0
RC
136 GuiParseFeedback myFeedback;
137 IniDBBuilderPackage aBuilder(myFeedback);
aa1e3b4d 138
de6a1a64 139 for (size_t n = 1; n <= site_list.number (); n++)
dd3f7f9b 140 {
3272d625
RC
141 io_stream *compressed_ini_file =
142 get_url_to_membuf (site_list[n]->url + "/setup.bz2", owner);
143 io_stream *ini_file = 0;
144 if (!compressed_ini_file)
145 ini_file = get_url_to_membuf (site_list[n]->url + "/setup.ini", owner);
146 else
147 {
148 ini_file = compress::decompress (compressed_ini_file);
149 }
de6a1a64
RC
150
151 if (!ini_file)
152 {
3c054baf 153 note (owner, IDS_SETUPINI_MISSING, site_list[n]->url.cstr_oneuse());
de6a1a64
RC
154 continue;
155 }
aa1e3b4d
RC
156
157 if (compressed_ini_file)
158 myFeedback.iniName (site_list[n]->url + "/setup.bz2");
159 else
160 myFeedback.iniName (site_list[n]->url + "/setup.ini");
de6a1a64 161
67829ce0 162 aBuilder.parse_mirror = site_list[n]->url;
aa1e3b4d 163 ini_init (ini_file, &aBuilder, myFeedback);
de6a1a64
RC
164
165 /*yydebug = 1; */
166
167 if (yyparse () || error_count > 0)
168 MessageBox (0, error_buf,
169 error_count == 1 ? "Parse Error" : "Parse Errors", 0);
170 else
171 {
172 /* save known-good setup.ini locally */
3c054baf
RC
173 String const fp = String ("file://") + local_dir + "/" +
174 rfc1738_escape_part (site_list[n]->url) +
175 "/setup.ini";
de6a1a64
RC
176 io_stream::mkpath_p (PATH_TO_FILE, fp);
177 io_stream *inistream = io_stream::open (fp, "wb");
ea36e064 178 if (inistream)
de6a1a64 179 {
ea36e064
RC
180 if (compressed_ini_file)
181 {
182 delete ini_file;
183 compressed_ini_file->seek (0, IO_SEEK_SET);
184 ini_file = compress::decompress (compressed_ini_file);
185 }
186 else
187 ini_file->seek (0, IO_SEEK_SET);
de6a1a64 188 if (io_stream::copy (ini_file, inistream))
ea36e064 189 io_stream::remove (fp);
de6a1a64
RC
190 delete inistream;
191 }
5e0464a1 192 ++ini_count;
dd3f7f9b 193 }
67829ce0 194 if (aBuilder.timestamp > setup_timestamp)
b92028a4 195 {
67829ce0
RC
196 setup_timestamp = aBuilder.timestamp;
197 setup_version = aBuilder.version;
b92028a4 198 }
3272d625
RC
199 delete ini_file;
200 delete compressed_ini_file;
dd3f7f9b 201 }
de6a1a64
RC
202 return ini_count;
203}
204
ab57ceaa
RC
205static void
206do_ini_thread (HINSTANCE h, HWND owner)
de6a1a64
RC
207{
208 size_t ini_count = 0;
209 if (source == IDC_SOURCE_CWD)
ab57ceaa 210 ini_count = do_local_ini (owner);
de6a1a64 211 else
ab57ceaa 212 ini_count = do_remote_ini (owner);
de6a1a64
RC
213
214 if (ini_count == 0)
215 {
216 next_dialog = source == IDC_SOURCE_CWD ? IDD_S_FROM_CWD : IDD_SITE;
217 return;
218 }
23c9e63c 219
3c054baf 220 if (get_root_dir ().cstr_oneuse())
23c9e63c 221 {
b24c88b3 222 io_stream::mkpath_p (PATH_TO_DIR, "cygfile:///etc/setup");
04d6e06b
DD
223
224 unsigned int old_timestamp = 0;
b24c88b3
RC
225 io_stream *ots =
226 io_stream::open ("cygfile:///etc/setup/timestamp", "rt");
04d6e06b 227 if (ots)
23c9e63c 228 {
b24c88b3
RC
229 char temp[20];
230 memset (temp, '\0', 20);
231 if (ots->read (temp, 19))
232 sscanf (temp, "%u", &old_timestamp);
233 delete ots;
04d6e06b
DD
234 if (old_timestamp && setup_timestamp
235 && (old_timestamp > setup_timestamp))
236 {
ab57ceaa 237 int yn = yesno (owner, IDS_OLD_SETUPINI);
04d6e06b 238 if (yn == IDNO)
9f4a0c62 239 LogSingleton::GetInstance().exit (1);
04d6e06b 240 }
23c9e63c 241 }
04d6e06b 242 if (setup_timestamp)
23c9e63c 243 {
b24c88b3
RC
244 io_stream *nts =
245 io_stream::open ("cygfile:///etc/setup/timestamp", "wt");
04d6e06b
DD
246 if (nts)
247 {
b24c88b3
RC
248 char temp[20];
249 sprintf (temp, "%u", setup_timestamp);
250 nts->write (temp, strlen (temp));
251 delete nts;
04d6e06b 252 }
23c9e63c
DD
253 }
254 }
255
b92028a4
RC
256 msg ("setup_version is %s, our_version is %s", setup_version.size() ?
257 setup_version.cstr_oneuse() : "(null)",
b24c88b3 258 version);
b92028a4 259 if (setup_version.size())
13d27274 260 {
3c054baf
RC
261 String ini_version = canonicalize_version (setup_version);
262 String our_version = canonicalize_version (version);
263 // XXX useversion < operator
264 if (our_version.compare (ini_version) < 0)
b92028a4 265 note (owner, IDS_OLD_SETUP_VERSION, version, setup_version.cstr_oneuse());
13d27274
DD
266 }
267
f6a81f69 268 next_dialog = IDD_CHOOSE;
23c9e63c
DD
269}
270
45e01f23 271static DWORD WINAPI
ab57ceaa
RC
272do_ini_thread_reflector(void* p)
273{
274 HANDLE *context;
275 context = (HANDLE*)p;
276
277 do_ini_thread((HINSTANCE)context[0], (HWND)context[1]);
278
279 // Tell the progress page that we're done downloading
280 Progress.PostMessage(WM_APP_SETUP_INI_DOWNLOAD_COMPLETE, 0, next_dialog);
281
45e01f23 282 ExitThread(0);
ab57ceaa
RC
283}
284
285static HANDLE context[2];
286
287void
288do_ini (HINSTANCE h, HWND owner)
289{
45e01f23
RC
290 context[0] = h;
291 context[1] = owner;
292
293 DWORD threadID;
294 CreateThread (NULL, 0, do_ini_thread_reflector, context, 0, &threadID);
ab57ceaa
RC
295}
296
297
b11b49f3 298extern int yylineno;
0d4e0aad 299extern int yybol ();
b11b49f3 300
6391823e
RC
301extern int
302yyerror (String const &s)
23c9e63c 303{
0d4e0aad 304 char buf[MAX_PATH + 1000];
b11b49f3 305 int len;
0d4e0aad 306 sprintf (buf, "%s line %d: ", ini_filename, yylineno - yybol ());
6391823e 307 sprintf (buf + strlen (buf), s.cstr_oneuse());
b11b49f3
DD
308 OutputDebugString (buf);
309 if (error_buf)
310 {
311 strcat (error_buf, "\n");
312 len = strlen (error_buf) + strlen (buf) + 5;
313 error_buf = (char *) realloc (error_buf, len);
314 strcat (error_buf, buf);
315 }
316 else
317 {
318 len = strlen (buf) + 5;
319 error_buf = (char *) malloc (len);
320 strcpy (error_buf, buf);
321 }
322 error_count++;
b24c88b3
RC
323 /* TODO: is return 0 correct? */
324 return 0;
23c9e63c
DD
325}
326
b24c88b3 327extern "C" int fprintf (FILE * f, const char *s, ...);
23c9e63c 328
b11b49f3
DD
329static char stderrbuf[1000];
330
23c9e63c 331int
b24c88b3 332fprintf (FILE * f, const char *fmt, ...)
23c9e63c
DD
333{
334 char buf[1000];
335 int rv;
336 va_list args;
337 va_start (args, fmt);
338 if (f == stderr)
339 {
08cd08c3
RC
340 rv = vsnprintf (buf, 1000, fmt, args);
341 /* todo check here for overflows too */
b11b49f3
DD
342 strcat (stderrbuf, buf);
343 if (char *nl = strchr (stderrbuf, '\n'))
344 {
345 *nl = 0;
b24c88b3 346 /*OutputDebugString (stderrbuf); */
b11b49f3
DD
347 MessageBox (0, buf, "Cygwin Setup", 0);
348 stderrbuf[0] = 0;
349 }
42bf5b92 350
23c9e63c
DD
351 }
352 else
353 {
354 rv = vfprintf (f, fmt, args);
355 }
356 return rv;
357}
This page took 0.075622 seconds and 5 git commands to generate.