]> cygwin.com Git - cygwin-apps/setup.git/blame - ini.cc
Run d2u.
[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
3bac26a1
RC
139 for (SiteList::const_iterator n = site_list.begin();
140 n != site_list.end(); ++n)
dd3f7f9b 141 {
3272d625 142 io_stream *compressed_ini_file =
3bac26a1 143 get_url_to_membuf (n->url + "/setup.bz2", owner);
3272d625
RC
144 io_stream *ini_file = 0;
145 if (!compressed_ini_file)
3bac26a1 146 ini_file = get_url_to_membuf (n->url + "/setup.ini", owner);
3272d625
RC
147 else
148 {
149 ini_file = compress::decompress (compressed_ini_file);
150 }
de6a1a64
RC
151
152 if (!ini_file)
153 {
3bac26a1 154 note (owner, IDS_SETUPINI_MISSING, n->url.cstr_oneuse());
de6a1a64
RC
155 continue;
156 }
aa1e3b4d
RC
157
158 if (compressed_ini_file)
3bac26a1 159 myFeedback.iniName (n->url + "/setup.bz2");
aa1e3b4d 160 else
3bac26a1 161 myFeedback.iniName (n->url + "/setup.ini");
de6a1a64 162
3bac26a1 163 aBuilder.parse_mirror = n->url;
aa1e3b4d 164 ini_init (ini_file, &aBuilder, myFeedback);
de6a1a64
RC
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 */
3c054baf 174 String const fp = String ("file://") + local_dir + "/" +
3bac26a1 175 rfc1738_escape_part (n->url) +
3c054baf 176 "/setup.ini";
de6a1a64
RC
177 io_stream::mkpath_p (PATH_TO_FILE, fp);
178 io_stream *inistream = io_stream::open (fp, "wb");
ea36e064 179 if (inistream)
de6a1a64 180 {
ea36e064
RC
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);
de6a1a64 189 if (io_stream::copy (ini_file, inistream))
ea36e064 190 io_stream::remove (fp);
de6a1a64
RC
191 delete inistream;
192 }
5e0464a1 193 ++ini_count;
dd3f7f9b 194 }
67829ce0 195 if (aBuilder.timestamp > setup_timestamp)
b92028a4 196 {
67829ce0
RC
197 setup_timestamp = aBuilder.timestamp;
198 setup_version = aBuilder.version;
b92028a4 199 }
3272d625
RC
200 delete ini_file;
201 delete compressed_ini_file;
dd3f7f9b 202 }
de6a1a64
RC
203 return ini_count;
204}
205
ab57ceaa
RC
206static void
207do_ini_thread (HINSTANCE h, HWND owner)
de6a1a64
RC
208{
209 size_t ini_count = 0;
210 if (source == IDC_SOURCE_CWD)
ab57ceaa 211 ini_count = do_local_ini (owner);
de6a1a64 212 else
ab57ceaa 213 ini_count = do_remote_ini (owner);
de6a1a64
RC
214
215 if (ini_count == 0)
216 {
217 next_dialog = source == IDC_SOURCE_CWD ? IDD_S_FROM_CWD : IDD_SITE;
218 return;
219 }
23c9e63c 220
3c054baf 221 if (get_root_dir ().cstr_oneuse())
23c9e63c 222 {
b24c88b3 223 io_stream::mkpath_p (PATH_TO_DIR, "cygfile:///etc/setup");
04d6e06b
DD
224
225 unsigned int old_timestamp = 0;
b24c88b3
RC
226 io_stream *ots =
227 io_stream::open ("cygfile:///etc/setup/timestamp", "rt");
04d6e06b 228 if (ots)
23c9e63c 229 {
b24c88b3
RC
230 char temp[20];
231 memset (temp, '\0', 20);
232 if (ots->read (temp, 19))
233 sscanf (temp, "%u", &old_timestamp);
234 delete ots;
04d6e06b
DD
235 if (old_timestamp && setup_timestamp
236 && (old_timestamp > setup_timestamp))
237 {
ab57ceaa 238 int yn = yesno (owner, IDS_OLD_SETUPINI);
04d6e06b 239 if (yn == IDNO)
9f4a0c62 240 LogSingleton::GetInstance().exit (1);
04d6e06b 241 }
23c9e63c 242 }
04d6e06b 243 if (setup_timestamp)
23c9e63c 244 {
b24c88b3
RC
245 io_stream *nts =
246 io_stream::open ("cygfile:///etc/setup/timestamp", "wt");
04d6e06b
DD
247 if (nts)
248 {
b24c88b3
RC
249 char temp[20];
250 sprintf (temp, "%u", setup_timestamp);
251 nts->write (temp, strlen (temp));
252 delete nts;
04d6e06b 253 }
23c9e63c
DD
254 }
255 }
256
b92028a4
RC
257 msg ("setup_version is %s, our_version is %s", setup_version.size() ?
258 setup_version.cstr_oneuse() : "(null)",
b24c88b3 259 version);
b92028a4 260 if (setup_version.size())
13d27274 261 {
3c054baf
RC
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)
b92028a4 266 note (owner, IDS_OLD_SETUP_VERSION, version, setup_version.cstr_oneuse());
13d27274
DD
267 }
268
f6a81f69 269 next_dialog = IDD_CHOOSE;
23c9e63c
DD
270}
271
45e01f23 272static DWORD WINAPI
ab57ceaa
RC
273do_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
45e01f23 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
RC
302extern int
303yyerror (String const &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 ());
6391823e 308 sprintf (buf + strlen (buf), s.cstr_oneuse());
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.079023 seconds and 5 git commands to generate.