]> cygwin.com Git - cygwin-apps/setup.git/blobdiff - site.cc
2002-07-15 Robert Collins <rbtcollins@hotmail.com>
[cygwin-apps/setup.git] / site.cc
diff --git a/site.cc b/site.cc
index 67e6580ada91511af5028a294f870bdb0a419b31..61045e2f7e1dfd7360d66186ad81435b85a91577 100644 (file)
--- a/site.cc
+++ b/site.cc
 /* 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')
@@ -216,102 +190,281 @@ get_site_list (HINSTANCE h)
          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;
 }
-
This page took 0.034836 seconds and 5 git commands to generate.