/* The purpose of this file is to get the list of mirror sites and ask
the user which mirror site they want to download from. */
-static char *cvsid = "\n%%% $Id$\n";
+#if 0
+static const char *cvsid =
+ "\n%%% $Id$\n";
+#endif
+#include "site.h"
#include "win32.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <process.h>
+#include <algorithm>
#include "dialog.h"
#include "resource.h"
#include "state.h"
#include "geturl.h"
#include "msg.h"
-#include "concat.h"
-#include "mount.h"
+#include "LogSingleton.h"
+#include "io_stream.h"
+#include "site.h"
#include "port.h"
-#define NO_IDX (-1)
-#define OTHER_IDX (-2)
+#include "propsheet.h"
-typedef struct {
- char *url;
- char *displayed_url;
- char *sort_key;
-} site_list_type;
+#include "threebar.h"
+extern ThreeBarProgressPage Progress;
-static site_list_type *site_list = 0;
-static int list_idx = NO_IDX;
-static int mirror_idx = NO_IDX;
+SiteList site_list;
+SiteList all_site_list;
-static void
-check_if_enable_next (HWND h)
+void
+site_list_type::init (String const &newurl)
{
- EnableWindow (GetDlgItem (h, IDOK), (mirror_idx != NO_IDX) ? 1 : 0);
-}
+ url = newurl;
-static void
-load_dialog (HWND h)
-{
- HWND listbox = GetDlgItem (h, IDC_URL_LIST);
- SendMessage (listbox, LB_SETCURSEL, list_idx, 0);
- check_if_enable_next (h);
-}
+ char *dots = newurl.cstr();
+ char *dot = strchr (dots, '.');
+ if (dot)
+ {
+ dot = strchr (dot, '/');
+ if (dot)
+ *dot = 0;
+ }
+ displayed_url = String (dots);
-static void
-save_dialog (HWND h)
-{
- HWND listbox = GetDlgItem (h, IDC_URL_LIST);
- list_idx = SendMessage (listbox, LB_GETCURSEL, 0, 0);
- if (list_idx == LB_ERR)
- {
- mirror_site = 0;
- mirror_idx = NO_IDX;
- list_idx = NO_IDX;
- }
- else
+
+ dot = dots + strlen (dots);
+ char *dpsave, *dp = new char[2 * newurl.size() + 3];
+ dpsave = dp;
+ while (dot != dots)
{
- mirror_idx = SendMessage (listbox, LB_GETITEMDATA, list_idx, 0);
- if (mirror_idx == OTHER_IDX)
- mirror_site = 0;
- else
- mirror_site = site_list[mirror_idx].url;
+ if (*dot == '.' || *dot == '/')
+ {
+ char *sp;
+ if (dot[3] == 0)
+ *dp++ = '~'; /* sort .com/.edu/.org together */
+ for (sp = dot + 1; *sp && *sp != '.' && *sp != '/';)
+ *dp++ = *sp++;
+ *dp++ = ' ';
+ }
+ --dot;
}
+ *dp++ = ' ';
+ strcpy (dp, dots);
+ delete[] dots;
+ key = String (dp);
+ delete[] dpsave;
}
-static void
-get_root_dir ()
+site_list_type::site_list_type (String const &newurl)
{
- int istext;
- int issystem;
- if (root_dir)
- return;
- root_dir = find_root_mount (&istext, &issystem);
+ init (newurl);
}
-void
-save_site_url ()
+site_list_type::site_list_type (site_list_type const &rhs)
{
- if (! MIRROR_SITE)
- return;
-
- get_root_dir ();
- if (! root_dir)
- return;
-
- FILE *f = fopen (concat (root_dir, "/etc/setup/last-mirror", 0), "wb");
- if (!f)
- return;
- fprintf (f, "%s\n", MIRROR_SITE);
- fclose (f);
+ key = rhs.key;
+ url = rhs.url;
+ displayed_url = rhs.displayed_url;
}
-static BOOL
-dialog_cmd (HWND h, int id, HWND hwndctl, UINT code)
+site_list_type &
+site_list_type::operator= (site_list_type const &rhs)
{
- switch (id)
- {
-
- case IDC_URL_LIST:
- save_dialog (h);
- check_if_enable_next (h);
- break;
-
- case IDOK:
- save_dialog (h);
- if (mirror_idx == OTHER_IDX)
- NEXT (IDD_OTHER_URL);
- else
- {
- other_url = 0;
- save_site_url ();
- NEXT (IDD_S_LOAD_INI);
- }
- break;
+ key = rhs.key;
+ url = rhs.url;
+ displayed_url = rhs.displayed_url;
+ return *this;
+}
- case IDC_BACK:
- save_dialog (h);
- NEXT (IDD_NET);
- break;
+bool
+site_list_type::operator == (site_list_type const &rhs) const
+{
+ return key.casecompare (rhs.key) == 0;
+}
- case IDCANCEL:
- NEXT (0);
- break;
- }
+bool
+site_list_type::operator < (site_list_type const &rhs) const
+{
+ return key.casecompare (rhs.key) < 0;
}
-static BOOL CALLBACK
-dialog_proc (HWND h, UINT message, WPARAM wParam, LPARAM lParam)
+static void
+save_dialog (HWND h)
{
- int i, j;
- HWND listbox;
- switch (message)
+ // Remove anything that was previously in the selected site list.
+ site_list.clear ();
+
+ HWND listbox = GetDlgItem (h, IDC_URL_LIST);
+ int sel_count = SendMessage (listbox, LB_GETSELCOUNT, 0, 0);
+ if (sel_count > 0)
{
- case WM_INITDIALOG:
- listbox = GetDlgItem (h, IDC_URL_LIST);
- for (i=0; site_list[i].url; i++)
+ int sel_buffer[sel_count];
+ int sel_count2 = SendMessage (listbox, LB_GETSELITEMS, sel_count,
+ (LPARAM) sel_buffer);
+ if (sel_count != sel_count2)
{
- j = SendMessage (listbox, LB_ADDSTRING, 0, (LPARAM)site_list[i].displayed_url);
- SendMessage (listbox, LB_SETITEMDATA, j, i);
+ NEXT (IDD_SITE);
+ }
+ for (int n = 0; n < sel_count; n++)
+ {
+ int mirror =
+ SendMessage (listbox, LB_GETITEMDATA, sel_buffer[n], 0);
+ site_list.push_back (all_site_list[mirror]);
}
- j = SendMessage (listbox, LB_ADDSTRING, 0, (LPARAM)"Other URL");
- SendMessage (listbox, LB_SETITEMDATA, j, OTHER_IDX);
- load_dialog (h);
- return FALSE;
- case WM_COMMAND:
- return HANDLE_WM_COMMAND (h, wParam, lParam, dialog_cmd);
}
- return FALSE;
}
-static int
-site_sort (const void *va, const void *vb)
+void
+save_site_url ()
{
- site_list_type *a = (site_list_type *)va;
- site_list_type *b = (site_list_type *)vb;
- return strcmp (a->sort_key, b->sort_key);
+ io_stream *f = io_stream::open ("cygfile:///etc/setup/last-mirror", "wb");
+ if (f)
+ {
+ for (SiteList::const_iterator n = site_list.begin ();
+ n != site_list.end (); ++n)
+ f->write ((n->url + "\n").cstr_oneuse(), n->url.size() + 1);
+ delete f;
+ }
}
static int
-get_site_list (HINSTANCE h)
+get_site_list (HINSTANCE h, HWND owner)
{
char mirror_url[1000];
+
if (LoadString (h, IDS_MIRROR_LST, mirror_url, sizeof (mirror_url)) <= 0)
return 1;
- char *mirrors = get_url_to_string (mirror_url);
- dismiss_url_status_dialog ();
- if (!mirrors)
+ char *bol, *eol, *nl, *theString;
+ {
+ String mirrors = get_url_to_string (mirror_url, owner);
+ if (!mirrors.size())
return 1;
- char *bol, *eol, *nl;
-
-
- /* null plus account for possibly missing NL plus account for "Other
- URL" from previous run. */
- int nmirrors = 3;
+ nl = theString = mirrors.cstr();}
- for (bol=mirrors; *bol; bol++)
- if (*bol == '\n')
- nmirrors ++;
-
- site_list = (site_list_type *) malloc (nmirrors * sizeof (site_list_type));
- nmirrors = 0;
-
- nl = mirrors;
while (*nl)
{
bol = nl;
- for (eol = bol; *eol && *eol != '\n'; eol++) ;
+ for (eol = bol; *eol && *eol != '\n'; eol++);
if (*eol)
- nl = eol+1;
+ nl = eol + 1;
else
nl = eol;
while (eol > bol && eol[-1] == '\r')
char *semi = strchr (bol, ';');
if (semi)
*semi = 0;
- site_list[nmirrors].url = _strdup (bol);
- site_list[nmirrors].displayed_url = _strdup (bol);
- char *dot = strchr (site_list[nmirrors].displayed_url, '.');
- if (dot)
- {
- dot = strchr (dot, '/');
- if (dot)
- *dot = 0;
- }
- site_list[nmirrors].sort_key = (char *) malloc (2*strlen (bol) + 3);
-
- dot = site_list[nmirrors].displayed_url;
- dot += strlen (dot);
- char *dp = site_list[nmirrors].sort_key;
- while (dot != site_list[nmirrors].displayed_url)
+ site_list_type newsite (bol);
+ SiteList::iterator i = find (all_site_list.begin(),
+ all_site_list.end(), newsite);
+ if (i == all_site_list.end())
{
- if (*dot == '.' || *dot == '/')
- {
- char *sp;
- if (dot[3] == 0)
- *dp++ = '~'; /* sort .com/.edu/.org together */
- for (sp=dot+1; *sp && *sp != '.' && *sp != '/';)
- *dp++ = *sp++;
- *dp++ = ' ';
- }
- dot--;
+ SiteList result;
+ merge (all_site_list.begin(), all_site_list.end(),
+ &newsite, &newsite + 1,
+ inserter (result, result.begin()));
+ all_site_list = result;
}
- *dp++ = ' ';
- strcpy (dp, site_list[nmirrors].displayed_url);
-
- nmirrors++;
+ else
+ //TODO: remove and remerge
+ *i = newsite;
}
}
- site_list[nmirrors].url = 0;
-
- qsort (site_list, nmirrors, sizeof (site_list_type), site_sort);
+ delete[] theString;
return 0;
}
+/* List of machines that should not be used by default when saved
+ in "last-mirror". */
+#define NOSAVE1 "ftp://sources.redhat.com/"
+#define NOSAVE1_LEN (sizeof ("ftp://sources.redhat.com/") - 1)
+#define NOSAVE2 "ftp://sourceware.cygnus.com/"
+#define NOSAVE2_LEN (sizeof ("ftp://sourceware.cygnus.com/") - 1)
+#define NOSAVE3 "ftp://gcc.gnu.org/"
+#define NOSAVE3_LEN (sizeof ("ftp://gcc.gnu.org/") - 1)
+
static void
-get_initial_list_idx ()
+get_saved_sites ()
{
- get_root_dir ();
- if (! root_dir)
- return;
-
- FILE *f = fopen (concat (root_dir, "/etc/setup/last-mirror", 0), "rt");
+ io_stream *f = io_stream::open ("cygfile:///etc/setup/last-mirror", "rt");
if (!f)
return;
char site[1000];
- site[0]='\0';
- char * fg_ret = fgets (site, 1000, f);
- fclose (f);
- if (! fg_ret)
- return;
+ char *fg_ret;
+ while ((fg_ret = f->gets (site, 1000)))
+ {
- char *eos = site + strlen (site) - 1;
- while (eos >= site && (*eos == '\n' || *eos == '\r'))
- *eos-- = '\0';
+ char *eos = site + strlen (site) - 1;
+ while (eos >= site && (*eos == '\n' || *eos == '\r'))
+ *eos-- = '\0';
- if (eos < site)
- return;
+ if (eos < site)
+ continue;
- int i;
- for (i = 0; site_list[i].url; i++)
- if (strcmp (site_list[i].url, site) == 0)
- break;
+ site_list_type tempSite(site);
+ SiteList::iterator i = find (all_site_list.begin(),
+ all_site_list.end(), tempSite);
+ if (i == all_site_list.end())
+ {
+ /* Don't default to certain machines ever since they suffer
+ from bandwidth limitations. */
+ if (strnicmp (site, NOSAVE1, NOSAVE1_LEN) == 0
+ || strnicmp (site, NOSAVE2, NOSAVE2_LEN) == 0
+ || strnicmp (site, NOSAVE3, NOSAVE3_LEN) == 0)
+ return;
+ SiteList result;
+ merge (all_site_list.begin(), all_site_list.end(),
+ &tempSite, &tempSite + 1,
+ inserter (result, result.begin()));
+ all_site_list = result;
+ site_list.push_back (tempSite);
+ }
+ else
+ site_list.push_back (tempSite);
+ }
+ delete f;
- if (! site_list[i].url)
+}
+
+static DWORD WINAPI
+do_download_site_info_thread (void *p)
+{
+ HANDLE *context;
+ HINSTANCE hinst;
+ HWND h;
+ context = (HANDLE *) p;
+
+ hinst = (HINSTANCE) (context[0]);
+ h = (HWND) (context[1]);
+
+ if (all_site_list.size() == 0
+ && get_site_list (hinst, h))
+ {
+ // Error: Couldn't download the site info. Go back to the Net setup page.
+ MessageBox (h, TEXT ("Can't get list of download sites.\n\
+Make sure your network settings are correct and try again."), NULL, MB_OK);
+
+ // Tell the progress page that we're done downloading
+ Progress.PostMessage (WM_APP_SITE_INFO_DOWNLOAD_COMPLETE, 0,
+ IDD_NET);
+
+ }
+ else
+ // Everything worked, go to the site select page
+ // Tell the progress page that we're done downloading
+ Progress.PostMessage (WM_APP_SITE_INFO_DOWNLOAD_COMPLETE, 0, IDD_SITE);
+
+ ExitThread(0);
+}
+
+static HANDLE context[2];
+
+void
+do_download_site_info (HINSTANCE hinst, HWND owner)
+{
+
+ context[0] = hinst;
+ context[1] = owner;
+
+ DWORD threadID;
+ CreateThread (NULL, 0, do_download_site_info_thread, context, 0, &threadID);
+}
+
+bool SitePage::Create ()
+{
+ return PropertyPage::Create (IDD_SITE);
+}
+
+void
+SitePage::OnInit ()
+{
+ get_saved_sites ();
+}
+
+long
+SitePage::OnNext ()
+{
+ HWND h = GetHWND ();
+
+ save_dialog (h);
+ save_site_url ();
+
+ // Log all the selected URLs from the list.
+ for (SiteList::const_iterator n = site_list.begin ();
+ n != site_list.end (); ++n)
+ log (LOG_PLAIN) << "site: " << n->url << endLog;
+
+ Progress.SetActivateTask (WM_APP_START_SETUP_INI_DOWNLOAD);
+ return IDD_INSTATUS;
+
+ return 0;
+}
+
+long
+SitePage::OnBack ()
+{
+ HWND h = GetHWND ();
+
+ save_dialog (h);
+
+ // Go back to the net connection type page
+ return 0;
+}
+
+void
+SitePage::OnActivate ()
+{
+ // Fill the list box with all known sites.
+ PopulateListBox ();
+
+ // Load the user URL box with nothing - it is in the list already.
+ eset (GetHWND (), IDC_EDIT_USER_URL, "");
+
+ // Get the enabled/disabled states of the controls set accordingly.
+ CheckControlsAndDisableAccordingly ();
+}
+
+void
+SitePage::CheckControlsAndDisableAccordingly () const
+{
+ DWORD ButtonFlags = PSWIZB_BACK;
+
+ // Check that at least one download site is selected.
+ if (SendMessage (GetDlgItem (IDC_URL_LIST), LB_GETSELCOUNT, 0, 0) > 0)
{
- site_list[i].displayed_url =
- site_list[i].url = _strdup (site);
- site_list[i+1].url = 0;
+ // At least one site selected, enable "Next".
+ ButtonFlags |= PSWIZB_NEXT;
}
-
- mirror_idx = list_idx = i;
+ GetOwner ()->SetButtons (ButtonFlags);
}
void
-do_site (HINSTANCE h)
+SitePage::PopulateListBox ()
{
- int rv = 0;
+ int j;
+ HWND listbox = GetDlgItem (IDC_URL_LIST);
+
+ // Populate the list box with the URLs.
+ SendMessage (listbox, LB_RESETCONTENT, 0, 0);
+ for (SiteList::const_iterator i = all_site_list.begin ();
+ i != all_site_list.end (); ++i)
+ {
+ j = SendMessage (listbox, LB_ADDSTRING, 0,
+ (LPARAM) i->displayed_url.cstr_oneuse());
+ SendMessage (listbox, LB_SETITEMDATA, j, j);
+ }
+
+ // Select the selected ones.
+ for (SiteList::const_iterator n = site_list.begin ();
+ n != site_list.end (); ++n)
+ {
+ int index = SendMessage (listbox, LB_FINDSTRING, (WPARAM) - 1,
+ (LPARAM) n->displayed_url.cstr_oneuse());
+ if (index != LB_ERR)
+ {
+ // Highlight the selected item
+ SendMessage (listbox, LB_SELITEMRANGE, TRUE, (index << 16) | index);
+ // Make sure it's fully visible
+ SendMessage (listbox, LB_SETCARETINDEX, index, FALSE);
+ }
+ }
+}
- if (site_list == 0)
- if (get_site_list (h))
+bool SitePage::OnMessageCmd (int id, HWND hwndctl, UINT code)
+{
+ switch (id)
+ {
+ case IDC_EDIT_USER_URL:
{
- NEXT (0);
- return;
+ // FIXME: Make Enter here cause an ADD, not a NEXT.
+ break;
}
+ case IDC_URL_LIST:
+ {
+ if (code == LBN_SELCHANGE)
+ {
+ CheckControlsAndDisableAccordingly ();
+ save_dialog (GetHWND ());
+ }
+ break;
+ }
+ case IDC_BUTTON_ADD_URL:
+ {
+ if (code == BN_CLICKED)
+ {
+ // User pushed the Add button.
+ String other_url = egetString (GetHWND (), IDC_EDIT_USER_URL);
+ if (other_url.size())
+ {
+ site_list_type newsite (other_url);
+ SiteList::iterator i = find (all_site_list.begin(),
+ all_site_list.end(), newsite);
+ if (i == all_site_list.end())
+ {
+ all_site_list.push_back (newsite);
+ log (LOG_BABBLE) << "Adding site: " << other_url << endLog;
+ }
+ else
+ {
+ *i = newsite;
+ log (LOG_BABBLE) << "Replacing site: " << other_url << endLog;
+ }
+
+ // Assume the user wants to use it and select it for him.
+ site_list.push_back (newsite);
+
+ // Update the list box.
+ PopulateListBox ();
+ // And allow the user to continue
+ CheckControlsAndDisableAccordingly ();
+ eset (GetHWND (), IDC_EDIT_USER_URL, "");
+ }
+ }
+ break;
+ }
+ default:
+ // Wasn't recognized or handled.
+ return false;
+ }
- get_initial_list_idx ();
-
- rv = DialogBox (h, MAKEINTRESOURCE (IDD_SITE), 0, dialog_proc);
- if (rv == -1)
- fatal (IDS_DIALOG_FAILED);
+ // Was handled since we never got to default above.
+ return true;
}
-