Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
25bcc11997 | ||
|
|
7ca709fcbb | ||
|
|
c3ce878376 | ||
|
|
a06ac42eff | ||
|
|
444eb6c211 | ||
|
|
eb6cbe1ee0 | ||
|
|
bcae9a2c37 | ||
|
|
d411b34dae | ||
|
|
a0fad4375a | ||
|
|
ffb02984fe | ||
|
|
b400df2565 | ||
|
|
b06607cc37 | ||
|
|
8881f42470 | ||
|
|
6558d31680 | ||
|
|
6e949677ec | ||
|
|
72f2d166b6 | ||
|
|
7b13cdf7b3 | ||
|
|
c7bdaad30a | ||
|
|
fd9fce25fc | ||
|
|
5ba7add5b5 | ||
|
|
68889d3804 | ||
|
|
8ab18d433a | ||
|
|
13d83949c4 | ||
|
|
daf98009d4 | ||
|
|
0cf5848772 | ||
|
|
0ecc4bd8d3 | ||
|
|
388a195794 | ||
|
|
0f89010225 | ||
|
|
42da49c5c1 | ||
|
|
0ffba26b1f | ||
|
|
b19b094aaa | ||
|
|
5cc1e898b9 | ||
|
|
a4aa68a085 | ||
|
|
c954101bd9 | ||
|
|
d20aeb4121 | ||
|
|
9440de5ca9 | ||
|
|
c2955b508c | ||
|
|
fbf70814f0 | ||
|
|
a823790926 | ||
|
|
14838b82ae | ||
|
|
e11347c005 | ||
|
|
98842f238e | ||
|
|
5ffc87ad9b | ||
|
|
fb5d139443 | ||
|
|
9d6ee05660 | ||
|
|
1ee97606aa | ||
|
|
b6f721c167 | ||
|
|
ede4933819 | ||
|
|
70ce4a6d06 | ||
|
|
213c26db3f | ||
|
|
8ae3c42100 | ||
|
|
ff466a1d2d | ||
|
|
5e46ed7cb6 | ||
|
|
c197ba76fa | ||
|
|
fa2b10f3ce | ||
|
|
7b523aa075 | ||
|
|
0ca9971460 | ||
|
|
b3f23abec0 | ||
|
|
a2d735fee5 | ||
|
|
fb801d8ebb | ||
|
|
9a92bfec45 | ||
|
|
6d50abb3cf | ||
|
|
778872363a | ||
|
|
6c404d57c9 | ||
|
|
449b645278 | ||
|
|
02428a26c0 | ||
|
|
90bbc19923 | ||
|
|
4f5690c89b | ||
|
|
4000fa1a2e | ||
|
|
ba7ffafa7f | ||
|
|
33b59d5723 | ||
|
|
28551a9666 | ||
|
|
c5478d6a0e |
@@ -13,4 +13,4 @@ install-sh
|
||||
*.glade.cpp
|
||||
*.ui.cpp
|
||||
*.txt.cpp
|
||||
gsmartcontrol.spec
|
||||
.kdev4
|
||||
@@ -19,7 +19,7 @@ See LICENSE_gpl2.txt and LICENSE_gpl3.txt for details.
|
||||
|
||||
|
||||
All files which don't have any copyright notices, as well as tests and
|
||||
examples are covered under the Whatever License. See LICENSE_whatever.txt for
|
||||
examples are covered under the Unlicense. See LICENSE_unlicense.txt for
|
||||
details.
|
||||
|
||||
|
||||
@@ -9,8 +9,8 @@ All original code (except for the tests) is licensed under the Zlib License.
|
||||
See LICENSE_zlib.txt for details.
|
||||
|
||||
|
||||
All tests and examples are covered under the Whatever License. See
|
||||
LICENSE_whatever.txt for details.
|
||||
All tests and examples are covered under the Unlicense. See
|
||||
LICENSE_unlicense.txt for details.
|
||||
|
||||
|
||||
Portions of this software are copyright Regents of the University of
|
||||
@@ -1,4 +1,4 @@
|
||||
Copyright (c) 2005, Google Inc.
|
||||
Copyright (c) 2005 - 2010, Google Inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
@@ -0,0 +1,25 @@
|
||||
|
||||
This is free and unencumbered software released into the public domain.
|
||||
|
||||
Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||
distribute this software, either in source code form or as a compiled
|
||||
binary, for any purpose, commercial or non-commercial, and by any
|
||||
means.
|
||||
|
||||
In jurisdictions that recognize copyright laws, the author or authors
|
||||
of this software dedicate any and all copyright interest in the
|
||||
software to the public domain. We make this dedication for the benefit
|
||||
of the public at large and to the detriment of our heirs and
|
||||
successors. We intend this dedication to be an overt act of
|
||||
relinquishment in perpetuity of all present and future rights to this
|
||||
software under copyright law.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
For more information, please refer to <http://unlicense.org/>
|
||||
@@ -0,0 +1,155 @@
|
||||
|
||||
# Add autoconf.m4 directory to local macro search path
|
||||
ACLOCAL_AMFLAGS = -I autoconf.m4
|
||||
|
||||
SUBDIRS = data debian.dist src
|
||||
|
||||
|
||||
# These files are actually needed for compilation.
|
||||
noinst_DATA = AUTHORS.txt LICENSE_gsmartcontrol.txt README.txt
|
||||
|
||||
|
||||
# For the files to be bundled with the distribution, specify them in
|
||||
# one of the following.
|
||||
|
||||
# These will be installed into docdir.
|
||||
# Some of these files are actually needed for compilation (see src/res/Makefile.am).
|
||||
dist_doc_DATA = AUTHORS.txt ChangeLog NEWS README.txt \
|
||||
LICENSE_boost_1_0.txt \
|
||||
LICENSE_bsd-ac.txt \
|
||||
LICENSE_bsd-ucb.txt \
|
||||
LICENSE_gpl2.txt \
|
||||
LICENSE_gpl3.txt \
|
||||
LICENSE_gsmartcontrol.txt \
|
||||
LICENSE_hz.txt \
|
||||
LICENSE_pcrecpp.txt \
|
||||
LICENSE_unlicense.txt \
|
||||
LICENSE_zlib.txt
|
||||
|
||||
|
||||
# nobase_ preserves their directory names.
|
||||
nobase_dist_doc_DATA = contrib/cron-based_noadmin/README \
|
||||
contrib/cron-based_noadmin/cron_gather_smart.sh \
|
||||
contrib/cron-based_noadmin/crontab.example \
|
||||
contrib/cron-based_noadmin/smartctl_subst.sh
|
||||
|
||||
|
||||
# Extra files bundled with distribution.
|
||||
# file2csource.sh is needed for building but not installed.
|
||||
EXTRA_DIST = COPYING INSTALL configure autogen.sh \
|
||||
gsmartcontrol.kdev4 \
|
||||
file2csource.sh \
|
||||
gsmartcontrol.spec
|
||||
|
||||
|
||||
|
||||
# PCH support
|
||||
|
||||
global_macros.h.gch: $(top_srcdir)/src/global_macros.h
|
||||
$(CXX) $(CXXFLAGS) $(DEFS) -x "c++-header" $(top_srcdir)/src/global_macros.h -o global_macros.h.gch
|
||||
|
||||
gch: global_macros.h.gch
|
||||
|
||||
gch-clean:
|
||||
rm -f global_macros.h.gch
|
||||
|
||||
|
||||
|
||||
# rpm support
|
||||
|
||||
src-rpm: dist
|
||||
rpmbuild -ts $(distdir).tar.bz2
|
||||
|
||||
|
||||
# Don't use this - it does something weird, and gcc errors out with "long long long" errors, etc...
|
||||
#rpm: dist
|
||||
# rpmbuild -ta $(distdir).tar.bz2
|
||||
|
||||
|
||||
|
||||
# NSIS installer support.
|
||||
# Requires wine, installed NSIS, smartctl-nc.exe, smartctl.exe, update-smart-drivedb.exe.
|
||||
# Gtkmm dlls and pcre dlls are required if linking against them.
|
||||
# dos2unix on build machine.
|
||||
# Execute only with win32 build present.
|
||||
|
||||
WIN_ZIP_NAME = $(PACKAGE)-$(VERSION)-win32
|
||||
WIN_ZIP_NOGTK_NAME = $(PACKAGE)-$(VERSION)-win32-nogtk
|
||||
|
||||
|
||||
win-dist: win-dist-nocleanup win-dist-cleanup
|
||||
|
||||
win-dist-nocleanup: win-dist-prepare nsis-dist-nocleanup win-zip-dist-nocleanup
|
||||
|
||||
win-dist-cleanup: win-zip-dist-cleanup nsis-dist-cleanup
|
||||
rm -rf win-dist
|
||||
|
||||
win-dist-clean: win-dist-cleanup
|
||||
rm -f gsmartcontrol-*.exe gsmartcontrol-*.zip
|
||||
|
||||
|
||||
win-dist-prepare-all: nsis-dist-prepare win-zip-dist-prepare
|
||||
|
||||
|
||||
# Don't strip smartctl (it will only change the header), and
|
||||
# don't strip update-smart-drivedb (it will break its CRC check).
|
||||
win-dist-prepare: all
|
||||
$(MKDIR_P) win-dist
|
||||
cp $(top_srcdir)/data/icon_*.png win-dist/
|
||||
|
||||
$(MKDIR_P) win-dist/doc
|
||||
cp data/nsis/distribution*.txt win-dist/doc/
|
||||
cp $(top_srcdir)/AUTHORS.txt $(top_srcdir)/LICENSE_* $(top_srcdir)/README.txt win-dist/doc/
|
||||
cp $(top_srcdir)/NEWS win-dist/doc/NEWS.txt
|
||||
|
||||
cp src/gsmartcontrol.exe src/gsmartcontrol.exe.manifest win-dist/
|
||||
|
||||
unix2dos win-dist/doc/*.txt
|
||||
$(STRIP) win-dist/*.exe
|
||||
|
||||
cp -p "@WINDOWS_BINDIR@"/smartctl-nc.exe win-dist/
|
||||
cp -p "@WINDOWS_BINDIR@"/smartctl.exe win-dist/
|
||||
cp -p "@WINDOWS_BINDIR@"/update-smart-drivedb.exe win-dist/
|
||||
|
||||
|
||||
nsis-dist-prepare: win-dist-prepare
|
||||
cp -a win-dist nsis-dist
|
||||
cp $(top_srcdir)/data/gsmartcontrol.ico nsis-dist/
|
||||
cp data/nsis/*.nsi $(top_srcdir)/data/nsis/nsi_* nsis-dist/
|
||||
unix2dos nsis-dist/*.nsi
|
||||
cp "@WINDOWS_BINDIR@"/"@GTK_INSTALLER_NAME@".exe nsis-dist/
|
||||
|
||||
nsis-dist-nocleanup: nsis-dist-prepare
|
||||
cd nsis-dist && @NSIS_EXEC@ gsmartcontrol.nsi
|
||||
mv nsis-dist/$(PACKAGE)-$(VERSION).exe .
|
||||
cd nsis-dist && @NSIS_EXEC@ /DNO_GTK gsmartcontrol.nsi
|
||||
mv nsis-dist/$(PACKAGE)-$(VERSION)-nogtk.exe .
|
||||
|
||||
nsis-dist-cleanup:
|
||||
rm -rf nsis-dist
|
||||
|
||||
nsis-dist: nsis-dist-nocleanup nsis-dist-cleanup
|
||||
|
||||
|
||||
win-zip-dist-prepare:
|
||||
cp -a win-dist $(WIN_ZIP_NAME)
|
||||
cp -a win-dist $(WIN_ZIP_NOGTK_NAME)
|
||||
cp -a "@WINDOWS_BINDIR@"/"@GTK_INSTALLER_NAME@"/* $(WIN_ZIP_NAME)/
|
||||
|
||||
win-zip-dist-nocleanup: win-zip-dist-prepare
|
||||
zip -K -9r $(WIN_ZIP_NAME).zip $(WIN_ZIP_NAME) -x $(WIN_ZIP_NAME)/doc/distribution-nogtk.txt
|
||||
zip -K -9r $(WIN_ZIP_NOGTK_NAME).zip $(WIN_ZIP_NOGTK_NAME) -x $(WIN_ZIP_NOGTK_NAME)/doc/distribution.txt
|
||||
|
||||
win-zip-dist-cleanup:
|
||||
rm -rf $(WIN_ZIP_NAME)
|
||||
rm -rf $(WIN_ZIP_NOGTK_NAME)
|
||||
|
||||
win-zip-dist: win-zip-dist-nocleanup win-zip-dist-cleanup
|
||||
|
||||
|
||||
|
||||
|
||||
distclean-local: gch-clean win-dist-clean
|
||||
|
||||
|
||||
|
||||
@@ -1,4 +1,58 @@
|
||||
|
||||
Version 0.8.7, released on 2012-08-11
|
||||
Implemented support for Adaptec RAID 5805 controller and possibly other
|
||||
Adaptec models as well (Linux).
|
||||
Implemented support for Areca RAID controller detection under Linux
|
||||
(untested).
|
||||
Implemented support for 3ware 3w-sas-supported (twl) RAID controller
|
||||
detection under Linux (untested).
|
||||
Implemented support for systems with several different 3ware controllers
|
||||
(twa/twe/twl).
|
||||
Fixed invalid parsing of tw_cli output which caused non-detection of
|
||||
drives and controllers with controller or port numbers greater than 9
|
||||
if tw_cli was found (3ware linux, windows).
|
||||
The duplicate drives are no longer shown for some Intel matrix controllers
|
||||
under Windows; Intel RAID controllers are fully supported under
|
||||
Windows now.
|
||||
Added options to show device name and serial number under drive icons.
|
||||
Updated SMART attribute definitions and added warnings for SSD lifetime
|
||||
attributes.
|
||||
gsmartcontrol-root has a new argument "--desktop=..." which replaces the
|
||||
old positional argument; compatibility with the old invocation syntax
|
||||
has been retained.
|
||||
Completely documented the source using doxygen tags.
|
||||
Added support for Fedora's consolehelper.
|
||||
Made GSmartControl DPI-aware under Windows.
|
||||
Fixed compilation issues with clang and gcc 4.7, as well as glib 2.31.x
|
||||
and newer.
|
||||
Fixed minor issues in NSIS installer.
|
||||
Fixed other minor bugs and made minor improvements.
|
||||
|
||||
Version 0.8.6, released on 2011-06-12
|
||||
Support detecting drives behind 3ware controllers (Linux, Windows),
|
||||
including tw_cli/cx/px mode in Windows. Having tw_cli is recommended
|
||||
but not required.
|
||||
Added support for specifying -d option and extra parameters via command
|
||||
line, "Add Device" and "Preferences" dialogs. This change effectively
|
||||
adds full support for multiple drives behind a single device name.
|
||||
Beesu and su-to-root are supported by gsmartcontrol-root script now.
|
||||
Completely revamped the attribute database and its handling, should be a
|
||||
lot more usable and forward-compatible now; SSD attributes are also
|
||||
included.
|
||||
In-program help has been expanded considerably.
|
||||
General improvements to user interface have been implemented (better GNOME
|
||||
HIG compliance, better tooltips, dialogs, etc...).
|
||||
Added ability to show smartctl output for devices whose info could not be
|
||||
parsed fully.
|
||||
Attributes in "brief" format are supported now.
|
||||
The parser has been updated to reflect the recent changes in smartctl.
|
||||
Quit and rescan operations are no longer denied without confirmation when
|
||||
tests are running.
|
||||
The Windows NSIS installer has been vastly improved.
|
||||
Better support for Windows Vista and 7.
|
||||
Changed copyright notices for files with Whatever License to use Unlicense.
|
||||
Added other minor features and fixed quite a few bugs.
|
||||
|
||||
Version 0.8.5, released on 2009-09-05
|
||||
GSmartControl now uses XDG config directory for per-user configuration on
|
||||
UNIX and CSIDL_PROFILE directory on Windows. Existing configuration is
|
||||
@@ -10,8 +10,8 @@ Technology) data on modern hard disk drives. It allows you to inspect the
|
||||
drive's SMART data to determine its health, as well as run various tests on
|
||||
it.
|
||||
|
||||
Note: Only ATA drives (both PATA and SATA) and various USB to ATA bridges are
|
||||
supported for now.
|
||||
Note: GSmartControl supports ATA drives (both PATA and SATA), various USB to
|
||||
ATA bridges and drives behind 3ware RAID controllers.
|
||||
|
||||
http://gsmartcontrol.berlios.de
|
||||
|
||||
@@ -101,11 +101,10 @@ You need to have the following software installed:
|
||||
* Gtkmm, version 2.6 or higher - see http://www.gtkmm.org .
|
||||
|
||||
* libglademm, version 2.4 or higher - see http://www.gtkmm.org .
|
||||
Note: libglademm is not needed when using GTK 2.12 and Gtkmm 2.12.
|
||||
Note: libglademm is not needed when using GTK+ / Gtkmm 2.12 or newer.
|
||||
|
||||
Note that having GTK+ 2.12 and Gtkmm 2.12 is HIGHLY recommended. While earlier
|
||||
versions may work, they may produce suboptimal results and buggy behavior.
|
||||
Libglademm is not needed when using GTK / Gtkmm 2.12.
|
||||
|
||||
Most of these packages are probably already provided by your distribution.
|
||||
Here are the packages you need to have to build GSmartControl on some Linux
|
||||
@@ -143,14 +142,13 @@ The following operating systems are supported:
|
||||
|
||||
* OpenBSD - Tested with OpenBSD 4.3 / x86-64 / gcc-3.3.5.
|
||||
|
||||
* Windows (2000 SP4 or newer) - Tested with Windows 2000 SP4, XP SP2 and Vista
|
||||
SP1. The Windows port uses pd0, pd1, etc... for physical drives 0, 1, etc... .
|
||||
* Windows (2000 SP4 or newer) - Tested with Windows 2000 SP4, Windows XP SP3,
|
||||
Windows Vista SP2 (32-bit and 64-bit), Windows 7 SP1 (32-bit and 64-bit). The
|
||||
Windows port uses pd0, pd1, etc... for physical drives 0, 1, etc... .
|
||||
|
||||
* Solaris - Tested with Solaris 10 / x86 / gcc-3.4.3 / blastwave,
|
||||
Solaris 10 / x86 / sunstudio12 / sunfreeware. OpenSolaris should work but has
|
||||
not been tested yet. Note: smartctl doesn't seem to support ATA under Solaris,
|
||||
while GSmartControl doesn't support SCSI yet. This only leaves various USB to
|
||||
ATA bridges. See smartctl (5), -d option for details.
|
||||
not been tested yet.
|
||||
|
||||
* Mac OS X - 3rd-party testing by Fink project.
|
||||
|
||||
@@ -202,18 +200,24 @@ The most important parameters are:
|
||||
|
||||
-?, --help - Show help options.
|
||||
|
||||
-V, --version - Display version information.
|
||||
-l, --no-locale - Don't use system locale.
|
||||
|
||||
-l, --no-locale - Disable locale.
|
||||
-V, --version - Display version information.
|
||||
|
||||
--no-scan - Don't scan devices on startup.
|
||||
|
||||
--no-hide-tabs - Don't hide non-identity tabs when SMART is disabled.
|
||||
--no-hide-tabs - Don't hide non-identity tabs when SMART is disabled. Useful
|
||||
for debugging.
|
||||
|
||||
--add-virtual - Load smartctl data from file, creating a virtual drive.
|
||||
--add-virtual - Load smartctl data from file, creating a virtual drive. You
|
||||
can specify this option multiple times.
|
||||
|
||||
--add-device - Add this device to device list. Useful with --no-scan to list
|
||||
certain drives only.
|
||||
--add-device - Add this device to device list. The format of the device is
|
||||
"<device>::<type>::<extra_args>", where type and extra_args are optional. This
|
||||
option is useful with --no-scan to list certain drives only. You can specify
|
||||
this option multiple times.
|
||||
Example: --add-device /dev/sda --add-device /dev/twa0::3ware,2 --add-device
|
||||
'/dev/sdb::::-T permissive'.
|
||||
|
||||
-v, --verbose - Enable verbose logging; same as --verbosity-level 5.
|
||||
|
||||
@@ -281,8 +285,8 @@ For more information, see smartctl and smartd documentation.
|
||||
|
||||
Known Issues
|
||||
|
||||
Only ATA drives (both PATA and SATA) and various USB to ATA bridges are
|
||||
supported for now. The main reasons are:
|
||||
Only ATA drives (both PATA and SATA), various USB to ATA bridges and drives
|
||||
behind 3ware RAID controllers are supported for now. The main reasons are:
|
||||
|
||||
* We can't support drives which don't work with smartmontools. This affects
|
||||
drives which don't support SMART or don't export SMART data correctly (e.g.
|
||||
@@ -329,7 +333,7 @@ If you still think it's a GSmartControl issue, please collect the following
|
||||
information about your system. Without it, it may be very hard or impossible
|
||||
to fix the bug.
|
||||
|
||||
* Which operating system you use (for example, openSUSE Linux 11.0).
|
||||
* Which operating system you use (for example, openSUSE Linux 11.4).
|
||||
|
||||
* Which version of GTK and Gtkmm you have installed. Finding this out is very
|
||||
distribution-specific. For example, on openSUSE it would be
|
||||
@@ -0,0 +1,220 @@
|
||||
|
||||
|
||||
GTKMM Notes:
|
||||
|
||||
To transfer an ownership from your local code to a container, use
|
||||
Gtk::Button* pButton = Gtk::manage(new Gtk::Button("Test"));
|
||||
container->add(*pButton);
|
||||
(add() takes an object by reference).
|
||||
otherwise, you will need to delete() it.
|
||||
|
||||
local scope destruction also works if using stack variables.
|
||||
{
|
||||
Gtk::Button aButton;
|
||||
// destroyed here
|
||||
}
|
||||
|
||||
|
||||
A treeview (also iconview, combobox) from glade comes
|
||||
with existing model, which should be unset.
|
||||
|
||||
|
||||
Bugs / patches:
|
||||
Patch pangomm for Pango::strip_markup().
|
||||
|
||||
|
||||
|
||||
--------------------------------------------------------
|
||||
|
||||
TODO:
|
||||
|
||||
|
||||
Investiage the new "-l ssd" and "-l devstat" options (since 5.42)
|
||||
|
||||
|
||||
Add menu item - "update drive database" (not sure about linux, should
|
||||
check if it's supported first; also need to run it in terminal).
|
||||
|
||||
|
||||
Testing:
|
||||
If ETA time has elapsed, but it's still only at 10% completion,
|
||||
ETA 0 is displayed. Fix.
|
||||
If smartctl -t ... returns an error, testing=true should not be set.
|
||||
Can't reproduce it?
|
||||
Detect running tests on launch (maybe ask the user too? some tests
|
||||
may be stuck due to bad firmware, e.g. 3ware/windows).
|
||||
|
||||
|
||||
|
||||
48-bit ATA command support:
|
||||
'-l xerror' -> Extended Comprehensive Error log: An multi-sector and
|
||||
LBA48 capable version of '-l error'. Output is similar, except more
|
||||
entries can exists and the high bytes of the registers are also printed.
|
||||
Some newer drives (Samsung) only write to this log.
|
||||
|
||||
'-l xselftest' -> Extended Self Test Log: An multi-sector and LBA48
|
||||
capable version of '-l selftest'. Output will be similar, except more
|
||||
entries can exists and the LBA values can be somewhat longer.
|
||||
|
||||
"smartctl -l this_wont_exist" gives the list of supported logs - this
|
||||
is needed to detect xerror / xselftest support in smartctl.
|
||||
|
||||
|
||||
Rework drive properties UI:
|
||||
use 48-bit or not or auto.
|
||||
Enable/disable/dont_touch SMART on startup for this drive.
|
||||
Enable/disable/dont_touch AODC on startup for this drive.
|
||||
Add --init-smart-only option to only apply the SMART/AODC enabling status
|
||||
from the drive properties.
|
||||
Add also --no-init-smart to avoid doing that on GUI startup.
|
||||
|
||||
Notifications:
|
||||
Tied to (drive::subdrive, notif_key, exact_value(optional)).
|
||||
If exact_value isn't specified when ignoring, notify on every value change.
|
||||
Ignore options:
|
||||
Per-drive: Ignore all notifications for this key, ignore only this value.
|
||||
Don't generate multiple notifications for the same drive/key combo.
|
||||
Clearing in preferences: Clear all ignored, clear ignored for this drive, clear individual.
|
||||
Soft-warnings require "-a" by default, tricky for scsi (maybe try -a, then -i?).
|
||||
|
||||
Monitor:
|
||||
Needs root access, so not gonna happen until the dbus/udisks stuff
|
||||
is finalized.
|
||||
Same program, add --tray option to start in tray only.
|
||||
Option to enable the tray icon.
|
||||
Option to continue running in the tray on window close.
|
||||
Use freedesktop notifications when notifications are generated
|
||||
and we're running in tray only.
|
||||
Don't generate the same notification at a single run time if it was
|
||||
ignored (untouched) by the user; Change the tray icon and
|
||||
show them in the main window instead.
|
||||
Periodically re-run smartctl to refresh the notifications.
|
||||
Periodically see if drives were added / removed (possibly use OS callbacks
|
||||
instead of polling?)
|
||||
|
||||
Win7 widget:
|
||||
Can be done in html/js.
|
||||
Shows temperature
|
||||
Detects drives
|
||||
Opens GSmartControl
|
||||
|
||||
If a drive is not recognized, suggest using -d (sat, sat,12, ...)
|
||||
Refer the user to
|
||||
http://sourceforge.net/apps/trac/smartmontools/wiki/Supported_USB-Devices
|
||||
|
||||
|
||||
|
||||
RAID:
|
||||
http://sourceforge.net/apps/trac/smartmontools/wiki/Supported_RAID-Controllers
|
||||
|
||||
Areca FreeBSD: since 5.42.
|
||||
Call as: smartctl -a -d areca,[1-24] /dev/arcmsr1
|
||||
|
||||
3ware FreeBSD:
|
||||
Call as: smartctl -i -d 3ware,[0-127] /dev/twa0 (or twe0)
|
||||
Detection: unknown.
|
||||
|
||||
LSI MegaRAID (SCSI/SAS), Linux:
|
||||
Call as: smartctl -i -d megaraid,[0-?] /dev/sda
|
||||
We should differentiate between ordinary sda and RAID one (not sure if sda is detected).
|
||||
Detection: unknown.
|
||||
|
||||
HighPoint RocketRAID ((S)ATA) Linux:
|
||||
Call as: smartctl -i -d hpt,[1-8]/[1-8] /dev/sda
|
||||
Call as: smartctl -i -d hpt,[1-8]/[1-8]/[1-15] /dev/sda
|
||||
Note: /dev/sda should be derived from this controller.
|
||||
We should differentiate between ordinary sda and RAID one (not sure if sda is detected).
|
||||
Smartctl docs specify smaller limits, but the code says these are the ones.
|
||||
Detection: unknown.
|
||||
|
||||
HighPoint RocketRAID ((S)ATA) FreeBSD:
|
||||
Call as: smartctl -i -d hpt,[1-8]/[1-8] /dev/hptrr
|
||||
Call as: smartctl -i -d hpt,[1-8]/[1-8]/[1-15] /dev/hptrr
|
||||
Note: /dev/hptrr should be derived from this controller.
|
||||
Smartctl docs specify smaller limits, but the code says these are the ones.
|
||||
Detection: unknown.
|
||||
TODO: Analyze sent info.
|
||||
|
||||
CCISS (HP (Compaq) Smart Array Controller) Linux:
|
||||
Call as: smartctl -a -d cciss,[0-127] /dev/cciss/c0d0
|
||||
c0d0 is the controller (d0 seems to be a logical drive, doesn't matter?).
|
||||
/dev/cciss/c0d0p1 is the first ordinary partition (used in mount, etc...).
|
||||
The port limit had a brief regression in 5.39.x (limited to 15).
|
||||
5.39 doesn't seem to work at all (prereleases work with P400 controller)?
|
||||
Possibly a 64-bit-only issue?
|
||||
To detect controller presence: cat /proc/devices, contains "cciss0"
|
||||
for controller 0.
|
||||
There is a cciss_vol_status utility but it doesn't report anything except "OK" status.
|
||||
It may not return the "SMART Health Status: OK" line in smartctl -i for some reason?
|
||||
(It returns it in -a though, and in some freebsd output I found).
|
||||
If no /dev/cciss exists, you may need to run "cd /dev; ./MAKEDEV cciss".
|
||||
Smartctl SVN has some /dev/sg* stuff, check it out. (?)
|
||||
May need "-d sat+cciss,N" for SATA.
|
||||
|
||||
CCISS (HP (Compaq) Smart Array Controller) FreeBSD:
|
||||
Seems to be the same as Linux (uses the same driver?).
|
||||
Detection: unknown.
|
||||
|
||||
|
||||
|
||||
|
||||
libdebug:
|
||||
per-channel disabling.
|
||||
per-channel formatting.
|
||||
all flags should be per-channel.
|
||||
bug: if -q is passed, Execution log doesn't contain libdebug log. (requires per-channel status control).
|
||||
use format_time() instead of ctime() and friends, with ISO formatting.
|
||||
|
||||
|
||||
|
||||
'-l sataphy' -> SATA Phy event counters: Non-SMART feature, useful to detect SATA cabling problems.
|
||||
|
||||
|
||||
SCT Temperatures
|
||||
-l scttemp prints temperature and history.
|
||||
-t scttempint,N[,p] (N - count, p - preserve across reset or not).
|
||||
This configures temperature logging interval (1 min by default) and clears the history.
|
||||
-l scterc[,...] to get/set the SCT Error Recovery Control time limit (5.40 and newer).
|
||||
|
||||
|
||||
Add detection for Interix (i586-pc-interix3), maybe with debian?
|
||||
|
||||
|
||||
|
||||
|
||||
----------- SMART stuff ----------
|
||||
|
||||
|
||||
Run one-time Immediate Offline test (-t offline).
|
||||
Offline tests only update Attributes, and if errors are found they will
|
||||
appear in SMART error log. Self-test logs are unaffected.
|
||||
Abort (-X). Abort works with Offline only if there's
|
||||
"Abort Offline collection upon new command" capability.
|
||||
If the drive has "Suspend Offline collection upon new command" capability,
|
||||
immediate offline test may be tracked through --capabilities (not on mine!).
|
||||
If it's "Abort Offline collection upon new command", then the test
|
||||
will abort on --capabilities or --abort.
|
||||
|
||||
|
||||
Polling time
|
||||
The self-test routine recommended polling time shall be equal to the number of minutes that is the minimum
|
||||
recommended time before which the host should first poll for test completion status. Actual test time could
|
||||
be several times this value. Polling before this time could extend the self-test execution time or abort the test
|
||||
depending on the state of bit 2 of the off-line data capability bits.
|
||||
|
||||
Autosave
|
||||
This command enables and disables the optional attribute autosave feature of the device. This command
|
||||
may either allow the device, after some vendor specified event, to save the device updated attribute values
|
||||
to non-volatile memory; or this command may cause the autosave feature to be disabled. The state of the
|
||||
attribute autosave feature (either enabled or disabled) shall be preserved by the device across power cycles.
|
||||
A value of zero written by the host into the device’s Sector Count register before issuing this command shall
|
||||
cause this feature to be disabled. Disabling this feature does not preclude the device from saving SMART
|
||||
data to non-volatile memory during some other normal operation such as during a power-on or power-off
|
||||
sequence or during an error recovery sequence.
|
||||
A value of F1h written by the host into the device’s Sector Count register before issuing this command shall
|
||||
cause this feature to be enabled. Any other meaning of this value or any other non-zero value written by the
|
||||
host into this register before issuing this command may differ from device to device. The meaning of any
|
||||
non-zero value written to this register at this time shall be preserved by the device across power cycles.
|
||||
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ AC_DEFUN([APP_COMPILER_OPTIONS], [
|
||||
# ---- Common compiler options (warnings, etc...)
|
||||
|
||||
AC_ARG_ENABLE(common-options, AS_HELP_STRING([--enable-common-options=<compiler>|auto|none],
|
||||
[enable useful compilation options (warnings, mostly). Accepted values are auto, none, gnu, intel, sun. (Default: auto)]),
|
||||
[enable useful compilation options (warnings, mostly). Accepted values are auto, none, gnu, clang, intel, sun. (Default: auto)]),
|
||||
[app_cv_compiler_common_options=${enableval}], [app_cv_compiler_common_options=auto])
|
||||
|
||||
# the default value is "yes" (if no value given after =), treat it as auto.
|
||||
@@ -47,8 +47,8 @@ AC_DEFUN([APP_COMPILER_OPTIONS], [
|
||||
|
||||
if test "x$app_cv_compiler_common_options" != "xnone"; then
|
||||
|
||||
# gcc / gnu environment, mingw, cygwin.
|
||||
if test "x$app_cv_compiler_common_options" = "xgnu"; then
|
||||
# gcc (or clang) / gnu environment, mingw, cygwin.
|
||||
if test "x$app_cv_compiler_common_options" = "xgnu" || test "x$app_cv_compiler_common_options" = "xclang"; then
|
||||
|
||||
if test "x$app_cv_target_os_env" = "xmingw32" || test "x$app_cv_target_os_env" = "xmingw64" \
|
||||
|| test "x$app_cv_target_os_env" = "xcygwin"; then
|
||||
@@ -60,10 +60,13 @@ AC_DEFUN([APP_COMPILER_OPTIONS], [
|
||||
app_cv_compiler_options_ldflags="$app_cv_compiler_options_ldflags -mms-bitfields"
|
||||
fi
|
||||
|
||||
# Note: Disabled -Wconversion, it was causing lots of silly warnings under x86-64.
|
||||
app_cv_compiler_tmp_var="-Wall -Wcast-align -Wcast-qual -Wconversion \
|
||||
-Wctor-dtor-privacy -Wfloat-equal -Wnon-virtual-dtor -Woverloaded-virtual \
|
||||
-Wpointer-arith -Wshadow -Wsign-compare -Wsign-promo -Wundef -Wwrite-strings";
|
||||
if test "x$app_cv_compiler_common_options" = "xclang"; then
|
||||
# these are really annoying
|
||||
app_cv_compiler_tmp_var="$app_cv_compiler_tmp_var -Wno-sign-conversion -Wno-format-security"
|
||||
fi
|
||||
app_cv_compiler_options_cflags="$app_cv_compiler_options_cflags $app_cv_compiler_tmp_var";
|
||||
app_cv_compiler_options_cxxflags="$app_cv_compiler_options_cxxflags $app_cv_compiler_tmp_var";
|
||||
|
||||
@@ -103,7 +106,7 @@ AC_DEFUN([APP_COMPILER_OPTIONS], [
|
||||
# ---- Compiler options for debug builds
|
||||
|
||||
AC_ARG_ENABLE(debug-options, AS_HELP_STRING([--enable-debug-options=<compiler>|auto|none],
|
||||
[enable debug build options. Accepted values are auto, none, gnu, intel, sun. (Default: none)]),
|
||||
[enable debug build options. Accepted values are auto, none, gnu, clang, intel, sun. (Default: none)]),
|
||||
[app_cv_compiler_debug_options=${enableval}], [app_cv_compiler_debug_options=none])
|
||||
|
||||
# the default value is "yes" (if no value given after =), treat it as auto.
|
||||
@@ -125,7 +128,7 @@ AC_DEFUN([APP_COMPILER_OPTIONS], [
|
||||
AC_DEFINE([DEBUG_BUILD], [1], [Defined for debug builds])
|
||||
|
||||
# gcc, mingw
|
||||
if test "x$app_cv_compiler_debug_options" = "xgnu"; then
|
||||
if test "x$app_cv_compiler_debug_options" = "xgnu" || test "x$app_cv_compiler_debug_options" = "xclang"; then
|
||||
# We could put libstdc++ debug options here, but it generates binary-incompatible
|
||||
# C++ code, which leads to runtime errors with e.g. libsigc++.
|
||||
app_cv_compiler_options_cflags="$app_cv_compiler_options_cflags -g3 -O0";
|
||||
@@ -155,7 +158,7 @@ AC_DEFUN([APP_COMPILER_OPTIONS], [
|
||||
# ---- Compiler options for optimized builds
|
||||
|
||||
AC_ARG_ENABLE(optimize-options, AS_HELP_STRING([--enable-optimize-options=<compiler>|auto|none],
|
||||
[enable optimized build options. Accepted values are auto, none, gnu, intel, sun. (Default: none)]),
|
||||
[enable optimized build options. Accepted values are auto, none, gnu, clang, intel, sun. (Default: none)]),
|
||||
[app_cv_compiler_optimize_options=${enableval}], [app_cv_compiler_optimize_options=none])
|
||||
|
||||
# the default value is "yes" (if no value given after =), treat it as auto.
|
||||
@@ -173,7 +176,7 @@ AC_DEFUN([APP_COMPILER_OPTIONS], [
|
||||
if test "x$app_cv_compiler_optimize_options" != "xnone"; then
|
||||
|
||||
# gcc, mingw
|
||||
if test "x$app_cv_compiler_optimize_options" = "xgnu"; then
|
||||
if test "x$app_cv_compiler_optimize_options" = "xgnu" || test "x$app_cv_compiler_optimize_options" = "xclang"; then
|
||||
# -mtune=generic is since gcc 4.0 iirc
|
||||
if test "x$app_cv_target_os_env" = "xmingw32"; then
|
||||
app_cv_compiler_options_cflags="$app_cv_compiler_options_cflags -g0 -O3 -s -march=i686";
|
||||
@@ -69,6 +69,8 @@ AC_DEFUN([APP_DETECT_OS_KERNEL], [
|
||||
|
||||
x86_64-*-mingw* | x86_64-*-cygwin*)
|
||||
# mingw64 defines the same stuff as 32-bit one, plus _WIN64, __MINGW64__, etc... .
|
||||
# Keep in mind that if you're generating a 32-bit application, the kernel will
|
||||
# be windows32 even if you run it on 64-bit Windows.
|
||||
app_cv_[]$1[]_os_kernel="windows64";
|
||||
app_cv_[]$1[]_os_kernel_macro="WINDOWS64";
|
||||
;;
|
||||
@@ -55,8 +55,8 @@ AC_DEFUN([APP_GET_MT_FLAGS], [
|
||||
linux)
|
||||
# glibc manual says that defining either _REENTRANT or _THREAD_SAFE
|
||||
# enables some thread-safe implementations of glibc functions.
|
||||
if test "$ax_cv_cxx_compiler_vendor" = "gnu" || test "$ax_cv_cxx_compiler_vendor" = "intel" \
|
||||
|| test "$ax_cv_cxx_compiler_vendor" = "pathscale"; then
|
||||
if test "$ax_cv_cxx_compiler_vendor" = "gnu" || test "$ax_cv_cxx_compiler_vendor" = "clang" \
|
||||
|| test "$ax_cv_cxx_compiler_vendor" = "intel" || test "$ax_cv_cxx_compiler_vendor" = "pathscale"; then
|
||||
app_cv_target_thread_cflags="-pthread -D_MT -D_THREAD_SAFE"
|
||||
app_cv_target_thread_cxxflags="-pthread -D_MT -D_THREAD_SAFE"
|
||||
app_cv_target_thread_libs="-pthread"
|
||||
@@ -77,12 +77,12 @@ AC_DEFUN([APP_GET_MT_FLAGS], [
|
||||
;;
|
||||
|
||||
windows*)
|
||||
# NOTE: Not sure about cygwin.
|
||||
# NOTE: Not sure about cygwin or clang.
|
||||
# NOTE: This only enables multithreaded code generation. For linking
|
||||
# with pthreads-win32 you need additional flags.
|
||||
# gcc man page: -mthreads: Support thread-safe exception handling on Mingw32.
|
||||
# -mthreads defines -D_MT, and links with -lmingwthrd.
|
||||
if test "$ax_cv_cxx_compiler_vendor" = "gnu"; then
|
||||
if test "$ax_cv_cxx_compiler_vendor" = "gnu" || test "$ax_cv_cxx_compiler_vendor" = "clang"; then
|
||||
app_cv_target_thread_cflags="-mthreads -D_THREAD_SAFE"
|
||||
app_cv_target_thread_cxxflags="-mthreads -D_THREAD_SAFE"
|
||||
app_cv_target_thread_libs="-mthreads"
|
||||
@@ -104,7 +104,7 @@ AC_DEFUN([APP_GET_MT_FLAGS], [
|
||||
# NOTE: Not sure about debian gnu/kfreebsd and gnu/netbsd.
|
||||
# Freebsd had -kthread, but it has been discontinued (afaik).
|
||||
# For freebsd -pthread replaces libc with libc_r.
|
||||
if test "$ax_cv_cxx_compiler_vendor" = "gnu"; then
|
||||
if test "$ax_cv_cxx_compiler_vendor" = "gnu" || test "$ax_cv_cxx_compiler_vendor" = "clang"; then
|
||||
app_cv_target_thread_cflags="-pthread -D_MT -D_THREAD_SAFE"
|
||||
app_cv_target_thread_cxxflags="-pthread -D_MT -D_THREAD_SAFE"
|
||||
app_cv_target_thread_libs="-pthread"
|
||||
@@ -113,7 +113,7 @@ AC_DEFUN([APP_GET_MT_FLAGS], [
|
||||
;;
|
||||
|
||||
openbsd)
|
||||
if test "$ax_cv_cxx_compiler_vendor" = "gnu"; then
|
||||
if test "$ax_cv_cxx_compiler_vendor" = "gnu" || test "$ax_cv_cxx_compiler_vendor" = "clang"; then
|
||||
app_cv_target_thread_cflags="-pthread -D_REENTRANT"
|
||||
app_cv_target_thread_cxxflags="-pthread -D_REENTRANT"
|
||||
app_cv_target_thread_libs="-pthread"
|
||||
@@ -123,7 +123,7 @@ AC_DEFUN([APP_GET_MT_FLAGS], [
|
||||
|
||||
netbsd)
|
||||
# See sys/featuretest.h
|
||||
if test "$ax_cv_cxx_compiler_vendor" = "gnu"; then
|
||||
if test "$ax_cv_cxx_compiler_vendor" = "gnu" || test "$ax_cv_cxx_compiler_vendor" = "clang"; then
|
||||
app_cv_target_thread_cflags="-pthread -D_REENTRANT"
|
||||
app_cv_target_thread_cxxflags="-pthread -D_REENTRANT"
|
||||
app_cv_target_thread_libs="-pthread"
|
||||
@@ -132,7 +132,7 @@ AC_DEFUN([APP_GET_MT_FLAGS], [
|
||||
;;
|
||||
|
||||
solaris)
|
||||
if test "$ax_cv_cxx_compiler_vendor" = "gnu"; then
|
||||
if test "$ax_cv_cxx_compiler_vendor" = "gnu" || test "$ax_cv_cxx_compiler_vendor" = "clang"; then
|
||||
# gnu documentation mentions -threads (and its aliases, -pthreads and -pthread).
|
||||
# _REENTRANT is needed to enable some thread-safe equivalents of standard
|
||||
# functions.
|
||||
@@ -159,14 +159,14 @@ AC_DEFUN([APP_GET_MT_FLAGS], [
|
||||
;;
|
||||
|
||||
darwin)
|
||||
if test "$ax_cv_cxx_compiler_vendor" = "gnu"; then
|
||||
if test "$ax_cv_cxx_compiler_vendor" = "gnu" || test "$ax_cv_cxx_compiler_vendor" = "clang"; then
|
||||
# Darwin produces mt code by default, and -pthread is an error.
|
||||
app_cv_target_thread_found="yes"
|
||||
fi
|
||||
;;
|
||||
|
||||
qnx)
|
||||
if test "$ax_cv_cxx_compiler_vendor" = "gnu"; then
|
||||
if test "$ax_cv_cxx_compiler_vendor" = "gnu" || test "$ax_cv_cxx_compiler_vendor" = "clang"; then
|
||||
# afaik, gcc/qnx produces mt code by default (at least on newer qnx releases),
|
||||
# so no flags are needed.
|
||||
app_cv_target_thread_found="yes"
|
||||
@@ -53,7 +53,7 @@ AC_DEFUN([AX_COMPILER_VENDOR],
|
||||
AC_CACHE_CHECK([for _AC_LANG compiler vendor], ax_cv_[]_AC_LANG_ABBREV[]_compiler_vendor,
|
||||
[ax_cv_[]_AC_LANG_ABBREV[]_compiler_vendor=unknown
|
||||
# note: don't check for gcc first since some other compilers define __GNUC__
|
||||
for ventest in intel:__ICC,__ECC,__INTEL_COMPILER ibm:__xlc__,__xlC__,__IBMC__,__IBMCPP__ pathscale:__PATHCC__,__PATHSCALE__ gnu:__GNUC__ sun:__SUNPRO_C,__SUNPRO_CC hp:__HP_cc,__HP_aCC dec:__DECC,__DECCXX,__DECC_VER,__DECCXX_VER borland:__BORLANDC__,__TURBOC__ comeau:__COMO__ cray:_CRAYC kai:__KCC lcc:__LCC__ metrowerks:__MWERKS__ sgi:__sgi,sgi microsoft:_MSC_VER watcom:__WATCOMC__ portland:__PGI; do
|
||||
for ventest in clang:__clang__ intel:__ICC,__ECC,__INTEL_COMPILER ibm:__xlc__,__xlC__,__IBMC__,__IBMCPP__ pathscale:__PATHCC__,__PATHSCALE__ gnu:__GNUC__ sun:__SUNPRO_C,__SUNPRO_CC hp:__HP_cc,__HP_aCC dec:__DECC,__DECCXX,__DECC_VER,__DECCXX_VER borland:__BORLANDC__,__TURBOC__ comeau:__COMO__ cray:_CRAYC kai:__KCC lcc:__LCC__ metrowerks:__MWERKS__ sgi:__sgi,sgi microsoft:_MSC_VER watcom:__WATCOMC__ portland:__PGI; do
|
||||
vencpp="defined("`echo $ventest | cut -d: -f2 | sed 's/,/) || defined(/g'`")"
|
||||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM(,[
|
||||
#if !($vencpp)
|
||||
@@ -0,0 +1,72 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Configure a build directory according to developer flags
|
||||
|
||||
type="$1";
|
||||
configure_script="$2";
|
||||
|
||||
if [ "$type" == "" ]; then
|
||||
echo "Usage: $0 <type> [<configure_script>]"
|
||||
echo "where <type> is one of:"
|
||||
echo "debug optimized icc clang win32 win32-debug win64-debug sun portland open64";
|
||||
echo "<configure_script> is ../configure by default"
|
||||
exit 1;
|
||||
fi
|
||||
|
||||
if [ "$configure_script" == "" ]; then
|
||||
configure_script="../configure";
|
||||
fi
|
||||
|
||||
|
||||
flags="";
|
||||
|
||||
case $type in
|
||||
optimized)
|
||||
flags="--disable-user-flags --enable-optimize-options --enable-tests" ;;
|
||||
debug)
|
||||
flags="--enable-debug-options --enable-tests" ;;
|
||||
clang)
|
||||
flags="CC=clang CXX=clang++ --enable-debug-options --enable-tests" ;;
|
||||
icc)
|
||||
flags="CC=icc64 CXX=icpc64 --disable-user-flags --enable-tests" ;;
|
||||
win32)
|
||||
flags="CC=i386-pc-mingw32-gcc CXX=i386-pc-mingw32-g++ \
|
||||
PKG_CONFIG_PATH=/cross/w32/target/lib/pkgconfig PKG_CONFIG_LIBDIR=\"\" \
|
||||
PATH=\"/cross/w32/gcc-bin:/cross/w32/target/bin:$PATH\" \
|
||||
--with-windows-gtk-name=gtk2-runtime-2.16.6-2010-05-12-ash --disable-user-flags \
|
||||
--enable-optimize-options --enable-tests --build=i686-linux --host=i386-pc-mingw32" ;;
|
||||
win32-debug)
|
||||
flags="CC=i386-pc-mingw32-gcc CXX=i386-pc-mingw32-g++ \
|
||||
PKG_CONFIG_PATH=/cross/w32/target/lib/pkgconfig PKG_CONFIG_LIBDIR=\"\" \
|
||||
PATH=\"/cross/w32/gcc-bin:/cross/w32/target/bin:$PATH\" \
|
||||
--disable-user-flags --enable-debug-options --enable-tests --build=i686-linux --host=i386-pc-mingw32" ;;
|
||||
win64-debug)
|
||||
flags="CC=x86_64-pc-mingw32-gcc CXX=x86_64-pc-mingw32-g++
|
||||
PKG_CONFIG_PATH=/cross/w64/target/lib/pkgconfig \
|
||||
PKG_CONFIG_LIBDIR=\"\" PATH=\"/cross/w64/gcc-bin:/cross/w64/target/bin:$PATH\" \
|
||||
--disable-user-flags --enable-optimize-options --enable-tests --build=i686-linux \
|
||||
--host=x86_64-pc-mingw32" ;;
|
||||
sun)
|
||||
flags="CC=suncc CXX=sunCC CFLAGS=\"-errwarn=%all -I/opt/sun/target64/include\" \
|
||||
CXXFLAGS=\"-I/opt/sun/target64/include\" PATH=\"/opt/sun/sunstudio/bin:$PATH\" \
|
||||
LDFLAGS=\"-R/opt/sun/target64/lib64 -L/opt/sun/target64/lib64\" \
|
||||
PKG_CONFIG_PATH=\"/opt/sun/target64/lib64/pkgconfig:/usr/lib64/pkgconfig\" \
|
||||
PKG_CONFIG_LIBDIR=\"\" --enable-tests" ;;
|
||||
portland)
|
||||
flags="CC=pgcc CXX=pgCC LDFLAGS=\"-s\" CFLAGS=\"-Minform=warn -Bstatic_pgi\" \
|
||||
CXXFLAGS=\"-Minform=warn -Bstatic_pgi -noswitcherror -define_macro=HZ_NO_COMPILER_AUTOINCLUDE\" \
|
||||
--enable-tests" ;;
|
||||
|
||||
open64)
|
||||
flags="CC=/opt/open64/bin/opencc CXX=/opt/open64/bin/openCC CXXFLAGS=\"-Wall\" \
|
||||
--enable-tests" ;;
|
||||
esac
|
||||
|
||||
|
||||
echo "Running:"
|
||||
echo $configure_script $flags;
|
||||
|
||||
$configure_script $flags
|
||||
|
||||
|
||||
exit $?
|
||||
@@ -1,5 +1,5 @@
|
||||
|
||||
AC_INIT([GSmartControl],[0.8.5],[],[gsmartcontrol])
|
||||
AC_INIT([GSmartControl],[0.8.7],[],[gsmartcontrol])
|
||||
|
||||
AC_CONFIG_SRCDIR([configure.ac])
|
||||
AC_CONFIG_HEADERS([config.h])
|
||||
@@ -274,7 +274,7 @@ LIBS="$LIBS $PCRE_LIBS"
|
||||
AC_ARG_WITH([nsis], [AS_HELP_STRING([--with-nsis=<location>|auto],
|
||||
[specify makensis.exe location to support making NSIS packages]
|
||||
[ (default: "C:\Program Files\NSIS\makensis.exe" for windows, ]
|
||||
["~/.wine/drive_c/Program Files/NSIS/makensis.exe" for others)])],
|
||||
["~/.wine/drive_c/Program Files/NSIS/Unicode/makensis.exe" for others)])],
|
||||
[with_nsis=${withval}], [with_nsis=auto])
|
||||
|
||||
AC_ARG_ENABLE([nsis-wine], [AS_HELP_STRING([--enable-nsis-wine=yes|no|auto],
|
||||
@@ -285,16 +285,22 @@ AC_ARG_WITH([windows-bindir], [AS_HELP_STRING([--with-windows-bindir],
|
||||
[specify location of Windows dlls and executables when making Windows packages (default: /cross/w32/target/bin)])],
|
||||
[with_windows_bindir=${withval}], [with_windows_bindir=auto])
|
||||
|
||||
AC_ARG_WITH([windows-gtk-name], [AS_HELP_STRING([--with-windows-gtk-name],
|
||||
[specify name of Windows GTK+ runtime (installer and unpacked directory) when making Windows packages. It will be looked in windows-bindir.])],
|
||||
[with_windows_gtk_name=${withval}], [with_windows_gtk_name=])
|
||||
|
||||
if test "x$with_nsis" = "xauto" || test "x$with_nsis" = "x"; then
|
||||
if test "x$app_cv_build_os_kernel" = "xwindows"; then
|
||||
with_nsis="~/\".wine/drive_c/Program Files/NSIS/makensis.exe\"";
|
||||
else
|
||||
# if building on windows, use native paths
|
||||
if test "x$app_cv_build_os_kernel" = "xwindows32" || test "x$app_cv_build_os_kernel" = "xwindows64"; then
|
||||
with_nsis="\"C:\\Program Files\\NSIS\\makensis.exe\"";
|
||||
else
|
||||
with_nsis="~/\".wine/drive_c/Program Files/NSIS/Unicode/makensis.exe\"";
|
||||
fi
|
||||
fi
|
||||
|
||||
if test "x$with_nsis_wine" = "xauto"; then
|
||||
if test "x$app_cv_build_os_kernel" = "xwindows"; then
|
||||
# if not building on windows, use wine
|
||||
if test "x$app_cv_build_os_kernel" = "xwindows32" || test "x$app_cv_build_os_kernel" = "xwindows64"; then
|
||||
with_nsis_wine="no";
|
||||
else
|
||||
with_nsis_wine="yes";
|
||||
@@ -311,8 +317,28 @@ if test "x$with_windows_bindir" = "xauto" || test "x$with_windows_bindir" = "x";
|
||||
fi
|
||||
WINDOWS_BINDIR="$with_windows_bindir";
|
||||
|
||||
GTK_INSTALLER_NAME="$with_windows_gtk_name";
|
||||
|
||||
AC_SUBST(NSIS_EXEC)
|
||||
AC_SUBST(WINDOWS_BINDIR)
|
||||
AC_SUBST(GTK_INSTALLER_NAME)
|
||||
|
||||
|
||||
# -------------------------------------------------------------------------------------
|
||||
|
||||
# -------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
# Win32 security manifest support
|
||||
|
||||
WINDOWS_ARCH=""
|
||||
if test "x$app_cv_target_os_kernel" = "xwindows32"; then
|
||||
WINDOWS_ARCH="x86"
|
||||
elif test "x$app_cv_target_os_kernel" = "xwindows64"; then
|
||||
WINDOWS_ARCH="amd64"
|
||||
fi
|
||||
|
||||
AC_SUBST(WINDOWS_ARCH)
|
||||
|
||||
|
||||
# -------------------------------------------------------------------------------------
|
||||
@@ -321,6 +347,7 @@ AC_SUBST(WINDOWS_BINDIR)
|
||||
|
||||
|
||||
RES_FILES="src/res/gsc_about_dialog.glade \
|
||||
src/res/gsc_add_device_window.glade \
|
||||
src/res/gsc_executor_log_window.glade \
|
||||
src/res/gsc_help_window.glade \
|
||||
src/res/gsc_info_window.glade \
|
||||
@@ -407,7 +434,8 @@ _AM_SUBST_NOTMAKE([RES_TARGETS])
|
||||
|
||||
ADDITIONAL_FLAGS="-DPACKAGE_PKGDATA_DIR=\"\\\"\$(pkgdatadir)\\\"\" \
|
||||
-DPACKAGE_SYSCONF_DIR=\"\\\"\$(sysconfdir)\\\"\" \
|
||||
-DTOP_SRC_DIR=\"\\\"\$(top_srcdir)\\\"\""
|
||||
-DTOP_SRC_DIR=\"\\\"\$(top_srcdir)\\\"\" \
|
||||
-DHZ_USE_GLOBAL_MACROS=1"
|
||||
|
||||
#CFLAGS="$CFLAGS $ADDITIONAL_FLAGS"
|
||||
CXXFLAGS="$CXXFLAGS $ADDITIONAL_FLAGS"
|
||||
@@ -424,13 +452,13 @@ ADDITIONAL_INCLUDES="-I\$(top_builddir) -I\$(top_srcdir)/src -I\$(top_srcdir)/sr
|
||||
# with pgi and older sunstudio (the one in solaris10, for example).
|
||||
# Note: some gcc-frontend-based compilers may have to be added here
|
||||
# (e.g. gccfss (gcc frontend / sun backend), etc...).
|
||||
if test "$ax_cv_cxx_compiler_vendor" = "gnu" || test "$ax_cv_cxx_compiler_vendor" = "intel" \
|
||||
|| test "$ax_cv_cxx_compiler_vendor" = "pathscale"; then
|
||||
# This auto-includes this file when compiling any file. Benefits include pch support.
|
||||
ADDITIONAL_INCLUDES="$ADDITIONAL_INCLUDES -include global_macros.h"
|
||||
else # sun, pgi, others...
|
||||
# This forces the file to be included manually.
|
||||
ADDITIONAL_INCLUDES="$ADDITIONAL_INCLUDES -DHZ_NO_COMPILER_AUTOINCLUDE"
|
||||
# We use -include only when using pch.
|
||||
if test "x$app_cv_compiler_gcc_pch" = "xyes"; then
|
||||
if test "$ax_cv_cxx_compiler_vendor" = "gnu" || test "$ax_cv_cxx_compiler_vendor" = "clang" \
|
||||
|| test "$ax_cv_cxx_compiler_vendor" = "intel" || test "$ax_cv_cxx_compiler_vendor" = "pathscale"; then
|
||||
# This auto-includes this file when compiling any file. Benefits include pch support.
|
||||
ADDITIONAL_INCLUDES="$ADDITIONAL_INCLUDES -include global_macros.h"
|
||||
fi
|
||||
fi
|
||||
|
||||
# our flags must be before all the others
|
||||
@@ -502,9 +530,9 @@ AC_SUBST(AUTODIRS)
|
||||
|
||||
|
||||
AC_CONFIG_FILES([ data/gsmartcontrol.desktop \
|
||||
data/nsis/distribution.txt data/nsis/gsmartcontrol.nsi \
|
||||
data/nsis/distribution.txt data/nsis/distribution-nogtk.txt data/nsis/gsmartcontrol.nsi \
|
||||
debian.dist/changelog \
|
||||
src/gsc_winres.rc \
|
||||
src/gsc_winres.rc src/gsmartcontrol.exe.manifest \
|
||||
gsmartcontrol.spec version compilation_flags ])
|
||||
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
#!/bin/bash
|
||||
############################################################################
|
||||
# Copyright:
|
||||
# (C) 2008 - 2009 Alex Butcher <alex dot butcher 'at' assursys.co.uk>
|
||||
# (C) 2008 - 2009 Alexander Shaduri <ashaduri 'at' gmail.com>
|
||||
# License: See LICENSE_whatever.txt file
|
||||
# (C) 2008 - 2010 Alex Butcher <alex dot butcher 'at' assursys.co.uk>
|
||||
# (C) 2008 - 2010 Alexander Shaduri <ashaduri 'at' gmail.com>
|
||||
# License: See LICENSE_unlicense.txt file
|
||||
############################################################################
|
||||
|
||||
device="$1";
|
||||
@@ -1,9 +1,9 @@
|
||||
#!/bin/bash
|
||||
############################################################################
|
||||
# Copyright:
|
||||
# (C) 2008 - 2009 Alex Butcher <alex dot butcher 'at' assursys.co.uk>
|
||||
# (C) 2008 - 2009 Alexander Shaduri <ashaduri 'at' gmail.com>
|
||||
# License: See LICENSE_whatever.txt file
|
||||
# (C) 2008 - 2010 Alex Butcher <alex dot butcher 'at' assursys.co.uk>
|
||||
# (C) 2008 - 2010 Alexander Shaduri <ashaduri 'at' gmail.com>
|
||||
# License: See LICENSE_unlicense.txt file
|
||||
############################################################################
|
||||
|
||||
if [ "$1" = "-V" ]; then
|
||||
|
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 3.4 KiB After Width: | Height: | Size: 3.4 KiB |
|
Before Width: | Height: | Size: 4.0 KiB After Width: | Height: | Size: 4.0 KiB |
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 45 KiB After Width: | Height: | Size: 45 KiB |
|
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 2.0 KiB |
|
Before Width: | Height: | Size: 3.8 KiB After Width: | Height: | Size: 3.8 KiB |
|
Before Width: | Height: | Size: 5.8 KiB After Width: | Height: | Size: 5.8 KiB |
@@ -0,0 +1,161 @@
|
||||
#!/usr/bin/env bash
|
||||
############################################################################
|
||||
# Copyright:
|
||||
# (C) 2008 - 2012 Alexander Shaduri <ashaduri 'at' gmail.com>
|
||||
# License: See LICENSE_zlib.txt file
|
||||
############################################################################
|
||||
|
||||
# Run gsmartcontrol with root, asking for root password first.
|
||||
# export GSMARTCONTROL_SU to override a su command (e.g. "kdesu -c").
|
||||
|
||||
EXEC_BIN="@prefix@/bin/gsmartcontrol";
|
||||
prog_name="gsmartcontrol"
|
||||
|
||||
|
||||
# Preserve quotes in arguments
|
||||
final_args_quoted="";
|
||||
for i in "$@";do
|
||||
final_args_quoted="$final_args_quoted \"${i//\"/\\\"}\"";
|
||||
done;
|
||||
|
||||
|
||||
DESKTOP="auto";
|
||||
|
||||
# Compatibility with old syntax:
|
||||
# gsmartcontrol-root [<desktop> [program_options]]
|
||||
if [ "$1" == "auto" ] || [ "$1" == "kde" ] || [ "$1" == "gnome" ] || [ "$1" == "other" ]; then
|
||||
DESKTOP="$1";
|
||||
shift; # remove $1
|
||||
else
|
||||
# New syntax:
|
||||
# gsmartcontrol-root [--desktop=<auto|kde|gnome|other>] [program_options]
|
||||
|
||||
for arg in $*; do
|
||||
case $arg in
|
||||
--desktop=*)
|
||||
DESKTOP="${arg#*=}";
|
||||
final_args_quoted="${final_args_quoted/\"$arg\"/}";
|
||||
;;
|
||||
*)
|
||||
# unknown option
|
||||
;;
|
||||
esac
|
||||
done
|
||||
fi
|
||||
|
||||
if [ "$DESKTOP" != "auto" ] && [ "$DESKTOP" != "kde" ] && \
|
||||
[ "$DESKTOP" != "gnome" ] && [ "$DESKTOP" != "other" ]; then
|
||||
echo "Usage: $0 [--desktop=<auto|kde|gnome|other>] [<${prog_name}_options>]";
|
||||
exit 1;
|
||||
fi
|
||||
|
||||
|
||||
# Auto-detect current desktop if auto was specified.
|
||||
if [ "$DESKTOP" = "auto" ]; then
|
||||
# KDE_SESSION_UID is present on kde3 and kde4.
|
||||
# Note that it may be empty (but still set)
|
||||
if [ "${KDE_SESSION_UID+set}" = "set" ]; then
|
||||
DESKTOP="kde";
|
||||
# same with gnome
|
||||
elif [ "${GNOME_DESKTOP_SESSION_ID+set}" = "set" ]; then
|
||||
DESKTOP="gnome";
|
||||
else
|
||||
DESKTOP="other";
|
||||
fi
|
||||
fi
|
||||
|
||||
# echo $DESKTOP;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# They're basically the same, only the order is different.
|
||||
# sux requires xterm to ask for the password.
|
||||
# xdg-su is basically like this script, except worse :)
|
||||
# su-to-root is a debian/ubuntu official method (although gksu is available).
|
||||
gnome_sus="su-to-root gnomesu gksu kdesu beesu xdg-su sux";
|
||||
kde_sus="su-to-root kdesu gnomesu gksu beesu xdg-su sux";
|
||||
other_sus="$gnome_sus";
|
||||
|
||||
|
||||
candidates="";
|
||||
found_su=""
|
||||
|
||||
if [ "$DESKTOP" = "gnome" ]; then
|
||||
candidates="$gnome_sus";
|
||||
elif [ "$DESKTOP" = "kde" ]; then
|
||||
candidates="$kde_sus";
|
||||
elif [ "$DESKTOP" = "other" ]; then
|
||||
candidates="$other_sus";
|
||||
fi
|
||||
|
||||
if [ "$GSMARTCONTROL_SU" = "" ]; then
|
||||
for subin in $candidates; do
|
||||
which $subin &>/dev/null
|
||||
if [ $? -eq 0 ]; then
|
||||
found_su="$subin";
|
||||
break;
|
||||
fi
|
||||
done
|
||||
|
||||
if [ "$found_su" = "" ]; then
|
||||
xmessage "Error launching ${prog_name}: No suitable su mechanism found.
|
||||
Try installing kdesu, gnomesu, gksu, beesu or sux first.";
|
||||
exit 1;
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
# gnomesu and gksu (but not kdesu, not sure about others) fail to adopt
|
||||
# root's PATH. Since the user's PATH may not contain /usr/sbin (with smartctl)
|
||||
# on some distributions (e.g. mandriva), add it manually. We also add
|
||||
# /usr/local/sbin, since that's the default location of custom-compiled smartctl.
|
||||
# Add these directories _before_ existing PATH, so that the user is not
|
||||
# tricked into running it from some other path (we're running as root with
|
||||
# the user's env after all).
|
||||
# Add @prefix@/sbin as well (freebsd seems to require it).
|
||||
# Note that beesu won't show a GUI login box if /usr/sbin is before /usr/bin,
|
||||
# so add it first as well.
|
||||
EXTRA_PATHS="/usr/bin:/usr/sbin:/usr/local/sbin:@prefix@/sbin";
|
||||
export PATH="$EXTRA_PATHS:$PATH"
|
||||
|
||||
|
||||
# echo $found_su;
|
||||
|
||||
# Examples:
|
||||
# gnomesu -c 'gsmartcontrol --no-scan'
|
||||
# kdesu -c 'gsmartcontrol --no-scan'
|
||||
# beesu -P 'gsmartcontrol --no-scan'
|
||||
# su-to-root -X -c 'gsmartcontrol --no-scan'
|
||||
# xterm -e sux -c 'gsmartcontrol --no-scan' # sux asks for password in a terminal
|
||||
|
||||
|
||||
full_cmd="";
|
||||
|
||||
if [ "$GSMARTCONTROL_SU" != "" ]; then
|
||||
full_cmd="$GSMARTCONTROL_SU '$EXEC_BIN $final_args_quoted'";
|
||||
|
||||
elif [ "$found_su" = "sux" ]; then
|
||||
full_cmd="xterm -e sux -c '$EXEC_BIN $final_args_quoted'";
|
||||
|
||||
elif [ "$found_su" = "gksu" ]; then
|
||||
full_cmd="$found_su '$EXEC_BIN $final_args_quoted'";
|
||||
|
||||
elif [ "$found_su" = "beesu" ]; then
|
||||
full_cmd="$found_su -P '$EXEC_BIN $final_args_quoted'";
|
||||
|
||||
elif [ "$found_su" = "su-to-root" ]; then
|
||||
full_cmd="$found_su -X -c '$EXEC_BIN $final_args_quoted'";
|
||||
|
||||
else # gnomesu, kdesu, xdg-su
|
||||
full_cmd="$found_su -c '$EXEC_BIN $final_args_quoted'";
|
||||
fi
|
||||
|
||||
|
||||
# echo $full_cmd
|
||||
eval $full_cmd
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ GSmartControl \- Hard disk drive health inspection tool
|
||||
.SH SYNOPSIS
|
||||
\fBgsmartcontrol\fP [OPTIONS]
|
||||
|
||||
\fBgsmartcontrol\-root\fP [\fI<desktop>\fP [OPTIONS]]
|
||||
\fBgsmartcontrol\-root\fP [--desktop=\fI<desktop>\fP] [OPTIONS]
|
||||
.SH DESCRIPTION
|
||||
\fBGSmartControl\fP is a graphical user interface for smartctl (from
|
||||
smartmontools), which is a tool for querying and controlling SMART
|
||||
@@ -37,7 +37,7 @@ Show logging options
|
||||
.SS "Application Options:"
|
||||
.TP
|
||||
\fB\-l\fP, \fB\-\-no\-locale\fP
|
||||
Disable locale
|
||||
Don't use system locale
|
||||
.TP
|
||||
\fB\-V\fP, \fB\-\-version\fP
|
||||
Display version information
|
||||
@@ -49,10 +49,17 @@ Don't scan devices on startup
|
||||
Don't hide non\-identity tabs when SMART is disabled. Useful for debugging.
|
||||
.TP
|
||||
\fB\-\-add\-virtual\fP
|
||||
Load smartctl data from file, creating a virtual drive
|
||||
Load smartctl data from file, creating a virtual drive. You
|
||||
can specify this option multiple times.
|
||||
.TP
|
||||
\fB\-\-add\-device\fP
|
||||
Add this device to device list. Useful with \fB\-\-no\-scan\fP to list certain drives only.
|
||||
Add this device to device list. The format of the device is
|
||||
\fI<device>::<type>::<extra_args>\fP, where type and extra_args are optional.
|
||||
This option is useful with \fB\-\-no\-scan\fP to list certain drives only. You
|
||||
can specify this option multiple times. Example:\fR
|
||||
.nf
|
||||
\-\-add\-device /dev/sda \-\-add\-device /dev/twa0::3ware,2 \-\-add\-device '/dev/sdb::::-T permissive'
|
||||
.fi
|
||||
.TP
|
||||
\fB\-\-display\fP=\fIDISPLAY\fP
|
||||
X display to use
|
||||
@@ -67,8 +74,8 @@ Disable logging; same as \fB\-\-verbosity\-level\fP 0
|
||||
Set verbosity level [0\-5]
|
||||
.PP
|
||||
.SH COPYRIGHT
|
||||
Copyright \(co 2008 \- 2009 Alexander Shaduri <ashaduri \'at\' gmail.com>
|
||||
Copyright \(co 2008 \- 2012 Alexander Shaduri <ashaduri \'at\' gmail.com>
|
||||
.PP
|
||||
.SH AUTHOR
|
||||
This manual page was originally written by Giuseppe Iuculano
|
||||
<giuseppe@iuculano.it>, for the Debian project.
|
||||
<giuseppe@iuculano.it> for the Debian project.
|
||||
@@ -24,6 +24,3 @@ Icon=gsmartcontrol
|
||||
|
||||
# Run with root permissions.
|
||||
Exec="@prefix@/bin/gsmartcontrol-root"
|
||||
|
||||
# Build service rpmlint gives errors without this
|
||||
X-SuSE-translate=false
|
||||
|
Before Width: | Height: | Size: 95 KiB After Width: | Height: | Size: 95 KiB |
|
Before Width: | Height: | Size: 4.6 KiB After Width: | Height: | Size: 4.6 KiB |
|
Before Width: | Height: | Size: 3.8 KiB After Width: | Height: | Size: 3.8 KiB |
@@ -9,7 +9,7 @@ and
|
||||
http://developer.berlios.de/project/showfiles.php?group_id=10075
|
||||
|
||||
You need GTK+ for Windows Runtime package to use this program. You can get one
|
||||
at http://gtk-win.sf.net (you must download at least version 2.14.4-2008-11-11
|
||||
at http://gtk-win.sf.net (you must download at least version 2.16.6-2010-02-21
|
||||
of gtk2-runtime).
|
||||
|
||||
|
||||
@@ -20,9 +20,9 @@ binary was compiled for 32-bit Windows, and should work on both 32-bit and
|
||||
64-bit Windows. The binary was statically compiled against Gtkmm
|
||||
(http://www.gtkmm.org/) and related libraries, and PCRE (http://www.pcre.org/).
|
||||
|
||||
* Smartctl binaries (from smartmontools 5.39-0-20090826-r2878,
|
||||
http://smartmontools.sf.net/) - smartctl-nc.exe (compiled without console
|
||||
output), smartctl.exe (compiled with console output).
|
||||
* Smartctl binaries (from smartmontools 5.43, http://smartmontools.sf.net/)
|
||||
- smartctl-nc.exe (compiled without console output), smartctl.exe (compiled
|
||||
with console output), update-smart-drivedb.exe (drive database updater).
|
||||
|
||||
|
||||
The combined distribution is multi-licensed under GNU GPL versions 2 and 3.
|
||||
@@ -0,0 +1,28 @@
|
||||
|
||||
GSmartControl - Hard disk drive health inspection tool
|
||||
Version @VERSION@
|
||||
|
||||
The latest version of this distribution, as well as the source code of
|
||||
GSmartControl, can be found at
|
||||
http://gsmartcontrol.berlios.de
|
||||
and
|
||||
http://developer.berlios.de/project/showfiles.php?group_id=10075
|
||||
|
||||
|
||||
This distribution includes:
|
||||
|
||||
* GSmartControl binary (gsmartcontrol.exe) and associated resources. The
|
||||
binary was compiled for 32-bit Windows, and should work on both 32-bit and
|
||||
64-bit Windows. The binary was statically compiled against Gtkmm
|
||||
(http://www.gtkmm.org/) and related libraries, and PCRE (http://www.pcre.org/).
|
||||
|
||||
* Smartctl binaries (from smartmontools 5.43, http://smartmontools.sf.net/)
|
||||
- smartctl-nc.exe (compiled without console output), smartctl.exe (compiled
|
||||
with console output), update-smart-drivedb.exe (drive database updater).
|
||||
|
||||
* GTK+ for Windows Runtime package (@GTK_INSTALLER_NAME@)
|
||||
from http://gtk-win.sf.net, either in original or unpacked form.
|
||||
|
||||
|
||||
The combined distribution is multi-licensed under GNU GPL versions 2 and 3.
|
||||
See LICENSE_gpl2.txt and LICENSE_gpl3.txt for details.
|
||||
@@ -0,0 +1,531 @@
|
||||
|
||||
; NSIS2 Script
|
||||
; by Alexander Shaduri <ashaduri 'at' gmail.com>.
|
||||
; Compatible with NSIS Unicode 2.45.
|
||||
; Public Domain
|
||||
|
||||
; pass /DNO_GTK to makensis to disable inclusion of gtk.
|
||||
|
||||
; gtk installer name for embedding
|
||||
!define GTK_INSTALLER_EXE "@GTK_INSTALLER_NAME@.exe"
|
||||
|
||||
!define PRODUCT_VERSION "@VERSION@"
|
||||
!define PRODUCT_NAME "GSmartControl"
|
||||
!define PRODUCT_NAME_SMALL "gsmartcontrol"
|
||||
!define PRODUCT_PUBLISHER "Alexander Shaduri"
|
||||
!define PRODUCT_WEB_SITE "http://gsmartcontrol.berlios.de"
|
||||
|
||||
;!define PRODUCT_DIR_REGKEY "Software\Microsoft\Windows\CurrentVersion\App Paths\AppMainExe.exe"
|
||||
!define PRODUCT_UNINST_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}"
|
||||
!define PRODUCT_UNINST_ROOT_KEY "HKLM"
|
||||
|
||||
!define REGISTRY_APP_PATHS "Software\Microsoft\Windows\CurrentVersion\App Paths"
|
||||
|
||||
|
||||
!include "FileFunc.nsh" ; GetOptions
|
||||
|
||||
|
||||
|
||||
; --------------- General Settings
|
||||
|
||||
|
||||
; This is needed for proper start menu item manipulation (for all users) in vista
|
||||
RequestExecutionLevel admin
|
||||
|
||||
; This compressor gives us the best results
|
||||
SetCompressor /SOLID lzma
|
||||
|
||||
; Do a CRC check before installing
|
||||
CRCCheck On
|
||||
|
||||
; This is used in titles
|
||||
Name "${PRODUCT_NAME}" ; ${PRODUCT_VERSION}
|
||||
|
||||
; Output File Name
|
||||
!ifdef NO_GTK
|
||||
OutFile "${PRODUCT_NAME_SMALL}-${PRODUCT_VERSION}-nogtk.exe"
|
||||
!else
|
||||
OutFile "${PRODUCT_NAME_SMALL}-${PRODUCT_VERSION}.exe"
|
||||
!endif
|
||||
|
||||
|
||||
; The Default Installation Directory:
|
||||
; Try to install to the same directory as runtime.
|
||||
InstallDir "$PROGRAMFILES\${PRODUCT_NAME}"
|
||||
; If already installed, try here
|
||||
InstallDirRegKey HKLM "SOFTWARE\${PRODUCT_NAME}" "InstallationDirectory"
|
||||
|
||||
|
||||
ShowInstDetails show
|
||||
ShowUnInstDetails show
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
; --------------------- MUI INTERFACE
|
||||
|
||||
; MUI 2.0 compatible install
|
||||
!include "MUI2.nsh"
|
||||
!include "InstallOptions.nsh" ; section description macros
|
||||
|
||||
; Backgound Colors. uncomment to enable fullscreen.
|
||||
; BGGradient 0000FF 000000 FFFFFF
|
||||
|
||||
; MUI Settings
|
||||
!define MUI_ABORTWARNING
|
||||
!define MUI_ICON "nsi_install.ico"
|
||||
!define MUI_UNICON "nsi_uninstall.ico"
|
||||
|
||||
|
||||
; Things that need to be extracted on first (keep these lines before any File command!).
|
||||
; Only useful for BZIP2 compression.
|
||||
;!insertmacro MUI_RESERVEFILE_LANGDLL
|
||||
;!insertmacro MUI_RESERVEFILE_INSTALLOPTIONS
|
||||
|
||||
|
||||
; Language Selection Dialog Settings
|
||||
;!define MUI_LANGDLL_REGISTRY_ROOT "${PRODUCT_UNINST_ROOT_KEY}"
|
||||
;!define MUI_LANGDLL_REGISTRY_KEY "${PRODUCT_UNINST_KEY}"
|
||||
;!define MUI_LANGDLL_REGISTRY_VALUENAME "NSIS:Language"
|
||||
|
||||
!ifdef NO_GTK
|
||||
!define LICENSE_FILE "doc\distribution-nogtk.txt"
|
||||
!else
|
||||
!define LICENSE_FILE "doc\distribution.txt"
|
||||
!endif
|
||||
|
||||
; Pages to show during installation
|
||||
!insertmacro MUI_PAGE_WELCOME
|
||||
!insertmacro MUI_PAGE_LICENSE "${LICENSE_FILE}"
|
||||
!ifndef NO_GTK
|
||||
!define MUI_PAGE_CUSTOMFUNCTION_LEAVE on_components_page_leave
|
||||
!insertmacro MUI_PAGE_COMPONENTS
|
||||
!endif
|
||||
!insertmacro MUI_PAGE_DIRECTORY
|
||||
!insertmacro MUI_PAGE_INSTFILES
|
||||
|
||||
;!define MUI_FINISHPAGE_RUN "$INSTDIR\gsmartcontrol.exe"
|
||||
;!define MUI_FINISHPAGE_SHOWREADME "$INSTDIR\Example.file"
|
||||
;!define MUI_FINISHPAGE_RUN_NOTCHECKED
|
||||
!define MUI_FINISHPAGE_NOAUTOCLOSE
|
||||
!define MUI_FINISHPAGE_NOREBOOTSUPPORT
|
||||
!insertmacro MUI_PAGE_FINISH
|
||||
|
||||
|
||||
|
||||
; Uninstaller page
|
||||
!insertmacro MUI_UNPAGE_CONFIRM
|
||||
!insertmacro MUI_UNPAGE_INSTFILES
|
||||
|
||||
|
||||
|
||||
; Language files
|
||||
!insertmacro MUI_LANGUAGE "English"
|
||||
|
||||
|
||||
; --------------- END MUI
|
||||
|
||||
LangString TEXT_IO_TITLE ${LANG_ENGLISH} "GSmartControl"
|
||||
|
||||
|
||||
var install_option_removeold ; uninstall the old version first (if present): yes (default), no.
|
||||
|
||||
|
||||
|
||||
; ----------------- INSTALLATION TYPES
|
||||
|
||||
; InstType "Recommended"
|
||||
; InstType "Full"
|
||||
; InstType "Minimal"
|
||||
|
||||
|
||||
|
||||
|
||||
Section "!GSmartControl" SecMain
|
||||
SectionIn 1 RO
|
||||
SetShellVarContext all ; use all user variables as opposed to current user
|
||||
SetOutPath "$INSTDIR"
|
||||
|
||||
SetOverwrite Off ; don't overwrite the config file
|
||||
; File "gsmartcontrol.conf"
|
||||
|
||||
SetOverwrite On
|
||||
File gsmartcontrol.exe
|
||||
File gsmartcontrol.exe.manifest
|
||||
File gsmartcontrol.ico
|
||||
File icon_*.png
|
||||
; File *.dll
|
||||
File smartctl-nc.exe
|
||||
File smartctl.exe
|
||||
File update-smart-drivedb.exe
|
||||
|
||||
; Include the "doc" directory completely, excluding the file we're not using (e.g. the -nogtk file in gtk installer).
|
||||
!ifdef NO_GTK
|
||||
File /r /x distribution.txt doc
|
||||
!else
|
||||
File /r /x distribution-nogtk.txt doc
|
||||
!endif
|
||||
|
||||
; Add Shortcuts (this inherits the exe's run permissions)
|
||||
CreateShortCut "$SMPROGRAMS\GSmartControl.lnk" "$INSTDIR\gsmartcontrol.exe" "" \
|
||||
"$INSTDIR\gsmartcontrol.ico" "" SW_SHOWNORMAL "" "GSmartControl - Hard disk drive health inspection tool"
|
||||
|
||||
SectionEnd
|
||||
|
||||
|
||||
|
||||
!ifndef NO_GTK
|
||||
|
||||
; The SecGtkPrivate and SecGtkPublic sections are mutually exclusive.
|
||||
|
||||
Section "GTK+ (for this program only)" SecGtkPrivate
|
||||
SectionIn 1
|
||||
SetShellVarContext all ; use all user variables as opposed to current user
|
||||
AddSize 12200 ; ~ size of unpacked gtk
|
||||
SetOutPath "$INSTDIR"
|
||||
File "${GTK_INSTALLER_EXE}"
|
||||
; TODO: in the future, when we have translations for this program,
|
||||
; make the GTK+ translations installation dependent on their installation status.
|
||||
ExecWait '"${GTK_INSTALLER_EXE}" /sideeffects=no /dllpath=root /translations=no /compatdlls=no /S /D=$INSTDIR'
|
||||
Delete "$INSTDIR\${GTK_INSTALLER_EXE}"
|
||||
SectionEnd
|
||||
|
||||
; disabled by default
|
||||
Section /o "GTK+ (shared installation)" SecGtkPublic
|
||||
SectionIn 1
|
||||
SetShellVarContext all ; use all user variables as opposed to current user
|
||||
AddSize 12200 ; ~ size of unpacked gtk
|
||||
SetOutPath "$INSTDIR"
|
||||
File "${GTK_INSTALLER_EXE}"
|
||||
ExecWait '"${GTK_INSTALLER_EXE}"'
|
||||
Delete "$INSTDIR\${GTK_INSTALLER_EXE}"
|
||||
SectionEnd
|
||||
|
||||
!endif ; !NO_GTK
|
||||
|
||||
|
||||
!ifndef NO_GTK
|
||||
var gtk_mode ; "public", "private" or "none"
|
||||
var gtk_tmp ; temporary variable
|
||||
!endif
|
||||
|
||||
|
||||
; Executed on installation start
|
||||
Function .onInit
|
||||
SetShellVarContext all ; use all user variables as opposed to current user
|
||||
|
||||
${GetOptions} "$CMDLINE" "/removeold=" $install_option_removeold
|
||||
|
||||
Call PreventMultipleInstances
|
||||
|
||||
Call DetectPrevInstallation
|
||||
|
||||
; ask for gtk only if it's a non-gtk installer.
|
||||
!ifdef NO_GTK
|
||||
Call AskForGtk
|
||||
!endif
|
||||
|
||||
!ifndef NO_GTK
|
||||
StrCpy $gtk_mode "private" ; default
|
||||
!endif
|
||||
|
||||
FunctionEnd
|
||||
|
||||
|
||||
|
||||
function .onselchange
|
||||
|
||||
!ifndef NO_GTK
|
||||
; Remember which gtk section was selected.
|
||||
; Deselect the other section.
|
||||
|
||||
; If it was private, we check if public is checked and uncheck private.
|
||||
|
||||
StrCmp $gtk_mode "private" check_public ; old selection
|
||||
StrCmp $gtk_mode "public" check_private ; old selection
|
||||
goto check_exit
|
||||
|
||||
check_public:
|
||||
SectionGetFlags ${SecGtkPublic} $gtk_tmp ; see if it's checked
|
||||
IntOp $gtk_tmp $gtk_tmp & ${SF_SELECTED}
|
||||
IntCmp $gtk_tmp ${SF_SELECTED} "" check_exit check_exit
|
||||
SectionGetFlags ${SecGtkPrivate} $gtk_tmp ; unselect the other one
|
||||
IntOp $gtk_tmp $gtk_tmp & ${SECTION_OFF}
|
||||
SectionSetFlags ${SecGtkPrivate} $gtk_tmp
|
||||
goto check_exit
|
||||
|
||||
check_private:
|
||||
SectionGetFlags ${SecGtkPrivate} $gtk_tmp ; see if it's checked
|
||||
IntOp $gtk_tmp $gtk_tmp & ${SF_SELECTED}
|
||||
IntCmp $gtk_tmp ${SF_SELECTED} "" check_exit check_exit
|
||||
SectionGetFlags ${SecGtkPublic} $gtk_tmp ; unselect the other one
|
||||
IntOp $gtk_tmp $gtk_tmp & ${SECTION_OFF}
|
||||
SectionSetFlags ${SecGtkPublic} $gtk_tmp
|
||||
|
||||
check_exit:
|
||||
|
||||
|
||||
; store the current mode
|
||||
StrCpy $gtk_mode "none"
|
||||
|
||||
SectionGetFlags ${SecGtkPrivate} $gtk_tmp
|
||||
IntOp $gtk_tmp $gtk_tmp & ${SF_SELECTED}
|
||||
IntCmp $gtk_tmp ${SF_SELECTED} "" mode_end_private mode_end_private
|
||||
StrCpy $gtk_mode "private"
|
||||
mode_end_private:
|
||||
|
||||
SectionGetFlags ${SecGtkPublic} $gtk_tmp
|
||||
IntOp $gtk_tmp $gtk_tmp & ${SF_SELECTED}
|
||||
IntCmp $gtk_tmp ${SF_SELECTED} "" mode_end_public mode_end_public
|
||||
StrCpy $gtk_mode "public"
|
||||
mode_end_public:
|
||||
|
||||
; MessageBox MB_ICONINFORMATION|MB_OK "gtk_mode: $gtk_mode" /SD IDOK
|
||||
!endif ; !NO_GTK
|
||||
|
||||
functionend
|
||||
|
||||
|
||||
!ifndef NO_GTK
|
||||
Function on_components_page_leave
|
||||
StrCmp $gtk_mode "none" "" noabort
|
||||
Call AskForGtk
|
||||
noabort:
|
||||
FunctionEnd
|
||||
!endif ; !NO_GTK
|
||||
|
||||
|
||||
|
||||
|
||||
; Section descriptions
|
||||
!ifndef NO_GTK ; this page is shown only when using gtk
|
||||
!insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN
|
||||
!insertmacro MUI_DESCRIPTION_TEXT ${SecMain} "GSmartControl - hard disk drive health inspection tool"
|
||||
!insertmacro MUI_DESCRIPTION_TEXT ${SecGtkPrivate} "GTK+ libraries, needed by GSmartControl. \
|
||||
This will install a private version of GTK+, usable only by GSmartControl."
|
||||
!insertmacro MUI_DESCRIPTION_TEXT ${SecGtkPublic} "GTK+ libraries, needed by GSmartControl. \
|
||||
This will install a system-wide version of GTK+, shareable with other programs."
|
||||
!insertmacro MUI_FUNCTION_DESCRIPTION_END
|
||||
!endif
|
||||
|
||||
|
||||
; ------------------ POST INSTALL
|
||||
|
||||
|
||||
var gtk_dll_abs_path
|
||||
|
||||
Section -post
|
||||
SetShellVarContext all ; use all user variables as opposed to current user
|
||||
|
||||
; Don't set any paths for this exe if it has a private GTK+ installation.
|
||||
!ifndef NO_GTK
|
||||
StrCmp $gtk_mode "private" skip_exe_PATH
|
||||
!endif
|
||||
; set a special path for this exe, as GTK may not be in a global path.
|
||||
ReadRegStr $gtk_dll_abs_path HKLM "SOFTWARE\GTK\2.0" "DllPath"
|
||||
WriteRegStr HKLM "${REGISTRY_APP_PATHS}\gsmartcontrol.exe" "Path" "$gtk_dll_abs_path"
|
||||
!ifndef NO_GTK
|
||||
skip_exe_PATH:
|
||||
!endif
|
||||
|
||||
!ifndef NO_GTK
|
||||
WriteRegStr HKLM "SOFTWARE\${PRODUCT_NAME}" "GtkInstalledMode" "$gtk_mode"
|
||||
!endif
|
||||
|
||||
WriteRegStr HKLM "SOFTWARE\${PRODUCT_NAME}" "InstallationDirectory" "$INSTDIR"
|
||||
WriteRegStr HKLM "SOFTWARE\${PRODUCT_NAME}" "Vendor" "${PRODUCT_PUBLISHER}"
|
||||
|
||||
WriteRegStr HKLM "${PRODUCT_UNINST_KEY}" "DisplayName" "${PRODUCT_NAME}"
|
||||
WriteRegStr HKLM "${PRODUCT_UNINST_KEY}" "UninstallString" "$INSTDIR\gsmartcontrol_uninst.exe"
|
||||
WriteRegStr HKLM "${PRODUCT_UNINST_KEY}" "InstallLocation" "$INSTDIR"
|
||||
WriteRegStr HKLM "${PRODUCT_UNINST_KEY}" "Publisher" "${PRODUCT_PUBLISHER}"
|
||||
WriteRegStr HKLM "${PRODUCT_UNINST_KEY}" "DisplayIcon" "$INSTDIR\gsmartcontrol.ico"
|
||||
WriteRegStr HKLM "${PRODUCT_UNINST_KEY}" "URLInfoAbout" "${PRODUCT_WEB_SITE}"
|
||||
WriteRegStr HKLM "${PRODUCT_UNINST_KEY}" "DisplayVersion" "${PRODUCT_VERSION}"
|
||||
WriteRegDWORD HKLM "${PRODUCT_UNINST_KEY}" "NoModify" 1
|
||||
WriteRegDWORD HKLM "${PRODUCT_UNINST_KEY}" "NoRepair" 1
|
||||
|
||||
; We don't need this, MUI takes care for us
|
||||
; WriteRegStr HKCU "Software\${PRODUCT_NAME}" "Installer Language" $sUAGE
|
||||
|
||||
; write out uninstaller
|
||||
WriteUninstaller "$INSTDIR\gsmartcontrol_uninst.exe"
|
||||
|
||||
; uninstall shortcut
|
||||
;CreateDirectory "$SMPROGRAMS\GSmartControl"
|
||||
;CreateShortCut "$SMPROGRAMS\GSmartControl\Uninstall GSmartControl.lnk" "$INSTDIR\gsmartcontrol_uninst.exe" "" ""
|
||||
|
||||
SectionEnd ; post
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
; ---------------- UNINSTALL
|
||||
|
||||
|
||||
|
||||
Function un.onUninstSuccess
|
||||
HideWindow
|
||||
MessageBox MB_ICONINFORMATION|MB_OK "$(^Name) was successfully removed from your computer." /SD IDOK
|
||||
FunctionEnd
|
||||
|
||||
|
||||
|
||||
|
||||
Section Uninstall
|
||||
SetShellVarContext all ; use all user variables as opposed to current user
|
||||
SetAutoClose false
|
||||
|
||||
!ifndef NO_GTK
|
||||
ReadRegStr $gtk_mode HKLM "SOFTWARE\${PRODUCT_NAME}" "GtkInstalledMode"
|
||||
StrCmp $gtk_mode "private" "" skip_gtk_remove
|
||||
; remove private GTK+, specify the same custom options are during installation
|
||||
ExecWait "$INSTDIR\gtk2_runtime_uninst.exe /remove_config=yes /sideeffects=no /dllpath=root /translations=no /compatdlls=no /S"
|
||||
; _?=$INSTDIR
|
||||
; Delete "$INSTDIR\gtk2_runtime_uninst.exe" ; If using _? flag, it won't get deleted automatically, do it manually.
|
||||
skip_gtk_remove:
|
||||
!endif
|
||||
|
||||
; add delete commands to delete whatever files/registry keys/etc you installed here.
|
||||
Delete "$INSTDIR\gsmartcontrol_uninst.exe"
|
||||
|
||||
DeleteRegKey HKLM "SOFTWARE\${PRODUCT_NAME}"
|
||||
DeleteRegKey HKLM "${PRODUCT_UNINST_KEY}"
|
||||
|
||||
Delete "$INSTDIR\gsmartcontrol.exe"
|
||||
Delete "$INSTDIR\gsmartcontrol.exe.manifest"
|
||||
Delete "$INSTDIR\gsmartcontrol.ico"
|
||||
Delete "$INSTDIR\icon_*.png"
|
||||
; Delete "$INSTDIR\*.dll"
|
||||
Delete "$INSTDIR\smartctl-nc.exe"
|
||||
Delete "$INSTDIR\smartctl.exe"
|
||||
Delete "$INSTDIR\update-smart-drivedb.exe"
|
||||
|
||||
; update-smart-drivedb may leave these
|
||||
Delete "$INSTDIR\drivedb.h"
|
||||
Delete "$INSTDIR\drivedb.h.new"
|
||||
Delete "$INSTDIR\drivedb.h.old"
|
||||
Delete "$INSTDIR\drivedb.h.error"
|
||||
Delete "$INSTDIR\drivedb.h.lastcheck"
|
||||
|
||||
RMDir /r "$INSTDIR\doc"
|
||||
|
||||
; clean up generated stuff
|
||||
Delete "$INSTDIR\*stdout.txt"
|
||||
Delete "$INSTDIR\*stderr.txt"
|
||||
|
||||
RMDir "$INSTDIR" ; only if empty
|
||||
|
||||
; For some reason, sometimes it's not deleted in the sections, so do it here.
|
||||
Delete "$INSTDIR\${GTK_INSTALLER_EXE}"
|
||||
|
||||
!ifndef NO_GTK
|
||||
StrCmp $gtk_mode "private" skip_exe_PATH_remove
|
||||
!endif
|
||||
DeleteRegKey HKLM "${REGISTRY_APP_PATHS}\gsmartcontrol.exe"
|
||||
!ifndef NO_GTK
|
||||
skip_exe_PATH_remove:
|
||||
!endif
|
||||
|
||||
Delete "$SMPROGRAMS\GSmartControl.lnk"
|
||||
;Delete "$SMPROGRAMS\GSmartControl\Uninstall GSmartControl.lnk"
|
||||
|
||||
SectionEnd ; end of uninstall section
|
||||
|
||||
|
||||
|
||||
; --------------- Helpers
|
||||
|
||||
; Detect previous installation
|
||||
Function DetectPrevInstallation
|
||||
; if /removeold=no option is given, don't check anything.
|
||||
StrCmp $install_option_removeold "no" old_detect_done
|
||||
|
||||
SetShellVarContext all ; use all user variables as opposed to current user
|
||||
push $R0
|
||||
|
||||
; detect previous installation
|
||||
ReadRegStr $R0 HKLM "${PRODUCT_UNINST_KEY}" "UninstallString"
|
||||
StrCmp $R0 "" old_detect_done
|
||||
|
||||
MessageBox MB_OKCANCEL|MB_ICONEXCLAMATION \
|
||||
"${PRODUCT_NAME} is already installed. $\n$\nClick `OK` to remove the \
|
||||
previous version or `Cancel` to continue anyway." \
|
||||
/SD IDOK IDOK old_uninst
|
||||
; Abort
|
||||
goto old_detect_done
|
||||
|
||||
; Run the old uninstaller
|
||||
old_uninst:
|
||||
ClearErrors
|
||||
IfSilent old_silent_uninst old_nosilent_uninst
|
||||
|
||||
old_nosilent_uninst:
|
||||
ExecWait '$R0'
|
||||
goto old_uninst_continue
|
||||
|
||||
old_silent_uninst:
|
||||
ExecWait '$R0 /S _?=$INSTDIR'
|
||||
|
||||
old_uninst_continue:
|
||||
|
||||
IfErrors old_no_remove_uninstaller
|
||||
|
||||
; You can either use Delete /REBOOTOK in the uninstaller or add some code
|
||||
; here to remove to remove the uninstaller. Use a registry key to check
|
||||
; whether the user has chosen to uninstall. If you are using an uninstaller
|
||||
; components page, make sure all sections are uninstalled.
|
||||
old_no_remove_uninstaller:
|
||||
|
||||
old_detect_done: ; old installation not found, all ok
|
||||
|
||||
pop $R0
|
||||
FunctionEnd
|
||||
|
||||
|
||||
|
||||
; detect GTK installation (any of available versions)
|
||||
Function AskForGtk
|
||||
SetShellVarContext all ; use all user variables as opposed to current user
|
||||
push $R0
|
||||
|
||||
ReadRegStr $R0 HKLM "SOFTWARE\GTK\2.0" "DllPath"
|
||||
StrCmp $R0 "" no_gtk have_gtk
|
||||
|
||||
no_gtk:
|
||||
MessageBox MB_OKCANCEL|MB_ICONEXCLAMATION \
|
||||
"GTK2-Runtime is not installed. This product needs it to function properly.$\n\
|
||||
Please install GTK2-Runtime from http://gtk-win.sf.net/ first.$\n$\n\
|
||||
Click 'Cancel' to abort the installation \
|
||||
or 'OK' to continue anyway." \
|
||||
/SD IDOK IDOK have_gtk
|
||||
;Abort ; Abort has different meaning from onpage callbacks, so use Quit
|
||||
Quit
|
||||
goto end_gtk_check
|
||||
|
||||
have_gtk:
|
||||
; do nothing
|
||||
|
||||
end_gtk_check:
|
||||
|
||||
pop $R0
|
||||
FunctionEnd
|
||||
|
||||
|
||||
|
||||
; Prevent running multiple instances of the installer
|
||||
Function PreventMultipleInstances
|
||||
Push $R0
|
||||
System::Call 'kernel32::CreateMutexA(i 0, i 0, t ${PRODUCT_NAME}) ?e'
|
||||
Pop $R0
|
||||
StrCmp $R0 0 +3
|
||||
MessageBox MB_OK|MB_ICONEXCLAMATION "The installer is already running." /SD IDOK
|
||||
Abort
|
||||
Pop $R0
|
||||
FunctionEnd
|
||||
|
||||
|
||||
|
||||
; eof
|
||||
|
Before Width: | Height: | Size: 766 B After Width: | Height: | Size: 766 B |
|
Before Width: | Height: | Size: 766 B After Width: | Height: | Size: 766 B |
@@ -3,16 +3,16 @@ Section: utils
|
||||
Priority: extra
|
||||
Homepage: http://gsmartcontrol.berlios.de/
|
||||
Maintainer: Alexander Shaduri <ashaduriREMOVETHIS@gmail.com>
|
||||
# technically, we don't need libglademm if gtkmm >= 2.12, but it won't get
|
||||
# into Depends if it's not needed, so let's leave it here.
|
||||
# libglademm is also needed if libgtkmm-2.4 < 2.12, but don't write it
|
||||
# here - newer distributions don't contain it.
|
||||
Build-Depends: debhelper (>= 5), autotools-dev,
|
||||
libpcre3-dev, libgtkmm-2.4-dev (>= 2.6.0), libglademm-2.4-dev
|
||||
libpcre3-dev, libgtkmm-2.4-dev (>= 2.6.0)
|
||||
Standards-Version: 3.7.3
|
||||
|
||||
Package: gsmartcontrol
|
||||
Architecture: any
|
||||
#Depends: ${shlibs:Depends}, ${misc:Depends}, smartmontools
|
||||
Depends: ${shlibs:Depends}, smartmontools
|
||||
#Depends: ${shlibs:Depends}, ${misc:Depends}, smartmontools, menu
|
||||
Depends: ${shlibs:Depends}, smartmontools, menu
|
||||
Description: Hard disk drive health inspection tool
|
||||
GSmartControl is a graphical user interface for smartctl (from smartmontools
|
||||
package), which is a tool for querying and controlling SMART
|
||||
@@ -5,7 +5,7 @@ It was downloaded from <http://gsmartcontrol.berlios.de/>
|
||||
|
||||
Copyright:
|
||||
|
||||
Copyright (C) 2008 - 2009 Alexander Shaduri <ashaduri 'at' gmail.com>
|
||||
Copyright (C) 2008 - 2012 Alexander Shaduri <ashaduri 'at' gmail.com>
|
||||
|
||||
License:
|
||||
|
||||
@@ -27,6 +27,6 @@ On Debian systems, the complete text of the GNU General
|
||||
Public Licenses can be found in `/usr/share/common-licenses/GPL-2' and
|
||||
`/usr/share/common-licenses/GPL-3'.
|
||||
|
||||
The Debian packaging is (C) 2008 - 2009 Alexander Shaduri <ashaduri 'at' gmail.com> and
|
||||
The Debian packaging is (C) 2008 - 2012 Alexander Shaduri <ashaduri 'at' gmail.com> and
|
||||
is licensed under the GPLv2 and GPLv3, see above.
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
/**************************************************************************
|
||||
Copyright:
|
||||
(C) 2012 Alexander Shaduri <ashaduri 'at' gmail.com>
|
||||
License: See LICENSE_gsmartcontrol.txt
|
||||
***************************************************************************/
|
||||
|
||||
// This file is for generating documentation only. Do NOT include it.
|
||||
/// \file
|
||||
/// \author Alexander Shaduri
|
||||
|
||||
/**
|
||||
\mainpage GSmartControl Index
|
||||
|
||||
|
||||
\section intro_section Introduction
|
||||
This is GSmartControl internal documentation.
|
||||
*/
|
||||
|
||||
// Group definitions and titles.
|
||||
|
||||
/**
|
||||
\addtogroup applib Application-Specific Components
|
||||
\addtogroup applib_tests Tests of Application-Specific Components
|
||||
\addtogroup hz HZ Common System Components
|
||||
\addtogroup hz_tests Tests for HZ Common System Components
|
||||
\addtogroup libdebug LibDebug Flexible Debug Logging
|
||||
\addtogroup libdebug_tests Tests for LibDebug Flexible Debug Logging
|
||||
\addtogroup rmn Resource Manager
|
||||
\addtogroup rmn_tests Tests for Resource Manager
|
||||
\addtogroup rconfig Resource Manager-Based Configuration
|
||||
\addtogroup rconfig_tests Tests for Resource Manager-Based Configuration
|
||||
\addtogroup gsc GSmartControl Application
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#!/bin/bash
|
||||
############################################################################
|
||||
# Copyright:
|
||||
# (C) 2008 - 2009 Alexander Shaduri <ashaduri 'at' gmail.com>
|
||||
# (C) 2008 - 2012 Alexander Shaduri <ashaduri 'at' gmail.com>
|
||||
# License: See LICENSE_zlib.txt file
|
||||
############################################################################
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
[Project]
|
||||
Manager=KDevCustomBuildSystem
|
||||
Name=gsmartcontrol
|
||||
@@ -15,14 +15,14 @@
|
||||
<projectname>gsmartcontrol</projectname>
|
||||
<projectdirectory>.</projectdirectory>
|
||||
<absoluteprojectpath>false</absoluteprojectpath>
|
||||
<description></description>
|
||||
<defaultencoding></defaultencoding>
|
||||
<description/>
|
||||
<defaultencoding/>
|
||||
<versioncontrol/>
|
||||
</general>
|
||||
<kdevautoproject>
|
||||
<general>
|
||||
<activetarget>src/gsmartcontrol</activetarget>
|
||||
<useconfiguration>suncc</useconfiguration>
|
||||
<useconfiguration>open64</useconfiguration>
|
||||
</general>
|
||||
<run>
|
||||
<mainprogram>/10/devel/projects/gsmartcontrol/current/gsmartcontrol/debuggy</mainprogram>
|
||||
@@ -81,16 +81,16 @@
|
||||
<ccompiler>kdevgccoptions</ccompiler>
|
||||
<cxxcompiler>kdevgppoptions</cxxcompiler>
|
||||
<f77compiler>kdevg77options</f77compiler>
|
||||
<cflags></cflags>
|
||||
<cxxflags></cxxflags>
|
||||
<cflags/>
|
||||
<cxxflags/>
|
||||
<envvars/>
|
||||
<topsourcedir></topsourcedir>
|
||||
<cppflags></cppflags>
|
||||
<ldflags></ldflags>
|
||||
<topsourcedir/>
|
||||
<cppflags/>
|
||||
<ldflags/>
|
||||
<ccompilerbinary>gcc-4.4</ccompilerbinary>
|
||||
<cxxcompilerbinary>g++-4.4</cxxcompilerbinary>
|
||||
<f77compilerbinary></f77compilerbinary>
|
||||
<f77flags></f77flags>
|
||||
<f77compilerbinary/>
|
||||
<f77flags/>
|
||||
</debuggy>
|
||||
<icc>
|
||||
<envvars/>
|
||||
@@ -111,7 +111,7 @@
|
||||
</icc>
|
||||
<win32>
|
||||
<envvars/>
|
||||
<configargs>--disable-user-flags --enable-optimize-options --enable-tests --build=i686-linux --host=i386-pc-mingw32 PKG_CONFIG_PATH=/cross/w32/target/lib/pkgconfig PKG_CONFIG_LIBDIR="" PATH="/cross/w32/gcc-bin:/cross/w32/target/bin:$PATH"</configargs>
|
||||
<configargs>--with-windows-gtk-name=gtk2-runtime-2.16.6-2010-02-24-ash --disable-user-flags --enable-optimize-options --enable-tests --build=i686-linux --host=i386-pc-mingw32 PKG_CONFIG_PATH=/cross/w32/target/lib/pkgconfig PKG_CONFIG_LIBDIR="" PATH="/cross/w32/gcc-bin:/cross/w32/target/bin:$PATH"</configargs>
|
||||
<builddir>win32</builddir>
|
||||
<topsourcedir/>
|
||||
<cppflags/>
|
||||
@@ -196,6 +196,40 @@
|
||||
<cxxflags/>
|
||||
<f77flags/>
|
||||
</win64-debug>
|
||||
<default>
|
||||
<envvars/>
|
||||
<configargs/>
|
||||
<builddir/>
|
||||
<topsourcedir/>
|
||||
<cppflags/>
|
||||
<ldflags/>
|
||||
<ccompiler>kdevgccoptions</ccompiler>
|
||||
<cxxcompiler>kdevgppoptions</cxxcompiler>
|
||||
<f77compiler>kdevg77options</f77compiler>
|
||||
<ccompilerbinary/>
|
||||
<cxxcompilerbinary/>
|
||||
<f77compilerbinary/>
|
||||
<cflags/>
|
||||
<cxxflags/>
|
||||
<f77flags/>
|
||||
</default>
|
||||
<open64>
|
||||
<envvars/>
|
||||
<configargs>--enable-tests</configargs>
|
||||
<builddir>open64</builddir>
|
||||
<topsourcedir/>
|
||||
<cppflags/>
|
||||
<ldflags/>
|
||||
<ccompiler>kdevgccoptions</ccompiler>
|
||||
<cxxcompiler>kdevgppoptions</cxxcompiler>
|
||||
<f77compiler>kdevg77options</f77compiler>
|
||||
<ccompilerbinary>/opt/open64/bin/opencc</ccompilerbinary>
|
||||
<cxxcompilerbinary>/opt/open64/bin/openCC</cxxcompilerbinary>
|
||||
<f77compilerbinary/>
|
||||
<cflags/>
|
||||
<cxxflags>-Wall</cxxflags>
|
||||
<f77flags/>
|
||||
</open64>
|
||||
</configurations>
|
||||
<make>
|
||||
<envvars>
|
||||
@@ -271,11 +305,11 @@
|
||||
</kdevdoctreeview>
|
||||
<kdevdebugger>
|
||||
<general>
|
||||
<dbgshell></dbgshell>
|
||||
<gdbpath></gdbpath>
|
||||
<configGdbScript></configGdbScript>
|
||||
<runShellScript></runShellScript>
|
||||
<runGdbScript></runGdbScript>
|
||||
<dbgshell/>
|
||||
<gdbpath/>
|
||||
<configGdbScript/>
|
||||
<runShellScript/>
|
||||
<runGdbScript/>
|
||||
<breakonloadinglibs>true</breakonloadinglibs>
|
||||
<separatetty>false</separatetty>
|
||||
<floatingtoolbar>false</floatingtoolbar>
|
||||
@@ -4,7 +4,7 @@ Release: 1as
|
||||
License: GPLv2, GPLv3
|
||||
Url: http://gsmartcontrol.berlios.de
|
||||
Vendor: Alexander Shaduri <ashaduri 'at' gmail.com>
|
||||
Packager: Alexander Shaduri <ashaduri 'at' gmail.com>
|
||||
# Packager: Alexander Shaduri <ashaduri 'at' gmail.com>
|
||||
Source: gsmartcontrol-%{version}.tar.bz2
|
||||
BuildRoot: %{_tmppath}/%{name}-%{version}-build
|
||||
Summary: GSmartControl - Hard Disk Health Inspection Tool
|
||||
@@ -15,12 +15,6 @@ Group: System/Kernel and hardware
|
||||
Group: Hardware/Other
|
||||
%endif
|
||||
|
||||
# Support build service rpmlint. Disabled - the build service
|
||||
# stopped recognizing the flag for some architectures.
|
||||
# %if 0%{?opensuse_bs} && 0%{?suse_version} >= 1010
|
||||
# Support: rpmlint-bs
|
||||
# %endif
|
||||
|
||||
|
||||
# Dependencies for various distributions. The actual deps are:
|
||||
# smartmontools, pcre, (gtkmm2 >= 2.12 || (gtkmm2 >= 2.6.0 && libglademm >= 2.4.0))
|
||||
@@ -46,6 +40,11 @@ Requires: smartmontools, pcre, gtkmm24 >= 2.6.0, libglademm >= 2.4.0
|
||||
BuildRequires: gcc-c++, libstdc++-devel, pcre-devel, gtkmm24-devel >= 2.6.0, libglademm-devel >= 2.4.0
|
||||
%endif
|
||||
%endif
|
||||
BuildRequires: update-desktop-files
|
||||
|
||||
%if 0%{?suse_version} >= 1030
|
||||
BuildRequires: fdupes
|
||||
%endif
|
||||
|
||||
%endif
|
||||
|
||||
@@ -62,6 +61,12 @@ Requires: smartmontools, pcre, gtkmm24 >= 2.6.0, libglademm24 >= 2.4.0
|
||||
BuildRequires: gcc-c++, pcre-devel, gtkmm24-devel >= 2.6.0, libglademm24-devel >= 2.4.0
|
||||
%endif
|
||||
|
||||
# Fedora with consolehelper.
|
||||
# usermode-gtk is for consolehelper-gtk.
|
||||
%if 0%{?fedora_version}
|
||||
Requires: usermode-gtk
|
||||
%endif
|
||||
|
||||
%endif
|
||||
|
||||
|
||||
@@ -98,21 +103,80 @@ SMART data to determine its health, as well as run various tests on it.
|
||||
|
||||
%build
|
||||
# Set up for parallel builds
|
||||
numprocs=`egrep -c ^cpu[0-9]+ /proc/stat || :`
|
||||
if [ "$numprocs" = "0" ]; then
|
||||
numprocs=1
|
||||
fi
|
||||
|
||||
make -j$numprocs
|
||||
# make
|
||||
#numprocs=`grep -E -c ^cpu[0-9]+ /proc/stat || :`
|
||||
#if [ "$numprocs" = "0" ]; then
|
||||
# numprocs=1
|
||||
#fi
|
||||
#make -j$numprocs
|
||||
make
|
||||
|
||||
|
||||
%install
|
||||
# %makeinstall
|
||||
|
||||
# %%makeinstall
|
||||
make DESTDIR=%buildroot install-strip
|
||||
# Remove the icon cache file "make install" generates, to avoid package conflicts.
|
||||
rm -f $RPM_BUILD_ROOT%{_datadir}/icons/hicolor/icon-theme.cache
|
||||
|
||||
%if 0%{?suse_version}
|
||||
%suse_update_desktop_file -n %{name}
|
||||
|
||||
|
||||
# There are some png file duplicates, hardlink them.
|
||||
%if 0%{?suse_version} >= 1030
|
||||
%fdupes
|
||||
%endif
|
||||
|
||||
|
||||
# We install icons, so this is needed.
|
||||
%if 0%{?suse_version} >= 1140
|
||||
%post
|
||||
%icon_theme_cache_post
|
||||
|
||||
%postun
|
||||
%icon_theme_cache_postun
|
||||
%endif
|
||||
|
||||
# endif suse
|
||||
%endif
|
||||
|
||||
|
||||
%if 0%{?fedora_version}
|
||||
# We still retain gsmartcontrol-root for consistency with other distributions.
|
||||
|
||||
# Make the desktop file run gsmartcontrol instead of gsmartcontrol-root
|
||||
sed "s|gsmartcontrol-root|gsmartcontrol|g" %{buildroot}%{_datadir}/applications/gsmartcontrol.desktop > %{buildroot}%{_datadir}/applications/gsmartcontrol.desktop.new
|
||||
mv -f %{buildroot}%{_datadir}/applications/gsmartcontrol.desktop.new %{buildroot}%{_datadir}/applications/gsmartcontrol.desktop
|
||||
|
||||
# The rest is taken from the official fedora spec:
|
||||
# http://pkgs.fedoraproject.org/cgit/gsmartcontrol.git/tree/
|
||||
|
||||
# Set up for console-helper
|
||||
mkdir -p %{buildroot}%{_sbindir}
|
||||
# Add a copy as "gsmartcontrol-noroot", since gsmartcontrol will always
|
||||
# ask for root password.
|
||||
cp %{buildroot}%{_bindir}/%{name} %{buildroot}%{_bindir}/%{name}-noroot
|
||||
mv %{buildroot}%{_bindir}/%{name} %{buildroot}%{_sbindir}/%{name}
|
||||
ln -s consolehelper %{buildroot}%{_bindir}/%{name}
|
||||
|
||||
mkdir -p %{buildroot}%{_sysconfdir}/pam.d
|
||||
cat <<EOF >%{buildroot}%{_sysconfdir}/pam.d/%{name}
|
||||
#%%PAM-1.0
|
||||
auth include config-util
|
||||
account include config-util
|
||||
session include config-util
|
||||
EOF
|
||||
|
||||
mkdir -p %{buildroot}%{_sysconfdir}/security/console.apps
|
||||
cat <<EOF >%{buildroot}%{_sysconfdir}/security/console.apps/%{name}
|
||||
USER=root
|
||||
PROGRAM=/usr/sbin/gsmartcontrol
|
||||
SESSION=true
|
||||
EOF
|
||||
|
||||
# endif fedora
|
||||
%endif
|
||||
|
||||
|
||||
%if 0%{?mandriva_version}
|
||||
desktop-file-install --vendor="" \
|
||||
@@ -131,26 +195,21 @@ rm -rf %buildroot
|
||||
%defattr(-,root,root)
|
||||
|
||||
%attr(0755,root,root) %{_bindir}/*
|
||||
# %attr(0644,root,root) %config(noreplace) %{_sysconfdir}/*
|
||||
# %%attr(0644,root,root) %%config(noreplace) %%{_sysconfdir}/*
|
||||
|
||||
%doc %{_datadir}/doc/gsmartcontrol
|
||||
%doc %{_mandir}/man1/*
|
||||
|
||||
%{_datadir}/gsmartcontrol
|
||||
# %{_datadir}/gsmartcontrol/*
|
||||
# %%{_datadir}/gsmartcontrol/*
|
||||
%{_datadir}/applications/*.desktop
|
||||
%{_datadir}/icons/*
|
||||
%{_datadir}/pixmaps/*
|
||||
|
||||
|
||||
%if 0%{?fedora_version}
|
||||
%config(noreplace) %{_sysconfdir}/pam.d/%{name}
|
||||
%config(noreplace) %{_sysconfdir}/security/console.apps/%{name}
|
||||
%{_sbindir}/gsmartcontrol
|
||||
%endif
|
||||
|
||||
%changelog
|
||||
* Fri Nov 14 2008 Alexander Shaduri <ashaduri 'at' gmail.com>
|
||||
- Updated .spec file to incorporate changes from the official Mandriva package.
|
||||
|
||||
* Mon Oct 06 2008 Alexander Shaduri <ashaduri 'at' gmail.com>
|
||||
- Updated .spec file to support OpenSUSE < 10.3, Fedora and friends,
|
||||
Mandriva (for OpenSUSE Build Service).
|
||||
|
||||
* Mon Sep 15 2008 Alexander Shaduri <ashaduri 'at' gmail.com>
|
||||
- Initial .spec file.
|
||||
@@ -1,12 +0,0 @@
|
||||
Whatever License
|
||||
|
||||
THIS SOFTWARE IS PROVIDED 'AS-IS', WITHOUT ANY EXPRESS OR IMPLIED
|
||||
WARRANTY. IN NO EVENT WILL THE AUTHORS BE HELD LIABLE FOR ANY DAMAGES
|
||||
ARISING FROM THE USE OF THIS SOFTWARE.
|
||||
|
||||
Everyone is permitted to copy and distribute verbatim or modified
|
||||
copies of this license document.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely.
|
||||
@@ -1,132 +0,0 @@
|
||||
|
||||
# Add autoconf.m4 directory to local macro search path
|
||||
ACLOCAL_AMFLAGS = -I autoconf.m4
|
||||
|
||||
SUBDIRS = data debian.dist src
|
||||
|
||||
|
||||
# These files are actually needed for compilation.
|
||||
noinst_DATA = AUTHORS.txt LICENSE_gsmartcontrol.txt README.txt
|
||||
|
||||
|
||||
# For the files to be bundled with the distribution, specify them in
|
||||
# one of the following.
|
||||
|
||||
# These will be installed into docdir.
|
||||
# Some of these files are actually needed for compilation (see src/res/Makefile.am).
|
||||
dist_doc_DATA = AUTHORS.txt ChangeLog NEWS README.txt \
|
||||
LICENSE_boost_1_0.txt \
|
||||
LICENSE_bsd-ac.txt \
|
||||
LICENSE_bsd-ucb.txt \
|
||||
LICENSE_gpl2.txt \
|
||||
LICENSE_gpl3.txt \
|
||||
LICENSE_gsmartcontrol.txt \
|
||||
LICENSE_hz.txt \
|
||||
LICENSE_pcrecpp.txt \
|
||||
LICENSE_whatever.txt \
|
||||
LICENSE_zlib.txt
|
||||
|
||||
|
||||
# nobase_ preserves their directory names.
|
||||
nobase_dist_doc_DATA = contrib/cron-based_noadmin/README \
|
||||
contrib/cron-based_noadmin/cron_gather_smart.sh \
|
||||
contrib/cron-based_noadmin/crontab.example \
|
||||
contrib/cron-based_noadmin/smartctl_subst.sh
|
||||
|
||||
|
||||
# Extra files bundled with distribution.
|
||||
# file2csource.sh is needed for building but not installed.
|
||||
EXTRA_DIST = COPYING TODO INSTALL configure autogen.sh \
|
||||
baqup gsmartcontrol.kdevelop \
|
||||
templates \
|
||||
file2csource.sh \
|
||||
gsmartcontrol.spec
|
||||
|
||||
|
||||
|
||||
# PCH support
|
||||
|
||||
global_macros.h.gch: $(top_srcdir)/src/global_macros.h
|
||||
$(CXX) $(CXXFLAGS) $(DEFS) -x "c++-header" $(top_srcdir)/src/global_macros.h -o global_macros.h.gch
|
||||
|
||||
gch: global_macros.h.gch
|
||||
|
||||
gch-clean:
|
||||
rm -f global_macros.h.gch
|
||||
|
||||
|
||||
|
||||
# rpm support
|
||||
|
||||
src-rpm: dist
|
||||
rpmbuild -ts $(distdir).tar.bz2
|
||||
|
||||
|
||||
# Don't use this - it does something weird, and gcc errors out with "long long long" errors, etc...
|
||||
#rpm: dist
|
||||
# rpmbuild -ta $(distdir).tar.bz2
|
||||
|
||||
|
||||
|
||||
# NSIS installer support.
|
||||
# Requires wine, installed NSIS, smartctl-nc.exe, smartctl.exe.
|
||||
# Gtkmm dlls and pcre dlls are required if linking against them.
|
||||
# dos2unix on build machine.
|
||||
# Execute only with win32 build present.
|
||||
|
||||
WIN_ZIP_NAME = $(PACKAGE)-$(VERSION)-win32
|
||||
|
||||
win-dist: win-dist-prepare nsis-dist-nocleanup win-zip-dist
|
||||
|
||||
win-dist-clean:
|
||||
rm -rf gsmartcontrol-*.exe gsmartcontrol-*.zip nsis-dist $(WIN_ZIP_NAME)
|
||||
|
||||
|
||||
win-dist-prepare: all win-dist-clean
|
||||
$(MKDIR_P) nsis-dist
|
||||
|
||||
cp data/nsis/gsmartcontrol.nsi $(top_srcdir)/data/nsis/nsi_* nsis-dist/
|
||||
cp $(top_srcdir)/data/gsmartcontrol.ico $(top_srcdir)/data/icon_*.png nsis-dist/
|
||||
|
||||
$(MKDIR_P) nsis-dist/doc
|
||||
cp data/nsis/distribution.txt nsis-dist/doc/
|
||||
cp $(top_srcdir)/AUTHORS.txt $(top_srcdir)/LICENSE_* $(top_srcdir)/README.txt nsis-dist/doc/
|
||||
cp $(top_srcdir)/NEWS nsis-dist/doc/NEWS.txt
|
||||
|
||||
unix2dos nsis-dist/*.nsi nsis-dist/doc/*.txt
|
||||
|
||||
cp "@WINDOWS_BINDIR@"/smartctl-nc.exe nsis-dist/
|
||||
cp "@WINDOWS_BINDIR@"/smartctl.exe nsis-dist/
|
||||
|
||||
cp src/gsmartcontrol.exe nsis-dist/
|
||||
|
||||
$(STRIP) nsis-dist/*.exe
|
||||
|
||||
|
||||
nsis-dist: nsis-dist-nocleanup nsis-cleanup
|
||||
|
||||
nsis-dist-nocleanup: win-dist-prepare
|
||||
cd nsis-dist && @NSIS_EXEC@ gsmartcontrol.nsi
|
||||
mv nsis-dist/$(PACKAGE)-$(VERSION).exe .
|
||||
|
||||
nsis-cleanup:
|
||||
rm -rf nsis-dist
|
||||
|
||||
|
||||
win-zip-dist: win-zip-dist-nocleanup win-zip-dist-cleanup
|
||||
|
||||
win-zip-dist-nocleanup: win-dist-prepare
|
||||
mv nsis-dist $(WIN_ZIP_NAME)
|
||||
rm -rf $(WIN_ZIP_NAME)/gsmartcontrol.ico $(WIN_ZIP_NAME)/nsi_* $(WIN_ZIP_NAME)/*.nsi
|
||||
zip -9r $(WIN_ZIP_NAME).zip $(WIN_ZIP_NAME)
|
||||
|
||||
win-zip-dist-cleanup:
|
||||
rm -rf $(WIN_ZIP_NAME)
|
||||
|
||||
|
||||
|
||||
|
||||
distclean-local: gch-clean win-dist-clean
|
||||
|
||||
|
||||
|
||||
@@ -1,170 +0,0 @@
|
||||
|
||||
|
||||
GTKMM Notes:
|
||||
|
||||
To transfer an ownership from your local code to a container, use
|
||||
Gtk::Button* pButton = Gtk::manage(new Gtk::Button("Test"));
|
||||
container->add(*pButton);
|
||||
(add() takes an object by reference).
|
||||
otherwise, you will need to delete() it.
|
||||
|
||||
local scope destruction also works if using stack variables.
|
||||
{
|
||||
Gtk::Button aButton;
|
||||
// destroyed here
|
||||
}
|
||||
|
||||
|
||||
A treeview (also iconview, combobox) from glade comes
|
||||
with existing model, which should be unset.
|
||||
|
||||
|
||||
|
||||
|
||||
--------------------------------------------------------
|
||||
|
||||
TODO:
|
||||
|
||||
|
||||
|
||||
Support Areca controller.
|
||||
|
||||
When adding device, have an option to specify "-d" type and other parameters.
|
||||
This is needed to support multi-disk devices.
|
||||
|
||||
|
||||
|
||||
Patch pangomm for Pango::strip_markup().
|
||||
|
||||
No Gtk::AboutDialog::set_logo(NULL);
|
||||
|
||||
|
||||
libdebug:
|
||||
per-channel disabling.
|
||||
per-channel formatting.
|
||||
all flags should be per-channel.
|
||||
bug: if -q is passed, Execution log doesn't contain libdebug log. (requires per-channel status control).
|
||||
use format_time() instead of ctime() and friends, with ISO formatting.
|
||||
|
||||
|
||||
|
||||
'-l sataphy' -> SATA Phy event counters: Non-SMART feature, useful to detect SATA cabling problems.
|
||||
|
||||
'-l xerror' -> Extended Comprehensive Error log: An multi-sector and
|
||||
LBA48 capable version of '-l error'. Output is similar, except more
|
||||
entries can exists and the high bytes of the registers are also printed.
|
||||
Some newer drives (Samsung) only write to this log.
|
||||
|
||||
'-l scttemp' -> SCT Temperature history table. See below.
|
||||
|
||||
'-l xselftest' -> Extended Self Test Log: An multi-sector and LBA48
|
||||
capable version of '-l selftest'. Output will be similar, except more
|
||||
entries can exists and the LBA values can be somewhat longer.
|
||||
|
||||
"smartctl -l this_wont_exist" gives the list of supported logs - this
|
||||
is needed to detect xerror / xselftest support in smartctl.
|
||||
|
||||
|
||||
Careful with GPL (xerror...) stuff until the jmicron situation clears up.
|
||||
|
||||
Add detection for Interix (i586-pc-interix3), maybe with debian?
|
||||
|
||||
Re-check long double printing - win32 libc doesn't support it, a cast
|
||||
to double is needed.
|
||||
The underlying problem is that in msvc, long double is the same size
|
||||
as double, so printf() has mingw-incompatible presentation of long double.
|
||||
|
||||
Support USB flash disks in CVS smartctl versions:
|
||||
Try smartctl -i /dev/sdc;
|
||||
If it returns "Smartctl: please specify device type with the -d option.",
|
||||
try "-d scsi", which should at least give us the name.
|
||||
|
||||
Maybe make it easier to specify "-d" (with a dropdown?)
|
||||
Not sure, "-l aaa /tmp" doesn't list all types.
|
||||
|
||||
|
||||
|
||||
----------- Feature List ----------
|
||||
|
||||
+Autodetect available devices
|
||||
|
||||
+Select current device (from autodetected list; manually whitelist devices).
|
||||
|
||||
+Smartctl binary (text entries in Options - binary, default command line options).
|
||||
+ Global command-line options for smartctl.
|
||||
+ Command-line options per-device in settings (e.g. -d ata).
|
||||
+ Search smartctl binary on startup (try to execute it with --version). If it's not there, alert the user.
|
||||
|
||||
+Indicate which of the devices has SMART supported / enabled.
|
||||
+ Enable / disable smart on devices.
|
||||
+ Indicate that this is until shutdown (but may be preserved on reboot).
|
||||
+ Direct them to smartd / smartctl documentation for permanent enabling.
|
||||
+ NOTE: SMART is sometimes preserved across power cycles.
|
||||
|
||||
+Enable / disable Automatic Offline Data Collection for devices. (-o on)
|
||||
+ Show its status in the main window.
|
||||
|
||||
+Show identity information for device (aka short info), --info.
|
||||
|
||||
+Show all SMART information for device (--all), includes:
|
||||
+ * Short info (--info)
|
||||
+ * SMART DATA
|
||||
+ * overall-health (-H, --health) - may check this automatically as well.
|
||||
+ * General SMART Values, aka Capabilities (-c, --capabilities)
|
||||
+ * Attributes (-A, --attributes). These need decoding.
|
||||
+ * Error Log (-l error)
|
||||
+ * Self-test log (-l selftest)
|
||||
+ * Selective self-test log and settings
|
||||
* SCT status and other stuff
|
||||
Display temperature somewhere (use SCT or Attr 194 for this).
|
||||
+ * Ability to save this information to a file.
|
||||
+ * On info window show: Ask to turn SMART on if it's disabled
|
||||
|
||||
+Program error reporting:
|
||||
+ invalid smartmontools version.
|
||||
+ cannot parse output - show log.
|
||||
+ smartctl exited with error - look it up in error map.
|
||||
|
||||
|
||||
SCT Temperatures
|
||||
-l scttemp prints temperature and history.
|
||||
-t scttempint,N[,p] (N - count, p - preserve across reset or not).
|
||||
This configures temperature logging interval (1 min by default) and clears the history.
|
||||
|
||||
|
||||
+Tests:
|
||||
Ability to detect a testing drive on boot, show its info with testing tab.
|
||||
|
||||
Run one-time Immediate Offline test (-t offline).
|
||||
Offline tests only update Attributes, and if errors are found they will
|
||||
appear in SMART error log. Self-test logs are unaffected.
|
||||
Abort (-X). Abort works with Offline only if there's
|
||||
"Abort Offline collection upon new command" capability.
|
||||
If the drive has "Suspend Offline collection upon new command" capability,
|
||||
immediate offline test may be tracked through --capabilities (not on mine!).
|
||||
If it's "Abort Offline collection upon new command", then the test
|
||||
will abort on --capabilities or --abort.
|
||||
|
||||
|
||||
Polling time
|
||||
The self-test routine recommended polling time shall be equal to the number of minutes that is the minimum
|
||||
recommended time before which the host should first poll for test completion status. Actual test time could
|
||||
be several times this value. Polling before this time could extend the self-test execution time or abort the test
|
||||
depending on the state of bit 2 of the off-line data capability bits.
|
||||
|
||||
Autosave
|
||||
This command enables and disables the optional attribute autosave feature of the device. This command
|
||||
may either allow the device, after some vendor specified event, to save the device updated attribute values
|
||||
to non-volatile memory; or this command may cause the autosave feature to be disabled. The state of the
|
||||
attribute autosave feature (either enabled or disabled) shall be preserved by the device across power cycles.
|
||||
A value of zero written by the host into the device’s Sector Count register before issuing this command shall
|
||||
cause this feature to be disabled. Disabling this feature does not preclude the device from saving SMART
|
||||
data to non-volatile memory during some other normal operation such as during a power-on or power-off
|
||||
sequence or during an error recovery sequence.
|
||||
A value of F1h written by the host into the device’s Sector Count register before issuing this command shall
|
||||
cause this feature to be enabled. Any other meaning of this value or any other non-zero value written by the
|
||||
host into this register before issuing this command may differ from device to device. The meaning of any
|
||||
non-zero value written to this register at this time shall be preserved by the device across power cycles.
|
||||
|
||||
|
||||
|
||||
@@ -1,111 +0,0 @@
|
||||
#!/bin/bash
|
||||
############################################################################
|
||||
# Copyright:
|
||||
# (C) 2008 Alexander Shaduri <ashaduri 'at' gmail.com>
|
||||
# License: See LICENSE_zlib.txt file
|
||||
############################################################################
|
||||
|
||||
# Run gsmartcontrol with root, asking for root password first.
|
||||
|
||||
EXEC_BIN="@prefix@/bin/gsmartcontrol";
|
||||
prog_name="gsmartcontrol"
|
||||
|
||||
DESKTOP="$1";
|
||||
|
||||
# This works for --help too
|
||||
if [ "$DESKTOP" = "" ]; then
|
||||
DESKTOP="auto"; # default
|
||||
|
||||
elif [ "$DESKTOP" != "auto" ] && [ "$DESKTOP" != "kde" ] && \
|
||||
[ "$DESKTOP" != "gnome" ] && [ "$DESKTOP" != "other" ]; then
|
||||
echo "Usage: $0 [<auto|kde|gnome|other> [<${prog_name}_options>] ]";
|
||||
exit 1;
|
||||
fi
|
||||
shift; # remove $1
|
||||
|
||||
|
||||
# Auto-detect current desktop if auto was specified.
|
||||
if [ "$DESKTOP" = "auto" ]; then
|
||||
# KDE_SESSION_UID is present on kde3 and kde4.
|
||||
# Note that it may be empty (but still set)
|
||||
if [ "${KDE_SESSION_UID+set}" = "set" ]; then
|
||||
DESKTOP="kde";
|
||||
# same with gnome
|
||||
elif [ "${GNOME_DESKTOP_SESSION_ID+set}" = "set" ]; then
|
||||
DESKTOP="gnome";
|
||||
else
|
||||
DESKTOP="other";
|
||||
fi
|
||||
fi
|
||||
|
||||
# echo $DESKTOP;
|
||||
|
||||
|
||||
# They're basically the same, only the order is different.
|
||||
# sux requires xterm to ask for the password.
|
||||
# xdg-su is basically like this script, except worse :)
|
||||
gnome_sus="gnomesu gksu kdesu xdg-su sux";
|
||||
kde_sus="kdesu gnomesu gksu xdg-su sux";
|
||||
other_sus="$gnome_sus";
|
||||
|
||||
|
||||
candidates="";
|
||||
found_su=""
|
||||
|
||||
if [ "$DESKTOP" = "gnome" ]; then
|
||||
candidates="$gnome_sus";
|
||||
elif [ "$DESKTOP" = "kde" ]; then
|
||||
candidates="$kde_sus";
|
||||
elif [ "$DESKTOP" = "other" ]; then
|
||||
candidates="$other_sus";
|
||||
fi
|
||||
|
||||
for subin in $candidates; do
|
||||
which $subin &>/dev/null
|
||||
if [ $? -eq 0 ]; then
|
||||
found_su="$subin";
|
||||
break;
|
||||
fi
|
||||
done
|
||||
|
||||
if [ "$found_su" = "" ]; then
|
||||
xmessage "Error launching ${prog_name}: No suitable su mechanism found.
|
||||
Try installing kdesu, gnomesu, gksu or sux first.";
|
||||
exit 1;
|
||||
fi
|
||||
|
||||
|
||||
# gnomesu and gksu (but not kdesu, not sure about others) fail to adopt
|
||||
# root's PATH. Since the user's PATH may not contain /usr/sbin (with smartctl)
|
||||
# on some distributions (e.g. mandriva), add it manually. We also add
|
||||
# /usr/local/sbin, since that's the default location of custom-compiled smartctl.
|
||||
# Add these directories _before_ existing PATH, so that the user is not
|
||||
# tricked into running it from some other path (we're running as root with
|
||||
# the user's env after all).
|
||||
export PATH="/usr/sbin:/usr/local/sbin:$PATH"
|
||||
|
||||
|
||||
# echo $found_su;
|
||||
|
||||
# Examples:
|
||||
# gnomesu -c 'gsmartcontrol --no-scan'
|
||||
# kdesu -c 'gsmartcontrol --no-scan'
|
||||
# xterm -e sux -c 'gsmartcontrol --no-scan' # sux asks for password in a terminal
|
||||
|
||||
full_cmd=""
|
||||
if [ "$found_su" = "sux" ]; then
|
||||
full_cmd="xterm -e sux -c '$EXEC_BIN $@'"
|
||||
|
||||
elif [ "$found_su" = "gksu" ]; then
|
||||
full_cmd="$found_su '$EXEC_BIN $@'"
|
||||
|
||||
else # gnomesu, kdesu, xdg-su
|
||||
full_cmd="$found_su -c '$EXEC_BIN $@'"
|
||||
fi
|
||||
|
||||
|
||||
eval $full_cmd
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,293 +0,0 @@
|
||||
|
||||
; NSIS2 Script
|
||||
; Compatible with NSIS 2.40
|
||||
|
||||
|
||||
!define PRODUCT_VERSION "@VERSION@"
|
||||
!define PRODUCT_NAME "GSmartControl"
|
||||
!define PRODUCT_NAME_SMALL "gsmartcontrol"
|
||||
!define PRODUCT_PUBLISHER "Alexander Shaduri"
|
||||
!define PRODUCT_WEB_SITE "http://gsmartcontrol.berlios.de"
|
||||
|
||||
;!define PRODUCT_DIR_REGKEY "Software\Microsoft\Windows\CurrentVersion\App Paths\AppMainExe.exe"
|
||||
!define PRODUCT_UNINST_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}"
|
||||
!define PRODUCT_UNINST_ROOT_KEY "HKLM"
|
||||
|
||||
!define REGISTRY_APP_PATHS "Software\Microsoft\Windows\CurrentVersion\App Paths"
|
||||
|
||||
|
||||
|
||||
|
||||
; --------------- General Settings
|
||||
|
||||
|
||||
; This compressor gives us the best results
|
||||
SetCompressor /SOLID lzma
|
||||
|
||||
; Do a CRC check before installing
|
||||
CRCCheck On
|
||||
|
||||
; This is used in titles
|
||||
Name "${PRODUCT_NAME}" ; ${PRODUCT_VERSION}
|
||||
|
||||
; Output File Name
|
||||
OutFile "${PRODUCT_NAME_SMALL}-${PRODUCT_VERSION}.exe"
|
||||
|
||||
|
||||
|
||||
;The Default Installation Directory
|
||||
; try to install to the same directory as runtime.
|
||||
InstallDir "$PROGRAMFILES\${PRODUCT_NAME_SMALL}"
|
||||
; If already installed, try here
|
||||
InstallDirRegKey HKLM "SOFTWARE\${PRODUCT_NAME}" "InstallationDirectory"
|
||||
|
||||
|
||||
ShowInstDetails show
|
||||
ShowUnInstDetails show
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
; --------------------- MUI INTERFACE
|
||||
|
||||
; MUI 2.0 compatible install
|
||||
!include "MUI2.nsh"
|
||||
|
||||
;Backgound Colors. uncomment to enable fullscreen.
|
||||
; BGGradient 0000FF 000000 FFFFFF
|
||||
|
||||
; MUI Settings
|
||||
!define MUI_ABORTWARNING
|
||||
!define MUI_ICON "nsi_install.ico"
|
||||
!define MUI_UNICON "nsi_uninstall.ico"
|
||||
|
||||
|
||||
;Things that need to be extracted on first (keep these lines before any File command!)
|
||||
;Only useful for BZIP2 compression
|
||||
!insertmacro MUI_RESERVEFILE_LANGDLL
|
||||
;!insertmacro MUI_RESERVEFILE_INSTALLOPTIONS
|
||||
|
||||
|
||||
; Language Selection Dialog Settings
|
||||
!define MUI_LANGDLL_REGISTRY_ROOT "${PRODUCT_UNINST_ROOT_KEY}"
|
||||
!define MUI_LANGDLL_REGISTRY_KEY "${PRODUCT_UNINST_KEY}"
|
||||
!define MUI_LANGDLL_REGISTRY_VALUENAME "NSIS:Language"
|
||||
|
||||
|
||||
; Pages to show during installation
|
||||
!insertmacro MUI_PAGE_WELCOME
|
||||
!insertmacro MUI_PAGE_LICENSE "doc\distribution.txt"
|
||||
;!insertmacro MUI_PAGE_COMPONENTS
|
||||
!insertmacro MUI_PAGE_DIRECTORY
|
||||
!insertmacro MUI_PAGE_INSTFILES
|
||||
|
||||
;!define MUI_FINISHPAGE_RUN "$INSTDIR\gsmartcontrol.exe"
|
||||
;!define MUI_FINISHPAGE_SHOWREADME "$INSTDIR\Example.file"
|
||||
;!define MUI_FINISHPAGE_RUN_NOTCHECKED
|
||||
!define MUI_FINISHPAGE_NOAUTOCLOSE
|
||||
!define MUI_FINISHPAGE_NOREBOOTSUPPORT
|
||||
!insertmacro MUI_PAGE_FINISH
|
||||
|
||||
|
||||
|
||||
; Uninstaller page
|
||||
!insertmacro MUI_UNPAGE_CONFIRM
|
||||
!insertmacro MUI_UNPAGE_INSTFILES
|
||||
|
||||
|
||||
|
||||
; Language files
|
||||
!insertmacro MUI_LANGUAGE "English"
|
||||
|
||||
|
||||
; --------------- END MUI
|
||||
|
||||
LangString TEXT_IO_TITLE ${LANG_ENGLISH} "GSmartControl"
|
||||
|
||||
|
||||
|
||||
; --------------- START INSTALLATION
|
||||
|
||||
|
||||
Function .onInit
|
||||
|
||||
!insertmacro MUI_LANGDLL_DISPLAY
|
||||
|
||||
Push 2 ;F ;22 = number of languages, F = change font
|
||||
|
||||
;Language selection
|
||||
LangDLL::LangDialog "Installer Language" "Please select a language."
|
||||
|
||||
Pop $LANGUAGE
|
||||
StrCmp $LANGUAGE "cancel" 0 +2
|
||||
Abort
|
||||
|
||||
; detect previous installation
|
||||
ReadRegStr $R0 HKLM "${PRODUCT_UNINST_KEY}" "UninstallString"
|
||||
StrCmp $R0 "" no_prev
|
||||
|
||||
MessageBox MB_OKCANCEL|MB_ICONEXCLAMATION \
|
||||
"${PRODUCT_NAME} is already installed. $\n$\nClick 'OK' to remove the \
|
||||
previous version or 'Cancel' to continue anyway." \
|
||||
IDOK uninst_product
|
||||
; Abort
|
||||
goto no_prev ; if cancel was pressed, continue as if no old installation.
|
||||
|
||||
;Run the uninstaller
|
||||
uninst_product:
|
||||
ClearErrors
|
||||
ExecWait '$R0 _?=$INSTDIR' ;Do not copy the uninstaller to a temp file
|
||||
|
||||
IfErrors cannot_uninst_product
|
||||
|
||||
;You can either use Delete /REBOOTOK in the uninstaller or add some code
|
||||
;here to remove the uninstaller. Use a registry key to check
|
||||
;whether the user has chosen to uninstall. If you are using an uninstaller
|
||||
;components page, make sure all sections are uninstalled.
|
||||
cannot_uninst_product:
|
||||
|
||||
no_prev: ; no old installation found, all ok
|
||||
|
||||
|
||||
|
||||
|
||||
; detect GTK installation (any of available versions)
|
||||
ReadRegStr $R0 HKLM "SOFTWARE\GTK\2.0" "DllPath"
|
||||
StrCmp $R0 "" no_gtk
|
||||
|
||||
goto have_gtk
|
||||
|
||||
no_gtk:
|
||||
MessageBox MB_OKCANCEL|MB_ICONEXCLAMATION \
|
||||
"GTK2-Runtime is not installed. This product needs it to function properly.$\n\
|
||||
Please install GTK2-Runtime from http://gtk-win.sf.net/ first.$\n$\n\
|
||||
Click 'Cancel' to abort the installation \
|
||||
or 'OK' to continue anyway." \
|
||||
IDOK have_gtk
|
||||
Abort
|
||||
|
||||
have_gtk:
|
||||
; do nothing
|
||||
|
||||
|
||||
|
||||
FunctionEnd
|
||||
|
||||
|
||||
|
||||
|
||||
; ----------------- INSTALLATION TYPES
|
||||
|
||||
; InstType "Recommended"
|
||||
InstType "Full"
|
||||
;InstType "Minimal"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Section "Main" SecMain
|
||||
SectionIn 1
|
||||
SetOutPath "$INSTDIR"
|
||||
|
||||
SetOverwrite Off ; don't overwrite the config file
|
||||
; File "gsmartcontrol.conf"
|
||||
|
||||
SetOverwrite On
|
||||
File gsmartcontrol.exe
|
||||
File gsmartcontrol.ico
|
||||
File icon_*.png
|
||||
; File *.dll
|
||||
File smartctl-nc.exe
|
||||
File smartctl.exe
|
||||
|
||||
File /r doc
|
||||
|
||||
; set a special path for this exe, as GTK may not be in a global path.
|
||||
ReadRegStr $R3 HKLM "SOFTWARE\GTK\2.0" "DllPath"
|
||||
WriteRegStr HKLM "${REGISTRY_APP_PATHS}\gsmartcontrol.exe" "Path" "$R3"
|
||||
|
||||
;Add Shortcuts
|
||||
CreateShortCut "$SMPROGRAMS\GSmartControl.lnk" "$INSTDIR\gsmartcontrol.exe" "" "$INSTDIR\gsmartcontrol.ico" 0
|
||||
|
||||
SectionEnd
|
||||
|
||||
|
||||
|
||||
; ------------------ POST INSTALL
|
||||
|
||||
|
||||
!define TEMP $R0
|
||||
|
||||
Section -post
|
||||
|
||||
WriteRegStr HKLM "SOFTWARE\${PRODUCT_NAME}" "InstallationDirectory" "$INSTDIR"
|
||||
WriteRegStr HKLM "SOFTWARE\${PRODUCT_NAME}" "Vendor" "Alexander Shaduri"
|
||||
|
||||
WriteRegStr HKLM "${PRODUCT_UNINST_KEY}" "DisplayName" "${PRODUCT_NAME}"
|
||||
WriteRegStr HKLM "${PRODUCT_UNINST_KEY}" "UninstallString" "$INSTDIR\gsmartcontrol_uninst.exe"
|
||||
|
||||
; We don't need this, MUI takes care for us
|
||||
WriteRegStr HKCU "Software\${PRODUCT_NAME}" "Installer Language" $LANGUAGE
|
||||
|
||||
; uninstall shortcut
|
||||
; CreateDirectory "$SMPROGRAMS\GSmartControl"
|
||||
; CreateShortCut "$SMPROGRAMS\GSmartControl\Uninstall GSmartControl.lnk" "$INSTDIR\gsmartcontrol_uninst.exe" "" ""
|
||||
|
||||
|
||||
; write out uninstaller
|
||||
WriteUninstaller "$INSTDIR\gsmartcontrol_uninst.exe"
|
||||
|
||||
SectionEnd ; post
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
; ---------------- UNINSTALL
|
||||
|
||||
|
||||
|
||||
Function un.onUninstSuccess
|
||||
HideWindow
|
||||
MessageBox MB_ICONINFORMATION|MB_OK "$(^Name) was successfully removed from your computer."
|
||||
FunctionEnd
|
||||
|
||||
|
||||
|
||||
|
||||
Section Uninstall
|
||||
|
||||
SetAutoClose false
|
||||
|
||||
; add delete commands to delete whatever files/registry keys/etc you installed here.
|
||||
Delete "$INSTDIR\gsmartcontrol_uninst.exe"
|
||||
|
||||
DeleteRegKey HKLM "SOFTWARE\${PRODUCT_NAME}"
|
||||
DeleteRegKey HKLM "${PRODUCT_UNINST_KEY}"
|
||||
|
||||
Delete "$INSTDIR\gsmartcontrol.exe"
|
||||
Delete "$INSTDIR\gsmartcontrol.ico"
|
||||
Delete "$INSTDIR\icon_*.png"
|
||||
; Delete "$INSTDIR\*.dll"
|
||||
Delete "$INSTDIR\smartctl-nc.exe"
|
||||
Delete "$INSTDIR\smartctl.exe"
|
||||
|
||||
RMDir /r "$INSTDIR\doc"
|
||||
|
||||
RMDir "$INSTDIR" ; only if empty
|
||||
|
||||
DeleteRegKey HKLM "${REGISTRY_APP_PATHS}\gsmartcontrol.exe"
|
||||
|
||||
Delete "$SMPROGRAMS\GSmartControl.lnk"
|
||||
; Delete "$SMPROGRAMS\GSmartControl\Uninstall GSmartControl.lnk"
|
||||
|
||||
|
||||
SectionEnd ; end of uninstall section
|
||||
|
||||
|
||||
|
||||
|
||||
; eof
|
||||
@@ -1,97 +0,0 @@
|
||||
/**************************************************************************
|
||||
Copyright:
|
||||
(C) 2008 - 2009 Alexander Shaduri <ashaduri 'at' gmail.com>
|
||||
License: See LICENSE_gsmartcontrol.txt
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef APP_GTKMM_UTILS_H
|
||||
#define APP_GTKMM_UTILS_H
|
||||
|
||||
#include <string>
|
||||
#include <gtkmm/widget.h>
|
||||
#include <gtkmm/treeviewcolumn.h>
|
||||
#include <gtkmm/treemodelcolumn.h>
|
||||
#include <gtkmm/treeview.h>
|
||||
#include <gtkmm/combobox.h>
|
||||
#include <gtkmm/cellrenderertext.h>
|
||||
#include <gtkmm/iconview.h>
|
||||
#include <gtkmm/liststore.h>
|
||||
#include <gtkmm/icontheme.h> // must include (even if gtkmm.h is included) for older gtkmm (at least 2.6, but not 2.12)
|
||||
|
||||
#include "hz/down_cast.h"
|
||||
|
||||
|
||||
|
||||
// Note: This works only if the column has custom widget set.
|
||||
Gtk::Widget* app_gtkmm_get_column_header(Gtk::TreeViewColumn& column);
|
||||
|
||||
|
||||
// Read column header text and create a label with that text, set it as column's custom widget.
|
||||
Gtk::Widget* app_gtkmm_labelize_column(Gtk::TreeViewColumn& column);
|
||||
|
||||
|
||||
// unset model on treeview, cross-gtkmm-version.
|
||||
void app_gtkmm_treeview_unset_model(Gtk::TreeView* treeview);
|
||||
|
||||
|
||||
// unset model on combobox (there's no straight way to do it in gtkmm, I think)
|
||||
void app_gtkmm_combobox_unset_model(Gtk::ComboBox* box);
|
||||
|
||||
|
||||
// A wrapper around set_tooltip_*() for portability across different gtkmm versions.
|
||||
void app_gtkmm_set_widget_tooltip(Gtk::Widget& widget,
|
||||
const Glib::ustring& tooltip_text, bool use_markup = false);
|
||||
|
||||
|
||||
// A portable wrapper around TreeView::set_tooltip_column().
|
||||
void gtkmm_set_treeview_tooltip_column(Gtk::TreeView* treeview,
|
||||
Gtk::TreeModelColumn<Glib::ustring>& col_tooltip);
|
||||
|
||||
// A portable wrapper around IconView::set_tooltip_column().
|
||||
void gtkmm_set_iconview_tooltip_column(Gtk::IconView* iconview,
|
||||
Gtk::TreeModelColumn<Glib::ustring>& col_tooltip, Glib::RefPtr<Gtk::ListStore> model);
|
||||
|
||||
|
||||
|
||||
// Convenience function for creating a TreeViewColumn .
|
||||
template<typename T> inline
|
||||
int app_gtkmm_create_tree_view_column(Gtk::TreeModelColumn<T>& mcol, Gtk::TreeView& treeview,
|
||||
const Glib::ustring& title, const Glib::ustring& tooltip_text, bool sortable = false, bool cell_markup = false)
|
||||
{
|
||||
int num_tree_cols = treeview.append_column(title, mcol);
|
||||
Gtk::TreeViewColumn* tcol = treeview.get_column(num_tree_cols - 1);
|
||||
if (tcol) {
|
||||
if (sortable)
|
||||
tcol->set_sort_column(mcol);
|
||||
|
||||
app_gtkmm_labelize_column(*tcol);
|
||||
tcol->set_reorderable(true);
|
||||
tcol->set_resizable(true);
|
||||
}
|
||||
|
||||
Gtk::Widget* header = app_gtkmm_get_column_header(*tcol);
|
||||
if (header)
|
||||
app_gtkmm_set_widget_tooltip(*header, tooltip_text);
|
||||
|
||||
if (cell_markup) {
|
||||
Gtk::CellRendererText* cr_type = hz::down_cast<Gtk::CellRendererText*>(treeview.get_column_cell_renderer(num_tree_cols - 1));
|
||||
if (cr_type) { // may not be true if it's not Text (unless static_cast is used, in which case we're screwed)
|
||||
treeview.get_column(num_tree_cols - 1)->clear_attributes(*cr_type); // clear "text" attribute. "markup" won't work without this.
|
||||
treeview.get_column(num_tree_cols - 1)->add_attribute(cr_type->property_markup(), mcol); // render col_type as markup.
|
||||
}
|
||||
}
|
||||
|
||||
return num_tree_cols;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool app_gtkmm_icon_theme_has_icon(Glib::RefPtr<Gtk::IconTheme> theme,
|
||||
const Glib::ustring& icon_name, int size);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
@@ -1,312 +0,0 @@
|
||||
/**************************************************************************
|
||||
Copyright:
|
||||
(C) 2008 - 2009 Alexander Shaduri <ashaduri 'at' gmail.com>
|
||||
License: See LICENSE_gsmartcontrol.txt
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef APP_CMDEX_H
|
||||
#define APP_CMDEX_H
|
||||
|
||||
#include <string>
|
||||
#include <glib.h>
|
||||
|
||||
#include "hz/process_signal.h" // hz::SIGNAL_*
|
||||
#include "hz/error_holder.h"
|
||||
#include "hz/sync.h" // hz::SyncPolicyNone
|
||||
|
||||
|
||||
|
||||
/*
|
||||
There are two ways to detect when the command exits:
|
||||
|
||||
1. Add a callback to signal_exited.
|
||||
|
||||
2. Manually poll stopped_cleanup_needed() (from the same thread).
|
||||
|
||||
In both cases, stopped_cleanup() must be called afterwards
|
||||
(from the main thread).
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
// inheriting from sigc::trackable automatically disconnects this class's
|
||||
// slots upon destruction.
|
||||
class Cmdex : public hz::ErrorHolder<hz::SyncPolicyNone> {
|
||||
|
||||
public:
|
||||
|
||||
using hz::ErrorHolder<hz::SyncPolicyNone>::ptr_error_list_t; // auto-deleting container
|
||||
using hz::ErrorHolder<hz::SyncPolicyNone>::error_list_t;
|
||||
|
||||
typedef std::string (*exit_status_translator_func_t)(int, void*);
|
||||
typedef void (*exited_callback_func_t)(void*);
|
||||
|
||||
|
||||
Cmdex(
|
||||
// exit_status_translator_func_t translator_func,
|
||||
exited_callback_func_t exited_cb = NULL, void* exited_cb_data = NULL
|
||||
)
|
||||
: running_(false), kill_signal_sent_(0), child_watch_handler_called_(false),
|
||||
pid_(0), waitpid_status_(0),
|
||||
timer_(g_timer_new()),
|
||||
event_source_id_term(0), event_source_id_kill(0),
|
||||
fd_stdout_(0), fd_stderr_(0), channel_stdout_(0), channel_stderr_(0),
|
||||
channel_stdout_buffer_size_(100 * 1024), channel_stderr_buffer_size_(10 * 1024), // 100K and 10K
|
||||
event_source_id_stdout_(0), event_source_id_stderr_(0),
|
||||
translator_func_(0), translator_func_data_(0),
|
||||
exited_callback_(exited_cb), exited_callback_data_(exited_cb_data)
|
||||
{ }
|
||||
|
||||
|
||||
|
||||
// Please don't destroy this object unless the child has exited. It will leak stuff
|
||||
// and possibly crash, etc... .
|
||||
~Cmdex()
|
||||
{
|
||||
// This will help if object is destroyed after the command has exited, but before
|
||||
// stopped_cleanup() has been called.
|
||||
stopped_cleanup();
|
||||
|
||||
g_timer_destroy(timer_);
|
||||
|
||||
// no need to destroy the channels - stopped_cleanup() calls
|
||||
// cleanup_members(), which deletes them.
|
||||
}
|
||||
|
||||
|
||||
// Call before execute.
|
||||
// Note: The command and the arguments _must_ be shell-escaped.
|
||||
// Use g_shell_quote() or Glib::shell_quote(). Note that each argument
|
||||
// must be escaped separately.
|
||||
void set_command(const std::string& command_exec, const std::string& command_args)
|
||||
{
|
||||
command_exec_ = command_exec;
|
||||
command_args_ = command_args;
|
||||
}
|
||||
|
||||
|
||||
// launch the command.
|
||||
bool execute();
|
||||
|
||||
|
||||
// send SIGTERM(15) (terminate).
|
||||
// use after execute(). using it after the command has exited has no effect.
|
||||
bool try_stop(hz::signal_t sig = hz::SIGNAL_SIGTERM);
|
||||
|
||||
|
||||
// Send SIGKILL(9) (kill). This signal cannot be overridden in child process.
|
||||
// use after execute(). using it after the command has exited has no effect.
|
||||
bool try_kill()
|
||||
{
|
||||
return try_stop(hz::SIGNAL_SIGKILL);
|
||||
}
|
||||
|
||||
|
||||
// set a timeout (since call to this function) to terminate, kill or both (use 0 to ignore the parameter).
|
||||
// the timeouts will be unset automatically when the command exits.
|
||||
// This has an effect only if the command is running (after execute()).
|
||||
void set_stop_timeouts(int term_timeout_msec = 0, int kill_timeout_msec = 0);
|
||||
|
||||
// Unset timeouts. This will stop the timeout counters.
|
||||
// This has an effect only if the command is running (after execute()).
|
||||
void unset_stop_timeouts();
|
||||
|
||||
|
||||
// If stopped_cleanup_needed() returned true, call this. The command
|
||||
// should be exited by this time. Must be called before the next execute().
|
||||
void stopped_cleanup();
|
||||
|
||||
|
||||
// Returns true if command has stopped.
|
||||
// Call repeatedly in a waiting function, after execute(). When returns true, call stopped_cleanup().
|
||||
bool stopped_cleanup_needed()
|
||||
{
|
||||
return (child_watch_handler_called_);
|
||||
}
|
||||
|
||||
|
||||
// The process is running. Note that if this returns false, it doesn't mean that
|
||||
// the io channels have been closed or that the data may be read safely. Poll
|
||||
// stopped_cleanup_needed() instead.
|
||||
bool is_running() const
|
||||
{
|
||||
return running_;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Call this before execution. There is a race-like condition - when the command
|
||||
// outputs something, the io channel reads it from fd to its buffer and the event
|
||||
// source callback is called. If the command dies, the io channel callback reads
|
||||
// the remaining data to the channel buffer.
|
||||
// Since the event source callbacks (which read from the buffer and empty it)
|
||||
// happen rather sporadically (from the glib loop), the buffer may not get read and
|
||||
// emptied at all (before the command exits). This is why it's necessary to have
|
||||
// a buffer size which potentially can hold _all_ the command output.
|
||||
// A way to fight this is to increase event source priority (which may not help).
|
||||
// Another way is to delay the command exit so that the event source callback
|
||||
// catches on and reads the buffer.
|
||||
|
||||
// Use 0 to ignore the parameter. Call before execute().
|
||||
void set_buffer_sizes(int stdout_buffer_size = 0, int stderr_buffer_size = 0)
|
||||
{
|
||||
if (stdout_buffer_size)
|
||||
channel_stdout_buffer_size_ = stdout_buffer_size; // 100K by default
|
||||
if (stderr_buffer_size)
|
||||
channel_stderr_buffer_size_ = stderr_buffer_size; // 10K by default
|
||||
}
|
||||
|
||||
|
||||
|
||||
// If stdout_make_str_as_available_ is false, call this after stopped_cleanup(),
|
||||
// before next execute(). If it's true, you may call this before the command has
|
||||
// stopped, but it will decrease performance significantly.
|
||||
std::string get_stdout_str(bool clear_existing = false)
|
||||
{
|
||||
// debug_out_dump("app", str_stdout_);
|
||||
if (clear_existing) {
|
||||
std::string ret = str_stdout_;
|
||||
str_stdout_.clear();
|
||||
return ret;
|
||||
}
|
||||
return str_stdout_;
|
||||
}
|
||||
|
||||
|
||||
// See notes on get_stdout_str().
|
||||
std::string get_stderr_str(bool clear_existing = false)
|
||||
{
|
||||
if (clear_existing) {
|
||||
std::string ret = str_stderr_;
|
||||
str_stderr_.clear();
|
||||
return ret;
|
||||
}
|
||||
return str_stderr_;
|
||||
}
|
||||
|
||||
|
||||
// Return execution time, in seconds. Call after execute().
|
||||
double get_execution_time()
|
||||
{
|
||||
gulong microsec = 0;
|
||||
return g_timer_elapsed(timer_, µsec);
|
||||
}
|
||||
|
||||
|
||||
// this will disconnect earlier slots. Call before execute().
|
||||
void set_exit_status_translator(exit_status_translator_func_t func, void* user_data)
|
||||
{
|
||||
translator_func_ = func;
|
||||
translator_func_data_ = user_data;
|
||||
}
|
||||
|
||||
|
||||
// You can use stopped_cleanup_needed() polling instead.
|
||||
void set_exited_callback(exited_callback_func_t func, void* user_data)
|
||||
{
|
||||
exited_callback_ = func;
|
||||
exited_callback_data_ = user_data;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// these are sorta-private
|
||||
|
||||
// for passing to callback
|
||||
enum channel_t {
|
||||
channel_type_stdout,
|
||||
channel_type_stderr
|
||||
};
|
||||
|
||||
|
||||
// Callbacks (Note: These are called by the real callbacks)
|
||||
|
||||
static void on_child_watch_handler(GPid arg_pid, int waitpid_status, gpointer data);
|
||||
|
||||
static gboolean on_channel_io(GIOChannel* source,
|
||||
GIOCondition cond, Cmdex* self, channel_t type);
|
||||
|
||||
|
||||
private:
|
||||
|
||||
|
||||
void cleanup_members()
|
||||
{
|
||||
kill_signal_sent_ = 0;
|
||||
child_watch_handler_called_ = false;
|
||||
pid_ = 0;
|
||||
waitpid_status_ = 0;
|
||||
event_source_id_stdout_ = 0;
|
||||
event_source_id_stderr_ = 0;
|
||||
fd_stdout_ = 0;
|
||||
fd_stderr_ = 0;
|
||||
|
||||
if (channel_stdout_) {
|
||||
g_io_channel_shutdown(channel_stdout_, false, NULL);
|
||||
g_io_channel_unref(channel_stdout_);
|
||||
channel_stdout_ = 0;
|
||||
}
|
||||
if (channel_stderr_) {
|
||||
g_io_channel_shutdown(channel_stderr_, false, NULL);
|
||||
g_io_channel_unref(channel_stderr_);
|
||||
channel_stderr_ = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// default command and its args. std::strings, not ustrings.
|
||||
std::string command_exec_; // binary name. NOT affected by cleanup().
|
||||
std::string command_args_; // args that always go with binary. NOT affected by cleanup().
|
||||
|
||||
|
||||
bool running_; // child process is running now. NOT affected by cleanup().
|
||||
int kill_signal_sent_; // command has been sent this signal to terminate
|
||||
bool child_watch_handler_called_; // true after child_watch_handler callback, before stopped_cleanup().
|
||||
|
||||
GPid pid_; // int in Unix, pointer in win32
|
||||
int waitpid_status_; // after the command is stopped, before cleanup, this will be available.
|
||||
|
||||
|
||||
GTimer* timer_; // keep track of elapsed time since command execution. not used by this class, but may be handy.
|
||||
|
||||
int event_source_id_term;
|
||||
int event_source_id_kill;
|
||||
|
||||
|
||||
int fd_stdout_;
|
||||
int fd_stderr_;
|
||||
|
||||
GIOChannel* channel_stdout_;
|
||||
GIOChannel* channel_stderr_;
|
||||
|
||||
int channel_stdout_buffer_size_; // NOT affected by cleanup().
|
||||
int channel_stderr_buffer_size_; // NOT affected by cleanup().
|
||||
|
||||
int event_source_id_stdout_;
|
||||
int event_source_id_stderr_;
|
||||
|
||||
std::string str_stdout_; // NOT affected by cleanup().
|
||||
std::string str_stderr_; // NOT affected by cleanup().
|
||||
|
||||
|
||||
// signals
|
||||
|
||||
// convert command exit status to message string
|
||||
exit_status_translator_func_t translator_func_; // NOT affected by cleanup().
|
||||
void* translator_func_data_;
|
||||
|
||||
// "command exited" signal callback.
|
||||
exited_callback_func_t exited_callback_; // NOT affected by cleanup().
|
||||
void* exited_callback_data_;
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
@@ -1,120 +0,0 @@
|
||||
/**************************************************************************
|
||||
Copyright:
|
||||
(C) 2008 - 2009 Alexander Shaduri <ashaduri 'at' gmail.com>
|
||||
License: See LICENSE_gsmartcontrol.txt
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef APP_CMDEX_SYNC_GUI_H
|
||||
#define APP_CMDEX_SYNC_GUI_H
|
||||
|
||||
#include <gtkmm/messagedialog.h>
|
||||
#include <glibmm/timer.h>
|
||||
|
||||
#include "hz/noncopyable.h"
|
||||
|
||||
#include "cmdex_sync.h"
|
||||
|
||||
|
||||
|
||||
// CmdexSync with GUI support
|
||||
|
||||
|
||||
|
||||
// same as CmdexSync, but with GTK UI stuff.
|
||||
// this one is noncopyable, because we don't copy the dialogs, etc...
|
||||
class CmdexSyncGui : public CmdexSync, public hz::noncopyable {
|
||||
|
||||
public:
|
||||
|
||||
CmdexSyncGui(const std::string& cmd, const std::string& cmdargs)
|
||||
: CmdexSync(cmd, cmdargs), execution_running_(false), should_abort_(false),
|
||||
running_dialog_(0), running_dialog_shown_(false), running_dialog_abort_mode_(false)
|
||||
{
|
||||
signal_execute_tick.connect(sigc::mem_fun(*this, &CmdexSyncGui::execute_tick_func));
|
||||
}
|
||||
|
||||
|
||||
CmdexSyncGui()
|
||||
: execution_running_(false), should_abort_(false),
|
||||
running_dialog_(0), running_dialog_shown_(false), running_dialog_abort_mode_(false)
|
||||
{
|
||||
signal_execute_tick.connect(sigc::mem_fun(*this, &CmdexSyncGui::execute_tick_func));
|
||||
}
|
||||
|
||||
|
||||
~CmdexSyncGui()
|
||||
{
|
||||
delete running_dialog_;
|
||||
}
|
||||
|
||||
|
||||
virtual bool execute();
|
||||
|
||||
|
||||
// UI callbacks may use this to abort execution.
|
||||
void set_should_abort()
|
||||
{
|
||||
should_abort_ = true;
|
||||
}
|
||||
|
||||
|
||||
// create a dialog or return already existing one.
|
||||
// the dialog will be auto-created and displayed on execute().
|
||||
// you need the function only if you intend to modify it before execute().
|
||||
Gtk::MessageDialog* create_running_dialog(Gtk::Window* parent = 0, const Glib::ustring& msg = "");
|
||||
|
||||
|
||||
Gtk::MessageDialog* get_running_dialog()
|
||||
{
|
||||
return running_dialog_;
|
||||
}
|
||||
|
||||
|
||||
// this actually shows the dialog only after some time has passed,
|
||||
// to avoid very quick show/hide.
|
||||
void show_hide_dialog(bool show);
|
||||
|
||||
|
||||
// called from ticker function in running mode, to show the dialog when requested time elapses.
|
||||
void update_dialog_show_timer();
|
||||
|
||||
|
||||
|
||||
// switch the dialog to "Aborting..." mode
|
||||
void set_running_dialog_abort_mode(bool aborting);
|
||||
|
||||
|
||||
|
||||
private:
|
||||
|
||||
// dialog callback.
|
||||
void on_running_dialog_response(int response_id)
|
||||
{
|
||||
// Try to abort if Cancel was clicked
|
||||
if (response_id == Gtk::RESPONSE_CANCEL)
|
||||
set_should_abort();
|
||||
}
|
||||
|
||||
|
||||
// this function is called every time something happens
|
||||
// with the executor.
|
||||
bool execute_tick_func(tick_status_t status);
|
||||
|
||||
|
||||
bool execution_running_;
|
||||
bool should_abort_; // GUI callbacks may set this to abort the execution
|
||||
|
||||
Gtk::MessageDialog* running_dialog_;
|
||||
bool running_dialog_shown_;
|
||||
bool running_dialog_abort_mode_;
|
||||
Glib::Timer running_dialog_timer_;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
@@ -1,143 +0,0 @@
|
||||
/**************************************************************************
|
||||
Copyright:
|
||||
(C) 2008 - 2009 Alexander Shaduri <ashaduri 'at' gmail.com>
|
||||
License: See LICENSE_gsmartcontrol.txt
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef SELFTEST_H
|
||||
#define SELFTEST_H
|
||||
|
||||
#include <string>
|
||||
#include <glibmm/timer.h>
|
||||
|
||||
#include "hz/cstdint.h"
|
||||
#include "hz/intrusive_ptr.h"
|
||||
|
||||
#include "storage_device.h"
|
||||
#include "cmdex_sync.h"
|
||||
|
||||
|
||||
|
||||
class SelfTest : public hz::intrusive_ptr_referenced {
|
||||
public:
|
||||
|
||||
enum test_t {
|
||||
type_ioffline, // immediate offline, not supported yet
|
||||
type_short,
|
||||
type_long,
|
||||
type_conveyance
|
||||
};
|
||||
|
||||
static std::string get_test_name(test_t t)
|
||||
{
|
||||
switch (t) {
|
||||
case type_ioffline: return "Immediate Offline Test";
|
||||
case type_short: return "Short Self-test";
|
||||
case type_long: return "Extended Self-test";
|
||||
case type_conveyance: return "Conveyance Self-test";
|
||||
};
|
||||
return "[error]";
|
||||
}
|
||||
|
||||
|
||||
// The drive must have the capabilities present in properties.
|
||||
SelfTest(StorageDeviceRefPtr drive, test_t type)
|
||||
: drive_(drive), type_(type)
|
||||
{
|
||||
clear();
|
||||
}
|
||||
|
||||
|
||||
void clear() // clear results of previous test
|
||||
{
|
||||
status_ = StorageSelftestEntry::status_unknown;
|
||||
remaining_percent_ = -1;
|
||||
last_seen_percent_ = -1;
|
||||
total_duration_ = -1;
|
||||
poll_in_seconds_ = -1;
|
||||
}
|
||||
|
||||
|
||||
bool is_active() const
|
||||
{
|
||||
return (status_ == StorageSelftestEntry::status_in_progress);
|
||||
}
|
||||
|
||||
|
||||
// returns -1 if n/a or unknown.
|
||||
int8_t get_remaining_percent() const
|
||||
{
|
||||
return remaining_percent_;
|
||||
}
|
||||
|
||||
|
||||
// Returns estimated time of completion for the test. returns -1 if n/a or unknown. 0 is a valid value.
|
||||
int64_t get_remaining_seconds() const;
|
||||
|
||||
|
||||
test_t get_test_type() const
|
||||
{
|
||||
return type_;
|
||||
}
|
||||
|
||||
|
||||
StorageSelftestEntry::status_t get_status() const
|
||||
{
|
||||
return status_;
|
||||
}
|
||||
|
||||
|
||||
// get the number of seconds after which the caller should call update().
|
||||
int64_t get_poll_in_seconds() const
|
||||
{
|
||||
return poll_in_seconds_;
|
||||
}
|
||||
|
||||
|
||||
// gets a constant "test duration during idle" capability drive's stored capabilities. -1 if N/A.
|
||||
int64_t get_min_duration_seconds() const;
|
||||
|
||||
|
||||
// gets the current test type support status from drive's stored capabilities.
|
||||
bool is_supported() const;
|
||||
|
||||
|
||||
// These return an error message, or empty string if no error.
|
||||
|
||||
// start the test
|
||||
std::string start(hz::intrusive_ptr<CmdexSync> smartctl_ex = 0);
|
||||
|
||||
|
||||
// abort the running test
|
||||
std::string force_stop(hz::intrusive_ptr<CmdexSync> smartctl_ex = 0);
|
||||
|
||||
|
||||
// update status variables
|
||||
std::string update(hz::intrusive_ptr<CmdexSync> smartctl_ex = 0);
|
||||
|
||||
|
||||
private:
|
||||
StorageDeviceRefPtr drive_;
|
||||
|
||||
test_t type_;
|
||||
|
||||
// status variables:
|
||||
StorageSelftestEntry::status_t status_;
|
||||
int8_t remaining_percent_; // 0 means unknown, -1 means n/a. Set to 100 on start.
|
||||
int8_t last_seen_percent_; // to detect changes in percentage (needed for timer update)
|
||||
mutable int64_t total_duration_; // total duration needed for the test, as reported by drive. constant. this is a cache.
|
||||
int64_t poll_in_seconds_; // the user is asked to poll after this much seconds have passed.
|
||||
|
||||
Glib::Timer timer_; // counts time since the last percent change
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
typedef hz::intrusive_ptr<SelfTest> SelfTestPtr;
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
@@ -1,64 +0,0 @@
|
||||
/**************************************************************************
|
||||
Copyright:
|
||||
(C) 2008 - 2009 Alexander Shaduri <ashaduri 'at' gmail.com>
|
||||
License: See LICENSE_gsmartcontrol.txt
|
||||
***************************************************************************/
|
||||
|
||||
#include "smartctl_executor.h"
|
||||
|
||||
#include "hz/fs_path.h"
|
||||
#include "hz/win32_tools.h"
|
||||
#include "rconfig/rconfig_mini.h"
|
||||
|
||||
|
||||
|
||||
// returns an empty string if not found.
|
||||
std::string get_smartctl_binary()
|
||||
{
|
||||
std::string smartctl_binary;
|
||||
rconfig::get_data("system/smartctl_binary", smartctl_binary);
|
||||
|
||||
#ifdef _WIN32
|
||||
// look in smartmontools installation directory.
|
||||
do {
|
||||
bool use_smt = false;
|
||||
rconfig::get_data("system/win32_search_smartctl_in_smartmontools", use_smt);
|
||||
if (!use_smt)
|
||||
break;
|
||||
|
||||
std::string smt_regpath, smt_regkey, smt_smartctl;
|
||||
rconfig::get_data("system/win32_smartmontools_regpath", smt_regpath);
|
||||
rconfig::get_data("system/win32_smartmontools_regkey", smt_regkey);
|
||||
rconfig::get_data("system/win32_smartmontools_smartctl_binary", smt_smartctl);
|
||||
|
||||
if (smt_regpath.empty() || smt_regkey.empty() || smt_smartctl.empty())
|
||||
break;
|
||||
|
||||
std::string smt_inst_dir;
|
||||
hz::win32_get_registry_value_string(HKEY_LOCAL_MACHINE, smt_regpath, smt_regkey, smt_inst_dir);
|
||||
|
||||
if (smt_inst_dir.empty()) {
|
||||
debug_out_info("app", DBG_FUNC_MSG << "Smartmontools installation not found in \"HKLM\\"
|
||||
<< smt_regpath << "\\" << smt_regkey << "\".\n");
|
||||
break;
|
||||
}
|
||||
debug_out_info("app", DBG_FUNC_MSG << "Smartmontools installation found at \"" << smt_inst_dir
|
||||
<< "\", using \"" << smt_smartctl << "\".\n");
|
||||
|
||||
hz::FsPath p(smt_inst_dir);
|
||||
p.append(smt_smartctl);
|
||||
|
||||
if (!p.exists() || !p.is_file())
|
||||
break;
|
||||
|
||||
smartctl_binary = p.str();
|
||||
|
||||
} while (false);
|
||||
|
||||
#endif
|
||||
|
||||
return smartctl_binary;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,704 +0,0 @@
|
||||
/**************************************************************************
|
||||
Copyright:
|
||||
(C) 2008 - 2009 Alexander Shaduri <ashaduri 'at' gmail.com>
|
||||
License: See LICENSE_gsmartcontrol.txt
|
||||
***************************************************************************/
|
||||
|
||||
#include "hz/hz_config.h" // CONFIG_*
|
||||
|
||||
#include <ios> // std::boolalpha
|
||||
#include <algorithm> // std::find
|
||||
#include <cstdio> // std::fgets(), std::FILE
|
||||
#include <cerrno> // ENXIO
|
||||
|
||||
#if defined CONFIG_KERNEL_OPENBSD || defined CONFIG_KERNEL_NETBSD
|
||||
#include <util.h> // getrawpartition()
|
||||
#endif
|
||||
|
||||
#if defined CONFIG_KERNEL_FAMILY_WINDOWS
|
||||
#include <windows.h> // CreateFileA(), CloseHandle(), etc...
|
||||
#endif
|
||||
|
||||
#include "hz/debug.h"
|
||||
#include "hz/fs_dir.h"
|
||||
#include "hz/fs_file.h"
|
||||
#include "hz/string_sprintf.h"
|
||||
#include "hz/local_algo.h" // hz::shell_sort()
|
||||
#include "rconfig/rconfig_mini.h"
|
||||
|
||||
#include "app_pcrecpp.h"
|
||||
#include "smartctl_executor.h"
|
||||
#include "storage_detector.h"
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
|
||||
// Note: Since 3ware RAID controllers need additional flags on most (all?) OSes,
|
||||
// and they may ignore the actual devices names, I have no idea how to support them.
|
||||
|
||||
|
||||
#if defined CONFIG_KERNEL_LINUX
|
||||
|
||||
|
||||
// Linux 2.6 with udev. Scan /dev/disk/by-id - the directory entries there
|
||||
// are symlinks to respective /dev devices. Some devices have multiple
|
||||
// links pointing to them, so unique filter is needed.
|
||||
/*
|
||||
Sample listing:
|
||||
------------------------------------------------------------
|
||||
# ls -1 /dev/disk/by-id
|
||||
ata-ST31000340AS_9QJ0FFG7
|
||||
ata-ST31000340AS_9QJ0FFG7-part1
|
||||
ata-ST31000340AS_9QJ0FFG7-part2
|
||||
ata-ST3500630AS_9QG0R38D
|
||||
ata-ST3500630AS_9QG0R38D-part1
|
||||
scsi-SATA_ST31000340AS_9QJ0FFG7
|
||||
scsi-SATA_ST31000340AS_9QJ0FFG7-part1
|
||||
scsi-SATA_ST31000340AS_9QJ0FFG7-part2
|
||||
scsi-SATA_ST3500630AS_9QG0R38D
|
||||
scsi-SATA_ST3500630AS_9QG0R38D-part1
|
||||
*/
|
||||
inline std::string detect_drives_linux_udev_byid(std::vector<std::string>& devices)
|
||||
{
|
||||
debug_out_info("app", DBG_FUNC_MSG << "Detecting through device scan directory /dev/disk/by-id...\n");
|
||||
|
||||
std::string dev_dir; // this defaults to "/dev/disk/by-id"
|
||||
if (!rconfig::get_data("system/linux_udev_byid_path", dev_dir) || dev_dir.empty()) {
|
||||
debug_out_warn("app", DBG_FUNC_MSG << "Device scan directory path is not set.\n");
|
||||
return "Device scan directory path is not set.";
|
||||
}
|
||||
|
||||
hz::Dir dir(dev_dir);
|
||||
|
||||
std::vector<std::string> all_devices;
|
||||
if (!dir.list(all_devices, false)) { // this outputs to debug too.
|
||||
std::string error_msg = dir.get_error_utf8();
|
||||
if (!dir.exists()) {
|
||||
debug_out_warn("app", DBG_FUNC_MSG << "Device scan directory doesn't exist.\n");
|
||||
} else {
|
||||
debug_out_error("app", DBG_FUNC_MSG << "Cannot list directory entries.\n");
|
||||
}
|
||||
return error_msg;
|
||||
}
|
||||
|
||||
std::vector<std::string> blacklist;
|
||||
blacklist.push_back("/-part[0-9]+$/");
|
||||
|
||||
// filter-out the ones with "partN" in them
|
||||
for (unsigned int i = 0; i < all_devices.size(); ++i) {
|
||||
std::string entry = all_devices[i];
|
||||
if (entry == "." || entry == "..")
|
||||
continue;
|
||||
|
||||
// platform blacklist
|
||||
bool blacked = false;
|
||||
for (std::vector<std::string>::const_iterator iter = blacklist.begin(); iter != blacklist.end(); ++iter) {
|
||||
if (app_pcre_match(*iter, entry)) {
|
||||
blacked = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (blacked)
|
||||
continue;
|
||||
|
||||
hz::FsPath path = dev_dir + hz::DIR_SEPARATOR_S + all_devices[i];
|
||||
|
||||
// those are usually relative links, so find out where they are pointing to.
|
||||
std::string link_dest;
|
||||
if (path.get_link_destination(link_dest)) {
|
||||
path = (hz::path_is_absolute(link_dest) ? link_dest : (dev_dir + hz::DIR_SEPARATOR_S + link_dest));
|
||||
path.compress(); // compress in case there are ../-s.
|
||||
}
|
||||
|
||||
// skip number-ended devices, in case we couldn't filter out the scan directory correctly
|
||||
// (it's user-settable after all).
|
||||
// if (app_pcre_match("/[0-9]+$/", path.str()))
|
||||
// continue;
|
||||
|
||||
if (std::find(devices.begin(), devices.end(), path.str()) == devices.end()) // there may be duplicates
|
||||
devices.push_back(path.str());
|
||||
}
|
||||
|
||||
return std::string();
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Procfs files don't support SEEK_END or ftello() (I think). Anyway, they can't
|
||||
// be read through hz::File::get_contents, so use this function instead.
|
||||
inline bool read_proc_partitions_file(hz::File& file, std::vector<std::string>& lines)
|
||||
{
|
||||
if (!file.open("rb")) // closed automatically
|
||||
return false; // the error message is in File itself.
|
||||
|
||||
std::FILE* fp = file.get_handle();
|
||||
if (!fp)
|
||||
return false;
|
||||
|
||||
char line[256];
|
||||
while (std::fgets(line, static_cast<int>(sizeof(line)), fp) != NULL) {
|
||||
if (*line != '\0')
|
||||
lines.push_back(line);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Linux (tested with 2.4 and 2.6) /proc/partitions. Parses the file, appends /dev to each entry.
|
||||
// Note that file format changed from 2.4 to 2.6 (some statistics fields moved to another file).
|
||||
// No /proc/partitions on at least freebsd, solaris and osx, afaik.
|
||||
/*
|
||||
Sample 1 (2.4, devfs, with statistics):
|
||||
------------------------------------------------------------
|
||||
# cat /proc/partitions
|
||||
major minor #blocks name rio rmerge rsect ruse wio wmerge wsect wuse running use aveq
|
||||
|
||||
3 0 60051600 ide/host0/bus0/target0/lun0/disc 72159 136746 1668720 467190 383039 658435 8342136 1659840 -429 17038808 22703194
|
||||
3 1 1638598 ide/host0/bus0/target0/lun0/part1 0 0 0 0 0 0 0 0 0 0 0
|
||||
3 2 1028160 ide/host0/bus0/target0/lun0/part2 0 0 0 0 0 0 0 0 0 0 0
|
||||
3 3 3092512 ide/host0/bus0/target0/lun0/part3 0 0 0 0 0 0 0 0 0 0 0
|
||||
3 4 1 ide/host0/bus0/target0/lun0/part4 0 0 0 0 0 0 0 0 0 0 0
|
||||
3 5 514048 ide/host0/bus0/target0/lun0/part5 1458 7877 74680 9070 2140 18285 166272 42490 0 10100 52000
|
||||
------------------------------------------------------------
|
||||
Sample 2 (2.6):
|
||||
------------------------------------------------------------
|
||||
# cat /proc/partitions
|
||||
major minor #blocks name
|
||||
|
||||
1 0 4096 ram0
|
||||
8 0 156290904 sda
|
||||
8 1 39070048 sda1
|
||||
8 2 7560 sda2
|
||||
8 3 1 sda3
|
||||
------------------------------------------------------------
|
||||
Sample 3 (2.6 on nokia n8xx, spaces may be missing):
|
||||
------------------------------------------------------------
|
||||
# cat /proc/partitions
|
||||
major minor #blocks name
|
||||
|
||||
31 0 128 mtdblock0
|
||||
31 1 384 mtdblock1
|
||||
31 2 2048 mtdblock2
|
||||
31 3 2048 mtdblock3
|
||||
31 4 257536 mtdblock4
|
||||
254 0 3932160 mmcblk0
|
||||
254 1 3928064 mmcblk0p1
|
||||
254 8 1966080 mmcblk1
|
||||
254 9 2007032 mmcblk1p1
|
||||
*/
|
||||
inline std::string detect_drives_linux_proc_partitions(std::vector<std::string>& devices)
|
||||
{
|
||||
debug_out_info("app", DBG_FUNC_MSG << "Detecting through /proc/partitions...\n");
|
||||
|
||||
std::string parts_file;
|
||||
if (!rconfig::get_data("system/linux_proc_partitions_path", parts_file) || parts_file.empty()) {
|
||||
debug_out_warn("app", DBG_FUNC_MSG << "Partitions file path is not set.\n");
|
||||
return "Partitions file path is not set.";
|
||||
}
|
||||
|
||||
hz::File file(parts_file);
|
||||
// std::string contents;
|
||||
std::vector<std::string> lines;
|
||||
// if (!f.get_contents(contents)) {
|
||||
if (!read_proc_partitions_file(file, lines)) { // this outputs to debug too
|
||||
std::string error_msg = file.get_error_utf8(); // save before calling other file functions
|
||||
if (!file.exists()) {
|
||||
debug_out_warn("app", DBG_FUNC_MSG << "Partitions file doesn't exist.\n");
|
||||
} else {
|
||||
debug_out_error("app", DBG_FUNC_MSG << "Partitions file exists but cannot be read.\n");
|
||||
}
|
||||
return error_msg;
|
||||
}
|
||||
|
||||
// debug_out_dump("app", DBG_FUNC_MSG << "Dumping partitions file:\n" << contents << "\n");
|
||||
|
||||
// hz::string_split(contents, '\n', lines, true);
|
||||
|
||||
std::vector<std::string> blacklist;
|
||||
// fixme: not sure about how partitions are visible with twa0.
|
||||
blacklist.push_back("/d[a-z][0-9]+$/"); // sda1, hdb2 - partitions. twa0 and twe1 are drives, not partitions.
|
||||
blacklist.push_back("/ram[0-9]+$/"); // ramdisks?
|
||||
blacklist.push_back("/loop[0-9]*$/"); // not sure if loop devices go there, but anyway...
|
||||
blacklist.push_back("/part[0-9]+$/"); // devfs had them
|
||||
blacklist.push_back("/p[0-9]+$/"); // partitions are usually marked this way
|
||||
blacklist.push_back("/md[0-9]*$/"); // linux software raid
|
||||
|
||||
|
||||
for (unsigned int i = 0; i < lines.size(); ++i) {
|
||||
std::string line = hz::string_trim_copy(lines[i]);
|
||||
if (line.empty() || app_pcre_match("/^major/", line)) // file header
|
||||
continue;
|
||||
|
||||
std::string dev;
|
||||
if (!app_pcre_match("/^[ \\t]*[^ \\t\\n]+[ \\t]+[^ \\t\\n]+[ \\t]+[^ \\t\\n]+[ \\t]+([^ \\t\\n]+)/", line, &dev) || dev.empty()) {
|
||||
debug_out_warn("app", DBG_FUNC_MSG << "Cannot parse line \"" << line << "\".\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
// platform blacklist
|
||||
bool blacked = false;
|
||||
for (std::vector<std::string>::const_iterator iter = blacklist.begin(); iter != blacklist.end(); ++iter) {
|
||||
if (app_pcre_match(*iter, dev)) {
|
||||
blacked = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (blacked)
|
||||
continue;
|
||||
|
||||
std::string path = "/dev/" + dev; // let's just hope the it's /dev.
|
||||
if (std::find(devices.begin(), devices.end(), path) == devices.end()) // there may be duplicates
|
||||
devices.push_back(path);
|
||||
}
|
||||
|
||||
return std::string();
|
||||
}
|
||||
|
||||
|
||||
|
||||
#elif defined CONFIG_KERNEL_FAMILY_WINDOWS
|
||||
|
||||
|
||||
// smartctl accepts various variants, the most straight being pdN,
|
||||
// (or /dev/pdN, /dev/ being optional) where N comes from
|
||||
// "\\.\PhysicalDriveN" (winnt only).
|
||||
|
||||
inline std::string detect_drives_win32(std::vector<std::string>& devices)
|
||||
{
|
||||
for (int drive_num = 0; ; ++drive_num) {
|
||||
std::string name = hz::string_sprintf("\\\\.\\PhysicalDrive%d", drive_num);
|
||||
|
||||
// If the drive is openable, then it's there.
|
||||
// NOTE: Administrative privileges are required to open it.
|
||||
// Yes, CreateFile() is open, not create. Yes, it's silly (ah, win32...).
|
||||
// We don't use any long/unopenable files here, so use the ANSI version.
|
||||
HANDLE h = CreateFileA(name.c_str(), 0, FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||
NULL, OPEN_EXISTING, 0, NULL);
|
||||
|
||||
// The numbers seem to be consecutive, so break on first invalid.
|
||||
if (h == INVALID_HANDLE_VALUE)
|
||||
break;
|
||||
|
||||
CloseHandle(h);
|
||||
|
||||
devices.push_back(hz::string_sprintf("pd%d", drive_num));
|
||||
}
|
||||
|
||||
return std::string();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#else // FreeBSD, Solaris, etc... .
|
||||
|
||||
|
||||
inline std::string detect_drives_dev(std::vector<std::string>& devices)
|
||||
{
|
||||
debug_out_info("app", DBG_FUNC_MSG << "Detecting through /dev...\n");
|
||||
|
||||
std::string sdev_config_path;
|
||||
#if defined CONFIG_KERNEL_SOLARIS
|
||||
sdev_config_path = "system/solaris_dev_path";
|
||||
#else // other unixes
|
||||
sdev_config_path = "system/unix_sdev_path";
|
||||
#endif
|
||||
|
||||
std::string dev_dir; // defaults to /dev for freebsd, /dev/rdsk for solaris.
|
||||
if (!rconfig::get_data(sdev_config_path, dev_dir) || dev_dir.empty()) {
|
||||
debug_out_warn("app", DBG_FUNC_MSG << "Device directory path is not set.\n");
|
||||
return "Device directory path is not set.";
|
||||
}
|
||||
|
||||
hz::Dir dir(dev_dir);
|
||||
|
||||
std::vector<std::string> all_devices;
|
||||
if (!dir.list(all_devices, false, hz::DirSortNone())) { // this outputs to debug too.
|
||||
std::string error_msg = dir.get_error_utf8();
|
||||
if (!dir.exists()) {
|
||||
debug_out_warn("app", DBG_FUNC_MSG << "Device directory doesn't exist.\n");
|
||||
} else {
|
||||
debug_out_error("app", DBG_FUNC_MSG << "Cannot list directory entries.\n");
|
||||
}
|
||||
return error_msg;
|
||||
}
|
||||
|
||||
|
||||
// platform whitelist
|
||||
std::vector<std::string> whitelist;
|
||||
|
||||
|
||||
#if defined CONFIG_KERNEL_FREEBSD || defined CONFIG_KERNEL_DRAGONFLY
|
||||
// FreeBSD example device names:
|
||||
// * /dev/ad0 - ide disk 0. /dev/ad0a - non-slice dos partition 1.
|
||||
// * /dev/da1s1e - scsi disk 1 (second disk), slice 1 (aka dos partition 1),
|
||||
// bsd partition e (multiple bsd partitions may be inside one dos partition).
|
||||
// * /dev/acd0 - first cdrom. /dev/acd0c - ?.
|
||||
// Info: http://www.freebsd.org/doc/en/books/handbook/disks-naming.html
|
||||
|
||||
// Of two machines I had access to, freebsd 6.3 had only real devices,
|
||||
// while freebsd 4.10 had lots of dummy ones (ad1, ad2, ad3, da0, da1, da2, da3, sa0, ...).
|
||||
|
||||
whitelist.push_back("/^ad[0-9]+$/"); // adN without suffix - fbsd ide
|
||||
whitelist.push_back("/^da[0-9]+$/"); // daN without suffix - fbsd scsi, usb
|
||||
// whitelist.push_back("/ ^sa[0-9]+$/"); // saN without suffix - fbsd scsi tape
|
||||
// whitelist.push_back("/^ast[0-9]+$/"); // astN without suffix - fbsd ide tape
|
||||
whitelist.push_back("/^aacd[0-9]+$/"); // fbsd adaptec raid
|
||||
whitelist.push_back("/^mlxd[0-9]+$/"); // fbsd mylex raid
|
||||
whitelist.push_back("/^mlyd[0-9]+$/"); // fbsd mylex raid
|
||||
whitelist.push_back("/^amrd[0-9]+$/"); // fbsd AMI raid
|
||||
whitelist.push_back("/^idad[0-9]+$/"); // fbsd compaq raid
|
||||
whitelist.push_back("/^twed[0-9]+$/"); // fbsd 3ware raid
|
||||
// these are checked by smartctl, but they are not mentioned in freebsd docs:
|
||||
whitelist.push_back("/^tw[ae][0-9]+$/"); // fbsd 3ware raid
|
||||
// unused: acd - ide cdrom, cd - scsi cdrom, mcd - mitsumi cdrom, scd - sony cdrom,
|
||||
// fd - floppy, fla - diskonchip flash.
|
||||
|
||||
|
||||
#elif defined CONFIG_KERNEL_SOLARIS
|
||||
|
||||
// /dev/rdsk contains "raw" physical char devices, as opposed to
|
||||
// "filesystem" block devices in /dev/dsk. smartctl needs rdsk.
|
||||
|
||||
// x86:
|
||||
|
||||
// /dev/rdsk/c0t0d0p0:1
|
||||
// Where c0 is the controller number.
|
||||
// t0 is the target (SCSI ID number) (omit for ATAPI)
|
||||
// d0 is always 0 for SCSI, the drive # for ATAPI
|
||||
// p0 is the partition (p0 is the entire disk, or p1 - p4)
|
||||
// :1 is the logical drive (c - z or 1 - 24) (that is, logical partitions inside extended partition)
|
||||
|
||||
// /dev/rdsk/c0d0p2:1
|
||||
// where p2 means the extended partition (type 0x05) is partition 2 (out of 1-4) and
|
||||
// ":1" is the 2nd extended partition (:0 would be the first extended partition). -- not sure about this!
|
||||
|
||||
// p0 whole physical disk
|
||||
// p1 - p4 Four primary fdisk partitions
|
||||
// p5 - p30 26 logical drives in extended DOS partition (not implemented by Solaris)
|
||||
// s0 - s15 16 slices in the Solaris FDISK partition (SPARC has only 8)
|
||||
// On Solaris, by convention, s2 is the whole Solaris partition.
|
||||
|
||||
// SPARC: There are no *p* devices on sparc afaik, only slices. By convention,
|
||||
// s2 is used as a "whole" disk there (but not with EFI partitions!).
|
||||
// So, c0d0s2 is the whole disk there.
|
||||
// x86 has both c0d0s2 and c0d0p2, where s2 is a whole solaris partition.
|
||||
|
||||
// NOTE: It seems that smartctl searches for s0 (aka root partition) in the end. I'm not sure
|
||||
// what implications this has for x86, but we replicate this behaviour.
|
||||
|
||||
// Note: Cdroms are ATAPI, so they pose as SCSI, as opposed to IDE hds.
|
||||
|
||||
// TODO: No idea how to implement /dev/rmt (scsi tape devices),
|
||||
// I have no files in that directory.
|
||||
|
||||
whitelist.push_back("/^c[0-9]+(?:t[0-9]+)?d[0-9]+s0$/");
|
||||
|
||||
|
||||
|
||||
#elif defined CONFIG_KERNEL_OPENBSD || defined CONFIG_KERNEL_NETBSD
|
||||
|
||||
// OpenBSD / NetBSD have /dev/wdNc for IDE/ATA, /dev/sdNc for SCSI disk,
|
||||
// /dev/stNc for scsi tape. N is [0-9]+. "c" means "whole disk" (not sure about
|
||||
// different architectures though). There are no "sdN" devices, only "sdNP".
|
||||
// Another manual says that wd0d would be a whole disk, while wd0c is its
|
||||
// bsd part only (on x86) (only on netbsd?). Anyway, getrawpartition() gives
|
||||
// us the letter we need.
|
||||
// There is no additional level of names for BSD subpartitions (unlike freebsd).
|
||||
// cd0a is cdrom.
|
||||
// Dummy devices are present.
|
||||
|
||||
// Note: This detection may take a while (probably due to open() check).
|
||||
|
||||
char whole_part = 'a' + getrawpartition(); // from bsd's util.h
|
||||
|
||||
whitelist.push_back(hz::string_sprintf("/^wd[0-9]+%c$/", whole_part));
|
||||
whitelist.push_back(hz::string_sprintf("/^sd[0-9]+%c$/", whole_part));
|
||||
whitelist.push_back(hz::string_sprintf("/^st[0-9]+%c$/", whole_part));
|
||||
|
||||
|
||||
|
||||
#elif defined CONFIG_KERNEL_DARWIN
|
||||
|
||||
// Darwin has /dev/disk0, /dev/disk0s1, etc...
|
||||
// Only real devices are present, so no need for additional checks.
|
||||
|
||||
whitelist.push_back("/^disk[0-9]+$/");
|
||||
|
||||
|
||||
|
||||
#elif defined CONFIG_KERNEL_QNX
|
||||
|
||||
// QNX has /dev/hd0, /dev/hd0t78 (partition?).
|
||||
// Afaik, IDE and SCSI have the same prefix. fd for floppy, cd for cdrom.
|
||||
// Not sure about the tapes.
|
||||
// Only real devices are present, so no need for additional checks.
|
||||
|
||||
whitelist.push_back("/^hd[0-9]+$/");
|
||||
|
||||
|
||||
#endif // unix platforms
|
||||
|
||||
|
||||
std::vector<std::string> matched_devices;
|
||||
|
||||
for (unsigned int i = 0; i < all_devices.size(); ++i) {
|
||||
std::string entry = all_devices[i];
|
||||
if (entry == "." || entry == "..")
|
||||
continue;
|
||||
|
||||
bool matched = false;
|
||||
for (std::vector<std::string>::const_iterator iter = whitelist.begin(); iter != whitelist.end(); ++iter) {
|
||||
if (app_pcre_match(*iter, entry)) {
|
||||
matched = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!matched)
|
||||
continue;
|
||||
|
||||
hz::FsPath path = dev_dir + hz::DIR_SEPARATOR_S + all_devices[i];
|
||||
|
||||
// In case these are links, trace them to originals.
|
||||
// We don't replace /dev files with real devices - it leads to really bad paths (pci ids for solaris, etc...).
|
||||
std::string link_dest;
|
||||
hz::FsPath real_dev_path;
|
||||
if (path.get_link_destination(link_dest)) {
|
||||
real_dev_path = (hz::path_is_absolute(link_dest) ? link_dest : (dev_dir + hz::DIR_SEPARATOR_S + link_dest));
|
||||
real_dev_path.compress(); // compress in case there are ../-s.
|
||||
|
||||
// solaris has dangling links for non-existant devices, so filter them out.
|
||||
if (!real_dev_path.exists())
|
||||
continue;
|
||||
}
|
||||
|
||||
matched_devices.push_back(path.str());
|
||||
}
|
||||
|
||||
|
||||
// List ones who need dummy device filtering
|
||||
#if defined CONFIG_KERNEL_FREEBSD || defined CONFIG_KERNEL_DRAGONFLY \
|
||||
|| defined CONFIG_KERNEL_OPENBSD || defined CONFIG_KERNEL_NETBSD
|
||||
// Since we may have encountered dummy devices, we should check
|
||||
// if they really exist. Unfortunately, this involves opening them, which
|
||||
// is not good with some media (e.g. it may hang on audio cd (freebsd, maybe others), etc...).
|
||||
// That's why we don't whitelist cd devices. Let's hope usb and others are
|
||||
// ok with this. Dummy devices give errno ENXIO (6, Device not configured) on *bsd.
|
||||
// In Linux ENXIO is (6, No such device or address).
|
||||
|
||||
// Don't do this on solaris - we can't distinguish between cdroms and hds there.
|
||||
|
||||
// If there are less than 4 devices, they are probably not dummy (newer freebsd).
|
||||
bool open_needed = (matched_devices.size() >= 4);
|
||||
if (open_needed) {
|
||||
debug_out_info("app", DBG_FUNC_MSG << "Number of matched devices is "
|
||||
<< matched_devices.size() << ", will try to filter non-existent ones out.\n");
|
||||
} else {
|
||||
debug_out_info("app", DBG_FUNC_MSG << "Number of matched devices is "
|
||||
<< matched_devices.size() << ", no need for filtering them out.\n");
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; i < matched_devices.size(); ++i) {
|
||||
hz::File dev_file(matched_devices[i]);
|
||||
|
||||
// we check errno because OS may deny us for some other reason on valid devices.
|
||||
if (open_needed && !dev_file.open("rb") && dev_file.get_errno() == ENXIO) {
|
||||
debug_out_dump("app", DBG_FUNC_MSG << "Device \"" << dev_file.str() << "\" failed to open, ignoring.\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (open_needed)
|
||||
debug_out_dump("app", DBG_FUNC_MSG << "Device \"" << dev_file.str() << "\" opened successfully, adding to device list.\n");
|
||||
|
||||
devices.push_back(dev_file.str());
|
||||
}
|
||||
|
||||
#else // not *BSD
|
||||
for (unsigned int i = 0; i < matched_devices.size(); ++i) {
|
||||
devices.push_back(matched_devices[i]);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
hz::shell_sort(devices.begin(), devices.end());
|
||||
|
||||
return std::string();
|
||||
}
|
||||
|
||||
|
||||
#endif // platforms
|
||||
|
||||
|
||||
|
||||
} // anon. ns
|
||||
|
||||
|
||||
|
||||
|
||||
std::string StorageDetector::detect(std::vector<StorageDeviceRefPtr>& drives)
|
||||
{
|
||||
debug_out_info("app", DBG_FUNC_MSG << "Starting drive detection.\n");
|
||||
|
||||
std::vector<std::string> devices;
|
||||
std::string error_msg;
|
||||
bool found = false;
|
||||
|
||||
// Try each one and move to next if it fails.
|
||||
|
||||
#if defined CONFIG_KERNEL_LINUX
|
||||
|
||||
// Disable by-id detection - it's unreliable on broken systems.
|
||||
// For example, on Ubuntu 8.04, /dev/disk/by-id contains two device
|
||||
// links for two drives, but both point to the same sdb (instead of
|
||||
// sda and sdb). Plus, there are no "*-partN" files (not that we need them).
|
||||
/*
|
||||
if (!found) {
|
||||
error_msg = detect_drives_linux_udev_byid(devices); // linux udev
|
||||
// we check for devices vector emptiness because it could be a dummy directory
|
||||
// with no files, so treat it as an error.
|
||||
if (error_msg.empty() && !devices.empty()) {
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
*/
|
||||
if (!found) {
|
||||
error_msg = detect_drives_linux_proc_partitions(devices); // linux /proc/partitions as fallback.
|
||||
if (error_msg.empty() && !devices.empty()) {
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
|
||||
#elif defined CONFIG_KERNEL_FAMILY_WINDOWS
|
||||
|
||||
if (!found) {
|
||||
error_msg = detect_drives_win32(devices); // win32
|
||||
if (error_msg.empty() && !devices.empty()) {
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#else // freebsd, etc...
|
||||
|
||||
if (!found) {
|
||||
error_msg = detect_drives_dev(devices); // bsd, etc... . scans /dev.
|
||||
if (error_msg.empty() && !devices.empty()) {
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
if (!found) {
|
||||
debug_out_warn("app", DBG_FUNC_MSG << "Cannot detect drives: None of the drive detection methods returned any drives.\n");
|
||||
return error_msg; // last error message should be ok.
|
||||
}
|
||||
|
||||
|
||||
for (std::vector<std::string>::const_iterator iter = devices.begin(); iter != devices.end(); ++iter) {
|
||||
std::string dev = *iter;
|
||||
|
||||
// try to match against patterns
|
||||
// for (unsigned int i = 0; i < match_patterns_.size(); i++) {
|
||||
// try to match against general filter
|
||||
// if (!app_pcre_match(match_patterns_[i], dev))
|
||||
// continue;
|
||||
|
||||
// matched, check the blacklist
|
||||
bool blacked = false;
|
||||
for (unsigned int j = 0; j < blacklist_patterns_.size(); j++) {
|
||||
if (app_pcre_match(blacklist_patterns_[j], dev)) { // matched the blacklist too
|
||||
blacked = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
StorageDeviceRefPtr drive(new StorageDevice(dev));
|
||||
debug_out_info("app", "Found device: \"" << drive->get_device() << "\".\n");
|
||||
|
||||
if (!blacked) {
|
||||
drives.push_back(drive);
|
||||
// break; // no need to match other patters, go to next device
|
||||
|
||||
} else { // blacklisted
|
||||
debug_out_info("app", "Device \"" << drive->get_device() << "\" is blacklisted, ignoring.\n");
|
||||
// break; // go to next device
|
||||
}
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
debug_out_info("app", DBG_FUNC_MSG << "Drive detection finished.\n");
|
||||
return std::string();
|
||||
}
|
||||
|
||||
|
||||
|
||||
std::string StorageDetector::fetch_basic_data(std::vector<StorageDeviceRefPtr>& drives,
|
||||
hz::intrusive_ptr<CmdexSync> smartctl_ex, bool return_first_error)
|
||||
{
|
||||
fetch_data_errors_.clear();
|
||||
fetch_data_error_outputs_.clear();
|
||||
|
||||
|
||||
// If it doesn't exist, create a default one. Even though it will be auto-created later,
|
||||
// we need it here to get its errors afterwards.
|
||||
if (!smartctl_ex)
|
||||
smartctl_ex = new SmartctlExecutor(); // will be auto-deleted
|
||||
|
||||
for (unsigned int i = 0; i < drives.size(); ++i) {
|
||||
StorageDeviceRefPtr drive = drives[i];
|
||||
debug_out_info("app", "Retrieving basic information about the device...\n");
|
||||
|
||||
smartctl_ex->set_running_msg("Running %s on " + drive->get_device() + "...");
|
||||
|
||||
// don't show any errors here - we don't want a screen flood.
|
||||
// no need for gui-based executors here, we already show the message in
|
||||
// iconview background (if called from main window)
|
||||
std::string error_msg = drive->fetch_basic_data_and_parse(smartctl_ex);
|
||||
|
||||
// normally we skip drives with errors - possibly scsi, etc...
|
||||
if (return_first_error && !error_msg.empty())
|
||||
return error_msg;
|
||||
|
||||
if (!error_msg.empty()) {
|
||||
// use original executor error if present (permits matches by our users).
|
||||
// if (!smartctl_ex->get_error_msg().empty())
|
||||
// error_msg = smartctl_ex->get_error_msg();
|
||||
|
||||
fetch_data_errors_.push_back(error_msg);
|
||||
fetch_data_error_outputs_.push_back(smartctl_ex->get_stdout_str());
|
||||
}
|
||||
|
||||
debug_out_dump("app", "Device information for " << drive->get_device() << ":\n"
|
||||
<< "\tModel: " << drive->get_model_name() << "\n"
|
||||
<< "\tType: " << StorageDevice::get_type_readable_name(drive->get_type()) << "\n"
|
||||
<< "\tSMART status: " << StorageDevice::get_status_name(drive->get_smart_status()) << "\n"
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
return std::string();
|
||||
}
|
||||
|
||||
|
||||
|
||||
std::string StorageDetector::detect_and_fetch_basic_data(std::vector<StorageDeviceRefPtr>& put_drives_here,
|
||||
hz::intrusive_ptr<CmdexSync> smartctl_ex)
|
||||
{
|
||||
std::string error_msg = detect(put_drives_here);
|
||||
|
||||
if (error_msg.empty())
|
||||
fetch_basic_data(put_drives_here, smartctl_ex, false); // ignore its errors, there may be plenty of them.
|
||||
|
||||
return error_msg;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,82 +0,0 @@
|
||||
/**************************************************************************
|
||||
Copyright:
|
||||
(C) 2008 - 2009 Alexander Shaduri <ashaduri 'at' gmail.com>
|
||||
License: See LICENSE_gsmartcontrol.txt
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef STORAGE_DETECTOR_H
|
||||
#define STORAGE_DETECTOR_H
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
#include "hz/intrusive_ptr.h"
|
||||
|
||||
#include "storage_device.h"
|
||||
#include "cmdex_sync.h"
|
||||
|
||||
|
||||
|
||||
class StorageDetector {
|
||||
|
||||
public:
|
||||
|
||||
StorageDetector()
|
||||
{
|
||||
// match_patterns_.push_back("/.+/"); // accept anything, the scanner picks up disks only anyway.
|
||||
}
|
||||
|
||||
|
||||
// detects a list of drives. returns detection error if error occurs.
|
||||
std::string detect(std::vector<StorageDeviceRefPtr>& put_drives_here);
|
||||
|
||||
|
||||
// fetch basic data of "drives" elements
|
||||
std::string fetch_basic_data(std::vector<StorageDeviceRefPtr>& drives,
|
||||
hz::intrusive_ptr<CmdexSync> smartctl_ex = 0, bool return_first_error = false);
|
||||
|
||||
|
||||
// do both of the above, return detection error.
|
||||
std::string detect_and_fetch_basic_data(std::vector<StorageDeviceRefPtr>& put_drives_here,
|
||||
hz::intrusive_ptr<CmdexSync> smartctl_ex = 0);
|
||||
|
||||
|
||||
// void add_match_patterns(std::vector<std::string>& patterns)
|
||||
// {
|
||||
// match_patterns_.insert(match_patterns_.end(), patterns.begin(), patterns.end());
|
||||
// }
|
||||
|
||||
|
||||
void add_blacklist_patterns(std::vector<std::string>& patterns)
|
||||
{
|
||||
blacklist_patterns_.insert(blacklist_patterns_.end(), patterns.begin(), patterns.end());
|
||||
}
|
||||
|
||||
|
||||
const std::vector<std::string>& get_fetch_data_errors() const
|
||||
{
|
||||
return fetch_data_errors_;
|
||||
}
|
||||
|
||||
const std::vector<std::string>& get_fetch_data_error_outputs() const
|
||||
{
|
||||
return fetch_data_error_outputs_;
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
|
||||
// std::vector<std::string> match_patterns_; // first each file is matched against these
|
||||
std::vector<std::string> blacklist_patterns_; // and then these
|
||||
|
||||
std::vector<std::string> fetch_data_errors_; // errors not returned via functions
|
||||
std::vector<std::string> fetch_data_error_outputs_; // corresponding outputs
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
@@ -1,431 +0,0 @@
|
||||
/**************************************************************************
|
||||
Copyright:
|
||||
(C) 2008 - 2009 Alexander Shaduri <ashaduri 'at' gmail.com>
|
||||
License: See LICENSE_gsmartcontrol.txt
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef STORAGE_DEVICE_H
|
||||
#define STORAGE_DEVICE_H
|
||||
|
||||
#include <string>
|
||||
#include <sigc++/sigc++.h>
|
||||
|
||||
#include "hz/optional_value.h"
|
||||
#include "hz/intrusive_ptr.h"
|
||||
|
||||
#include "storage_property.h"
|
||||
#include "smartctl_parser.h" // prop_list_t
|
||||
#include "smartctl_executor.h"
|
||||
|
||||
|
||||
|
||||
class StorageDevice;
|
||||
|
||||
|
||||
class StorageDevice : public hz::intrusive_ptr_referenced {
|
||||
|
||||
public:
|
||||
|
||||
// these may be used to force smartctl to a special type, as well as
|
||||
// to display the correct icon
|
||||
enum type_t {
|
||||
type_unknown, // unknown. will be autodetected by smartctl
|
||||
type_invalid, // this is set by smartctl executor if it detects invalid type (but not if it's scsi).
|
||||
type_cddvd, // unsupported by smartctl, only basic info is given.
|
||||
type_scsi // this is used to force "-d scsi" to execute IDENTIFY command.
|
||||
};
|
||||
|
||||
|
||||
// this gives a string which can be displayed in outputs
|
||||
static std::string get_type_readable_name(type_t type)
|
||||
{
|
||||
switch (type) {
|
||||
case type_unknown: return "unknown";
|
||||
case type_invalid: return "invalid";
|
||||
case type_cddvd: return "cd/dvd";
|
||||
case type_scsi: return "scsi";
|
||||
}
|
||||
return "[internal_error]";
|
||||
}
|
||||
|
||||
|
||||
// this gives a string which, if not empty, can be given as a parameter of "-d".
|
||||
static std::string get_type_arg_name(type_t type)
|
||||
{
|
||||
switch (type) {
|
||||
case type_unknown: return "";
|
||||
case type_invalid: return "";
|
||||
case type_cddvd: return "";
|
||||
case type_scsi: return "scsi";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
enum status_t { // statuses of various states
|
||||
status_enabled, // smart, aodc
|
||||
status_disabled, // smart, aodc
|
||||
status_unsupported, // smart, aodc
|
||||
status_unknown // aodc - supported but unknown if it's enabled or not.
|
||||
};
|
||||
|
||||
static std::string get_status_name(status_t status, bool use_yesno = false)
|
||||
{
|
||||
switch (status) {
|
||||
case status_enabled: return (use_yesno ? "Yes" : "Enabled");
|
||||
case status_disabled: return (use_yesno ? "No" : "Disabled");
|
||||
case status_unsupported: return "Unsupported";
|
||||
case status_unknown: return "Unknown";
|
||||
};
|
||||
return "[internal_error]";
|
||||
}
|
||||
|
||||
|
||||
|
||||
StorageDevice(const std::string& dev_or_vfile, bool is_virtual = false)
|
||||
{
|
||||
type_ = type_unknown;
|
||||
// force_type_ = false;
|
||||
is_virtual_ = is_virtual;
|
||||
is_manually_added_ = false;
|
||||
fully_parsed_ = false;
|
||||
test_is_active_ = false;
|
||||
|
||||
if (is_virtual) {
|
||||
virtual_file_ = dev_or_vfile;
|
||||
} else {
|
||||
device_ = dev_or_vfile;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
StorageDevice(const StorageDevice& other)
|
||||
{
|
||||
*this = other;
|
||||
}
|
||||
|
||||
|
||||
StorageDevice& operator= (const StorageDevice& other)
|
||||
{
|
||||
info_output_ = other.info_output_;
|
||||
full_output_ = other.full_output_;
|
||||
|
||||
device_ = other.device_;
|
||||
|
||||
// force_type_ = other.force_type_;
|
||||
is_virtual_ = other.is_virtual_;
|
||||
virtual_file_ = other.virtual_file_;
|
||||
is_manually_added_ = other.is_manually_added_;
|
||||
|
||||
fully_parsed_ = other.fully_parsed_;
|
||||
test_is_active_ = other.test_is_active_;
|
||||
|
||||
type_ = other.type_;
|
||||
smart_supported_ = other.smart_supported_;
|
||||
smart_enabled_ = other.smart_enabled_;
|
||||
aodc_status_ = other.aodc_status_;
|
||||
model_name_ = other.model_name_;
|
||||
family_name_ = other.family_name_;
|
||||
size_ = other.size_;
|
||||
health_property_ = other.health_property_;
|
||||
|
||||
properties_ = other.properties_;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
// clear everything fetched before.
|
||||
void clear_fetched(bool including_outputs = true)
|
||||
{
|
||||
if (including_outputs) {
|
||||
info_output_.clear();
|
||||
full_output_.clear();
|
||||
}
|
||||
|
||||
fully_parsed_ = false;
|
||||
test_is_active_ = false; // not sure
|
||||
|
||||
smart_supported_.reset();
|
||||
smart_enabled_.reset();
|
||||
model_name_.reset();
|
||||
aodc_status_.reset();
|
||||
family_name_.reset();
|
||||
size_.reset();
|
||||
health_property_.reset();
|
||||
|
||||
properties_.clear();
|
||||
}
|
||||
|
||||
|
||||
// calls "smartctl --info" (info section), then parse_basic_data()
|
||||
// called during drive detection.
|
||||
// note: this will clear the non-basic properties!
|
||||
std::string fetch_basic_data_and_parse(hz::intrusive_ptr<CmdexSync> smartctl_ex = 0);
|
||||
|
||||
|
||||
// detects type, smart support, smart status (on / off).
|
||||
// note: this will clear the non-basic properties!
|
||||
std::string parse_basic_data(bool do_set_properties = true, bool emit_signal = true);
|
||||
|
||||
|
||||
// execute smartctl --all (all sections), get output, parse it, fill properties.
|
||||
std::string fetch_data_and_parse(hz::intrusive_ptr<CmdexSync> smartctl_ex = 0); // returns error message on error.
|
||||
|
||||
|
||||
std::string parse_data(); // returns error message on error.
|
||||
|
||||
|
||||
void set_fully_parsed(bool b)
|
||||
{
|
||||
fully_parsed_ = b;
|
||||
}
|
||||
|
||||
bool get_fully_parsed() const
|
||||
{
|
||||
return fully_parsed_;
|
||||
}
|
||||
|
||||
|
||||
// try to enable SMART. will return error message on error.
|
||||
std::string set_smart_enabled(bool b, hz::intrusive_ptr<CmdexSync> smartctl_ex = 0);
|
||||
|
||||
// try to enable Automatic Offline Data Collection. will return error message on error.
|
||||
std::string set_aodc_enabled(bool b, hz::intrusive_ptr<CmdexSync> smartctl_ex = 0);
|
||||
|
||||
|
||||
status_t get_smart_status() const;
|
||||
|
||||
status_t get_aodc_status() const;
|
||||
|
||||
// returns empty string on error, format size string on success.
|
||||
std::string get_device_size_str() const;
|
||||
|
||||
StorageProperty get_health_property() const;
|
||||
|
||||
|
||||
std::string get_device() const
|
||||
{
|
||||
return device_;
|
||||
}
|
||||
|
||||
|
||||
std::string get_device_base() const
|
||||
{
|
||||
if (is_virtual_)
|
||||
return "";
|
||||
|
||||
std::string::size_type pos = device_.rfind('/'); // find basename
|
||||
if (pos == std::string::npos)
|
||||
return device_; // fall back
|
||||
return device_.substr(pos+1, std::string::npos);
|
||||
}
|
||||
|
||||
|
||||
// for display purposes
|
||||
std::string get_device_pretty(bool extended = false) const
|
||||
{
|
||||
std::string ret;
|
||||
if (this->get_is_virtual()) {
|
||||
ret = "Virtual";
|
||||
if (extended) {
|
||||
std::string vf = this->get_virtual_filename();
|
||||
ret += (" (" + (vf.empty() ? "[empty]" : vf) + ")");
|
||||
}
|
||||
} else {
|
||||
ret = (extended ? this->get_device() : this->get_device_base());
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void set_type(type_t t)
|
||||
{
|
||||
type_ = t;
|
||||
}
|
||||
|
||||
type_t get_type() const
|
||||
{
|
||||
return type_;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool get_is_virtual() const
|
||||
{
|
||||
return is_virtual_;
|
||||
}
|
||||
|
||||
std::string get_virtual_file() const
|
||||
{
|
||||
return (is_virtual_ ? virtual_file_ : std::string());
|
||||
}
|
||||
|
||||
// get only the filename portion
|
||||
std::string get_virtual_filename() const;
|
||||
|
||||
|
||||
const SmartctlParser::prop_list_t& get_properties() const
|
||||
{
|
||||
return properties_;
|
||||
}
|
||||
|
||||
|
||||
StorageProperty lookup_property(const std::string& generic_name,
|
||||
StorageProperty::section_t section = StorageProperty::section_unknown, // if unknown, search in all.
|
||||
StorageProperty::subsection_t subsection = StorageProperty::subsection_unknown) const
|
||||
{
|
||||
for (SmartctlParser::prop_list_t::const_iterator iter = properties_.begin(); iter != properties_.end(); ++iter) {
|
||||
if (section != StorageProperty::section_unknown && iter->section != section)
|
||||
continue;
|
||||
if (subsection != StorageProperty::subsection_unknown && iter->subsection != subsection)
|
||||
continue;
|
||||
|
||||
if (iter->generic_name == generic_name)
|
||||
return *iter;
|
||||
}
|
||||
return StorageProperty(); // check with .empty()
|
||||
}
|
||||
|
||||
|
||||
// returns an empty string if unknown
|
||||
std::string get_model_name() const
|
||||
{
|
||||
return (model_name_.defined() ? model_name_.value() : "");
|
||||
}
|
||||
|
||||
|
||||
// returns an empty string if unknown
|
||||
std::string get_family_name() const
|
||||
{
|
||||
return (family_name_.defined() ? family_name_.value() : "");
|
||||
}
|
||||
|
||||
|
||||
void set_info_output(const std::string& s)
|
||||
{
|
||||
info_output_ = s;
|
||||
}
|
||||
|
||||
void set_full_output(const std::string& s)
|
||||
{
|
||||
full_output_ = s;
|
||||
}
|
||||
|
||||
|
||||
std::string get_info_output() const
|
||||
{
|
||||
return info_output_;
|
||||
}
|
||||
|
||||
std::string get_full_output() const
|
||||
{
|
||||
return full_output_;
|
||||
}
|
||||
|
||||
|
||||
void set_is_manually_added(bool b)
|
||||
{
|
||||
is_manually_added_ = b;
|
||||
}
|
||||
|
||||
bool get_is_manually_added() const
|
||||
{
|
||||
return is_manually_added_;
|
||||
}
|
||||
|
||||
|
||||
void set_test_is_active(bool b)
|
||||
{
|
||||
bool changed = (test_is_active_ != b);
|
||||
test_is_active_ = b;
|
||||
if (changed)
|
||||
signal_changed.emit(this); // so that everybody stops any test-aborting operations.
|
||||
}
|
||||
|
||||
bool get_test_is_active() const
|
||||
{
|
||||
return test_is_active_;
|
||||
}
|
||||
|
||||
|
||||
// get the recommended filename to save output to. includes model and date.
|
||||
std::string get_save_filename() const;
|
||||
|
||||
|
||||
std::string get_device_options() const; // get smartctl options for this device from config and type info.
|
||||
|
||||
|
||||
// execute smartctl on this device. nothing is modified in this class.
|
||||
std::string execute_smartctl(const std::string& command_options,
|
||||
hz::intrusive_ptr<CmdexSync> smartctl_ex, std::string& output, bool check_type = false);
|
||||
|
||||
|
||||
// emitted whenever new information is available
|
||||
sigc::signal<void, StorageDevice*> signal_changed;
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
void set_properties(const SmartctlParser::prop_list_t& props)
|
||||
{
|
||||
properties_ = props;
|
||||
}
|
||||
|
||||
|
||||
std::string info_output_; // "smartctl --info" output
|
||||
std::string full_output_; // "smartctl --all" output
|
||||
|
||||
std::string device_; // e.g. /dev/sda. empty if virtual.
|
||||
|
||||
// bool force_type_; // force "-d type" to smartctl, e.g. "-d scsi". DISCONTINUED, use per-device options.
|
||||
bool is_virtual_; // if true, then this is not a real device - merely a loaded description of it.
|
||||
std::string virtual_file_; // a file (smartctl data) the virtual device was loaded from
|
||||
bool is_manually_added_; // StorageDevice doesn't use it, but it's useful for its users.
|
||||
|
||||
bool fully_parsed_;
|
||||
|
||||
// sort of "lock". if true, the device is not allowed to perform any commands
|
||||
// except "-l selftest" and maybe "--capabilities" and "--info" (not sure).
|
||||
bool test_is_active_;
|
||||
|
||||
// these are detected through info output
|
||||
type_t type_; // e.g. type_ata
|
||||
hz::OptionalValue<bool> smart_supported_;
|
||||
hz::OptionalValue<bool> smart_enabled_;
|
||||
mutable hz::OptionalValue<status_t> aodc_status_; // cached aodc status.
|
||||
hz::OptionalValue<std::string> model_name_;
|
||||
hz::OptionalValue<std::string> family_name_;
|
||||
hz::OptionalValue<std::string> size_; // formatted size
|
||||
mutable hz::OptionalValue<StorageProperty> health_property_; // cached health property.
|
||||
|
||||
// smart properties. detected through full output.
|
||||
SmartctlParser::prop_list_t properties_;
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
typedef hz::intrusive_ptr<StorageDevice> StorageDeviceRefPtr;
|
||||
|
||||
|
||||
// for sorting, hard drives first
|
||||
inline bool operator< (const StorageDeviceRefPtr& d1, const StorageDeviceRefPtr& d2)
|
||||
{
|
||||
if (d1->get_type() != d2->get_type()) {
|
||||
return (d1->get_type() == StorageDevice::type_unknown); // hard drives first
|
||||
}
|
||||
return d1->get_device_base() < d2->get_device_base();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||