2 * Copyright (c) 2000, Red Hat, Inc.
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.
9 * A copy of the GNU General Public License can be found at
12 * Written by DJ Delorie <dj@cygnus.com>
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. */
22 static const char *cvsid
=
28 #include "csu_util/version_compare.h"
30 #include "setup_version.h"
50 #include "IniParseFindVisitor.h"
51 #include "IniParseFeedback.h"
52 //#include "filemanip.h"
54 #include "io_stream.h"
60 #include "IniDBBuilderPackage.h"
62 #include "Exception.h"
64 extern ThreeBarProgressPage Progress
;
66 unsigned int setup_timestamp
= 0;
67 String ini_setup_version
;
69 extern int yyparse ();
70 /*extern int yydebug;*/
72 static char *error_buf
= 0;
73 static int error_count
= 0;
75 static const char *ini_filename
;
77 class GuiParseFeedback
: public IniParseFeedback
80 GuiParseFeedback () : lastpct (0)
82 Progress
.SetText2 ("");
83 Progress
.SetText3 ("");
84 Progress
.SetText4 ("Progress:");
86 virtual void progress(unsigned long const pos
, unsigned long const max
)
89 /* length not known or eof */
92 /* rounding down should mean this only ever fires once */
94 if (pos
* 100 / max
> lastpct
)
96 lastpct
= pos
* 100 / max
;
97 log (LOG_BABBLE
, String (lastpct
) + "% (" + String (pos
) + " of " + String (max
) + " bytes of ini file read");
99 Progress
.SetBar1(pos
, max
);
101 virtual void iniName (String
const &name
)
103 Progress
.SetText1 ((String ("Parsing ini file \"") + name
+ "\"").cstr_oneuse());
105 virtual void babble(String
const &message
)const
107 log (LOG_BABBLE
, message
);
109 virtual void warning (String
const &message
)const
111 MessageBox (0, message
.cstr_oneuse(), "Warning", 0);
113 virtual void error(String
const &message
)const
115 MessageBox (0, message
.cstr_oneuse(), "Error parsing", 0);
117 virtual ~ GuiParseFeedback ()
119 Progress
.SetText4("Package:");
122 unsigned char lastpct
;
126 do_local_ini (HWND owner
)
128 GuiParseFeedback myFeedback
;
129 IniDBBuilderPackage
findBuilder(myFeedback
);
130 IniParseFindVisitor
myVisitor (findBuilder
, local_dir
, myFeedback
);
131 Find (local_dir
).accept(myVisitor
);
132 setup_timestamp
= myVisitor
.timeStamp();
133 ini_setup_version
= myVisitor
.version();
134 return myVisitor
.iniCount();
138 do_remote_ini (HWND owner
)
140 size_t ini_count
= 0;
141 GuiParseFeedback myFeedback
;
142 IniDBBuilderPackage
aBuilder(myFeedback
);
144 for (SiteList::const_iterator n
= site_list
.begin();
145 n
!= site_list
.end(); ++n
)
147 io_stream
*compressed_ini_file
=
148 get_url_to_membuf (n
->url
+ "/setup.bz2", owner
);
149 io_stream
*ini_file
= 0;
150 if (!compressed_ini_file
)
151 ini_file
= get_url_to_membuf (n
->url
+ "/setup.ini", owner
);
154 ini_file
= compress::decompress (compressed_ini_file
);
159 note (owner
, IDS_SETUPINI_MISSING
, n
->url
.cstr_oneuse());
163 if (compressed_ini_file
)
164 myFeedback
.iniName (n
->url
+ "/setup.bz2");
166 myFeedback
.iniName (n
->url
+ "/setup.ini");
168 aBuilder
.parse_mirror
= n
->url
;
169 ini_init (ini_file
, &aBuilder
, myFeedback
);
173 if (yyparse () || error_count
> 0)
174 MessageBox (0, error_buf
,
175 error_count
== 1 ? "Parse Error" : "Parse Errors", 0);
178 /* save known-good setup.ini locally */
179 String
const fp
= String ("file://") + local_dir
+ "/" +
180 rfc1738_escape_part (n
->url
) +
182 io_stream::mkpath_p (PATH_TO_FILE
, fp
);
183 io_stream
*inistream
= io_stream::open (fp
, "wb");
186 if (compressed_ini_file
)
189 compressed_ini_file
->seek (0, IO_SEEK_SET
);
190 ini_file
= compress::decompress (compressed_ini_file
);
193 ini_file
->seek (0, IO_SEEK_SET
);
194 if (io_stream::copy (ini_file
, inistream
))
195 io_stream::remove (fp
);
200 if (aBuilder
.timestamp
> setup_timestamp
)
202 setup_timestamp
= aBuilder
.timestamp
;
203 ini_setup_version
= aBuilder
.version
;
206 delete compressed_ini_file
;
212 do_ini_thread (HINSTANCE h
, HWND owner
)
214 size_t ini_count
= 0;
215 if (source
== IDC_SOURCE_CWD
)
216 ini_count
= do_local_ini (owner
);
218 ini_count
= do_remote_ini (owner
);
223 if (get_root_dir ().cstr_oneuse())
225 io_stream::mkpath_p (PATH_TO_DIR
, "cygfile:///etc/setup");
227 unsigned int old_timestamp
= 0;
229 io_stream::open ("cygfile:///etc/setup/timestamp", "rt");
233 memset (temp
, '\0', 20);
234 if (ots
->read (temp
, 19))
235 sscanf (temp
, "%u", &old_timestamp
);
237 if (old_timestamp
&& setup_timestamp
238 && (old_timestamp
> setup_timestamp
))
240 int yn
= yesno (owner
, IDS_OLD_SETUPINI
);
242 LogSingleton::GetInstance().exit (1);
248 io_stream::open ("cygfile:///etc/setup/timestamp", "wt");
252 sprintf (temp
, "%u", setup_timestamp
);
253 nts
->write (temp
, strlen (temp
));
259 msg (".ini setup_version is %s, our setup_version is %s", ini_setup_version
.size() ?
260 ini_setup_version
.cstr_oneuse() : "(null)",
262 if (ini_setup_version
.size())
264 if (version_compare(setup_version
, ini_setup_version
) < 0)
265 note (owner
, IDS_OLD_SETUP_VERSION
, setup_version
,
266 ini_setup_version
.cstr_oneuse());
273 do_ini_thread_reflector(void* p
)
276 context
= (HANDLE
*)p
;
280 bool succeeded
= do_ini_thread((HINSTANCE
)context
[0], (HWND
)context
[1]);
282 // Tell the progress page that we're done downloading
283 Progress
.PostMessage(WM_APP_SETUP_INI_DOWNLOAD_COMPLETE
, 0, succeeded
);
285 TOPLEVEL_CATCH("ini");
290 static HANDLE context
[2];
293 do_ini (HINSTANCE h
, HWND owner
)
299 CreateThread (NULL
, 0, do_ini_thread_reflector
, context
, 0, &threadID
);
307 yyerror (String
const &s
)
309 char buf
[MAX_PATH
+ 1000];
311 sprintf (buf
, "%s line %d: ", ini_filename
, yylineno
- yybol ());
312 sprintf (buf
+ strlen (buf
), s
.cstr_oneuse());
313 OutputDebugString (buf
);
316 strcat (error_buf
, "\n");
317 len
= strlen (error_buf
) + strlen (buf
) + 5;
318 error_buf
= (char *) realloc (error_buf
, len
);
319 strcat (error_buf
, buf
);
323 len
= strlen (buf
) + 5;
324 error_buf
= (char *) malloc (len
);
325 strcpy (error_buf
, buf
);
328 /* TODO: is return 0 correct? */
332 extern "C" int fprintf (FILE * f
, const char *s
, ...);
334 static char stderrbuf
[1000];
337 fprintf (FILE * f
, const char *fmt
, ...)
342 va_start (args
, fmt
);
345 rv
= vsnprintf (buf
, 1000, fmt
, args
);
346 /* todo check here for overflows too */
347 strcat (stderrbuf
, buf
);
348 if (char *nl
= strchr (stderrbuf
, '\n'))
351 /*OutputDebugString (stderrbuf); */
352 MessageBox (0, buf
, "Cygwin Setup", 0);
359 rv
= vfprintf (f
, fmt
, args
);