]> cygwin.com Git - cygwin-apps/setup.git/blob - site.cc
2003-03-10 Robert Collins <rbtcollins@hotmail.com>
[cygwin-apps/setup.git] / site.cc
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 the list of mirror sites and ask
17 the user which mirror site they want to download from. */
18
19 #if 0
20 static const char *cvsid =
21 "\n%%% $Id$\n";
22 #endif
23
24 #include "site.h"
25 #include "win32.h"
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include <process.h>
30 #include <algorithm>
31
32 #include "dialog.h"
33 #include "resource.h"
34 #include "state.h"
35 #include "geturl.h"
36 #include "msg.h"
37 #include "LogSingleton.h"
38 #include "io_stream.h"
39 #include "site.h"
40
41 #include "port.h"
42
43 #include "propsheet.h"
44
45 #include "threebar.h"
46 extern ThreeBarProgressPage Progress;
47
48 #include "getopt++/StringOption.h"
49
50 using namespace std;
51
52 SiteList site_list;
53 SiteList all_site_list;
54
55 StringOption SiteOption("", 's', "site", "Download site");
56
57 /* XXX make into a singleton? */
58 static SiteSetting ChosenSites;
59
60 void
61 site_list_type::init (String const &newurl)
62 {
63 url = newurl;
64
65 char *dots = newurl.cstr();
66 char *dot = strchr (dots, '.');
67 if (dot)
68 {
69 dot = strchr (dot, '/');
70 if (dot)
71 *dot = 0;
72 }
73 displayed_url = String (dots);
74
75
76 dot = dots + strlen (dots);
77 char *dpsave, *dp = new char[2 * newurl.size() + 3];
78 dpsave = dp;
79 while (dot != dots)
80 {
81 if (*dot == '.' || *dot == '/')
82 {
83 char *sp;
84 if (dot[3] == 0)
85 *dp++ = '~'; /* sort .com/.edu/.org together */
86 for (sp = dot + 1; *sp && *sp != '.' && *sp != '/';)
87 *dp++ = *sp++;
88 *dp++ = ' ';
89 }
90 --dot;
91 }
92 *dp++ = ' ';
93 strcpy (dp, dots);
94 delete[] dots;
95 key = String (dp);
96 delete[] dpsave;
97 }
98
99 site_list_type::site_list_type (String const &newurl)
100 {
101 init (newurl);
102 }
103
104 site_list_type::site_list_type (site_list_type const &rhs)
105 {
106 key = rhs.key;
107 url = rhs.url;
108 displayed_url = rhs.displayed_url;
109 }
110
111 site_list_type &
112 site_list_type::operator= (site_list_type const &rhs)
113 {
114 key = rhs.key;
115 url = rhs.url;
116 displayed_url = rhs.displayed_url;
117 return *this;
118 }
119
120 bool
121 site_list_type::operator == (site_list_type const &rhs) const
122 {
123 return key.casecompare (rhs.key) == 0;
124 }
125
126 bool
127 site_list_type::operator < (site_list_type const &rhs) const
128 {
129 return key.casecompare (rhs.key) < 0;
130 }
131
132 static void
133 save_dialog (HWND h)
134 {
135 // Remove anything that was previously in the selected site list.
136 site_list.clear ();
137
138 HWND listbox = GetDlgItem (h, IDC_URL_LIST);
139 int sel_count = SendMessage (listbox, LB_GETSELCOUNT, 0, 0);
140 if (sel_count > 0)
141 {
142 int sel_buffer[sel_count];
143 int sel_count2 = SendMessage (listbox, LB_GETSELITEMS, sel_count,
144 (LPARAM) sel_buffer);
145 if (sel_count != sel_count2)
146 {
147 NEXT (IDD_SITE);
148 }
149 for (int n = 0; n < sel_count; n++)
150 {
151 int mirror =
152 SendMessage (listbox, LB_GETITEMDATA, sel_buffer[n], 0);
153 site_list.push_back (all_site_list[mirror]);
154 }
155 }
156 }
157
158 void
159 save_site_url ()
160 {
161 io_stream *f = io_stream::open ("cygfile:///etc/setup/last-mirror", "wb");
162 if (f)
163 {
164 for (SiteList::const_iterator n = site_list.begin ();
165 n != site_list.end (); ++n)
166 f->write ((n->url + "\n").cstr_oneuse(), n->url.size() + 1);
167 delete f;
168 }
169 }
170
171 static int
172 get_site_list (HINSTANCE h, HWND owner)
173 {
174 char mirror_url[1000];
175
176 if (LoadString (h, IDS_MIRROR_LST, mirror_url, sizeof (mirror_url)) <= 0)
177 return 1;
178 char *bol, *eol, *nl, *theString;
179 {
180 String mirrors = get_url_to_string (mirror_url, owner);
181 if (!mirrors.size())
182 return 1;
183
184 nl = theString = mirrors.cstr();}
185
186 while (*nl)
187 {
188 bol = nl;
189 for (eol = bol; *eol && *eol != '\n'; eol++);
190 if (*eol)
191 nl = eol + 1;
192 else
193 nl = eol;
194 while (eol > bol && eol[-1] == '\r')
195 eol--;
196 *eol = 0;
197 if (bol[0] != '#' && bol[0] > ' ')
198 {
199 char *semi = strchr (bol, ';');
200 if (semi)
201 *semi = 0;
202 site_list_type newsite (bol);
203 SiteList::iterator i = find (all_site_list.begin(),
204 all_site_list.end(), newsite);
205 if (i == all_site_list.end())
206 {
207 SiteList result;
208 merge (all_site_list.begin(), all_site_list.end(),
209 &newsite, &newsite + 1,
210 inserter (result, result.begin()));
211 all_site_list = result;
212 }
213 else
214 //TODO: remove and remerge
215 *i = newsite;
216 }
217 }
218 delete[] theString;
219
220 return 0;
221 }
222
223 /* List of machines that should not be used by default when saved
224 in "last-mirror". */
225 #define NOSAVE1 "ftp://sources.redhat.com/"
226 #define NOSAVE1_LEN (sizeof ("ftp://sources.redhat.com/") - 1)
227 #define NOSAVE2 "ftp://sourceware.cygnus.com/"
228 #define NOSAVE2_LEN (sizeof ("ftp://sourceware.cygnus.com/") - 1)
229 #define NOSAVE3 "ftp://gcc.gnu.org/"
230 #define NOSAVE3_LEN (sizeof ("ftp://gcc.gnu.org/") - 1)
231
232 static void
233 register_saved_site (const char * site)
234 {
235 site_list_type tempSite(site);
236 SiteList::iterator i = find (all_site_list.begin(),
237 all_site_list.end(), tempSite);
238 if (i == all_site_list.end())
239 {
240 /* Don't default to certain machines ever since they suffer
241 from bandwidth limitations. */
242 if (strnicmp (site, NOSAVE1, NOSAVE1_LEN) == 0
243 || strnicmp (site, NOSAVE2, NOSAVE2_LEN) == 0
244 || strnicmp (site, NOSAVE3, NOSAVE3_LEN) == 0)
245 return;
246 SiteList result;
247 merge (all_site_list.begin(), all_site_list.end(),
248 &tempSite, &tempSite + 1,
249 inserter (result, result.begin()));
250 all_site_list = result;
251 site_list.push_back (tempSite);
252 }
253 else
254 site_list.push_back (tempSite);
255 }
256
257 static void
258 get_saved_sites ()
259 {
260 io_stream *f = io_stream::open ("cygfile:///etc/setup/last-mirror", "rt");
261 if (!f)
262 return;
263
264 char site[1000];
265 char *fg_ret;
266 while ((fg_ret = f->gets (site, 1000)))
267 {
268
269 char *eos = site + strlen (site) - 1;
270 while (eos >= site && (*eos == '\n' || *eos == '\r'))
271 *eos-- = '\0';
272
273 if (eos < site)
274 continue;
275
276 register_saved_site (site);
277
278 }
279 delete f;
280
281 }
282
283 static DWORD WINAPI
284 do_download_site_info_thread (void *p)
285 {
286 HANDLE *context;
287 HINSTANCE hinst;
288 HWND h;
289 context = (HANDLE *) p;
290
291 hinst = (HINSTANCE) (context[0]);
292 h = (HWND) (context[1]);
293
294 if (all_site_list.size() == 0
295 && get_site_list (hinst, h))
296 {
297 // Error: Couldn't download the site info. Go back to the Net setup page.
298 MessageBox (h, TEXT ("Can't get list of download sites.\n\
299 Make sure your network settings are correct and try again."), NULL, MB_OK);
300
301 // Tell the progress page that we're done downloading
302 Progress.PostMessage (WM_APP_SITE_INFO_DOWNLOAD_COMPLETE, 0,
303 IDD_NET);
304
305 }
306 else
307 // Everything worked, go to the site select page
308 // Tell the progress page that we're done downloading
309 Progress.PostMessage (WM_APP_SITE_INFO_DOWNLOAD_COMPLETE, 0, IDD_SITE);
310
311 ExitThread(0);
312 }
313
314 static HANDLE context[2];
315
316 void
317 do_download_site_info (HINSTANCE hinst, HWND owner)
318 {
319
320 context[0] = hinst;
321 context[1] = owner;
322
323 DWORD threadID;
324 CreateThread (NULL, 0, do_download_site_info_thread, context, 0, &threadID);
325 }
326
327 bool SitePage::Create ()
328 {
329 return PropertyPage::Create (IDD_SITE);
330 }
331
332 void
333 SitePage::OnInit ()
334 {
335 string SiteOptionString = SiteOption;
336 if (SiteOptionString.size())
337 register_saved_site (SiteOptionString.c_str());
338 else
339 get_saved_sites ();
340 }
341
342 long
343 SitePage::OnNext ()
344 {
345 HWND h = GetHWND ();
346
347 save_dialog (h);
348 save_site_url ();
349
350 // Log all the selected URLs from the list.
351 for (SiteList::const_iterator n = site_list.begin ();
352 n != site_list.end (); ++n)
353 log (LOG_PLAIN) << "site: " << n->url << endLog;
354
355 Progress.SetActivateTask (WM_APP_START_SETUP_INI_DOWNLOAD);
356 return IDD_INSTATUS;
357
358 return 0;
359 }
360
361 long
362 SitePage::OnBack ()
363 {
364 HWND h = GetHWND ();
365
366 save_dialog (h);
367
368 // Go back to the net connection type page
369 return 0;
370 }
371
372 void
373 SitePage::OnActivate ()
374 {
375 // Fill the list box with all known sites.
376 PopulateListBox ();
377
378 // Load the user URL box with nothing - it is in the list already.
379 eset (GetHWND (), IDC_EDIT_USER_URL, "");
380
381 // Get the enabled/disabled states of the controls set accordingly.
382 CheckControlsAndDisableAccordingly ();
383 }
384
385 long
386 SitePage::OnUnattended ()
387 {
388 if (SendMessage (GetDlgItem (IDC_URL_LIST), LB_GETSELCOUNT, 0, 0) > 0)
389 return OnNext ();
390 else
391 return -2;
392 }
393
394 void
395 SitePage::CheckControlsAndDisableAccordingly () const
396 {
397 DWORD ButtonFlags = PSWIZB_BACK;
398
399 // Check that at least one download site is selected.
400 if (SendMessage (GetDlgItem (IDC_URL_LIST), LB_GETSELCOUNT, 0, 0) > 0)
401 {
402 // At least one site selected, enable "Next".
403 ButtonFlags |= PSWIZB_NEXT;
404 }
405 GetOwner ()->SetButtons (ButtonFlags);
406 }
407
408 void
409 SitePage::PopulateListBox ()
410 {
411 int j;
412 HWND listbox = GetDlgItem (IDC_URL_LIST);
413
414 // Populate the list box with the URLs.
415 SendMessage (listbox, LB_RESETCONTENT, 0, 0);
416 for (SiteList::const_iterator i = all_site_list.begin ();
417 i != all_site_list.end (); ++i)
418 {
419 j = SendMessage (listbox, LB_ADDSTRING, 0,
420 (LPARAM) i->displayed_url.cstr_oneuse());
421 SendMessage (listbox, LB_SETITEMDATA, j, j);
422 }
423
424 // Select the selected ones.
425 for (SiteList::const_iterator n = site_list.begin ();
426 n != site_list.end (); ++n)
427 {
428 int index = SendMessage (listbox, LB_FINDSTRING, (WPARAM) - 1,
429 (LPARAM) n->displayed_url.cstr_oneuse());
430 if (index != LB_ERR)
431 {
432 // Highlight the selected item
433 SendMessage (listbox, LB_SELITEMRANGE, TRUE, (index << 16) | index);
434 // Make sure it's fully visible
435 SendMessage (listbox, LB_SETCARETINDEX, index, FALSE);
436 }
437 }
438 }
439
440 bool SitePage::OnMessageCmd (int id, HWND hwndctl, UINT code)
441 {
442 switch (id)
443 {
444 case IDC_EDIT_USER_URL:
445 {
446 // FIXME: Make Enter here cause an ADD, not a NEXT.
447 break;
448 }
449 case IDC_URL_LIST:
450 {
451 if (code == LBN_SELCHANGE)
452 {
453 CheckControlsAndDisableAccordingly ();
454 save_dialog (GetHWND ());
455 }
456 break;
457 }
458 case IDC_BUTTON_ADD_URL:
459 {
460 if (code == BN_CLICKED)
461 {
462 // User pushed the Add button.
463 String other_url = egetString (GetHWND (), IDC_EDIT_USER_URL);
464 if (other_url.size())
465 {
466 site_list_type newsite (other_url);
467 SiteList::iterator i = find (all_site_list.begin(),
468 all_site_list.end(), newsite);
469 if (i == all_site_list.end())
470 {
471 all_site_list.push_back (newsite);
472 log (LOG_BABBLE) << "Adding site: " << other_url << endLog;
473 }
474 else
475 {
476 *i = newsite;
477 log (LOG_BABBLE) << "Replacing site: " << other_url << endLog;
478 }
479
480 // Assume the user wants to use it and select it for him.
481 site_list.push_back (newsite);
482
483 // Update the list box.
484 PopulateListBox ();
485 // And allow the user to continue
486 CheckControlsAndDisableAccordingly ();
487 eset (GetHWND (), IDC_EDIT_USER_URL, "");
488 }
489 }
490 break;
491 }
492 default:
493 // Wasn't recognized or handled.
494 return false;
495 }
496
497 // Was handled since we never got to default above.
498 return true;
499 }
This page took 0.05578 seconds and 5 git commands to generate.