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