]> cygwin.com Git - cygwin-apps/setup.git/blame - ini.cc
Add missing ChangeLog entry.
[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
d9f4a2ba 206static bool
ab57ceaa 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)
d9f4a2ba 216 return false;
23c9e63c 217
3c054baf 218 if (get_root_dir ().cstr_oneuse())
23c9e63c 219 {
b24c88b3 220 io_stream::mkpath_p (PATH_TO_DIR, "cygfile:///etc/setup");
04d6e06b
DD
221
222 unsigned int old_timestamp = 0;
b24c88b3
RC
223 io_stream *ots =
224 io_stream::open ("cygfile:///etc/setup/timestamp", "rt");
04d6e06b 225 if (ots)
23c9e63c 226 {
b24c88b3
RC
227 char temp[20];
228 memset (temp, '\0', 20);
229 if (ots->read (temp, 19))
230 sscanf (temp, "%u", &old_timestamp);
231 delete ots;
04d6e06b
DD
232 if (old_timestamp && setup_timestamp
233 && (old_timestamp > setup_timestamp))
234 {
ab57ceaa 235 int yn = yesno (owner, IDS_OLD_SETUPINI);
04d6e06b 236 if (yn == IDNO)
9f4a0c62 237 LogSingleton::GetInstance().exit (1);
04d6e06b 238 }
23c9e63c 239 }
04d6e06b 240 if (setup_timestamp)
23c9e63c 241 {
b24c88b3
RC
242 io_stream *nts =
243 io_stream::open ("cygfile:///etc/setup/timestamp", "wt");
04d6e06b
DD
244 if (nts)
245 {
b24c88b3
RC
246 char temp[20];
247 sprintf (temp, "%u", setup_timestamp);
248 nts->write (temp, strlen (temp));
249 delete nts;
04d6e06b 250 }
23c9e63c
DD
251 }
252 }
253
b92028a4
RC
254 msg ("setup_version is %s, our_version is %s", setup_version.size() ?
255 setup_version.cstr_oneuse() : "(null)",
b24c88b3 256 version);
b92028a4 257 if (setup_version.size())
13d27274 258 {
3c054baf
RC
259 String ini_version = canonicalize_version (setup_version);
260 String our_version = canonicalize_version (version);
261 // XXX useversion < operator
262 if (our_version.compare (ini_version) < 0)
b92028a4 263 note (owner, IDS_OLD_SETUP_VERSION, version, setup_version.cstr_oneuse());
13d27274
DD
264 }
265
d9f4a2ba 266 return true;
23c9e63c
DD
267}
268
45e01f23 269static DWORD WINAPI
ab57ceaa
RC
270do_ini_thread_reflector(void* p)
271{
272 HANDLE *context;
273 context = (HANDLE*)p;
274
d9f4a2ba 275 bool succeeded = do_ini_thread((HINSTANCE)context[0], (HWND)context[1]);
ab57ceaa
RC
276
277 // Tell the progress page that we're done downloading
d9f4a2ba 278 Progress.PostMessage(WM_APP_SETUP_INI_DOWNLOAD_COMPLETE, 0, succeeded);
ab57ceaa 279
45e01f23 280 ExitThread(0);
ab57ceaa
RC
281}
282
283static HANDLE context[2];
284
285void
286do_ini (HINSTANCE h, HWND owner)
287{
45e01f23
RC
288 context[0] = h;
289 context[1] = owner;
290
291 DWORD threadID;
292 CreateThread (NULL, 0, do_ini_thread_reflector, context, 0, &threadID);
ab57ceaa
RC
293}
294
295
b11b49f3 296extern int yylineno;
0d4e0aad 297extern int yybol ();
b11b49f3 298
6391823e
RC
299extern int
300yyerror (String const &s)
23c9e63c 301{
0d4e0aad 302 char buf[MAX_PATH + 1000];
b11b49f3 303 int len;
0d4e0aad 304 sprintf (buf, "%s line %d: ", ini_filename, yylineno - yybol ());
6391823e 305 sprintf (buf + strlen (buf), s.cstr_oneuse());
b11b49f3
DD
306 OutputDebugString (buf);
307 if (error_buf)
308 {
309 strcat (error_buf, "\n");
310 len = strlen (error_buf) + strlen (buf) + 5;
311 error_buf = (char *) realloc (error_buf, len);
312 strcat (error_buf, buf);
313 }
314 else
315 {
316 len = strlen (buf) + 5;
317 error_buf = (char *) malloc (len);
318 strcpy (error_buf, buf);
319 }
320 error_count++;
b24c88b3
RC
321 /* TODO: is return 0 correct? */
322 return 0;
23c9e63c
DD
323}
324
b24c88b3 325extern "C" int fprintf (FILE * f, const char *s, ...);
23c9e63c 326
b11b49f3
DD
327static char stderrbuf[1000];
328
23c9e63c 329int
b24c88b3 330fprintf (FILE * f, const char *fmt, ...)
23c9e63c
DD
331{
332 char buf[1000];
333 int rv;
334 va_list args;
335 va_start (args, fmt);
336 if (f == stderr)
337 {
08cd08c3
RC
338 rv = vsnprintf (buf, 1000, fmt, args);
339 /* todo check here for overflows too */
b11b49f3
DD
340 strcat (stderrbuf, buf);
341 if (char *nl = strchr (stderrbuf, '\n'))
342 {
343 *nl = 0;
b24c88b3 344 /*OutputDebugString (stderrbuf); */
b11b49f3
DD
345 MessageBox (0, buf, "Cygwin Setup", 0);
346 stderrbuf[0] = 0;
347 }
42bf5b92 348
23c9e63c
DD
349 }
350 else
351 {
352 rv = vfprintf (f, fmt, args);
353 }
354 return rv;
355}
This page took 0.084093 seconds and 5 git commands to generate.