[PATCH setup v4 0/6] Distinguish between user URLs and cygwin mirrors in UI

classic Classic list List threaded Threaded
9 messages Options
Reply | Threaded
Open this post in threaded view
|

[PATCH setup v4 0/6] Distinguish between user URLs and cygwin mirrors in UI

Ken Brown-6
This is a followup to

  https://cygwin.com/ml/cygwin-apps/2011-04/msg00014.html,

in which Jon suggested splitting site selection into two pages, one
for cygwin.com mirrors (including private mirrors) and one for URLs of
other package repositories.  The latter would be visible only if the
user had previously checked a suitable checkbox.  This patch series
implements that suggestion.  [I hope that I now understand the
suggestion correctly.]

The page for mirrors shows the area and location of official mirrors
(from mirrors.lst), as suggested by Brian Inglis.  Private mirrors are
sorted last, with full URLs.

[Brian, see the last patch, which is in your name.  Feel free to
improve it.]

This version of the patch series introduces a new bool member
site_list_type::is_mirror to distinguish mirrors (including private
ones) from non-mirrors.

TODO: Implement a way of validating purported mirrors.  For example,
we could make sure they are signed with the cygwin signing key.  Or if
the user has used the -X option to turn off signature checking, we
could make sure that setup.ini contains "release: cygwin".

Once we finish discussing this patch series, I'll look into that.

Brian Inglis (1):
  Display area and location of official mirrors

Ken Brown (5):
  Use the IDD_SITE dialog for cygwin.com mirrors only
  Use SitePage for cygwin.com mirrors only
  Create new page UserSitePage for user URLs
  Keep the mirror list sorted properly
  Display full URLs of user sites and private mirrors

 Makefile.am |   2 +
 main.cc     |   4 +
 res.rc      |  43 ++++++++--
 resource.h  |   6 ++
 site.cc     | 267 ++++++++++++++++++++++++++++++++++++++++++-----------------
 site.h      |  10 ++-
 usersite.cc | 268 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 usersite.h  |  43 ++++++++++
 8 files changed, 558 insertions(+), 85 deletions(-)
 create mode 100644 usersite.cc
 create mode 100644 usersite.h

--
2.15.1

Reply | Threaded
Open this post in threaded view
|

[PATCH setup v4 1/6] Use the IDD_SITE dialog for cygwin.com mirrors only

Ken Brown-6
Change wording in the dialog template to make it clear that this
dialog is intended for mirrors only.

Add a checkbox IDC_ALLOW_USER_URL; checking this sets a new boolean
variable allow_user_url.  In a future commit, this will enable a new
page where the user can enter URLs for non-mirror package
repositories.
---
 res.rc     | 20 +++++++++++---------
 resource.h |  1 +
 site.cc    |  7 +++++++
 3 files changed, 19 insertions(+), 9 deletions(-)

diff --git a/res.rc b/res.rc
index 901cf76..5ea4c8b 100644
--- a/res.rc
+++ b/res.rc
@@ -131,25 +131,27 @@ IDD_SITE DIALOG DISCARDABLE  0, 0, SETUP_STANDARD_DIALOG_DIMS
 STYLE DS_MODALFRAME | DS_3DLOOK | DS_CENTER | WS_CHILD | WS_VISIBLE |
     WS_CAPTION | WS_SYSMENU
 EXSTYLE WS_EX_CONTROLPARENT
-CAPTION "Cygwin Setup - Choose Download Site(s)"
+CAPTION "Cygwin Setup - Choose Mirror(s)"
 FONT 8, "MS Shell Dlg"
 BEGIN
     ICON            IDI_CYGWIN,IDC_HEADICON,SETUP_HEADICON_X,0,21,20
-    LISTBOX         IDC_URL_LIST,66,45,185,110,LBS_NOINTEGRALHEIGHT |
+    LISTBOX         IDC_URL_LIST,66,41,183,109,LBS_NOINTEGRALHEIGHT |
                     LBS_EXTENDEDSEL | WS_VSCROLL | WS_HSCROLL | WS_GROUP |
                     WS_TABSTOP
-    LTEXT           "Available Download Sites:",IDC_STATIC,66,34,183,8,NOT
+    LTEXT           "Known Mirrors:",IDC_STATIC,66,30,183,8,NOT
                     WS_GROUP
-    CONTROL         "",IDC_HEADSEPARATOR,"Static",SS_BLACKFRAME | SS_SUNKEN,0,28,
+    CONTROL         "",IDC_HEADSEPARATOR,"Static",SS_BLACKFRAME | SS_SUNKEN,0,25,
                     SETUP_STANDARD_DIALOG_W,1
-    LTEXT           "Choose a site from this list, or add your own sites to the list",
+    LTEXT           "Choose a cygwin.com mirror from this list, or add your own mirrors to the list",
                     IDC_STATIC,21,9,239,16,NOT WS_GROUP
-    LTEXT           "Choose A Download Site",IDC_STATIC_HEADER_TITLE,7,0,258,
+    LTEXT           "Choose A Mirror",IDC_STATIC_HEADER_TITLE,7,0,258,
                     8,NOT WS_GROUP
-    EDITTEXT        IDC_EDIT_USER_URL,65,160,185,14,ES_AUTOHSCROLL |
+    EDITTEXT        IDC_EDIT_USER_URL,65,153,185,14,ES_AUTOHSCROLL |
                     WS_GROUP
-    LTEXT           "User URL:",IDC_SITE_USERURL,15,162,45,8,NOT WS_GROUP
-    PUSHBUTTON      "Add",IDC_BUTTON_ADD_URL,255,160,50,14
+    LTEXT           "Mirror URL:",IDC_SITE_USERURL,15,155,45,8,NOT WS_GROUP
+    PUSHBUTTON      "Add",IDC_BUTTON_ADD_URL,255,153,50,14
+    CONTROL         "Allow download sites that are not cygwin.com mirrors (to be chosen on the next page)",
+                    IDC_ALLOW_USER_URL,"Button",BS_AUTOCHECKBOX,15,171,350,8
 END
 
 IDD_NET DIALOG DISCARDABLE  0, 0, SETUP_STANDARD_DIALOG_DIMS
diff --git a/resource.h b/resource.h
index 79b876d..ed4f605 100644
--- a/resource.h
+++ b/resource.h
@@ -178,3 +178,4 @@
 #define IDC_NET_DIRECT_LEGACY             593
 #define IDC_DOWNLOAD_EDIT                 594
 #define IDC_CHOOSE_DO_SEARCH              595
+#define IDC_ALLOW_USER_URL                596
diff --git a/site.cc b/site.cc
index a945d28..c0ce487 100644
--- a/site.cc
+++ b/site.cc
@@ -64,6 +64,7 @@ static ControlAdjuster::ControlInfo SiteControlsInfo[] = {
   {IDC_EDIT_USER_URL, CP_STRETCH, CP_BOTTOM},
   {IDC_BUTTON_ADD_URL, CP_RIGHT,   CP_BOTTOM},
   {IDC_SITE_USERURL,            CP_LEFT,    CP_BOTTOM},
+  {IDC_ALLOW_USER_URL,          CP_LEFT,    CP_BOTTOM},
   {0, CP_LEFT, CP_TOP}
 };
 
@@ -78,6 +79,7 @@ SitePage::SitePage ()
 
 using namespace std;
 
+bool allow_user_url;
 bool cache_is_usable;
 bool cache_needs_writing;
 string cache_warn_urls;
@@ -720,6 +722,11 @@ bool SitePage::OnMessageCmd (int id, HWND hwndctl, UINT code)
     eset (GetHWND (), IDC_EDIT_USER_URL, "");
     }
   }
+      }
+    case IDC_ALLOW_USER_URL:
+      {
+ if (code == BN_CLICKED)
+  allow_user_url = IsButtonChecked (IDC_ALLOW_USER_URL);
  break;
       }
     default:
--
2.15.1

Reply | Threaded
Open this post in threaded view
|

[PATCH setup v4 2/6] Use SitePage for cygwin.com mirrors only

Ken Brown-6
In reply to this post by Ken Brown-6
Add a bool member 'site_list_type::is_mirror' to indicate whether a
site is a mirror (possibly private) rather than a user URL
(corresponding to a non-mirror package repo).

Display only mirrors in the site chooser listbox.

Rename several SiteList variables to indicate that they now contain
only mirrors.  Add a few new ones, as well as some variables for lists
of user URLs.

Start using the user setting "last-mirror" only for mirrors.  Add a
new user setting "last-user-site" for saved user URLs.

Set the initial state of allow_user_url depending on whether there are
any saved sites that are known not to be mirrors.

Implement the appropriate action if the user unchecks
IDC_ALLOW_USER_URL.

As an unrelated bit of cleanup, define a helper function merge_site()
to avoid repeating the same code several times.
---
 site.cc | 221 ++++++++++++++++++++++++++++++++++++++++++++++------------------
 site.h  |  10 ++-
 2 files changed, 167 insertions(+), 64 deletions(-)

diff --git a/site.cc b/site.cc
index c0ce487..f2fa9fa 100644
--- a/site.cc
+++ b/site.cc
@@ -84,17 +84,26 @@ bool cache_is_usable;
 bool cache_needs_writing;
 string cache_warn_urls;
 
-/* Selected sites */
+/* Selected sites; may be inaccurate until save_dialog() is called */
 SiteList site_list;
 
 /* Fresh mirrors + selected sites */
 SiteList all_site_list;
 
+/* Selected mirrors; recomputed by save_dialog() */
+SiteList selected_mirror_list;
+
+/* All mirrors; recomputed by PopulateListBox() */
+SiteList all_mirror_list;
+
 /* Previously fresh + cached before */
-SiteList cached_site_list;
+SiteList cached_mirror_list;
+
+/* Stale selected mirrors to warn about and add to cache */
+SiteList dropped_mirror_list;
 
-/* Stale selected sites to warn about and add to cache */
-SiteList dropped_site_list;
+/* Selected URLs for non-mirror package repos */
+SiteList selected_usersite_list;
 
 StringArrayOption SiteOption('s', "site", "Download site");
 
@@ -108,10 +117,14 @@ SiteSetting::SiteSetting (): saved (false)
     {
       for (vector<string>::const_iterator n = SiteOptionStrings.begin ();
    n != SiteOptionStrings.end (); ++n)
- registerSavedSite (n->c_str ());
+ // With no information to the contrary, assume the site is a mirror.
+ registerSavedSite (n->c_str (), true);
     }
   else
-    getSavedSites ();
+    {
+      getSavedSites (lastMirrorKey (), true);
+      getSavedSites ("last-user-site", false);
+    }
 }
 
 const char *
@@ -129,8 +142,17 @@ SiteSetting::save()
   io_stream *f = UserSettings::instance().open (lastMirrorKey ());
   if (f)
     {
-      for (SiteList::const_iterator n = site_list.begin ();
-   n != site_list.end (); ++n)
+      for (SiteList::const_iterator n = selected_mirror_list.begin ();
+   n != selected_mirror_list.end (); ++n)
+ *f << n->url;
+      delete f;
+    }
+
+  f = UserSettings::instance().open ("last-user-site");
+  if (f)
+    {
+      for (SiteList::const_iterator n = selected_usersite_list.begin ();
+   n != selected_usersite_list.end (); ++n)
  *f << n->url;
       delete f;
     }
@@ -147,13 +169,15 @@ site_list_type::site_list_type (const string &_url,
  const string &_servername,
  const string &_area,
  const string &_location,
- bool _from_mirrors_lst)
+ bool _from_mirrors_lst,
+ bool _is_mirror)
 {
   url = _url;
   servername = _servername;
   area = _area;
   location = _location;
   from_mirrors_lst = _from_mirrors_lst;
+  is_mirror = _is_mirror;
 
   /* Canonicalize URL to ensure it ends with a '/' */
   if (url.at(url.length()-1) != '/')
@@ -193,6 +217,7 @@ site_list_type::site_list_type (site_list_type const &rhs)
   area = rhs.area;
   location = rhs.location;
   from_mirrors_lst = rhs.from_mirrors_lst;
+  is_mirror = rhs.is_mirror;
   displayed_url = rhs.displayed_url;
 }
 
@@ -205,6 +230,7 @@ site_list_type::operator= (site_list_type const &rhs)
   area = rhs.area;
   location = rhs.location;
   from_mirrors_lst = rhs.from_mirrors_lst;
+  is_mirror = rhs.is_mirror;
   displayed_url = rhs.displayed_url;
   return *this;
 }
@@ -224,8 +250,8 @@ site_list_type::operator < (site_list_type const &rhs) const
 static void
 save_dialog (HWND h)
 {
-  // Remove anything that was previously in the selected site list.
-  site_list.clear ();
+  // Remove anything that was previously in the selected mirror list.
+  selected_mirror_list.clear ();
 
   HWND listbox = GetDlgItem (h, IDC_URL_LIST);
   int sel_count = SendMessage (listbox, LB_GETSELCOUNT, 0, 0);
@@ -237,9 +263,23 @@ save_dialog (HWND h)
  {
   int mirror =
     SendMessage (listbox, LB_GETITEMDATA, sel_buffer[n], 0);
-  site_list.push_back (all_site_list[mirror]);
+  selected_mirror_list.push_back (all_mirror_list[mirror]);
  }
     }
+  site_list = selected_mirror_list;
+  if (allow_user_url)
+    site_list.insert (site_list.end (), selected_usersite_list.begin (),
+      selected_usersite_list.end ());
+}
+
+static void
+merge_site (SiteList & sites, site_list_type newsite)
+{
+  SiteList result;
+  merge (sites.begin(), sites.end(),
+        &newsite, &newsite + 1,
+        inserter (result, result.begin()));
+  sites = result;
 }
 
 // This is called only for lists of mirrors that came (now or in a
@@ -294,17 +334,11 @@ load_site_list (SiteList& theSites, char *theString)
   if (!semi || !semi2 || !semi3)
     continue;
 
-  site_list_type newsite (bol, semi, semi2, semi3, true);
+  site_list_type newsite (bol, semi, semi2, semi3, true, true);
   SiteList::iterator i = find (theSites.begin(),
        theSites.end(), newsite);
   if (i == theSites.end())
-    {
-      SiteList result;
-      merge (theSites.begin(), theSites.end(),
-     &newsite, &newsite + 1,
-     inserter (result, result.begin()));
-      theSites = result;
-    }
+    merge_site (theSites, newsite);
   else
     //TODO: remove and remerge
     *i = newsite;
@@ -316,6 +350,17 @@ load_site_list (SiteList& theSites, char *theString)
     }
 }
 
+// all_site_list should have the latest info about which URLs are mirrors.
+static bool
+not_mirror (site_list_type site)
+{
+  SiteList::iterator i = find (all_site_list.begin (), all_site_list.end (),
+       site);
+  if (i == all_site_list.end ())
+    return true;
+  return !i->is_mirror;
+}
+
 static int
 get_site_list (HINSTANCE h, HWND owner)
 {
@@ -361,11 +406,20 @@ get_site_list (HINSTANCE h, HWND owner)
   theCachedString = new_cstr_char_array (cached_mirrors);
 
   load_site_list (all_site_list, theMirrorString);
-  load_site_list (cached_site_list, theCachedString);
+  load_site_list (cached_mirror_list, theCachedString);
   
   delete[] theMirrorString;
   delete[] theCachedString;
 
+  // Did any saved user sites turn out to be mirrors?
+  SiteList::iterator i = partition (selected_usersite_list.begin (),
+    selected_usersite_list.end (), not_mirror);
+  selected_mirror_list.insert (selected_mirror_list.end (), i,
+       selected_usersite_list. end ());
+  selected_usersite_list.erase (i, selected_usersite_list.end ());
+
+  allow_user_url = selected_usersite_list.size ();
+
   return 0;
 }
 
@@ -379,11 +433,18 @@ get_site_list (HINSTANCE h, HWND owner)
 #define NOSAVE3_LEN (sizeof (NOSAVE3) - 1)
 
 void
-SiteSetting::registerSavedSite (const char * site)
+SiteSetting::registerSavedSite (const char * site, bool mirror)
 {
-  site_list_type tempSite(site, "", "", "", false);
+  site_list_type tempSite(site, "", "", "", false, mirror);
   SiteList::iterator i = find (all_site_list.begin(),
        all_site_list.end(), tempSite);
+  if (i != all_site_list.end() && i->is_mirror)
+    {
+      /* site was already registered as a mirror; leave it alone. */
+      selected_mirror_list.push_back (*i);
+      return;
+    }
+
   if (i == all_site_list.end())
     {
       /* Don't default to certain machines if they suffer
@@ -392,26 +453,26 @@ SiteSetting::registerSavedSite (const char * site)
   || 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 (*i);
+    all_site_list.erase (i);
+
+  merge_site (all_site_list, tempSite);
+  if (mirror)
+    selected_mirror_list.push_back (tempSite);
+  else
+    selected_usersite_list.push_back (tempSite);
 }
 
 void
-SiteSetting::getSavedSites ()
+SiteSetting::getSavedSites (const char *key, bool mirror)
 {
-  const char *buf = UserSettings::instance().get (lastMirrorKey ());
+  const char *buf = UserSettings::instance().get (key);
   if (!buf)
     return;
   char *fg_ret = strdup (buf);
   for (char *site = strtok (fg_ret, "\n"); site; site = strtok (NULL, "\n"))
-    registerSavedSite (site);
+    registerSavedSite (site, mirror);
   free (fg_ret);
 }
 
@@ -504,22 +565,28 @@ drop_proc (HWND h, UINT message, WPARAM wParam, LPARAM lParam)
 int check_dropped_mirrors (HWND h)
 {
   cache_warn_urls = "";
-  dropped_site_list.clear ();
+  dropped_mirror_list.clear ();
 
-  for (SiteList::const_iterator n = site_list.begin ();
-       n != site_list.end (); ++n)
+  for (SiteList::const_iterator n = selected_mirror_list.begin ();
+       n != selected_mirror_list.end (); ++n)
     {
       SiteList::iterator i = find (all_site_list.begin(), all_site_list.end(),
    *n);
       if (i == all_site_list.end() || !i->from_mirrors_lst)
  {
-  SiteList::iterator j = find (cached_site_list.begin(),
-       cached_site_list.end(), *n);
-  if (j != cached_site_list.end())
+         SiteList::iterator j = find (cached_mirror_list.begin(),
+                                      cached_mirror_list.end(), *n);
+         if (j != cached_mirror_list.end())
     {
+      // *i is stale.
+      // FIXME - There should be a better way to determine this.
+      // Copy info from *j to *i...
+      *i = *j;
+      // ...but remember that *i is stale.
+      i->from_mirrors_lst = false;
       Log (LOG_PLAIN) << "Dropped selected mirror: " << n->url
   << endLog;
-      dropped_site_list.push_back (*j);
+      dropped_mirror_list.push_back (*j);
       if (cache_warn_urls.size())
  cache_warn_urls += "\r\n";
       cache_warn_urls += i->url;
@@ -552,13 +619,13 @@ void save_cache_file (int cache_action)
   io_stream *f = UserSettings::instance().open ("mirrors-lst");
   if (f)
     {
-      write_cache_list (f, all_site_list);
+      write_cache_list (f, all_mirror_list);
       if (cache_action == CACHE_ACCEPT_WARN)
  {
   Log (LOG_PLAIN) << "Adding dropped mirrors to cache to warn again."
       << endLog;
   *f << "# Following mirrors re-added by setup.exe to warn again about dropped urls.";
-  write_cache_list (f, dropped_site_list);
+  write_cache_list (f, dropped_mirror_list);
  }
       delete f;
     }
@@ -569,6 +636,13 @@ bool SitePage::Create ()
   return PropertyPage::Create (IDD_SITE);
 }
 
+void
+SitePage::OnInit ()
+{
+  int a = allow_user_url ? BST_CHECKED : BST_UNCHECKED;
+  CheckDlgButton (GetHWND (), IDC_ALLOW_USER_URL, a);
+}
+
 long
 SitePage::OnNext ()
 {
@@ -583,10 +657,10 @@ SitePage::OnNext ()
   if (cache_needs_writing)
     save_cache_file (cache_action);
 
-  // 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;
+  // Log all the selected mirrors.
+  for (SiteList::const_iterator n = selected_mirror_list.begin ();
+       n != selected_mirror_list.end (); ++n)
+    Log (LOG_PLAIN) << "mirror: " << n->url << endLog;
 
   Progress.SetActivateTask (WM_APP_START_SETUP_INI_DOWNLOAD);
   return IDD_INSTATUS;
@@ -608,10 +682,10 @@ SitePage::OnBack ()
 void
 SitePage::OnActivate ()
 {
-  // Fill the list box with all known sites.
+  // Fill the list box with all known mirrors.
   PopulateListBox ();
 
-  // Load the user URL box with nothing - it is in the list already.
+  // Load the mirror 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.
@@ -647,10 +721,16 @@ SitePage::PopulateListBox ()
   int j;
   HWND listbox = GetDlgItem (IDC_URL_LIST);
 
+  // Recompute all_mirror_list.
+  all_mirror_list.clear ();
+  copy_if (all_site_list.begin (), all_site_list.end (),
+   back_inserter (all_mirror_list),
+   [] (site_list_type s) {return s.is_mirror;});
+
   // 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)
+  for (SiteList::const_iterator i = all_mirror_list.begin ();
+       i != all_mirror_list.end (); ++i)
     {
       j = SendMessage (listbox, LB_ADDSTRING, 0,
        (LPARAM) i->displayed_url.c_str());
@@ -658,14 +738,14 @@ SitePage::PopulateListBox ()
     }
 
   // Select the selected ones.
-  for (SiteList::const_iterator n = site_list.begin ();
-       n != site_list.end (); ++n)
+  for (SiteList::const_iterator n = selected_mirror_list.begin ();
+       n != selected_mirror_list.end (); ++n)
     {
-      SiteList::iterator i = find (all_site_list.begin(),
-                                   all_site_list.end(), *n);
-      if (i != all_site_list.end())
+      SiteList::iterator i = find (all_mirror_list.begin(),
+                                   all_mirror_list.end(), *n);
+      if (i != all_mirror_list.end())
         {
-          int index = i - all_site_list.begin();
+          int index = i - all_mirror_list.begin();
 
   // Highlight the selected item
   SendMessage (listbox, LB_SELITEMRANGE, TRUE, (index << 16) | index);
@@ -703,17 +783,31 @@ bool SitePage::OnMessageCmd (int id, HWND hwndctl, UINT code)
     std::string other_url = egetString (GetHWND (), IDC_EDIT_USER_URL);
     if (other_url.size())
     {
-    site_list_type newsite (other_url, "", "", "", false);
+    site_list_type newsite (other_url, "", "", "", false, true);
     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;
- site_list.push_back (newsite);
+ Log (LOG_BABBLE) << "Adding mirror: " << other_url << endLog;
+ selected_mirror_list.push_back (newsite);
       }
     else
-      site_list.push_back (*i);
+      {
+ if (i->is_mirror)
+  selected_mirror_list.push_back (*i);
+ else
+  {
+    all_site_list.erase (i);
+    merge_site (all_site_list, newsite);
+    selected_mirror_list.push_back (newsite);
+    SiteList::iterator j = find (selected_usersite_list. begin (),
+ selected_usersite_list.end (),
+ newsite);
+    if (j != selected_usersite_list.end ())
+      selected_usersite_list.erase (j);
+  }
+      }
 
     // Update the list box.
     PopulateListBox ();
@@ -722,11 +816,16 @@ bool SitePage::OnMessageCmd (int id, HWND hwndctl, UINT code)
     eset (GetHWND (), IDC_EDIT_USER_URL, "");
     }
   }
+ break;
       }
     case IDC_ALLOW_USER_URL:
       {
  if (code == BN_CLICKED)
-  allow_user_url = IsButtonChecked (IDC_ALLOW_USER_URL);
+  {
+    allow_user_url = IsButtonChecked (IDC_ALLOW_USER_URL);
+    if (!allow_user_url)
+      selected_usersite_list.clear ();
+  }
  break;
       }
     default:
diff --git a/site.h b/site.h
index d16db8e..3525931 100644
--- a/site.h
+++ b/site.h
@@ -21,6 +21,7 @@
 
 #include "proppage.h"
 
+// For mirrors of cygwin.com.
 class SitePage : public PropertyPage
 {
 public:
@@ -31,6 +32,7 @@ public:
 
   bool Create ();
 
+  virtual void OnInit ();
   virtual void OnActivate ();
   virtual long OnNext ();
   virtual long OnBack ();
@@ -50,7 +52,7 @@ public:
   site_list_type () : url (), displayed_url (), key () {};
   site_list_type (const site_list_type &);
   site_list_type (const std::string& , const std::string& ,
-                  const std::string& , const std::string&, bool);
+                  const std::string& , const std::string&, bool, bool);
   ~site_list_type () {};
   site_list_type &operator= (const site_list_type &);
   std::string url;
@@ -60,6 +62,8 @@ public:
   std::string location;
   // did this site come from mirrors.lst?
   bool from_mirrors_lst;
+  // is it a mirror of cygwin.com (possibly private)?
+  bool is_mirror;
   std::string displayed_url;
   // sort key
   std::string key;
@@ -86,8 +90,8 @@ class SiteSetting
     ~SiteSetting ();
   private:
     bool saved;
-    void getSavedSites();
-    void registerSavedSite(char const *);
+    void getSavedSites(char const *, bool);
+    void registerSavedSite(char const *, bool);
     const char *lastMirrorKey();
 };
 
--
2.15.1

Reply | Threaded
Open this post in threaded view
|

[PATCH setup v4 3/6] Create new page UserSitePage for user URLs

Ken Brown-6
In reply to this post by Ken Brown-6
This is done in two new files, usersite.h and usersite.cc, based on
site.h and site.cc.  The new page is activated after the mirror
selection page if IDC_ALLOW_USER_URL is checked.
---
 Makefile.am |   2 +
 main.cc     |   4 +
 res.rc      |  25 ++++++
 resource.h  |   5 ++
 site.cc     |  19 +++--
 usersite.cc | 268 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 usersite.h  |  43 ++++++++++
 7 files changed, 357 insertions(+), 9 deletions(-)
 create mode 100644 usersite.cc
 create mode 100644 usersite.h

diff --git a/Makefile.am b/Makefile.am
index a238d88..a0b0450 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -258,6 +258,8 @@ inilint_SOURCES = \
  threebar.h \
  UserSettings.cc \
  UserSettings.h \
+ usersite.cc \
+ usersite.h \
  win32.cc \
  win32.h \
  window.cc \
diff --git a/main.cc b/main.cc
index b44f9b6..a01fb43 100644
--- a/main.cc
+++ b/main.cc
@@ -53,6 +53,7 @@
 #include "localdir.h"
 #include "net.h"
 #include "site.h"
+#include "usersite.h"
 #include "choose.h"
 #include "prereq.h"
 #include "threebar.h"
@@ -133,6 +134,7 @@ main_display ()
   LocalDirPage LocalDir;
   NetPage Net;
   SitePage Site;
+  UserSitePage UserSite;
   ChooserPage Chooser;
   PrereqPage Prereq;
   DesktopSetupPage Desktop;
@@ -173,6 +175,7 @@ main_display ()
   LocalDir.Create ();
   Net.Create ();
   Site.Create ();
+  UserSite.Create ();
   Chooser.Create ();
   Prereq.Create ();
   Progress.Create ();
@@ -187,6 +190,7 @@ main_display ()
   MainWindow.AddPage (&LocalDir);
   MainWindow.AddPage (&Net);
   MainWindow.AddPage (&Site);
+  MainWindow.AddPage (&UserSite);
   MainWindow.AddPage (&Chooser);
   MainWindow.AddPage (&Prereq);
   MainWindow.AddPage (&Progress);
diff --git a/res.rc b/res.rc
index 5ea4c8b..85c7aea 100644
--- a/res.rc
+++ b/res.rc
@@ -154,6 +154,31 @@ BEGIN
                     IDC_ALLOW_USER_URL,"Button",BS_AUTOCHECKBOX,15,171,350,8
 END
 
+IDD_USERSITE DIALOG DISCARDABLE  0, 0, SETUP_STANDARD_DIALOG_DIMS
+STYLE DS_MODALFRAME | DS_3DLOOK | DS_CENTER | WS_CHILD | WS_VISIBLE |
+    WS_CAPTION | WS_SYSMENU
+EXSTYLE WS_EX_CONTROLPARENT
+CAPTION "Cygwin Setup - Choose Additional Package Repositories"
+FONT 8, "MS Shell Dlg"
+BEGIN
+    ICON            IDI_CYGWIN,IDC_HEADICON,SETUP_HEADICON_X,0,21,20
+    LISTBOX         IDC_USER_URL_LIST,66,45,185,110,LBS_NOINTEGRALHEIGHT |
+                    LBS_EXTENDEDSEL | WS_VSCROLL | WS_HSCROLL | WS_GROUP |
+                    WS_TABSTOP
+    LTEXT           "Known sites:",IDC_STATIC,66,34,183,8,NOT
+                    WS_GROUP
+    CONTROL         "",IDC_HEADSEPARATOR,"Static",SS_BLACKFRAME | SS_SUNKEN,0,28,
+                    SETUP_STANDARD_DIALOG_W,1
+    LTEXT           "Choose a site from this list, or add additional sites",
+                    IDC_STATIC,21,9,239,16,NOT WS_GROUP
+    LTEXT           "Choose A Site",IDC_STATIC_HEADER_TITLE,7,0,258,
+                    8,NOT WS_GROUP
+    EDITTEXT        IDC_USERSITE_EDIT_URL,65,160,185,14,ES_AUTOHSCROLL |
+                    WS_GROUP
+    LTEXT           "User URL:",IDC_USERSITE_USERURL,15,162,45,8,NOT WS_GROUP
+    PUSHBUTTON      "Add",IDC_BUTTON_ADD_USER_URL,255,160,50,14
+END
+
 IDD_NET DIALOG DISCARDABLE  0, 0, SETUP_STANDARD_DIALOG_DIMS
 STYLE DS_MODALFRAME | DS_CENTER | WS_CHILD | WS_CAPTION | WS_SYSMENU
 CAPTION "Cygwin Setup - Select Connection Type"
diff --git a/resource.h b/resource.h
index ed4f605..79575fb 100644
--- a/resource.h
+++ b/resource.h
@@ -67,6 +67,7 @@
 #define IDD_POSTINSTALL                   222
 #define IDD_FILE_INUSE                    223
 #define IDD_DOWNLOAD_ERROR                224
+#define IDD_USERSITE                      225
 
 // Bitmaps
 
@@ -179,3 +180,7 @@
 #define IDC_DOWNLOAD_EDIT                 594
 #define IDC_CHOOSE_DO_SEARCH              595
 #define IDC_ALLOW_USER_URL                596
+#define IDC_USER_URL_LIST                 597
+#define IDC_USERSITE_EDIT_URL             598
+#define IDC_USERSITE_USERURL              599
+#define IDC_BUTTON_ADD_USER_URL           600
diff --git a/site.cc b/site.cc
index f2fa9fa..dc9b0ee 100644
--- a/site.cc
+++ b/site.cc
@@ -662,10 +662,10 @@ SitePage::OnNext ()
        n != selected_mirror_list.end (); ++n)
     Log (LOG_PLAIN) << "mirror: " << n->url << endLog;
 
+  if (allow_user_url)
+    return IDD_USERSITE;
   Progress.SetActivateTask (WM_APP_START_SETUP_INI_DOWNLOAD);
   return IDD_INSTATUS;
-
-  return 0;
 }
 
 long
@@ -695,7 +695,8 @@ SitePage::OnActivate ()
 long
 SitePage::OnUnattended ()
 {
-  if (SendMessage (GetDlgItem (IDC_URL_LIST), LB_GETSELCOUNT, 0, 0) > 0)
+  if (allow_user_url
+      || SendMessage (GetDlgItem (IDC_URL_LIST), LB_GETSELCOUNT, 0, 0) > 0)
     return OnNext ();
   else
     return -2;
@@ -706,12 +707,11 @@ 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)
-    {
-      // At least one site selected, enable "Next".
-      ButtonFlags |= PSWIZB_NEXT;
-    }
+  // Enable Next if at least one mirror is selected or if we'll be
+  // going to the user URL page.
+  if (allow_user_url
+      || SendMessage (GetDlgItem (IDC_URL_LIST), LB_GETSELCOUNT, 0, 0) > 0)
+    ButtonFlags |= PSWIZB_NEXT;
   GetOwner ()->SetButtons (ButtonFlags);
 }
 
@@ -825,6 +825,7 @@ bool SitePage::OnMessageCmd (int id, HWND hwndctl, UINT code)
     allow_user_url = IsButtonChecked (IDC_ALLOW_USER_URL);
     if (!allow_user_url)
       selected_usersite_list.clear ();
+    CheckControlsAndDisableAccordingly ();
   }
  break;
       }
diff --git a/usersite.cc b/usersite.cc
new file mode 100644
index 0000000..91cabe7
--- /dev/null
+++ b/usersite.cc
@@ -0,0 +1,268 @@
+/*
+ * Copyright (c) 2017, Ken Brown
+ *
+ *     This program is free software; you can redistribute it and/or modify
+ *     it under the terms of the GNU General Public License as published by
+ *     the Free Software Foundation; either version 2 of the License, or
+ *     (at your option) any later version.
+ *
+ *     A copy of the GNU General Public License can be found at
+ *     http://www.gnu.org/
+ *
+ * Based on site.cc, written by DJ Delorie <[hidden email]>
+ *
+ */
+
+/* The purpose of this file is to let the user choose download sites
+   that are not cygwin.com mirrors.  */
+
+#include <string>
+#include <algorithm>
+
+#include "usersite.h"
+#include "site.h"
+#include "win32.h"
+#include "dialog.h"
+#include "resource.h"
+#include "state.h"
+#include "LogSingleton.h"
+#include "io_stream.h"
+#include "propsheet.h"
+#include "threebar.h"
+#include "ControlAdjuster.h"
+
+using namespace std;
+
+extern ThreeBarProgressPage Progress;
+
+/*
+  Sizing information.
+ */
+static ControlAdjuster::ControlInfo UserSiteControlsInfo[] = {
+  {IDC_USER_URL_LIST, CP_STRETCH, CP_STRETCH},
+  {IDC_USERSITE_EDIT_URL, CP_STRETCH, CP_BOTTOM},
+  {IDC_BUTTON_ADD_USER_URL, CP_RIGHT,   CP_BOTTOM},
+  {IDC_USERSITE_USERURL,        CP_LEFT,    CP_BOTTOM},
+  {0, CP_LEFT, CP_TOP}
+};
+
+UserSitePage::UserSitePage ()
+{
+  sizeProcessor.AddControlInfo (UserSiteControlsInfo);
+}
+
+using namespace std;
+
+// Recomputed by PopulateListBox()
+SiteList all_usersite_list;
+
+// Selected sites; may be inaccurate until save_dialog() is called
+extern SiteList site_list;
+
+// Selected mirrors
+extern SiteList selected_mirror_list;
+
+// Selected URLs for non-mirror package repos; recomputed by save_dialog()
+extern SiteList selected_usersite_list;
+
+static void
+save_dialog (HWND h)
+{
+  // Remove anything that was previously in the selected usersite list.
+  selected_usersite_list.clear ();
+
+  HWND listbox = GetDlgItem (h, IDC_USER_URL_LIST);
+  int sel_count = SendMessage (listbox, LB_GETSELCOUNT, 0, 0);
+  if (sel_count > 0)
+    {
+      int sel_buffer[sel_count];
+      SendMessage (listbox, LB_GETSELITEMS, sel_count, (LPARAM) sel_buffer);
+      for (int n = 0; n < sel_count; n++)
+ {
+  int mirror =
+    SendMessage (listbox, LB_GETITEMDATA, sel_buffer[n], 0);
+  selected_usersite_list.push_back (all_usersite_list[mirror]);
+ }
+    }
+  site_list = selected_mirror_list;
+  site_list.insert (site_list.end (), selected_usersite_list.begin (),
+    selected_usersite_list.end ());
+}
+
+bool UserSitePage::Create ()
+{
+  return PropertyPage::Create (IDD_USERSITE);
+}
+
+long
+UserSitePage::OnNext ()
+{
+  HWND h = GetHWND ();
+
+  save_dialog (h);
+
+  // Log all the selected URLs from the list.
+  for (SiteList::const_iterator n = selected_usersite_list.begin ();
+       n != selected_usersite_list.end (); ++n)
+    Log (LOG_PLAIN) << "user site: " << n->url << endLog;
+
+  Progress.SetActivateTask (WM_APP_START_SETUP_INI_DOWNLOAD);
+  return IDD_INSTATUS;
+}
+
+long
+UserSitePage::OnBack ()
+{
+  HWND h = GetHWND ();
+
+  save_dialog (h);
+
+  // Go back to the mirror selection page
+  return 0;
+}
+
+void
+UserSitePage::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 ();
+}
+
+long
+UserSitePage::OnUnattended ()
+{
+  if (site_list.size ())
+    return OnNext ();
+  else
+    return -2;
+}
+
+void
+UserSitePage::CheckControlsAndDisableAccordingly () const
+{
+  DWORD ButtonFlags = PSWIZB_BACK;
+
+  // Enable Next if at least one download site is selected.
+  if (selected_mirror_list.size ()
+      || SendMessage (GetDlgItem (IDC_USER_URL_LIST), LB_GETSELCOUNT, 0, 0) > 0)
+    ButtonFlags |= PSWIZB_NEXT;
+  GetOwner ()->SetButtons (ButtonFlags);
+}
+
+void
+UserSitePage::PopulateListBox ()
+{
+  int j;
+  HWND listbox = GetDlgItem (IDC_USER_URL_LIST);
+
+  // Recompute all_usersite_list.
+  all_usersite_list.clear ();
+  copy_if (all_site_list.begin (), all_site_list.end (),
+     back_inserter (all_usersite_list),
+     [] (site_list_type s) {return !s.is_mirror;});
+
+  // Populate the list box with the URLs.
+  SendMessage (listbox, LB_RESETCONTENT, 0, 0);
+  for (SiteList::const_iterator i = all_usersite_list.begin ();
+       i != all_usersite_list.end (); ++i)
+    {
+      j = SendMessage (listbox, LB_ADDSTRING, 0,
+       (LPARAM) i->displayed_url.c_str());
+      SendMessage (listbox, LB_SETITEMDATA, j, j);
+    }
+
+  // Select the selected ones.
+  for (SiteList::const_iterator n = selected_usersite_list.begin ();
+       n != selected_usersite_list.end (); ++n)
+    {
+      SiteList::iterator i = find (all_usersite_list.begin(),
+                                   all_usersite_list.end(), *n);
+      if (i != all_usersite_list.end())
+        {
+          int index = i - all_usersite_list.begin();
+
+  // Highlight the selected item
+  SendMessage (listbox, LB_SELITEMRANGE, TRUE, (index << 16) | index);
+  // Make sure it's fully visible
+  SendMessage (listbox, LB_SETCARETINDEX, index, FALSE);
+ }
+    }
+}
+
+bool UserSitePage::OnMessageCmd (int id, HWND hwndctl, UINT code)
+{
+  switch (id)
+    {
+    case IDC_USERSITE_EDIT_URL:
+      {
+ // Set the default pushbutton to ADD if the user is entering text.
+ if (code == EN_CHANGE)
+  SendMessage (GetHWND (), DM_SETDEFID,
+       (WPARAM) IDC_BUTTON_ADD_USER_URL, 0);
+ break;
+      }
+    case IDC_USER_URL_LIST:
+      {
+ if (code == LBN_SELCHANGE)
+  {
+    CheckControlsAndDisableAccordingly ();
+    save_dialog (GetHWND ());
+  }
+ break;
+      }
+    case IDC_BUTTON_ADD_USER_URL:
+      {
+ if (code == BN_CLICKED)
+  {
+    // User pushed the Add button.
+    std::string other_url = egetString (GetHWND (),
+ IDC_USERSITE_EDIT_URL);
+    if (other_url.size())
+      {
+ site_list_type newsite (other_url, "", "", "", false, false);
+ 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);
+    selected_usersite_list.push_back (newsite);
+  }
+ else if (!i->is_mirror)
+  selected_usersite_list.push_back (*i);
+ else
+  {
+    // Assume user knows what they're doing.
+    Log (LOG_BABBLE) << "Changing  status of " << other_url
+     << " from mirror to user url." << endLog;
+    *i = newsite;
+    selected_usersite_list.push_back (newsite);
+    SiteList::iterator j = find (selected_mirror_list.begin (),
+ selected_mirror_list.end (),
+ newsite);
+    if (j != selected_mirror_list.end ())
+      selected_mirror_list.erase (j);
+  }
+
+ // Update the list box.
+ PopulateListBox ();
+ // And allow the user to continue
+ CheckControlsAndDisableAccordingly ();
+ eset (GetHWND (), IDC_USERSITE_EDIT_URL, "");
+      }
+  }
+ break;
+      }
+    default:
+      // Wasn't recognized or handled.
+      return false;
+    }
+
+  // Was handled since we never got to default above.
+  return true;
+}
diff --git a/usersite.h b/usersite.h
new file mode 100644
index 0000000..842a0b0
--- /dev/null
+++ b/usersite.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2017, Ken Brown
+ *
+ *     This program is free software; you can redistribute it and/or modify
+ *     it under the terms of the GNU General Public License as published by
+ *     the Free Software Foundation; either version 2 of the License, or
+ *     (at your option) any later version.
+ *
+ *     A copy of the GNU General Public License can be found at
+ *     http://www.gnu.org/
+ *
+ * Based on site.h, written by Robert Collins <[hidden email]>
+ *
+ */
+
+#ifndef SETUP_USERSITE_H
+#define SETUP_USERSITE_H
+
+#include "proppage.h"
+
+// For user URLs that are not mirrors of cygwin.com.
+class UserSitePage : public PropertyPage
+{
+public:
+  UserSitePage ();
+  virtual ~ UserSitePage ()
+  {
+  };
+
+  bool Create ();
+
+  virtual void OnActivate ();
+  virtual long OnNext ();
+  virtual long OnBack ();
+  virtual long OnUnattended ();
+
+  virtual bool OnMessageCmd (int id, HWND hwndctl, UINT code);
+
+  void PopulateListBox();
+  void CheckControlsAndDisableAccordingly () const;
+};
+
+#endif /* SETUP_USERSITE_H */
--
2.15.1

Reply | Threaded
Open this post in threaded view
|

[PATCH setup v4 4/6] Keep the mirror list sorted properly

Ken Brown-6
In reply to this post by Ken Brown-6
When site.cc:load_site_list() added a mirror whose URL was already in
the list, it put the new entry in the same position as the old.
Remove the old entry and merge the new one instead.
---
 site.cc | 8 +++-----
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/site.cc b/site.cc
index dc9b0ee..44cd114 100644
--- a/site.cc
+++ b/site.cc
@@ -337,11 +337,9 @@ load_site_list (SiteList& theSites, char *theString)
   site_list_type newsite (bol, semi, semi2, semi3, true, true);
   SiteList::iterator i = find (theSites.begin(),
        theSites.end(), newsite);
-  if (i == theSites.end())
-    merge_site (theSites, newsite);
-  else
-    //TODO: remove and remerge
-    *i = newsite;
+  if (i != theSites.end ())
+    theSites.erase (i);
+  merge_site (theSites, newsite);
  }
         else
         {
--
2.15.1

Reply | Threaded
Open this post in threaded view
|

[PATCH setup v4 5/6] Display full URLs of user sites and private mirrors

Ken Brown-6
In reply to this post by Ken Brown-6
---
 site.cc | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/site.cc b/site.cc
index 44cd114..a1a5e3f 100644
--- a/site.cc
+++ b/site.cc
@@ -207,6 +207,12 @@ site_list_type::site_list_type (const string &_url,
       idx = 0;
   } while (idx > 0);
   key += url;
+  if (!from_mirrors_lst)
+    {
+      /* Display full URL (without trailing slash) */
+      displayed_url = url;
+      displayed_url.erase (displayed_url.end () - 1);
+    }
 }
 
 site_list_type::site_list_type (site_list_type const &rhs)
--
2.15.1

Reply | Threaded
Open this post in threaded view
|

[PATCH setup v4 6/6] Display area and location of official mirrors

Ken Brown-6
In reply to this post by Ken Brown-6
From: Brian Inglis <[hidden email]>

Mirrors from mirrors.lst have area and location info, which we now
display and add to the sort key.  For private mirrors, continue to
display only the (full) URL, but make them sort last.

Change site_list_type::operator== to compare URLs rather than keys,
since the key no longer depends only on the URL.
---
 site.cc | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/site.cc b/site.cc
index a1a5e3f..fdf0721 100644
--- a/site.cc
+++ b/site.cc
@@ -207,11 +207,19 @@ site_list_type::site_list_type (const string &_url,
       idx = 0;
   } while (idx > 0);
   key += url;
-  if (!from_mirrors_lst)
+
+  if (from_mirrors_lst)
+    {
+      displayed_url = area + " - " + location + " - " + displayed_url;
+      key = area + " " + location + " " + displayed_url;
+    }
+  else
     {
       /* Display full URL (without trailing slash) */
       displayed_url = url;
       displayed_url.erase (displayed_url.end () - 1);
+      if (is_mirror)
+ key = "zzzz " + key;
     }
 }
 
@@ -244,7 +252,7 @@ site_list_type::operator= (site_list_type const &rhs)
 bool
 site_list_type::operator == (site_list_type const &rhs) const
 {
-  return stricmp (key.c_str(), rhs.key.c_str()) == 0;
+  return stricmp (url.c_str(), rhs.url.c_str()) == 0;
 }
 
 bool
--
2.15.1

Reply | Threaded
Open this post in threaded view
|

Re: [PATCH setup v4 6/6] Display area and location of official mirrors

Brian Inglis
On 2017-12-11 01:37, Corinna Vinschen wrote:

> On Dec 10 22:06, Brian Inglis wrote:
>> On 2017-12-10 11:50, Ken Brown wrote:
>>> On 12/10/2017 1:40 PM, Brian Inglis wrote:
>>>> On 2017-12-10 10:49, Ken Brown wrote:
>>>>> Mirrors from mirrors.lst have area and location info, which we now
>>>>> display and add to the sort key.
>>>> You didn't increase the list box width - are the hosts visible without scrolling?
>>> No, that was an oversight.  I'll fix that locally and use it in future versions
>>> (or in the commit, if this version is accepted).
>> You could cherry pick my patch against res.rc as a start to tweak your layouts
>> and tests.
> Doesn't this thread belong to cygwin-apps?

Indeed - sorry I got our wires crossed from a cc - heading back.

--
Take care. Thanks, Brian Inglis, Calgary, Alberta, Canada
Reply | Threaded
Open this post in threaded view
|

Re: [PATCH setup v4 0/6] Distinguish between user URLs and cygwin mirrors in UI

Ken Brown-6
In reply to this post by Ken Brown-6
On 12/10/2017 12:49 PM, Ken Brown wrote:
> TODO: Implement a way of validating purported mirrors.  For example,
> we could make sure they are signed with the cygwin signing key.  Or if
> the user has used the -X option to turn off signature checking, we
> could make sure that setup.ini contains "release: cygwin".
>
> Once we finish discussing this patch series, I'll look into that.

I went ahead and did this, just to make sure it would work as expected.
I'll post it shortly as a second patch series (depending on this one).

Ken