]> cygwin.com Git - cygwin-apps/setup.git/blame - site.cc
2003-06-22 Max Bowsher <maxb@ukf.net>
[cygwin-apps/setup.git] / site.cc
CommitLineData
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
20static 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"
46extern ThreeBarProgressPage Progress;
47
f2ff9838
RC
48#include "getopt++/StringOption.h"
49
6625e635
RC
50using namespace std;
51
3bac26a1
RC
52SiteList site_list;
53SiteList all_site_list;
23c9e63c 54
f2ff9838
RC
55StringOption SiteOption("", 's', "site", "Download site");
56
ead15931
RC
57/* XXX make into a singleton? */
58static SiteSetting ChosenSites;
59
de6a1a64 60void
3c054baf 61site_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 99site_list_type::site_list_type (String const &newurl)
de6a1a64
RC
100{
101 init (newurl);
102}
103
3bac26a1
RC
104site_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
111site_list_type &
112site_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
120bool
121site_list_type::operator == (site_list_type const &rhs) const
122{
123 return key.casecompare (rhs.key) == 0;
124}
125
126bool
127site_list_type::operator < (site_list_type const &rhs) const
128{
129 return key.casecompare (rhs.key) < 0;
130}
131
23c9e63c 132static void
b7301c43 133save_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
158void
159save_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 171static int
ab57ceaa 172get_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
232static void
233register_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 257static void
de6a1a64 258get_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 283static DWORD WINAPI
ab57ceaa 284do_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 299Make 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
314static HANDLE context[2];
315
316void
317do_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 327bool SitePage::Create ()
ab57ceaa 328{
b7301c43 329 return PropertyPage::Create (IDD_SITE);
ab57ceaa
RC
330}
331
332void
333SitePage::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
342long
343SitePage::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
361long
362SitePage::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
372void
373SitePage::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
385long
386SitePage::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
394void
395SitePage::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
408void
409SitePage::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
440bool 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}
This page took 0.096043 seconds and 5 git commands to generate.