]> cygwin.com Git - cygwin-apps/setup.git/blob - site.cc
2002-07-05 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 SiteList site_list;
49 SiteList all_site_list;
50
51 void
52 site_list_type::init (String const &newurl)
53 {
54 url = newurl;
55
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);
68 char *dpsave, *dp = new char[2 * newurl.size() + 3];
69 dpsave = dp;
70 while (dot != dots)
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, dots);
85 delete[] dots;
86 key = String (dp);
87 delete[] dpsave;
88 }
89
90 site_list_type::site_list_type (String const &newurl)
91 {
92 init (newurl);
93 }
94
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
123 static void
124 save_dialog (HWND h)
125 {
126 // Remove anything that was previously in the selected site list.
127 site_list.clear ();
128
129 HWND listbox = GetDlgItem (h, IDC_URL_LIST);
130 int sel_count = SendMessage (listbox, LB_GETSELCOUNT, 0, 0);
131 if (sel_count > 0)
132 {
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);
144 site_list.push_back (all_site_list[mirror]);
145 }
146 }
147 }
148
149 void
150 save_site_url ()
151 {
152 io_stream *f = io_stream::open ("cygfile:///etc/setup/last-mirror", "wb");
153 if (f)
154 {
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);
158 delete f;
159 }
160 }
161
162 static int
163 get_site_list (HINSTANCE h, HWND owner)
164 {
165 char mirror_url[1000];
166
167 if (LoadString (h, IDS_MIRROR_LST, mirror_url, sizeof (mirror_url)) <= 0)
168 return 1;
169 char *bol, *eol, *nl, *theString;
170 {
171 String mirrors = get_url_to_string (mirror_url, owner);
172 if (!mirrors.size())
173 return 1;
174
175 nl = theString = mirrors.cstr();}
176
177 while (*nl)
178 {
179 bol = nl;
180 for (eol = bol; *eol && *eol != '\n'; eol++);
181 if (*eol)
182 nl = eol + 1;
183 else
184 nl = eol;
185 while (eol > bol && eol[-1] == '\r')
186 eol--;
187 *eol = 0;
188 if (bol[0] != '#' && bol[0] > ' ')
189 {
190 char *semi = strchr (bol, ';');
191 if (semi)
192 *semi = 0;
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())
197 {
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;
203 }
204 else
205 //TODO: remove and remerge
206 *i = newsite;
207 }
208 }
209 delete[] theString;
210
211 return 0;
212 }
213
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
223 static void
224 get_saved_sites ()
225 {
226 io_stream *f = io_stream::open ("cygfile:///etc/setup/last-mirror", "rt");
227 if (!f)
228 return;
229
230 char site[1000];
231 char *fg_ret;
232 while ((fg_ret = f->gets (site, 1000)))
233 {
234
235 char *eos = site + strlen (site) - 1;
236 while (eos >= site && (*eos == '\n' || *eos == '\r'))
237 *eos-- = '\0';
238
239 if (eos < site)
240 continue;
241
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())
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;
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);
259 }
260 else
261 site_list.push_back (tempSite);
262 }
263 delete f;
264
265 }
266
267 static DWORD WINAPI
268 do_download_site_info_thread (void *p)
269 {
270 HANDLE *context;
271 HINSTANCE hinst;
272 HWND h;
273 context = (HANDLE *) p;
274
275 hinst = (HINSTANCE) (context[0]);
276 h = (HWND) (context[1]);
277
278 if (all_site_list.size() == 0
279 && get_site_list (hinst, h))
280 {
281 // Error: Couldn't download the site info. Go back to the Net setup page.
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);
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
289 }
290 else
291 // Everything worked, go to the site select page
292 // Tell the progress page that we're done downloading
293 Progress.PostMessage (WM_APP_SITE_INFO_DOWNLOAD_COMPLETE, 0, IDD_SITE);
294
295 ExitThread(0);
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
307 DWORD threadID;
308 CreateThread (NULL, 0, do_download_site_info_thread, context, 0, &threadID);
309 }
310
311 bool SitePage::Create ()
312 {
313 return PropertyPage::Create (IDD_SITE);
314 }
315
316 void
317 SitePage::OnInit ()
318 {
319 get_saved_sites ();
320 }
321
322 long
323 SitePage::OnNext ()
324 {
325 HWND h = GetHWND ();
326
327 save_dialog (h);
328 save_site_url ();
329
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;
334
335 Progress.SetActivateTask (WM_APP_START_SETUP_INI_DOWNLOAD);
336 return IDD_INSTATUS;
337
338 return 0;
339 }
340
341 long
342 SitePage::OnBack ()
343 {
344 HWND h = GetHWND ();
345
346 save_dialog (h);
347
348 // Go back to the net connection type page
349 return 0;
350 }
351
352 void
353 SitePage::OnActivate ()
354 {
355 // Fill the list box with all known sites.
356 PopulateListBox ();
357
358 // Load the user URL box with nothing - it is in the list already.
359 eset (GetHWND (), IDC_EDIT_USER_URL, "");
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 {
373 // At least one site selected, enable "Next".
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);
387 for (SiteList::const_iterator i = all_site_list.begin ();
388 i != all_site_list.end (); ++i)
389 {
390 j = SendMessage (listbox, LB_ADDSTRING, 0,
391 (LPARAM) i->displayed_url.cstr_oneuse());
392 SendMessage (listbox, LB_SETITEMDATA, j, j);
393 }
394
395 // Select the selected ones.
396 for (SiteList::const_iterator n = site_list.begin ();
397 n != site_list.end (); ++n)
398 {
399 int index = SendMessage (listbox, LB_FINDSTRING, (WPARAM) - 1,
400 (LPARAM) n->displayed_url.cstr_oneuse());
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 {
417 // FIXME: Make Enter here cause an ADD, not a NEXT.
418 break;
419 }
420 case IDC_URL_LIST:
421 {
422 if (code == LBN_SELCHANGE)
423 {
424 CheckControlsAndDisableAccordingly ();
425 save_dialog (GetHWND ());
426 }
427 break;
428 }
429 case IDC_BUTTON_ADD_URL:
430 {
431 if (code == BN_CLICKED)
432 {
433 // User pushed the Add button.
434 String other_url = egetString (GetHWND (), IDC_EDIT_USER_URL);
435 if (other_url.size())
436 {
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())
441 {
442 all_site_list.push_back (newsite);
443 log (LOG_BABBLE) << "Adding site: " << other_url << endLog;
444 }
445 else
446 {
447 *i = newsite;
448 log (LOG_BABBLE) << "Replacing site: " << other_url << endLog;
449 }
450
451 // Assume the user wants to use it and select it for him.
452 site_list.push_back (newsite);
453
454 // Update the list box.
455 PopulateListBox ();
456 // And allow the user to continue
457 CheckControlsAndDisableAccordingly ();
458 eset (GetHWND (), IDC_EDIT_USER_URL, "");
459 }
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 }
This page took 0.06081 seconds and 6 git commands to generate.