]>
Commit | Line | Data |
---|---|---|
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 the list of mirror sites and ask | |
17 | the user which mirror site they want to download from. */ | |
18 | ||
b24c88b3 RC |
19 | #if 0 |
20 | static const char *cvsid = | |
21 | "\n%%% $Id$\n"; | |
22 | #endif | |
8507f105 | 23 | |
3bac26a1 | 24 | #include "site.h" |
23c9e63c DD |
25 | #include "win32.h" |
26 | #include <stdio.h> | |
27 | #include <stdlib.h> | |
28 | #include <string.h> | |
ab57ceaa | 29 | #include <process.h> |
3bac26a1 | 30 | #include <algorithm> |
23c9e63c DD |
31 | |
32 | #include "dialog.h" | |
33 | #include "resource.h" | |
34 | #include "state.h" | |
35 | #include "geturl.h" | |
36 | #include "msg.h" | |
aa1e3b4d | 37 | #include "LogSingleton.h" |
b24c88b3 | 38 | #include "io_stream.h" |
de6a1a64 | 39 | #include "site.h" |
23c9e63c DD |
40 | |
41 | #include "port.h" | |
42 | ||
ab57ceaa RC |
43 | #include "propsheet.h" |
44 | ||
45 | #include "threebar.h" | |
46 | extern ThreeBarProgressPage Progress; | |
47 | ||
f2ff9838 RC |
48 | #include "getopt++/StringOption.h" |
49 | ||
6625e635 RC |
50 | using namespace std; |
51 | ||
3bac26a1 RC |
52 | SiteList site_list; |
53 | SiteList all_site_list; | |
23c9e63c | 54 | |
f2ff9838 RC |
55 | StringOption SiteOption("", 's', "site", "Download site"); |
56 | ||
ead15931 RC |
57 | /* XXX make into a singleton? */ |
58 | static SiteSetting ChosenSites; | |
59 | ||
de6a1a64 | 60 | void |
3c054baf | 61 | site_list_type::init (String const &newurl) |
de6a1a64 | 62 | { |
3c054baf | 63 | url = newurl; |
de6a1a64 | 64 | |
3c054baf RC |
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); | |
51ebb760 RC |
77 | char *dpsave, *dp = new char[2 * newurl.size() + 3]; |
78 | dpsave = dp; | |
3c054baf | 79 | while (dot != dots) |
de6a1a64 RC |
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 | } | |
3c054baf | 90 | --dot; |
de6a1a64 RC |
91 | } |
92 | *dp++ = ' '; | |
3c054baf RC |
93 | strcpy (dp, dots); |
94 | delete[] dots; | |
95 | key = String (dp); | |
51ebb760 | 96 | delete[] dpsave; |
de6a1a64 RC |
97 | } |
98 | ||
3c054baf | 99 | site_list_type::site_list_type (String const &newurl) |
de6a1a64 RC |
100 | { |
101 | init (newurl); | |
102 | } | |
103 | ||
3bac26a1 RC |
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 | ||
23c9e63c | 132 | static void |
b7301c43 | 133 | save_dialog (HWND h) |
23c9e63c | 134 | { |
b7301c43 | 135 | // Remove anything that was previously in the selected site list. |
3bac26a1 | 136 | site_list.clear (); |
23c9e63c | 137 | |
23c9e63c | 138 | HWND listbox = GetDlgItem (h, IDC_URL_LIST); |
de6a1a64 RC |
139 | int sel_count = SendMessage (listbox, LB_GETSELCOUNT, 0, 0); |
140 | if (sel_count > 0) | |
23c9e63c | 141 | { |
de6a1a64 RC |
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); | |
3bac26a1 | 153 | site_list.push_back (all_site_list[mirror]); |
de6a1a64 | 154 | } |
23c9e63c | 155 | } |
23c9e63c DD |
156 | } |
157 | ||
ed3e8b9b DD |
158 | void |
159 | save_site_url () | |
160 | { | |
b24c88b3 | 161 | io_stream *f = io_stream::open ("cygfile:///etc/setup/last-mirror", "wb"); |
3c054baf | 162 | if (f) |
b24c88b3 | 163 | { |
3bac26a1 RC |
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); | |
3c054baf | 167 | delete f; |
b24c88b3 | 168 | } |
ed3e8b9b DD |
169 | } |
170 | ||
23c9e63c | 171 | static int |
ab57ceaa | 172 | get_site_list (HINSTANCE h, HWND owner) |
23c9e63c DD |
173 | { |
174 | char mirror_url[1000]; | |
ab57ceaa | 175 | |
ed3e8b9b | 176 | if (LoadString (h, IDS_MIRROR_LST, mirror_url, sizeof (mirror_url)) <= 0) |
23c9e63c | 177 | return 1; |
3c054baf RC |
178 | char *bol, *eol, *nl, *theString; |
179 | { | |
180 | String mirrors = get_url_to_string (mirror_url, owner); | |
181 | if (!mirrors.size()) | |
23c9e63c DD |
182 | return 1; |
183 | ||
3c054baf | 184 | nl = theString = mirrors.cstr();} |
23c9e63c | 185 | |
23c9e63c DD |
186 | while (*nl) |
187 | { | |
188 | bol = nl; | |
b24c88b3 | 189 | for (eol = bol; *eol && *eol != '\n'; eol++); |
23c9e63c | 190 | if (*eol) |
b24c88b3 | 191 | nl = eol + 1; |
23c9e63c DD |
192 | else |
193 | nl = eol; | |
194 | while (eol > bol && eol[-1] == '\r') | |
195 | eol--; | |
196 | *eol = 0; | |
197 | if (bol[0] != '#' && bol[0] > ' ') | |
198 | { | |
b5b282c4 | 199 | char *semi = strchr (bol, ';'); |
23c9e63c DD |
200 | if (semi) |
201 | *semi = 0; | |
3bac26a1 RC |
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()) | |
84c4f5d1 | 206 | { |
3bac26a1 RC |
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; | |
84c4f5d1 | 212 | } |
3bac26a1 RC |
213 | else |
214 | //TODO: remove and remerge | |
215 | *i = newsite; | |
23c9e63c DD |
216 | } |
217 | } | |
3c054baf | 218 | delete[] theString; |
b5b282c4 | 219 | |
23c9e63c DD |
220 | return 0; |
221 | } | |
222 | ||
6fbc690d CF |
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 | ||
f2ff9838 RC |
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 | ||
ed3e8b9b | 257 | static void |
de6a1a64 | 258 | get_saved_sites () |
ed3e8b9b | 259 | { |
b24c88b3 | 260 | io_stream *f = io_stream::open ("cygfile:///etc/setup/last-mirror", "rt"); |
ed3e8b9b DD |
261 | if (!f) |
262 | return; | |
263 | ||
264 | char site[1000]; | |
de6a1a64 RC |
265 | char *fg_ret; |
266 | while ((fg_ret = f->gets (site, 1000))) | |
267 | { | |
ed3e8b9b | 268 | |
de6a1a64 RC |
269 | char *eos = site + strlen (site) - 1; |
270 | while (eos >= site && (*eos == '\n' || *eos == '\r')) | |
271 | *eos-- = '\0'; | |
ed3e8b9b | 272 | |
de6a1a64 RC |
273 | if (eos < site) |
274 | continue; | |
ed3e8b9b | 275 | |
f2ff9838 RC |
276 | register_saved_site (site); |
277 | ||
ed3e8b9b | 278 | } |
de6a1a64 | 279 | delete f; |
ed3e8b9b | 280 | |
ed3e8b9b DD |
281 | } |
282 | ||
45e01f23 | 283 | static DWORD WINAPI |
ab57ceaa | 284 | do_download_site_info_thread (void *p) |
23c9e63c | 285 | { |
ab57ceaa RC |
286 | HANDLE *context; |
287 | HINSTANCE hinst; | |
288 | HWND h; | |
289 | context = (HANDLE *) p; | |
290 | ||
291 | hinst = (HINSTANCE) (context[0]); | |
292 | h = (HWND) (context[1]); | |
23c9e63c | 293 | |
3bac26a1 | 294 | if (all_site_list.size() == 0 |
3c054baf | 295 | && get_site_list (hinst, h)) |
ab57ceaa RC |
296 | { |
297 | // Error: Couldn't download the site info. Go back to the Net setup page. | |
b7301c43 | 298 | MessageBox (h, TEXT ("Can't get list of download sites.\n\ |
89374d4a | 299 | Make sure your network settings are correct and try again."), NULL, MB_OK); |
ab57ceaa RC |
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 | ||
ab57ceaa | 305 | } |
3c054baf | 306 | else |
ab57ceaa | 307 | // Everything worked, go to the site select page |
ab57ceaa RC |
308 | // Tell the progress page that we're done downloading |
309 | Progress.PostMessage (WM_APP_SITE_INFO_DOWNLOAD_COMPLETE, 0, IDD_SITE); | |
310 | ||
45e01f23 | 311 | ExitThread(0); |
ab57ceaa RC |
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 | ||
45e01f23 RC |
323 | DWORD threadID; |
324 | CreateThread (NULL, 0, do_download_site_info_thread, context, 0, &threadID); | |
ab57ceaa RC |
325 | } |
326 | ||
b7301c43 | 327 | bool SitePage::Create () |
ab57ceaa | 328 | { |
b7301c43 | 329 | return PropertyPage::Create (IDD_SITE); |
ab57ceaa RC |
330 | } |
331 | ||
332 | void | |
333 | SitePage::OnInit () | |
334 | { | |
f2ff9838 RC |
335 | string SiteOptionString = SiteOption; |
336 | if (SiteOptionString.size()) | |
337 | register_saved_site (SiteOptionString.c_str()); | |
338 | else | |
339 | get_saved_sites (); | |
ab57ceaa | 340 | } |
89b1a15b | 341 | |
ab57ceaa RC |
342 | long |
343 | SitePage::OnNext () | |
344 | { | |
345 | HWND h = GetHWND (); | |
346 | ||
347 | save_dialog (h); | |
b7301c43 | 348 | save_site_url (); |
ab57ceaa | 349 | |
3bac26a1 RC |
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; | |
ab57ceaa | 354 | |
b7301c43 RC |
355 | Progress.SetActivateTask (WM_APP_START_SETUP_INI_DOWNLOAD); |
356 | return IDD_INSTATUS; | |
ab57ceaa RC |
357 | |
358 | return 0; | |
359 | } | |
360 | ||
361 | long | |
362 | SitePage::OnBack () | |
363 | { | |
364 | HWND h = GetHWND (); | |
365 | ||
366 | save_dialog (h); | |
b7301c43 RC |
367 | |
368 | // Go back to the net connection type page | |
ab57ceaa | 369 | return 0; |
23c9e63c | 370 | } |
b7301c43 RC |
371 | |
372 | void | |
373 | SitePage::OnActivate () | |
374 | { | |
375 | // Fill the list box with all known sites. | |
376 | PopulateListBox (); | |
377 | ||
3c054baf RC |
378 | // Load the user URL box with nothing - it is in the list already. |
379 | eset (GetHWND (), IDC_EDIT_USER_URL, ""); | |
b7301c43 RC |
380 | |
381 | // Get the enabled/disabled states of the controls set accordingly. | |
382 | CheckControlsAndDisableAccordingly (); | |
383 | } | |
384 | ||
f2ff9838 RC |
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 | ||
b7301c43 RC |
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 | { | |
3548fbc3 | 402 | // At least one site selected, enable "Next". |
b7301c43 RC |
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); | |
3bac26a1 RC |
416 | for (SiteList::const_iterator i = all_site_list.begin (); |
417 | i != all_site_list.end (); ++i) | |
b7301c43 RC |
418 | { |
419 | j = SendMessage (listbox, LB_ADDSTRING, 0, | |
3bac26a1 RC |
420 | (LPARAM) i->displayed_url.cstr_oneuse()); |
421 | SendMessage (listbox, LB_SETITEMDATA, j, j); | |
b7301c43 RC |
422 | } |
423 | ||
424 | // Select the selected ones. | |
3bac26a1 RC |
425 | for (SiteList::const_iterator n = site_list.begin (); |
426 | n != site_list.end (); ++n) | |
b7301c43 RC |
427 | { |
428 | int index = SendMessage (listbox, LB_FINDSTRING, (WPARAM) - 1, | |
3bac26a1 | 429 | (LPARAM) n->displayed_url.cstr_oneuse()); |
b7301c43 RC |
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 | { | |
3c054baf | 446 | // FIXME: Make Enter here cause an ADD, not a NEXT. |
b7301c43 RC |
447 | break; |
448 | } | |
449 | case IDC_URL_LIST: | |
450 | { | |
451 | if (code == LBN_SELCHANGE) | |
452 | { | |
453 | CheckControlsAndDisableAccordingly (); | |
3c054baf | 454 | save_dialog (GetHWND ()); |
b7301c43 RC |
455 | } |
456 | break; | |
457 | } | |
458 | case IDC_BUTTON_ADD_URL: | |
459 | { | |
460 | if (code == BN_CLICKED) | |
461 | { | |
462 | // User pushed the Add button. | |
3c054baf RC |
463 | String other_url = egetString (GetHWND (), IDC_EDIT_USER_URL); |
464 | if (other_url.size()) | |
465 | { | |
3bac26a1 RC |
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()) | |
b7301c43 | 470 | { |
3bac26a1 RC |
471 | all_site_list.push_back (newsite); |
472 | log (LOG_BABBLE) << "Adding site: " << other_url << endLog; | |
b7301c43 RC |
473 | } |
474 | else | |
475 | { | |
3bac26a1 RC |
476 | *i = newsite; |
477 | log (LOG_BABBLE) << "Replacing site: " << other_url << endLog; | |
b7301c43 RC |
478 | } |
479 | ||
480 | // Assume the user wants to use it and select it for him. | |
3bac26a1 | 481 | site_list.push_back (newsite); |
b7301c43 RC |
482 | |
483 | // Update the list box. | |
484 | PopulateListBox (); | |
3548fbc3 RC |
485 | // And allow the user to continue |
486 | CheckControlsAndDisableAccordingly (); | |
3c054baf RC |
487 | eset (GetHWND (), IDC_EDIT_USER_URL, ""); |
488 | } | |
b7301c43 RC |
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 | } |