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