]>
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 | ||
d60832c6 MB |
19 | #include <string> |
20 | #include <algorithm> | |
21 | ||
3bac26a1 | 22 | #include "site.h" |
23c9e63c DD |
23 | #include "win32.h" |
24 | #include <stdio.h> | |
25 | #include <stdlib.h> | |
ab57ceaa | 26 | #include <process.h> |
23c9e63c DD |
27 | |
28 | #include "dialog.h" | |
29 | #include "resource.h" | |
30 | #include "state.h" | |
31 | #include "geturl.h" | |
32 | #include "msg.h" | |
aa1e3b4d | 33 | #include "LogSingleton.h" |
b24c88b3 | 34 | #include "io_stream.h" |
de6a1a64 | 35 | #include "site.h" |
23c9e63c | 36 | |
ab57ceaa RC |
37 | #include "propsheet.h" |
38 | ||
39 | #include "threebar.h" | |
a8d753b6 | 40 | #include "ControlAdjuster.h" |
072fb49a | 41 | #include "Exception.h" |
08678720 | 42 | #include "String++.h" |
a8d753b6 | 43 | |
01878bdf JT |
44 | #define MIRROR_LIST_URL "https://cygwin.com/mirrors.lst" |
45 | ||
ab57ceaa RC |
46 | extern ThreeBarProgressPage Progress; |
47 | ||
e5e2eba8 CF |
48 | /* |
49 | What to do if dropped mirrors are selected. | |
50 | */ | |
51 | enum | |
52 | { | |
53 | CACHE_REJECT, // Go back to re-select mirrors. | |
54 | CACHE_ACCEPT_WARN, // Go on. Warn again next time. | |
55 | CACHE_ACCEPT_NOWARN // Go on. Don't warn again. | |
56 | }; | |
57 | ||
a8d753b6 RC |
58 | /* |
59 | Sizing information. | |
60 | */ | |
61 | static ControlAdjuster::ControlInfo SiteControlsInfo[] = { | |
62 | {IDC_URL_LIST, CP_STRETCH, CP_STRETCH}, | |
63 | {IDC_EDIT_USER_URL, CP_STRETCH, CP_BOTTOM}, | |
64 | {IDC_BUTTON_ADD_URL, CP_RIGHT, CP_BOTTOM}, | |
82306ac2 | 65 | {IDC_SITE_USERURL, CP_LEFT, CP_BOTTOM}, |
a8d753b6 RC |
66 | {0, CP_LEFT, CP_TOP} |
67 | }; | |
68 | ||
69 | SitePage::SitePage () | |
70 | { | |
71 | sizeProcessor.AddControlInfo (SiteControlsInfo); | |
72 | } | |
73 | ||
7c05cfce | 74 | #include "getopt++/StringArrayOption.h" |
da434346 | 75 | #include "getopt++/BoolOption.h" |
f0fd8856 | 76 | #include "UserSettings.h" |
f2ff9838 | 77 | |
e5e2eba8 CF |
78 | bool cache_is_usable; |
79 | bool cache_needs_writing; | |
155eacb6 | 80 | std::string cache_warn_urls; |
e5e2eba8 CF |
81 | |
82 | /* Selected sites */ | |
3bac26a1 | 83 | SiteList site_list; |
e5e2eba8 CF |
84 | |
85 | /* Fresh mirrors + selected sites */ | |
3bac26a1 | 86 | SiteList all_site_list; |
23c9e63c | 87 | |
e5e2eba8 CF |
88 | /* Previously fresh + cached before */ |
89 | SiteList cached_site_list; | |
90 | ||
91 | /* Stale selected sites to warn about and add to cache */ | |
92 | SiteList dropped_site_list; | |
93 | ||
20f237b4 JT |
94 | StringArrayOption SiteOption('s', "site", IDS_HELPTEXT_SITE); |
95 | BoolOption OnlySiteOption(false, 'O', "only-site", IDS_HELPTEXT_ONLY_SITE); | |
c123d344 | 96 | extern BoolOption UnsupportedOption; |
da434346 | 97 | |
f26f525f | 98 | SiteSetting::SiteSetting (): saved (false) |
dbdc1d9d | 99 | { |
155eacb6 | 100 | std::vector<std::string> SiteOptionStrings = SiteOption; |
7c05cfce JT |
101 | if (SiteOptionStrings.size()) |
102 | { | |
155eacb6 | 103 | for (std::vector<std::string>::const_iterator n = SiteOptionStrings.begin (); |
7c05cfce JT |
104 | n != SiteOptionStrings.end (); ++n) |
105 | registerSavedSite (n->c_str ()); | |
106 | } | |
dbdc1d9d RC |
107 | else |
108 | getSavedSites (); | |
109 | } | |
2bbf91cf | 110 | |
c123d344 JT |
111 | const char * |
112 | SiteSetting::lastMirrorKey () | |
113 | { | |
114 | if (UnsupportedOption) | |
115 | return "last-mirror-unsupported"; | |
116 | ||
117 | return "last-mirror"; | |
118 | } | |
119 | ||
2bbf91cf | 120 | void |
0df9be37 RC |
121 | SiteSetting::save() |
122 | { | |
c123d344 | 123 | io_stream *f = UserSettings::instance().open (lastMirrorKey ()); |
0df9be37 RC |
124 | if (f) |
125 | { | |
126 | for (SiteList::const_iterator n = site_list.begin (); | |
f26f525f CF |
127 | n != site_list.end (); ++n) |
128 | *f << n->url; | |
0df9be37 RC |
129 | delete f; |
130 | } | |
f26f525f CF |
131 | saved = true; |
132 | } | |
133 | ||
134 | SiteSetting::~SiteSetting () | |
135 | { | |
136 | if (!saved) | |
137 | save (); | |
0df9be37 | 138 | } |
2bbf91cf | 139 | |
155eacb6 AG |
140 | site_list_type::site_list_type (const std::string &_url, |
141 | const std::string &_servername, | |
142 | const std::string &_area, | |
143 | const std::string &_location, | |
dd645a18 | 144 | bool _from_mirrors_lst, |
f4653c81 JT |
145 | bool _noshow = false, |
146 | const std::string &_redir = "") | |
de6a1a64 | 147 | { |
d60832c6 | 148 | url = _url; |
e5e2eba8 CF |
149 | servername = _servername; |
150 | area = _area; | |
151 | location = _location; | |
c4ae0173 | 152 | from_mirrors_lst = _from_mirrors_lst; |
dd645a18 | 153 | noshow = _noshow; |
f4653c81 | 154 | redir = _redir; |
d4818fbe JT |
155 | |
156 | /* Canonicalize URL to ensure it ends with a '/' */ | |
157 | if (url.at(url.length()-1) != '/') | |
158 | url.append("/"); | |
159 | ||
160 | /* displayed_url is protocol and site name part of url */ | |
155eacb6 | 161 | std::string::size_type path_offset = url.find ("/", url.find ("//") + 2); |
978f04b6 | 162 | displayed_url = url.substr(0, path_offset); |
d60832c6 | 163 | |
978f04b6 JT |
164 | /* the sorting key is hostname components in reverse order (to sort by country code) |
165 | plus the url (to ensure uniqueness) */ | |
155eacb6 AG |
166 | key = std::string(); |
167 | std::string::size_type last_idx = displayed_url.length () - 1; | |
168 | std::string::size_type idx = url.find_last_of("./", last_idx); | |
d60832c6 MB |
169 | if (last_idx - idx == 3) |
170 | { | |
171 | /* Sort non-country TLDs (.com, .net, ...) together. */ | |
172 | key += " "; | |
173 | } | |
174 | do | |
175 | { | |
176 | key += url.substr(idx + 1, last_idx - idx); | |
177 | key += " "; | |
178 | last_idx = idx - 1; | |
179 | idx = url.find_last_of("./", last_idx); | |
155eacb6 | 180 | if (idx == std::string::npos) |
d60832c6 MB |
181 | idx = 0; |
182 | } while (idx > 0); | |
183 | key += url; | |
de6a1a64 RC |
184 | } |
185 | ||
3bac26a1 RC |
186 | bool |
187 | site_list_type::operator == (site_list_type const &rhs) const | |
188 | { | |
d60832c6 | 189 | return stricmp (key.c_str(), rhs.key.c_str()) == 0; |
3bac26a1 RC |
190 | } |
191 | ||
192 | bool | |
193 | site_list_type::operator < (site_list_type const &rhs) const | |
194 | { | |
d60832c6 | 195 | return stricmp (key.c_str(), rhs.key.c_str()) < 0; |
3bac26a1 RC |
196 | } |
197 | ||
57ddb743 JT |
198 | /* |
199 | A SiteList is maintained as an in-order std::vector of site_list_type, by | |
200 | replacing it with a new object with the new item inserted in the correct | |
201 | place. | |
202 | ||
203 | Yes, we could just use an ordered container, instead. | |
204 | */ | |
205 | static void | |
206 | site_list_insert(SiteList &site_list, site_list_type newsite) | |
207 | { | |
208 | SiteList::iterator i = find (site_list.begin(), site_list.end(), newsite); | |
209 | if (i == site_list.end()) | |
210 | { | |
211 | SiteList result; | |
212 | merge (site_list.begin(), site_list.end(), | |
213 | &newsite, &newsite + 1, | |
214 | inserter (result, result.begin())); | |
215 | site_list = result; | |
216 | } | |
217 | else | |
218 | *i = newsite; | |
219 | } | |
220 | ||
23c9e63c | 221 | static void |
b7301c43 | 222 | save_dialog (HWND h) |
23c9e63c | 223 | { |
b7301c43 | 224 | // Remove anything that was previously in the selected site list. |
3bac26a1 | 225 | site_list.clear (); |
23c9e63c | 226 | |
23c9e63c | 227 | HWND listbox = GetDlgItem (h, IDC_URL_LIST); |
de6a1a64 RC |
228 | int sel_count = SendMessage (listbox, LB_GETSELCOUNT, 0, 0); |
229 | if (sel_count > 0) | |
23c9e63c | 230 | { |
de6a1a64 | 231 | int sel_buffer[sel_count]; |
6d751ec8 | 232 | SendMessage (listbox, LB_GETSELITEMS, sel_count, (LPARAM) sel_buffer); |
de6a1a64 RC |
233 | for (int n = 0; n < sel_count; n++) |
234 | { | |
235 | int mirror = | |
236 | SendMessage (listbox, LB_GETITEMDATA, sel_buffer[n], 0); | |
3bac26a1 | 237 | site_list.push_back (all_site_list[mirror]); |
de6a1a64 | 238 | } |
23c9e63c | 239 | } |
23c9e63c DD |
240 | } |
241 | ||
c4ae0173 KB |
242 | // This is called only for lists of mirrors that came (now or in a |
243 | // previous setup run) from mirrors.lst. | |
e5e2eba8 CF |
244 | void |
245 | load_site_list (SiteList& theSites, char *theString) | |
23c9e63c | 246 | { |
e5e2eba8 CF |
247 | char *bol, *eol, *nl; |
248 | ||
249 | nl = theString; | |
23c9e63c DD |
250 | while (*nl) |
251 | { | |
252 | bol = nl; | |
b24c88b3 | 253 | for (eol = bol; *eol && *eol != '\n'; eol++); |
23c9e63c | 254 | if (*eol) |
b24c88b3 | 255 | nl = eol + 1; |
23c9e63c DD |
256 | else |
257 | nl = eol; | |
258 | while (eol > bol && eol[-1] == '\r') | |
259 | eol--; | |
260 | *eol = 0; | |
eff7a094 MB |
261 | if (*bol == '#' || !*bol) |
262 | continue; | |
263 | /* Accept only the URL schemes we can understand. */ | |
264 | if (strncmp(bol, "http://", 7) == 0 || | |
66d0ef98 JT |
265 | strncmp(bol, "https://", 8) == 0 || |
266 | strncmp(bol, "ftp://", 6) == 0 || | |
267 | strncmp(bol, "ftps://", 7) == 0) | |
dd645a18 JT |
268 | { |
269 | int i; | |
270 | char *semi[4]; | |
4ab6879c | 271 | |
dd645a18 JT |
272 | /* split into up to 4 semicolon-delimited parts */ |
273 | for (i = 0; i < 4; i++) | |
274 | semi[i] = 0; | |
4ab6879c | 275 | |
dd645a18 JT |
276 | char *p = bol; |
277 | for (i = 0; i < 4; i++) | |
278 | { | |
279 | semi[i] = strchr (p, ';'); | |
280 | if (!semi[i]) | |
281 | break; | |
282 | ||
283 | *semi[i] = 0; | |
284 | p = ++semi[i]; | |
285 | } | |
286 | ||
287 | /* Ignore malformed lines */ | |
288 | if (!semi[0] || !semi[1] || !semi[2]) | |
289 | continue; | |
290 | ||
f4653c81 JT |
291 | /* fourth part is an optional, comma-delimited set of flags */ |
292 | bool noshow = FALSE; | |
293 | const char *redir = ""; | |
dd645a18 | 294 | |
f4653c81 JT |
295 | char *flag = semi[3]; |
296 | while (flag) | |
297 | { | |
298 | if (strncmp(flag, "noshow", 6) == 0) | |
299 | noshow = TRUE; | |
300 | else if (strncmp(flag, "redir=", 6) == 0) | |
301 | redir = flag+6; | |
302 | ||
303 | flag = strchr (flag, ','); | |
304 | if (flag) | |
305 | *flag++ = 0; | |
306 | } | |
307 | ||
308 | /* add site to list */ | |
309 | site_list_type newsite (bol, semi[0], semi[1], semi[2], true, noshow, redir); | |
dd645a18 JT |
310 | site_list_insert (theSites, newsite); |
311 | } | |
66d0ef98 JT |
312 | else |
313 | { | |
314 | Log (LOG_BABBLE) << "Discarding line '" << bol << "' due to unknown protocol" << endLog; | |
315 | } | |
23c9e63c | 316 | } |
e5e2eba8 CF |
317 | } |
318 | ||
b4947fb6 JT |
319 | static void |
320 | migrate_selected_site_list() | |
321 | { | |
322 | const std::string http = "http://"; | |
323 | ||
324 | for (SiteList::iterator i = site_list.begin(); | |
325 | i != site_list.end(); | |
326 | ++i) | |
327 | { | |
328 | /* If the saved selected site URL starts with "http://", and the same URL, | |
329 | but starting with "https://" appears in the mirror list, migrate to | |
330 | "https://" */ | |
331 | if (strnicmp(i->url.c_str(), http.c_str(), strlen(http.c_str())) == 0) | |
332 | { | |
333 | std::string migrated_site = "https://"; | |
334 | migrated_site.append(i->url.substr(http.length())); | |
335 | ||
336 | site_list_type migrate(migrated_site, "", "", "", false); | |
337 | SiteList::iterator j = find (all_site_list.begin(), | |
338 | all_site_list.end(), migrate); | |
339 | if (j != all_site_list.end()) | |
340 | { | |
341 | Log (LOG_PLAIN) << "Migrated " << i->url << " to " << migrated_site << endLog; | |
342 | *i = migrate; | |
343 | } | |
344 | } | |
f4653c81 JT |
345 | |
346 | /* If the saved selected site URL appears in the site list with a redir | |
347 | flag, replace with the redirected URL */ | |
348 | { | |
349 | SiteList::iterator j = find (all_site_list.begin(), | |
350 | all_site_list.end(), *i); | |
351 | ||
352 | if (j != all_site_list.end()) | |
353 | { | |
354 | if (!j->redir.empty()) | |
355 | { | |
356 | site_list_type migrate(j->redir, "", "", "", false); | |
357 | Log (LOG_PLAIN) << "Migrated " << i->url << " to " << j->redir << endLog; | |
358 | *i = migrate; | |
359 | } | |
360 | } | |
361 | } | |
b4947fb6 JT |
362 | } |
363 | } | |
364 | ||
e5e2eba8 CF |
365 | static int |
366 | get_site_list (HINSTANCE h, HWND owner) | |
367 | { | |
e5e2eba8 | 368 | char *theMirrorString, *theCachedString; |
c123d344 JT |
369 | |
370 | if (UnsupportedOption) | |
371 | return 0; | |
372 | ||
da434346 | 373 | const char *cached_mirrors = OnlySiteOption ? NULL : UserSettings::instance().get ("mirrors-lst"); |
f26f525f CF |
374 | if (cached_mirrors) |
375 | { | |
157dc2b8 | 376 | Log (LOG_BABBLE) << "Loaded cached mirror list" << endLog; |
f26f525f CF |
377 | cache_is_usable = true; |
378 | } | |
379 | else | |
380 | { | |
157dc2b8 | 381 | Log (LOG_BABBLE) << "Cached mirror list unavailable" << endLog; |
f26f525f | 382 | cache_is_usable = false; |
ca09f44c | 383 | cached_mirrors = ""; |
f26f525f CF |
384 | } |
385 | ||
01878bdf | 386 | std::string mirrors = OnlySiteOption ? std::string ("") : get_url_to_string (MIRROR_LIST_URL, owner); |
f26f525f CF |
387 | if (mirrors.size()) |
388 | cache_needs_writing = true; | |
389 | else | |
390 | { | |
391 | if (!cached_mirrors[0]) | |
ad6cd84a JT |
392 | { |
393 | if (!OnlySiteOption) | |
394 | note(owner, IDS_NO_MIRROR_LST); | |
395 | Log (LOG_BABBLE) << "Defaulting to empty mirror list" << endLog; | |
396 | } | |
f26f525f CF |
397 | else |
398 | { | |
399 | mirrors = cached_mirrors; | |
157dc2b8 | 400 | Log (LOG_BABBLE) << "Using cached mirror list" << endLog; |
f26f525f CF |
401 | } |
402 | cache_is_usable = false; | |
403 | cache_needs_writing = false; | |
404 | } | |
405 | theMirrorString = new_cstr_char_array (mirrors); | |
406 | theCachedString = new_cstr_char_array (cached_mirrors); | |
e5e2eba8 CF |
407 | |
408 | load_site_list (all_site_list, theMirrorString); | |
409 | load_site_list (cached_site_list, theCachedString); | |
b4947fb6 | 410 | |
e5e2eba8 CF |
411 | delete[] theMirrorString; |
412 | delete[] theCachedString; | |
b5b282c4 | 413 | |
b4947fb6 JT |
414 | migrate_selected_site_list(); |
415 | ||
23c9e63c DD |
416 | return 0; |
417 | } | |
418 | ||
6fbc690d CF |
419 | /* List of machines that should not be used by default when saved |
420 | in "last-mirror". */ | |
e5e2eba8 CF |
421 | #define NOSAVE1 "ftp://sourceware.org/" |
422 | #define NOSAVE1_LEN (sizeof (NOSAVE2) - 1) | |
423 | #define NOSAVE2 "ftp://sources.redhat.com/" | |
424 | #define NOSAVE2_LEN (sizeof (NOSAVE1) - 1) | |
6fbc690d | 425 | #define NOSAVE3 "ftp://gcc.gnu.org/" |
e5e2eba8 | 426 | #define NOSAVE3_LEN (sizeof (NOSAVE3) - 1) |
6fbc690d | 427 | |
dbdc1d9d RC |
428 | void |
429 | SiteSetting::registerSavedSite (const char * site) | |
f2ff9838 | 430 | { |
c4ae0173 | 431 | site_list_type tempSite(site, "", "", "", false); |
57ddb743 JT |
432 | |
433 | /* Don't default to certain machines if they suffer from bandwidth | |
434 | limitations. */ | |
435 | if (strnicmp (site, NOSAVE1, NOSAVE1_LEN) == 0 | |
436 | || strnicmp (site, NOSAVE2, NOSAVE2_LEN) == 0 | |
437 | || strnicmp (site, NOSAVE3, NOSAVE3_LEN) == 0) | |
438 | return; | |
439 | ||
440 | site_list_insert (all_site_list, tempSite); | |
441 | site_list.push_back (tempSite); | |
f2ff9838 RC |
442 | } |
443 | ||
dbdc1d9d RC |
444 | void |
445 | SiteSetting::getSavedSites () | |
ed3e8b9b | 446 | { |
c123d344 | 447 | const char *buf = UserSettings::instance().get (lastMirrorKey ()); |
ca09f44c DK |
448 | if (!buf) |
449 | return; | |
f26f525f CF |
450 | char *fg_ret = strdup (buf); |
451 | for (char *site = strtok (fg_ret, "\n"); site; site = strtok (NULL, "\n")) | |
452 | registerSavedSite (site); | |
453 | free (fg_ret); | |
ed3e8b9b DD |
454 | } |
455 | ||
45e01f23 | 456 | static DWORD WINAPI |
ab57ceaa | 457 | do_download_site_info_thread (void *p) |
23c9e63c | 458 | { |
ab57ceaa RC |
459 | HANDLE *context; |
460 | HINSTANCE hinst; | |
461 | HWND h; | |
462 | context = (HANDLE *) p; | |
463 | ||
069cfbb4 JT |
464 | SetThreadUILanguage(langid); |
465 | ||
072fb49a MB |
466 | try |
467 | { | |
468 | hinst = (HINSTANCE) (context[0]); | |
469 | h = (HWND) (context[1]); | |
898fa4a1 JT |
470 | static bool downloaded = false; |
471 | if (!downloaded && get_site_list (hinst, h)) | |
072fb49a MB |
472 | { |
473 | // Error: Couldn't download the site info. | |
474 | // Go back to the Net setup page. | |
17d64747 | 475 | mbox (h, IDS_GET_SITELIST_ERROR, MB_OK); |
ab57ceaa | 476 | |
072fb49a | 477 | // Tell the progress page that we're done downloading |
6ab6abae | 478 | Progress.PostMessageNow (WM_APP_SITE_INFO_DOWNLOAD_COMPLETE, 0, IDD_NET); |
072fb49a | 479 | } |
898fa4a1 | 480 | else |
dbdc1d9d | 481 | { |
898fa4a1 | 482 | downloaded = true; |
dbdc1d9d RC |
483 | // Everything worked, go to the site select page |
484 | // Tell the progress page that we're done downloading | |
6ab6abae | 485 | Progress.PostMessageNow (WM_APP_SITE_INFO_DOWNLOAD_COMPLETE, 0, IDD_SITE); |
dbdc1d9d | 486 | } |
072fb49a | 487 | } |
703f1a44 | 488 | TOPLEVEL_CATCH((HWND) context[1], "site"); |
ab57ceaa | 489 | |
45e01f23 | 490 | ExitThread(0); |
ab57ceaa RC |
491 | } |
492 | ||
493 | static HANDLE context[2]; | |
494 | ||
495 | void | |
496 | do_download_site_info (HINSTANCE hinst, HWND owner) | |
497 | { | |
498 | ||
499 | context[0] = hinst; | |
500 | context[1] = owner; | |
501 | ||
45e01f23 RC |
502 | DWORD threadID; |
503 | CreateThread (NULL, 0, do_download_site_info_thread, context, 0, &threadID); | |
ab57ceaa RC |
504 | } |
505 | ||
e08abe3f | 506 | static INT_PTR CALLBACK |
e5e2eba8 CF |
507 | drop_proc (HWND h, UINT message, WPARAM wParam, LPARAM lParam) |
508 | { | |
509 | switch (message) | |
510 | { | |
511 | case WM_INITDIALOG: | |
512 | eset(h, IDC_DROP_MIRRORS, cache_warn_urls); | |
513 | /* Should this be set by default? */ | |
514 | // CheckDlgButton (h, IDC_DROP_NOWARN, BST_CHECKED); | |
515 | SetFocus (GetDlgItem(h, IDC_DROP_NOWARN)); | |
516 | return FALSE; | |
517 | break; | |
518 | case WM_COMMAND: | |
519 | switch (LOWORD (wParam)) | |
520 | { | |
521 | case IDYES: | |
522 | if (IsDlgButtonChecked (h, IDC_DROP_NOWARN) == BST_CHECKED) | |
523 | EndDialog (h, CACHE_ACCEPT_NOWARN); | |
524 | else | |
525 | EndDialog (h, CACHE_ACCEPT_WARN); | |
526 | break; | |
527 | ||
528 | case IDNO: | |
529 | EndDialog (h, CACHE_REJECT); | |
530 | break; | |
531 | ||
532 | default: | |
533 | return 0; | |
534 | } | |
535 | return TRUE; | |
536 | break; | |
537 | default: | |
538 | return FALSE; | |
539 | } | |
540 | } | |
541 | ||
542 | int check_dropped_mirrors (HWND h) | |
543 | { | |
544 | cache_warn_urls = ""; | |
545 | dropped_site_list.clear (); | |
546 | ||
547 | for (SiteList::const_iterator n = site_list.begin (); | |
548 | n != site_list.end (); ++n) | |
549 | { | |
550 | SiteList::iterator i = find (all_site_list.begin(), all_site_list.end(), | |
551 | *n); | |
c4ae0173 | 552 | if (i == all_site_list.end() || !i->from_mirrors_lst) |
e5e2eba8 CF |
553 | { |
554 | SiteList::iterator j = find (cached_site_list.begin(), | |
555 | cached_site_list.end(), *n); | |
556 | if (j != cached_site_list.end()) | |
557 | { | |
157dc2b8 | 558 | Log (LOG_PLAIN) << "Dropped selected mirror: " << n->url |
e5e2eba8 CF |
559 | << endLog; |
560 | dropped_site_list.push_back (*j); | |
561 | if (cache_warn_urls.size()) | |
562 | cache_warn_urls += "\r\n"; | |
563 | cache_warn_urls += i->url; | |
564 | } | |
565 | } | |
566 | } | |
567 | if (cache_warn_urls.size()) | |
568 | { | |
569 | if (unattended_mode) | |
570 | return CACHE_ACCEPT_WARN; | |
571 | return DialogBox (hinstance, MAKEINTRESOURCE (IDD_DROPPED), h, | |
572 | drop_proc); | |
573 | } | |
574 | return CACHE_ACCEPT_NOWARN; | |
575 | } | |
576 | ||
577 | void write_cache_list (io_stream *f, const SiteList& theSites) | |
578 | { | |
e5e2eba8 | 579 | for (SiteList::const_iterator n = theSites.begin (); |
f26f525f | 580 | n != theSites.end (); ++n) |
c4ae0173 | 581 | if (n->from_mirrors_lst) |
f26f525f CF |
582 | *f << (n->url + ";" + n->servername + ";" + n->area + ";" |
583 | + n->location); | |
e5e2eba8 CF |
584 | } |
585 | ||
586 | void save_cache_file (int cache_action) | |
587 | { | |
f26f525f | 588 | io_stream *f = UserSettings::instance().open ("mirrors-lst"); |
e5e2eba8 CF |
589 | if (f) |
590 | { | |
e5e2eba8 CF |
591 | write_cache_list (f, all_site_list); |
592 | if (cache_action == CACHE_ACCEPT_WARN) | |
593 | { | |
157dc2b8 | 594 | Log (LOG_PLAIN) << "Adding dropped mirrors to cache to warn again." |
e5e2eba8 | 595 | << endLog; |
f26f525f | 596 | *f << "# Following mirrors re-added by setup.exe to warn again about dropped urls."; |
e5e2eba8 CF |
597 | write_cache_list (f, dropped_site_list); |
598 | } | |
599 | delete f; | |
600 | } | |
601 | } | |
602 | ||
b7301c43 | 603 | bool SitePage::Create () |
ab57ceaa | 604 | { |
b7301c43 | 605 | return PropertyPage::Create (IDD_SITE); |
ab57ceaa RC |
606 | } |
607 | ||
00c4ebfd JT |
608 | void |
609 | SitePage::OnInit () | |
610 | { | |
611 | AddTooltip (IDC_EDIT_USER_URL, IDS_USER_URL_TOOLTIP); | |
612 | } | |
613 | ||
ab57ceaa RC |
614 | long |
615 | SitePage::OnNext () | |
616 | { | |
617 | HWND h = GetHWND (); | |
e5e2eba8 | 618 | int cache_action = CACHE_ACCEPT_NOWARN; |
ab57ceaa RC |
619 | |
620 | save_dialog (h); | |
e5e2eba8 CF |
621 | |
622 | if (cache_is_usable && !(cache_action = check_dropped_mirrors (h))) | |
623 | return -1; | |
624 | ||
625 | if (cache_needs_writing) | |
626 | save_cache_file (cache_action); | |
ab57ceaa | 627 | |
3bac26a1 RC |
628 | // Log all the selected URLs from the list. |
629 | for (SiteList::const_iterator n = site_list.begin (); | |
630 | n != site_list.end (); ++n) | |
157dc2b8 | 631 | Log (LOG_PLAIN) << "site: " << n->url << endLog; |
ab57ceaa | 632 | |
b7301c43 RC |
633 | Progress.SetActivateTask (WM_APP_START_SETUP_INI_DOWNLOAD); |
634 | return IDD_INSTATUS; | |
ab57ceaa RC |
635 | |
636 | return 0; | |
637 | } | |
638 | ||
639 | long | |
640 | SitePage::OnBack () | |
641 | { | |
642 | HWND h = GetHWND (); | |
643 | ||
644 | save_dialog (h); | |
b7301c43 RC |
645 | |
646 | // Go back to the net connection type page | |
ab57ceaa | 647 | return 0; |
23c9e63c | 648 | } |
b7301c43 RC |
649 | |
650 | void | |
651 | SitePage::OnActivate () | |
652 | { | |
653 | // Fill the list box with all known sites. | |
654 | PopulateListBox (); | |
655 | ||
3c054baf RC |
656 | // Load the user URL box with nothing - it is in the list already. |
657 | eset (GetHWND (), IDC_EDIT_USER_URL, ""); | |
b7301c43 RC |
658 | |
659 | // Get the enabled/disabled states of the controls set accordingly. | |
660 | CheckControlsAndDisableAccordingly (); | |
661 | } | |
662 | ||
f2ff9838 RC |
663 | long |
664 | SitePage::OnUnattended () | |
665 | { | |
666 | if (SendMessage (GetDlgItem (IDC_URL_LIST), LB_GETSELCOUNT, 0, 0) > 0) | |
667 | return OnNext (); | |
a8d773ed JT |
668 | |
669 | Log (LOG_PLAIN) << "No package repository site(s) specified" << endLog; | |
670 | return -2; | |
f2ff9838 RC |
671 | } |
672 | ||
b7301c43 RC |
673 | void |
674 | SitePage::CheckControlsAndDisableAccordingly () const | |
675 | { | |
676 | DWORD ButtonFlags = PSWIZB_BACK; | |
677 | ||
678 | // Check that at least one download site is selected. | |
679 | if (SendMessage (GetDlgItem (IDC_URL_LIST), LB_GETSELCOUNT, 0, 0) > 0) | |
680 | { | |
3548fbc3 | 681 | // At least one site selected, enable "Next". |
b7301c43 RC |
682 | ButtonFlags |= PSWIZB_NEXT; |
683 | } | |
684 | GetOwner ()->SetButtons (ButtonFlags); | |
685 | } | |
686 | ||
687 | void | |
688 | SitePage::PopulateListBox () | |
689 | { | |
dd645a18 | 690 | std::vector <int> sel_indicies; |
b7301c43 RC |
691 | HWND listbox = GetDlgItem (IDC_URL_LIST); |
692 | ||
693 | // Populate the list box with the URLs. | |
694 | SendMessage (listbox, LB_RESETCONTENT, 0, 0); | |
3bac26a1 RC |
695 | for (SiteList::const_iterator i = all_site_list.begin (); |
696 | i != all_site_list.end (); ++i) | |
b7301c43 | 697 | { |
dd645a18 JT |
698 | // If selected, always show |
699 | SiteList::iterator f = find (site_list.begin(), site_list.end(), *i); | |
700 | if (f == site_list.end()) | |
701 | { | |
702 | // Otherwise, hide redundant legacy URLs: | |
703 | if (i->noshow) | |
704 | continue; | |
705 | } | |
706 | ||
707 | int j = SendMessage (listbox, LB_ADDSTRING, 0, | |
708 | (LPARAM) i->displayed_url.c_str()); | |
709 | // Set the ListBox item data to the index into all_site_list | |
710 | SendMessage (listbox, LB_SETITEMDATA, j, (i - all_site_list.begin())); | |
711 | ||
712 | // For every selected item, remember the index | |
713 | if (f != site_list.end()) | |
714 | { | |
715 | sel_indicies.push_back(j); | |
716 | } | |
b7301c43 RC |
717 | } |
718 | ||
719 | // Select the selected ones. | |
dd645a18 JT |
720 | for (std::vector <int>::const_iterator n = sel_indicies.begin (); |
721 | n != sel_indicies.end (); ++n) | |
b7301c43 | 722 | { |
dd645a18 JT |
723 | int index = *n; |
724 | // Highlight the selected item | |
725 | SendMessage (listbox, LB_SELITEMRANGE, TRUE, (index << 16) | index); | |
726 | // Make sure it's fully visible | |
727 | SendMessage (listbox, LB_SETCARETINDEX, index, FALSE); | |
b7301c43 RC |
728 | } |
729 | } | |
730 | ||
731 | bool SitePage::OnMessageCmd (int id, HWND hwndctl, UINT code) | |
732 | { | |
733 | switch (id) | |
734 | { | |
735 | case IDC_EDIT_USER_URL: | |
736 | { | |
c3853939 KB |
737 | // Set the default pushbutton to ADD if the user is entering text. |
738 | if (code == EN_CHANGE) | |
739 | SendMessage (GetHWND (), DM_SETDEFID, (WPARAM) IDC_BUTTON_ADD_URL, 0); | |
b7301c43 RC |
740 | break; |
741 | } | |
742 | case IDC_URL_LIST: | |
743 | { | |
744 | if (code == LBN_SELCHANGE) | |
745 | { | |
746 | CheckControlsAndDisableAccordingly (); | |
3c054baf | 747 | save_dialog (GetHWND ()); |
b7301c43 RC |
748 | } |
749 | break; | |
750 | } | |
751 | case IDC_BUTTON_ADD_URL: | |
752 | { | |
753 | if (code == BN_CLICKED) | |
754 | { | |
755 | // User pushed the Add button. | |
08678720 | 756 | std::string other_url = egetString (GetHWND (), IDC_EDIT_USER_URL); |
3c054baf RC |
757 | if (other_url.size()) |
758 | { | |
c4ae0173 | 759 | site_list_type newsite (other_url, "", "", "", false); |
3bac26a1 RC |
760 | SiteList::iterator i = find (all_site_list.begin(), |
761 | all_site_list.end(), newsite); | |
762 | if (i == all_site_list.end()) | |
b7301c43 | 763 | { |
3bac26a1 | 764 | all_site_list.push_back (newsite); |
157dc2b8 | 765 | Log (LOG_BABBLE) << "Adding site: " << other_url << endLog; |
c4ae0173 | 766 | site_list.push_back (newsite); |
b7301c43 RC |
767 | } |
768 | else | |
c4ae0173 | 769 | site_list.push_back (*i); |
b7301c43 RC |
770 | |
771 | // Update the list box. | |
772 | PopulateListBox (); | |
3548fbc3 RC |
773 | // And allow the user to continue |
774 | CheckControlsAndDisableAccordingly (); | |
3c054baf RC |
775 | eset (GetHWND (), IDC_EDIT_USER_URL, ""); |
776 | } | |
b7301c43 RC |
777 | } |
778 | break; | |
779 | } | |
780 | default: | |
781 | // Wasn't recognized or handled. | |
782 | return false; | |
783 | } | |
784 | ||
785 | // Was handled since we never got to default above. | |
786 | return true; | |
787 | } |