* Makefile.in (OBJS): Add win32.o - win32 support functions.
* README: Update todos.
* archive.cc (extract_file): Support a suffix for appending to extracted files.
* archive.h: Ditto.
* choose.cc (set_view_mode): Use the new view::views class.
(view::views::Unknown): New static for defaulting view::views variables.
(view::views::PackageFull): New static for the current view.
(view::views::Package): Ditto.
(view::views::Category): Ditto.
(topbucket::paint): Remove.
(topbucket::empty): Rename to pick_category_line::empty.
(topbucket::~topbucket): Remove.
(paint): Use the new view::views class.
Don't paint 'all' as a category when showing package categoies.
(pick_category_line::actiontext): New method.
(pick_category_line::paint): Make showing the category optional, and show the
'category action'.
(pick_category_line::click): Make showing the category optional, and
differentiate between the name being clicked, and the action description.
(view::view): Use the new view::views class.
(view::set_view_mode): Ditto.
(view::mode_caption): Ditto.
(view::views::caption): New method.
(view::set_headers): Use the new view::views class.
(view::clear_view): Ditto.
(viewsplusplus): Replaced by
(view::views::operator++): New operator.
(set_view_mode): Use the new view::views class.
(create_listview): Ditto.
(dialog_cmd): Ditto.
* choose.h (actions): Remove.
(views): Remove.
(pick_line): Add a new convenience constructor.
(top_bucket): Remove.
(pick_category_line): Reparent under pick_line, and adsorb top_bucket.
(view::views): New class.
* ini.h: Don't include choose.h
(is_download_action): Remove.
(is_upgrade_action): Remove.
(is_uninstall_action): Remove.
(is_full_action): Remove.
* install.cc (num_replacements): New static.
(rebootneeded): Ditto.
(replace_one): Handle upgrades separate from removal or new installs.
(install_one_source): Handle in use files.
(install_one): Don't repeat upgrades.
(do_install_thread): Initialize new statics.
Order actions as uninstall, replace, install.
Warn about rebooting if needed.
* res.rc (IDS_REBOOT_REQUIRED): New string.
* resource.h (IDS_REBOOT_REQUIRED): Give value.
* win32.h: Declare class Win32, and update copyright and intent message.
* win32.cc: New file.
+2002-01-20 Robert Collins <rbtcollins@hotmail.com>
+
+ * Makefile.in (OBJS): Add win32.o - win32 support functions.
+ * README: Update todos.
+ * archive.cc (extract_file): Support a suffix for appending to extracted files.
+ * archive.h: Ditto.
+ * choose.cc (set_view_mode): Use the new view::views class.
+ (view::views::Unknown): New static for defaulting view::views variables.
+ (view::views::PackageFull): New static for the current view.
+ (view::views::Package): Ditto.
+ (view::views::Category): Ditto.
+ (topbucket::paint): Remove.
+ (topbucket::empty): Rename to pick_category_line::empty.
+ (topbucket::~topbucket): Remove.
+ (paint): Use the new view::views class.
+ Don't paint 'all' as a category when showing package categoies.
+ (pick_category_line::actiontext): New method.
+ (pick_category_line::paint): Make showing the category optional, and show the
+ 'category action'.
+ (pick_category_line::click): Make showing the category optional, and
+ differentiate between the name being clicked, and the action description.
+ (view::view): Use the new view::views class.
+ (view::set_view_mode): Ditto.
+ (view::mode_caption): Ditto.
+ (view::views::caption): New method.
+ (view::set_headers): Use the new view::views class.
+ (view::clear_view): Ditto.
+ (viewsplusplus): Replaced by
+ (view::views::operator++): New operator.
+ (set_view_mode): Use the new view::views class.
+ (create_listview): Ditto.
+ (dialog_cmd): Ditto.
+ * choose.h (actions): Remove.
+ (views): Remove.
+ (pick_line): Add a new convenience constructor.
+ (top_bucket): Remove.
+ (pick_category_line): Reparent under pick_line, and adsorb top_bucket.
+ (view::views): New class.
+ * ini.h: Don't include choose.h
+ (is_download_action): Remove.
+ (is_upgrade_action): Remove.
+ (is_uninstall_action): Remove.
+ (is_full_action): Remove.
+ * install.cc (num_replacements): New static.
+ (rebootneeded): Ditto.
+ (replace_one): Handle upgrades separate from removal or new installs.
+ (install_one_source): Handle in use files.
+ (install_one): Don't repeat upgrades.
+ (do_install_thread): Initialize new statics.
+ Order actions as uninstall, replace, install.
+ Warn about rebooting if needed.
+ * res.rc (IDS_REBOOT_REQUIRED): New string.
+ * resource.h (IDS_REBOOT_REQUIRED): Give value.
+ * win32.h: Declare class Win32, and update copyright and intent message.
+ * win32.cc: New file.
+
2002-01-15 Corinna Vinschen <corinna@vinschen.de>
* io_stream.cc (io_stream::gets): Eliminate trailing new line chars.
state.o \
threebar.o \
version.o \
+ win32.o \
window.o \
$E
net releases.
TODO:
+* Remove "/" from symlinks (etags.exe->/ctags.exe is an example
* Src tickbox /source only can be confusing.
* support rpm/deb files for reading the package from. (To allow the maintainers the use of rpm/deb tools to create packages.)
* make a librar(y|ies) for setup and cygcheck to use containing
}
int
-archive::extract_file (archive * source, const char *prefix)
+archive::extract_file (archive * source, const char *prefix, const char *suffix)
{
if (!source)
return 1;
- const char *destfilename = concat (prefix, source->next_file_name (), 0);
+ const char *destfilename = concat (prefix, source->next_file_name (), suffix, 0);
switch (source->next_file_type ())
{
case ARCHIVE_FILE_REGULAR:
* The stream is not taken over - it will not be automatically deleted
*/
virtual io_stream *extract_file () = NULL;
- /* extract the next file to the given prefix in one step
+ /* extract the next file to the given prefix in one step, and name it with the
+ * given suffix.
* returns 1 on failure.
*/
- static int extract_file (archive *, const char *);
+ static int extract_file (archive *, const char *, const char * = NULL);
/*
* To create a stream that will be compressed, you should open the url, and then get a new stream
{0, 0, 0, 0}
};
-static void set_view_mode (HWND h, views mode);
+static void set_view_mode (HWND h, view::views mode);
+
+// view:: views
+const view::views view::views::Unknown (0);
+const view::views view::views::PackageFull (1);
+const view::views view::views::Package = view::views (2);
+const view::views view::views::Category (3);
packageversion *
pkgtrustp (packagemeta const &pkg, trusts const t)
}
void
-topbucket::paint (HDC hdc, int x, int y, int row, int show_cat)
-{
- int accum_row = row;
- for (size_t n = 1; n <= bucket.number (); n++)
- {
- bucket[n]->paint (hdc, x, y, accum_row, show_cat);
- accum_row += bucket[n]->itemcount ();
- }
-}
-
-void
-topbucket::empty (void)
+pick_category_line::empty (void)
{
while (bucket.number ())
{
}
}
-topbucket::~topbucket (void)
-{
- empty ();
-}
-
-int
-topbucket::click (int const myrow, int const ClickedRow, int const x)
-{
- int accum_row = myrow;
- for (size_t n = 1; n <= bucket.number (); n++)
- {
- accum_row += bucket[n]->itemcount ();
- if (accum_row > ClickedRow)
- return bucket[n]->click (accum_row - bucket[n]->itemcount (),
- ClickedRow, x);
- }
- return 0;
-}
-
static void
paint (HWND hwnd)
{
cr.bottom);
chooser->contents.paint (hdc, x, y, 0, (chooser->get_view_mode () ==
- VIEW_CATEGORY) ? 0 : 1);
+ view::views::Category) ? 0 : 1);
if (chooser->contents.itemcount () == 0)
{
/* shows "first" category - do we want to show any? */
if (pkg.Categories.number () && show_cat)
{
+ int index = 1;
+ if (!strcasecmp (pkg.Categories[1]->key.name, "All"))
+ index = 2;
IntersectClipRect (hdc, x + chooser->headers[chooser->cat_col].x, by,
x + chooser->headers[chooser->cat_col].x +
chooser->headers[chooser->cat_col].x, by + 11);
TextOut (hdc, x + chooser->headers[chooser->cat_col].x + HMARGIN / 2, r,
- pkg.Categories[1]->key.name,
- strlen (pkg.Categories[1]->key.name));
+ pkg.Categories[index]->key.name,
+ strlen (pkg.Categories[index]->key.name));
SelectClipRgn (hdc, oldClip2);
}
RestoreDC (hdc, oldDC);
}
+char const *
+pick_category_line::actiontext ()
+{
+ switch (current_default)
+ {
+ case Default_action: return "Default";
+ case Install_action: return "Install";
+ case Reinstall_action: return "Reinstall";
+ case Uninstall_action: return "Uninstall";
+ }
+ // Pacify GCC: (all case options are checked above)
+ return 0;
+}
+
void
pick_category_line::paint (HDC hdc, int x, int y, int row, int show_cat)
{
int by = r + tm.tmHeight - 11;
TextOut (hdc, x + chooser->headers[chooser->cat_col].x + HMARGIN / 2 + depth * 8,
r, cat.name, strlen (cat.name));
- SIZE s;
- GetTextExtentPoint32 (hdc, cat.name, strlen (cat.name), &s);
+ if (!labellength)
+ {
+ SIZE s;
+ GetTextExtentPoint32 (hdc, cat.name, strlen (cat.name), &s);
+ labellength = s.cx;
+ }
SelectObject (bitmap_dc, bm_spin);
BitBlt (hdc,
x + chooser->headers[chooser->cat_col].x +
- s.cx + depth * 8 +
+ labellength + depth * 8 +
ICON_MARGIN +
HMARGIN / 2, by, 11, 11, bitmap_dc, 0, 0, SRCCOPY);
+ TextOut (hdc,
+ x + chooser->headers[chooser->cat_col].x +
+ labellength + depth * 8 +
+ ICON_MARGIN + SPIN_WIDTH +
+ HMARGIN, r, actiontext(), strlen (actiontext()));
}
if (collapsed)
return;
{
if (myrow == ClickedRow && show_label)
{
- collapsed = !collapsed;
- int accum_row = 0;
- for (size_t n = 1; n <= bucket.number (); n++)
- accum_row += bucket[n]->itemcount ();
- return collapsed ? accum_row : -accum_row;
+ if ((size_t) x >= chooser->headers[chooser->cat_col].x +
+ labellength + depth * 8 +
+ ICON_MARGIN +
+ HMARGIN / 2)
+ {
+ for (size_t n = 1; n <= bucket.number (); n++)
+ ;
+ return 0;
+ }
+ else
+ {
+ collapsed = !collapsed;
+ int accum_row = 0;
+ for (size_t n = 1; n <= bucket.number (); n++)
+ accum_row += bucket[n]->itemcount ();
+ return collapsed ? accum_row : -accum_row;
+ }
}
else
{
header_height = wp.cy;
- view_mode = VIEW_PACKAGE;
+ view_mode = view::views::Package;
set_headers ();
init_headers (dc);
- view_mode = VIEW_CATEGORY;
+ view_mode = view::views::Category;
set_headers ();
init_headers (dc);
}
void
-view::set_view_mode (views _mode)
+view::set_view_mode (view::views _mode)
{
- if (_mode == NVIEW)
- view_mode = VIEW_PACKAGE_FULL;
- else
- view_mode = _mode;
+ view_mode = _mode;
set_headers ();
}
const char *
view::mode_caption ()
{
- switch (view_mode)
+ return view_mode.caption ();
+}
+
+const char *
+view::views::caption ()
+{
+ switch (_value)
{
- case VIEW_UNKNOWN:
- return "";
- case VIEW_PACKAGE_FULL:
+ case 1:
return "Full";
- case VIEW_PACKAGE:
+ case 2:
return "Partial";
- case VIEW_CATEGORY:
+ case 3:
return "Category";
default:
return "";
void
view::set_headers ()
{
- switch (view_mode)
+ if (view_mode == views::Unknown)
+ return;
+ if (view_mode == views::PackageFull ||
+ view_mode == views::Package)
{
- case VIEW_UNKNOWN:
- return;
- case VIEW_PACKAGE_FULL:
- case VIEW_PACKAGE:
headers = pkg_headers;
current_col = 0;
new_col = 1;
cat_col = 3;
pkg_col = 4;
last_col = 4;
- break;
- case VIEW_CATEGORY:
+ }
+ else if (view_mode == views::Category)
+ {
headers = cat_headers;
current_col = 1;
new_col = 2;
cat_col = 0;
pkg_col = 4;
last_col = 4;
- break;
- default:
- return;
}
+ else
+ return;
while (int n = SendMessage (listheader, HDM_GETITEMCOUNT, 0, 0))
{
SendMessage (listheader, HDM_DELETEITEM, n - 1, 0);
void
view::insert_pkg (packagemeta & pkg)
{
- if (view_mode != VIEW_CATEGORY)
+ if (view_mode != views::Category)
{
pick_pkg_line & line = *new pick_pkg_line (pkg);
contents.insert (line);
view::clear_view (void)
{
contents.empty ();
- switch (view_mode)
- {
- case VIEW_UNKNOWN:
- break;
- case VIEW_PACKAGE_FULL:
- case VIEW_PACKAGE:
+ if (view_mode == views::Unknown)
+ return;
+ if (view_mode == views::PackageFull ||
+ view_mode == views::Package)
contents.ShowLabel (false);
- break;
- case VIEW_CATEGORY:
+ else if (view_mode == views::Category)
contents.ShowLabel ();
- break;
- default:
- return;
- }
}
-static views
-viewsplusplus (views theview)
+view::views&
+view::views::operator++ ()
{
- switch (theview)
- {
- case VIEW_UNKNOWN:
- return VIEW_PACKAGE_FULL;
- case VIEW_PACKAGE_FULL:
- return VIEW_PACKAGE;
- case VIEW_PACKAGE:
- return VIEW_CATEGORY;
- case VIEW_CATEGORY:
- return NVIEW;
- default:
- return VIEW_UNKNOWN;
- }
+ ++_value;
+ if (_value > Category._value)
+ _value = 1;
+ return *this;
}
int
}
static void
-set_view_mode (HWND h, views mode)
+set_view_mode (HWND h, view::views mode)
{
chooser->set_view_mode (mode);
chooser->clear_view ();
packagedb db;
- switch (chooser->get_view_mode ())
+ if (chooser->get_view_mode () == view::views::Package)
{
- case VIEW_PACKAGE:
for (size_t n = 1; n <= db.packages.number (); n++)
{
packagemeta & pkg = *db.packages[n];
&& (pkg.desired->srcpicked || pkg.desired->binpicked)))
chooser->insert_pkg (pkg);
}
- break;
- case VIEW_PACKAGE_FULL:
+ }
+ else if (chooser->get_view_mode () == view::views::PackageFull)
+ {
for (size_t n = 1; n <= db.packages.number (); n++)
{
packagemeta & pkg = *db.packages[n];
chooser->insert_pkg (pkg);
}
- break;
- case VIEW_CATEGORY:
+ }
+ else if (chooser->get_view_mode () == view::views::Category)
+ {
/* start collapsed. TODO: make this a chooser flag */
for (size_t n = 1; n <= db.categories.number (); n++)
chooser->insert_category (db.categories[n], CATEGORY_COLLAPSED);
- break;
- default:
- break;
}
RECT r;
hinstance, 0);
ShowWindow (lv, SW_SHOW);
packagedb db;
- chooser = new view (VIEW_CATEGORY, lv, db.categories.registerbykey("All"));
+ chooser = new view (view::views::Category, lv, db.categories.registerbykey("All"));
default_trust (lv, TRUST_CURR);
- set_view_mode (lv, VIEW_CATEGORY);
+ set_view_mode (lv, view::views::Category);
if (!SetDlgItemText (dlg, IDC_CHOOSE_VIEWCAPTION, chooser->mode_caption ()))
log (LOG_BABBLE, "Failed to set View button caption %ld",
GetLastError ());
set_view_mode (lv, chooser->get_view_mode ());
break;
case IDC_CHOOSE_VIEW:
- set_view_mode (lv, viewsplusplus (chooser->get_view_mode ()));
+ set_view_mode (lv, ++chooser->get_view_mode ());
if (!SetDlgItemText
(h, IDC_CHOOSE_VIEWCAPTION, chooser->mode_caption ()))
log (LOG_BABBLE, "Failed to set View button caption %ld",
#define CATEGORY_EXPANDED 0
#define CATEGORY_COLLAPSED 1
-typedef enum
-{
- /* Note that the next four items must be in the same order as the
- TRUST items in ini.h. */
- ACTION_UNKNOWN,
- ACTION_PREV,
- ACTION_CURR,
- ACTION_TEST,
- ACTION_SKIP,
- ACTION_UNINSTALL,
- ACTION_REDO,
- ACTION_SRC_ONLY,
- ACTION_LAST,
- ACTION_ERROR,
- /* Use ACTION_SAME when you want to leve the current version unaltered
- * even if it that version is not in setup.ini
- */
- ACTION_SAME = 100,
- /* Actions taken when installed version matches the selected version. */
- ACTION_SAME_PREV = ACTION_PREV + ACTION_SAME,
- ACTION_SAME_CURR = ACTION_CURR + ACTION_SAME,
- ACTION_SAME_TEST = ACTION_TEST + ACTION_SAME,
- /* Last action. */
- ACTION_SAME_LAST
-}
-actions;
-
-typedef enum
-{
- VIEW_UNKNOWN,
- VIEW_PACKAGE_FULL,
- VIEW_PACKAGE,
- VIEW_CATEGORY,
- NVIEW
-}
-views;
-
struct _header
{
const char *text;
{
};
protected:
- pick_line ()
- {
- };
+ pick_line () { };
+ pick_line (char const *aKey):key(aKey) {};
pick_line (pick_line const &);
pick_line & operator= (pick_line const &);
};
packagemeta & pkg;
};
-class topbucket:public pick_line
-{
-public:
- topbucket ()
- {
- key = 0;
- };
- virtual void paint (HDC hdc, int x, int y, int row, int show_cat);
- virtual int click (int const myrow, int const ClickedRow, int const x);
- virtual int itemcount () const
- {
- int t = 0;
- for (size_t n = 1; n <= bucket.number (); n++)
- t += bucket[n]->itemcount ();
- return t;
- };
- virtual bool IsContainer (void) const
- {
- return true;
- }
- virtual void insert (pick_line & aLine)
- {
- bucket.registerbyobject (aLine);
- }
- virtual void empty (void);
- virtual ~ topbucket ();
-protected:
- topbucket (topbucket const &);
- topbucket & operator= (topbucket const &);
- list < pick_line, char const *, strcasecmp > bucket;
-};
-
-
-class pick_category_line:public topbucket
+class pick_category_line:public pick_line
{
public:
pick_category_line (Category & _cat, size_t thedepth = 0, bool aBool =
- true, bool aBool2 = true):cat (_cat), depth(thedepth)
+ true, bool aBool2 = true):pick_line (_cat.key), current_default (Default_action),
+ cat (_cat), labellength (0), depth(thedepth)
{
if (aBool)
{
collapsed = false;
show_label = aBool2;
}
-
- key = _cat.key;
};
+ ~pick_category_line (){ empty (); }
void ShowLabel(bool aBool = true) {show_label = aBool; if (!show_label) collapsed = false;}
virtual void paint (HDC hdc, int x, int y, int row, int show_cat);
virtual int click (int const myrow, int const ClickedRow, int const x);
t += bucket[n]->itemcount ();
return t;
};
+ virtual bool IsContainer (void) const
+ {
+ return true;
+ }
+ virtual void insert (pick_line & aLine)
+ {
+ bucket.registerbyobject (aLine);
+ }
+ void empty ();
private:
+ enum _actions {
+ Default_action,
+ Install_action,
+ Reinstall_action,
+ Uninstall_action
+ } current_default;
+ char const * actiontext();
Category & cat;
bool collapsed;
bool show_label;
+ size_t labellength;
size_t depth;
+ pick_category_line (pick_category_line const &);
+ pick_category_line & operator= (pick_category_line const &);
+ list < pick_line, char const *, strcasecmp > bucket;
};
class view
{
+ class views;
public:
int num_columns;
views get_view_mode ()
return listheader;
}
+
+ class views {
+ public:
+ static const views Unknown;
+ static const views PackageFull;
+ static const views Package;
+ static const views Category;
+ static const views NView;
+ views () : _value (0) {};
+ views (int aInt) { _value = aInt; if (_value < 0 || _value > 3)
+ _value = 0;}
+ views& operator++ ();
+ bool operator == (views const &rhs) {return _value == rhs._value;}
+ bool operator != (views const &rhs) {return _value != rhs._value;}
+ const char * caption ();
+
+ private:
+ int _value;
+ };
+
private:
HWND listview;
HWND listheader;
#define YYSTYPE char *
#ifdef __cplusplus
-/* For enums */
-#include "choose.h"
/* When setup.ini is parsed, the information is stored according to
the declarations here. ini.cc (via inilex and iniparse)
}
excludes;
-#define is_download_action(pkg) \
- ((pkg)->action == ACTION_PREV || \
- (pkg)->action == ACTION_CURR || \
- (pkg)->action == ACTION_TEST || \
- (pkg)->action == ACTION_REDO || \
- (pkg)->action == ACTION_SRC_ONLY)
-
-#define is_upgrade_action(pkg) \
- (((pkg)->action >= ACTION_CURR && \
- (pkg)->action <= ACTION_TEST) || \
- (pkg)->action == ACTION_REDO)
-
-#define is_uninstall_action(pkg) \
- (is_upgrade_action (pkg) || \
- (pkg)->action == ACTION_PREV || \
- (pkg)->action == ACTION_UNINSTALL)
-
-#define is_full_action(pkg) \
- (((pkg)->action >= ACTION_SAME_PREV && (pkg)->action <= ACTION_SAME_TEST) \
- || (pkg)->action == ACTION_SKIP)
-
-#define SRCACTION_NO 0
-#define SRCACTION_YES 1
#endif
#endif /* _INI_H_ */
files in /etc/setup/\* and create the mount points. */
#if 0
-static const char *cvsid =
- "\n%%% $Id$\n";
+static const char *cvsid = "\n%%% $Id$\n";
#endif
#include "win32.h"
0
};
-static int num_installs, num_uninstalls;
+static int num_installs, num_replacements, num_uninstalls;
+static void uninstall_one (packagemeta &);
+static int replace_one (packagemeta &);
+static int install_one_source (packagemeta &, packagesource &, char const *,
+ package_type_t);
+static bool rebootneeded;
/* FIXME: upgrades should be a method too */
static void
num_uninstalls++;
}
+/* uninstall and install a package, preserving configuration
+ * files and the like.
+ * This method should also know about replacing in-use file.
+ * ASSUMPTIONS: pkgm is installed.
+ * pkgm has a desired package.
+ */
+static int
+replace_one (packagemeta & pkg)
+{
+ int errors = 0;
+ Progress.SetText1 ("Replacing...");
+ Progress.SetText2 (pkg.name);
+ log (0, "Replacing %s", pkg.name);
+ pkg.uninstall ();
+
+ errors +=
+ install_one_source (pkg, pkg.desired->bin, "cygfile:///", package_binary);
+ if (!errors)
+ pkg.installed = pkg.desired;
+ num_replacements++;
+ return errors;
+}
/* install one source at a given prefix. */
log (LOG_BABBLE, "Installing file %s%s", prefix, fn);
if (archive::extract_file (thefile, prefix) != 0)
{
- log (0, "Unable to install file %s%s", prefix, fn);
- errors++;
+ //extract to temp location
+ if (archive::extract_file (thefile, prefix, ".new") != 0)
+ {
+ log (0, "Unable to install file %s%s", prefix, fn);
+ errors++;
+ }
+ else
+ //switch Win32::OS
+ {
+ switch (Win32::OS ())
+ {
+ case Win32::Win9x:{
+ /* Get the short file names */
+ char source[MAX_PATH];
+ unsigned int len =
+ GetShortPathName (cygpath ("/", fn, ".new", 0),
+ source, MAX_PATH);
+ if (!len || len > MAX_PATH)
+ {
+ log (0,
+ "Unable to schedule reboot replacement of file %s with %s (Win32 Error %ld)",
+ cygpath ("/", fn, 0), cygpath ("/", fn, ".new",
+ 0),
+ GetLastError ());
+ ++errors;
+ }
+ else
+ {
+ char dest[MAX_PATH];
+ len =
+ GetShortPathName (cygpath ("/", fn, 0), dest,
+ MAX_PATH);
+ if (!len || len > MAX_PATH)
+ {
+ log (0,
+ "Unable to schedule reboot replacement of file %s with %s (Win32 Error %ld)",
+ cygpath ("/", fn, 0), cygpath ("/", fn,
+ ".new", 0),
+ GetLastError ());
+ ++errors;
+
+ }
+ else
+ /* trigger a replacement on reboot */
+ if (!WritePrivateProfileString
+ ("rename", dest, source, "WININIT.INI"))
+ {
+ log (0,
+ "Unable to schedule reboot replacement of file %s with %s (Win32 Error %ld)",
+ cygpath ("/", fn, 0), cygpath ("/", fn,
+ ".new", 0),
+ GetLastError ());
+ ++errors;
+ }
+
+ }
+ }
+ break;
+ case Win32::WinNT:
+ /* XXX FIXME: prefix may not be / for in use files -
+ * although it most likely is
+ * - we need a io method to get win32 paths
+ * or to wrap this system call
+ */
+ if (!MoveFileEx (cygpath ("/", fn, ".new", 0),
+ cygpath ("/", fn, 0),
+ MOVEFILE_DELAY_UNTIL_REBOOT |
+ MOVEFILE_REPLACE_EXISTING))
+ {
+ log (0,
+ "Unable to schedule reboot replacement of file %s with %s (Win32 Error %ld)",
+ cygpath ("/", fn, 0), cygpath ("/", fn, ".new",
+ 0),
+ GetLastError ());
+ ++errors;
+ }
+ else
+ rebootneeded = true;
+ break;
+ }
+ }
}
progress (tmp->tell ());
{
int errors = 0;
- if (pkg.desired->binpicked)
+ if (pkg.installed != pkg.desired && pkg.desired->binpicked)
{
errors +=
install_one_source (pkg, pkg.desired->bin, "cygfile:///",
int i;
int errors = 0;
- num_installs = 0, num_uninstalls = 0;
+ num_installs = 0, num_uninstalls = 0, num_replacements = 0;
+ rebootneeded = false;
next_dialog = IDD_DESKTOP;
}
}
+ /* start with uninstalls - remove files that new packages may replace */
for (size_t n = 1; n <= db.packages.number (); n++)
{
packagemeta & pkg = *db.packages[n];
if (pkg.installed && (!pkg.desired || pkg.desired != pkg.installed))
+ uninstall_one (pkg);
+ }
+
+ /* now in-place binary upgrades/reinstalls, as these may remove fils
+ * that have been moved into new packages
+ */
+
+ for (size_t n = 1; n <= db.packages.number (); n++)
+ {
+ packagemeta & pkg = *db.packages[n];
+ if (pkg.installed && pkg.desired && pkg.desired->binpicked)
{
- uninstall_one (pkg);
+ int e = 0;
+ e += replace_one (pkg);
+ if (e)
+ errors++;
}
+ }
+
+ for (size_t n = 1; n <= db.packages.number (); n++)
+ {
+ packagemeta & pkg = *db.packages[n];
if (pkg.desired && (pkg.desired->srcpicked || pkg.desired->binpicked))
{
}
} // end of big package loop
+ if (rebootneeded)
+ note (owner, IDS_REBOOT_REQUIRED);
+
int temperr;
if ((temperr = db.flush ()))
{
IDS_ERR_RENAME "Can't rename %s to %s: %s"
IDS_NOTHING_INSTALLED "Nothing needed to be installed"
IDS_INSTALL_COMPLETE "Installation Complete"
+ IDS_REBOOT_REQUIRED "In-use files have been replaced. You need to reboot as soon as possible to activate the new versions. Cygwin may operate incorrectly until you reboot."
END
STRINGTABLE DISCARDABLE
#define IDC_STATIC_WELCOME_TITLE 1061
#define IDC_EDIT_USER_URL 1062
#define IDC_BUTTON_ADD_URL 1063
+#define IDS_REBOOT_REQUIRED 1064
#define IDC_STATIC -1
// Next default values for new objects
#define _APS_3D_CONTROLS 1
#define _APS_NEXT_RESOURCE_VALUE 129
#define _APS_NEXT_COMMAND_VALUE 40003
-#define _APS_NEXT_CONTROL_VALUE 1064
+#define _APS_NEXT_CONTROL_VALUE 1065
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif
--- /dev/null
+/*
+ * Copyright (c) 2002, Robert Collins
+ *
+ * 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/
+ *
+ * Written by Robert Collins <rbtcollins@hotmail.com>
+ *
+ */
+
+/* The purpose of this file is to centralize all the message
+ functions. */
+
+#if 0
+static const char *cvsid =
+ "\n%%% $Id$\n";
+#endif
+
+#include "win32.h"
+
+enum Win32::_os
+Win32::OS ()
+{
+ OSVERSIONINFO VersionInfo;
+ VersionInfo.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);
+ if (!GetVersionEx (&VersionInfo))
+ {
+ // Throw an exception or something ??
+ }
+ if (VersionInfo.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS)
+ return Win9x;
+ else
+ return WinNT;
+}
* http://www.gnu.org/
*
* Written by DJ Delorie <dj@cygnus.com>
+ * and Robert Collins <rbtcollins@hotmail.com>
*
*/
-/* The purpose of this file is to limit the number of Win32 headers we
+/* The inital purpose of this file was limit the number of Win32 headers we
actually have to parse. The Setup program only uses a few of them,
so there's no point in parsing them all (even lean-n-mean). Doing
- this cuts compile time in half. */
+ this cuts compile time in half. Now it's also the header for the Win32
+ class which provides runtime information about the OS
+ */
+
+#ifndef SETUP_WIN32_H
+#define SETUP_WIN32_H
#define NOCOMATTRIBUTE
#include <wininet.h>
#include <windowsx.h>
+
+/* =========================== */
+#ifdef __cplusplus
+class Win32 {
+ public:
+ enum _os {
+ Win9x,
+ WinNT
+ };
+ static enum _os OS ();
+};
+
+#endif //_cplusplus
+#endif // SETUP_WIN32_H