Index: setup/res.rc =================================================================== RCS file: /cvs/cygwin-apps/setup/res.rc,v retrieving revision 2.67 diff -u -p -r2.67 res.rc --- setup/res.rc 9 Sep 2005 19:52:51 -0000 2.67 +++ setup/res.rc 16 Nov 2005 19:59:08 -0000 @@ -356,6 +356,32 @@ BEGIN END +IDD_DROPPED DIALOG DISCARDABLE 0, 0, 317, 142 +STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Cygwin Setup - Use dropped mirrors?" +FONT 8, "MS Shell Dlg" +BEGIN + LTEXT "Warning:",IDC_STATIC,7,8,40,8 + LTEXT "One or more mirrors you have selected is/are not on the" + "list of official Cygwin mirrors any more. " + "It/They may be out of date or missing some packages.\n" + "This affects the following mirror(s):", + IDC_STATIC,47,8,263,32 + EDITTEXT IDC_DROP_MIRRORS,7,40,303,40,WS_VSCROLL | WS_HSCROLL | + ES_LEFT | ES_MULTILINE | ES_READONLY | ES_AUTOHSCROLL | + ES_AUTOVSCROLL + LTEXT "If you experience installation problems, consider trying " + "official mirrors only.\n\n" + "Do you want to continue, using this/these mirror(s)?", + IDC_STATIC,7,88,303,24 + CONTROL "&Don't warn me about this/these mirror(s) again", + IDC_DROP_NOWARN,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, + 7,120,213,15 + PUSHBUTTON "&Yes",IDYES,220,120,45,15 + DEFPUSHBUTTON "&No",IDNO,265,120,45,15 + +END + ///////////////////////////////////////////////////////////////////////////// // // Manifest Index: setup/resource.h =================================================================== RCS file: /cvs/cygwin-apps/setup/resource.h,v retrieving revision 2.32 diff -u -p -r2.32 resource.h --- setup/resource.h 9 Sep 2005 19:52:51 -0000 2.32 +++ setup/resource.h 16 Nov 2005 19:59:09 -0000 @@ -55,6 +55,7 @@ #define IDD_VIRUS 218 #define IDD_DESKTOP 219 #define IDD_PREREQ 220 +#define IDD_DROPPED 221 // Bitmaps @@ -152,3 +153,5 @@ #define IDC_PREREQ_TEXT 576 #define IDC_PREREQ_EDIT 577 #define IDC_PREREQ_CHECK 578 +#define IDC_DROP_MIRRORS 579 +#define IDC_DROP_NOWARN 580 Index: setup/site.cc =================================================================== RCS file: /cvs/cygwin-apps/setup/site.cc,v retrieving revision 2.40 diff -u -p -r2.40 site.cc --- setup/site.cc 14 Oct 2005 04:23:14 -0000 2.40 +++ setup/site.cc 16 Nov 2005 19:59:13 -0000 @@ -46,6 +46,17 @@ static const char *cvsid = extern ThreeBarProgressPage Progress; + +/* + What to do if dropped mirrors are selected. +*/ +enum +{ + CACHE_REJECT, // Go back to re-select mirrors. + CACHE_ACCEPT_WARN, // Go on. Warn again next time. + CACHE_ACCEPT_NOWARN // Go on. Don't warn again. +}; + /* Sizing information. */ @@ -67,9 +78,22 @@ SitePage::SitePage () using namespace std; +bool cache_is_usable; +bool cache_needs_writing; +String cache_warn_urls; + +/* Selected sites */ SiteList site_list; + +/* Fresh mirrors + selected sites */ SiteList all_site_list; +/* Previously fresh + cached before */ +SiteList cached_site_list; + +/* Stale selected sites to warn about and add to cache */ +SiteList dropped_site_list; + StringOption SiteOption("", 's', "site", "Download site", false); /* XXX make into a singleton? */ @@ -99,9 +123,13 @@ SiteSetting::save() } void -site_list_type::init (String const &newurl) +site_list_type::init (String const &newurl, String const &newservername, + String const &newarea, String const &newlocation) { url = newurl; + servername = newservername; + area = newarea; + location = newlocation; char *dots = new_cstr_char_array (newurl); char *dot = strchr (dots, '.'); @@ -137,15 +165,21 @@ site_list_type::init (String const &newu delete[] dpsave; } -site_list_type::site_list_type (String const &newurl) +site_list_type::site_list_type (String const &newurl, + String const &newservername, + String const &newarea, + String const &newlocation) { - init (newurl); + init (newurl, newservername, newarea, newlocation); } site_list_type::site_list_type (site_list_type const &rhs) { key = rhs.key; url = rhs.url; + servername = rhs.servername; + area = rhs.area; + location = rhs.location; displayed_url = rhs.displayed_url; } @@ -154,6 +188,9 @@ site_list_type::operator= (site_list_typ { key = rhs.key; url = rhs.url; + servername = rhs.servername; + area = rhs.area; + location = rhs.location; displayed_url = rhs.displayed_url; return *this; } @@ -191,48 +228,12 @@ save_dialog (HWND h) } } -static int -get_site_list (HINSTANCE h, HWND owner) +void +load_site_list (SiteList& theSites, char *theString) { - char mirror_url[1000]; - - if (LoadString (h, IDS_MIRROR_LST, mirror_url, sizeof (mirror_url)) <= 0) - return 1; - char *bol, *eol, *nl, *theString; - { - String mirrors = get_url_to_string (mirror_url, owner); - if (mirrors.size()) - { - io_stream *f = UserSettings::Instance().settingFileForSave("mirrors-lst"); - if (f) - { - f->write(mirrors.c_str(), mirrors.size() + 1); - delete f; - } - } - else - { - io_stream *f = UserSettings::Instance().settingFileForLoad("mirrors-lst"); - if (f) - { - int len; - while (len = f->read (mirror_url, 999)) - { - mirror_url[len] = '\0'; - mirrors += mirror_url; - } - delete f; - log (LOG_BABBLE) << "Using cached mirror list" << endLog; - } - else - { - log (LOG_BABBLE) << "Defaulting to empty mirror list" << endLog; - } - } - theString = new_cstr_char_array (mirrors); - nl = theString; - } - + char *bol, *eol, *nl; + + nl = theString; while (*nl) { bol = nl; @@ -251,25 +252,99 @@ get_site_list (HINSTANCE h, HWND owner) strncmp(bol, "ftp://", 6) == 0) { char *semi = strchr (bol, ';'); + char *semi2 = NULL; + char *semi3 = NULL; if (semi) - *semi = 0; - site_list_type newsite (bol); - SiteList::iterator i = find (all_site_list.begin(), - all_site_list.end(), newsite); - if (i == all_site_list.end()) + { + *semi = 0; + semi++; + semi2 = strchr (semi, ';'); + if (semi2) + { + *semi2 = 0; + semi2++; + semi3 = strchr (semi2, ';'); + if (semi3) + { + *semi3 = 0; + semi3++; + } + } + } + site_list_type newsite (bol, semi, semi2, semi3); + SiteList::iterator i = find (theSites.begin(), + theSites.end(), newsite); + if (i == theSites.end()) { SiteList result; - merge (all_site_list.begin(), all_site_list.end(), + merge (theSites.begin(), theSites.end(), &newsite, &newsite + 1, inserter (result, result.begin())); - all_site_list = result; + theSites = result; } else //TODO: remove and remerge *i = newsite; } } - delete[] theString; +} + +static int +get_site_list (HINSTANCE h, HWND owner) +{ + char mirror_url[1000]; + + char *theMirrorString, *theCachedString; + { + cache_is_usable = false; + cache_needs_writing = false; + String cached_mirrors = ""; + io_stream *f = UserSettings::Instance().settingFileForLoad("mirrors-lst"); + if (f) + { + int len; + while (len = f->read (mirror_url, 999)) + { + mirror_url[len] = '\0'; + cached_mirrors += mirror_url; + } + delete f; + log (LOG_BABBLE) << "Loaded cached mirror list" << endLog; + cache_is_usable = true; + } + else + { + log (LOG_BABBLE) << "Cached mirror list unavailable" << endLog; + } + if (LoadString (h, IDS_MIRROR_LST, mirror_url, sizeof (mirror_url)) <= 0) + return 1; + String mirrors = get_url_to_string (mirror_url, owner); + if (mirrors.size()) + { + cache_needs_writing = true; + } + else + { + if (cached_mirrors.size()) + { + mirrors = cached_mirrors; + log (LOG_BABBLE) << "Using cached mirror list" << endLog; + } + else + { + log (LOG_BABBLE) << "Defaulting to empty mirror list" << endLog; + } + cache_is_usable = false; + } + theMirrorString = new_cstr_char_array (mirrors); + theCachedString = new_cstr_char_array (cached_mirrors); + } + + load_site_list (all_site_list, theMirrorString); + load_site_list (cached_site_list, theCachedString); + + delete[] theMirrorString; + delete[] theCachedString; return 0; } @@ -286,7 +361,7 @@ get_site_list (HINSTANCE h, HWND owner) void SiteSetting::registerSavedSite (const char * site) { - site_list_type tempSite(site); + site_list_type tempSite(site, "", "", ""); SiteList::iterator i = find (all_site_list.begin(), all_site_list.end(), tempSite); if (i == all_site_list.end()) @@ -384,6 +459,113 @@ do_download_site_info (HINSTANCE hinst, CreateThread (NULL, 0, do_download_site_info_thread, context, 0, &threadID); } +static BOOL CALLBACK +drop_proc (HWND h, UINT message, WPARAM wParam, LPARAM lParam) +{ + switch (message) + { + case WM_INITDIALOG: + eset(h, IDC_DROP_MIRRORS, cache_warn_urls); + /* Should this be set by default? */ + // CheckDlgButton (h, IDC_DROP_NOWARN, BST_CHECKED); + SetFocus (GetDlgItem(h, IDC_DROP_NOWARN)); + return FALSE; + break; + case WM_COMMAND: + switch (LOWORD (wParam)) + { + case IDYES: + if (IsDlgButtonChecked (h, IDC_DROP_NOWARN) == BST_CHECKED) + EndDialog (h, CACHE_ACCEPT_NOWARN); + else + EndDialog (h, CACHE_ACCEPT_WARN); + break; + + case IDNO: + EndDialog (h, CACHE_REJECT); + break; + + default: + return 0; + } + return TRUE; + break; + default: + return FALSE; + } +} + +int check_dropped_mirrors (HWND h) +{ + cache_warn_urls = ""; + dropped_site_list.clear (); + + for (SiteList::const_iterator n = site_list.begin (); + n != site_list.end (); ++n) + { + SiteList::iterator i = find (all_site_list.begin(), all_site_list.end(), + *n); + if (i == all_site_list.end() || !i->servername.size()) + { + SiteList::iterator j = find (cached_site_list.begin(), + cached_site_list.end(), *n); + if (j != cached_site_list.end()) + { + log (LOG_PLAIN) << "Dropped selected mirror: " << n->url + << endLog; + dropped_site_list.push_back (*j); + if (cache_warn_urls.size()) + cache_warn_urls += "\r\n"; + cache_warn_urls += i->url; + } + } + } + if (cache_warn_urls.size()) + { + if (unattended_mode) + return CACHE_ACCEPT_WARN; + return DialogBox (hinstance, MAKEINTRESOURCE (IDD_DROPPED), h, + drop_proc); + } + return CACHE_ACCEPT_NOWARN; +} + +void save_cache_file (int cache_action) +{ + String s; + io_stream *f = UserSettings::Instance().settingFileForSave("mirrors-lst"); + if (f) + { + s = "# Do not edit - see warning in http://cygwin.com/mirrors.html\n"; + f->write(s.c_str(), s.size()); + for (SiteList::const_iterator n = all_site_list.begin (); + n != all_site_list.end (); ++n) + if (n->servername.size()) + { + s = n->url + ";" + n->servername + ";" + n->area + ";" + + n->location + "\n"; + f->write(s.c_str(), s.size()); + } + if (cache_action == CACHE_ACCEPT_WARN) + { + log (LOG_PLAIN) << "Adding dropped mirrors to cache to warn again." + << endLog; + s = "# Following mirrors re-added by setup.exe to warn again about dropped urls.\n"; + f->write(s.c_str(), s.size()); + for (SiteList::const_iterator n = dropped_site_list.begin (); + n != dropped_site_list.end (); ++n) + if (n->servername.size()) + { + s = n->url + ";" + n->servername + ";" + n->area + ";" + + n->location + "\n"; + f->write(s.c_str(), s.size()); + } + + } + delete f; + } +} + bool SitePage::Create () { return PropertyPage::Create (IDD_SITE); @@ -393,8 +575,16 @@ long SitePage::OnNext () { HWND h = GetHWND (); + int cache_action = CACHE_ACCEPT_NOWARN; save_dialog (h); + + if (cache_is_usable && !(cache_action = check_dropped_mirrors (h))) + return -1; + + if (cache_needs_writing) + save_cache_file (cache_action); + ChosenSites.save (); // Log all the selected URLs from the list. @@ -513,7 +703,7 @@ bool SitePage::OnMessageCmd (int id, HWN String other_url = egetString (GetHWND (), IDC_EDIT_USER_URL); if (other_url.size()) { - site_list_type newsite (other_url); + 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()) Index: setup/site.h =================================================================== RCS file: /cvs/cygwin-apps/setup/site.h,v retrieving revision 2.15 diff -u -p -r2.15 site.h --- setup/site.h 1 Nov 2003 05:58:46 -0000 2.15 +++ setup/site.h 16 Nov 2005 19:59:13 -0000 @@ -54,12 +54,16 @@ public: { }; site_list_type (site_list_type const &); - site_list_type (String const &); + site_list_type (String const &, String const &, String const &, + String const &); /* workaround for missing placement new in gcc 2.95 */ - void init (String const &); + void init (String const &, String const &, String const &, String const &); ~site_list_type () {}; site_list_type &operator= (site_list_type const &); String url; + String servername; + String area; + String location; String displayed_url; String key; bool operator == (site_list_type const &) const;