mirror of
https://github.com/linuxmint/timeshift.git
synced 2024-09-11 17:07:43 +03:00
Improved detection of disk partitions
This commit is contained in:
parent
785828c212
commit
b5ba4ca92e
@ -5,7 +5,16 @@ DIR="$( cd "$( dirname "$0" )" && pwd )"
|
||||
cd "$DIR"
|
||||
|
||||
rm -rf ../builds
|
||||
|
||||
bzr builddeb --native --build-dir ../builds/temp --result-dir ../builds
|
||||
|
||||
#check for errors
|
||||
if [ $? -ne 0 ]; then
|
||||
cd "$backup"
|
||||
echo "Failed"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
ls -l ../builds
|
||||
|
||||
cd "$backup"
|
||||
|
@ -5,6 +5,21 @@ DIR="$( cd "$( dirname "$0" )" && pwd )"
|
||||
cd "$DIR"
|
||||
|
||||
sh build-deb.sh
|
||||
|
||||
#check for errors
|
||||
if [ $? -ne 0 ]; then
|
||||
cd "$backup"
|
||||
echo "Failed"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
sudo gdebi --non-interactive ../builds/timeshift*.deb
|
||||
|
||||
#check for errors
|
||||
if [ $? -ne 0 ]; then
|
||||
cd "$backup"
|
||||
echo "Failed"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cd "$backup"
|
||||
|
@ -24,12 +24,26 @@ mkdir -p ${arch}
|
||||
|
||||
sudo pbuilder --build --buildresult ${arch} --basetgz "${tgz}base-${arch}.tgz" ${dsc}
|
||||
|
||||
#check for errors
|
||||
if [ $? -ne 0 ]; then
|
||||
cd "$backup"
|
||||
echo "Failed"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
dpkg-deb -x ${arch}/timeshift*.deb ${arch}/extracted
|
||||
|
||||
cp -p --no-preserve=ownership -t ${arch}/extracted ./install.sh
|
||||
|
||||
makeself ${arch}/extracted ./timeshift-latest-${arch}.run "TimeShift (${arch})" ./install.sh
|
||||
|
||||
#check for errors
|
||||
if [ $? -ne 0 ]; then
|
||||
cd "$backup"
|
||||
echo "Failed"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cp -p --no-preserve=ownership -t /home/teejee/Dropbox/Public/linux ./timeshift-latest-${arch}.run
|
||||
|
||||
done
|
||||
|
@ -6,6 +6,26 @@ cd "$DIR"
|
||||
|
||||
sh push.sh
|
||||
|
||||
#check for errors
|
||||
if [ $? -ne 0 ]; then
|
||||
cd "$backup"
|
||||
echo "Failed"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
sh build-installer.sh
|
||||
|
||||
#check for errors
|
||||
if [ $? -ne 0 ]; then
|
||||
cd "$backup"
|
||||
echo "Failed"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cd installer
|
||||
for arch in i386 amd64
|
||||
do
|
||||
cp -p --no-preserve=ownership -t /home/teejee/Dropbox/Public/linux ./timeshift-latest-${arch}.run
|
||||
done
|
||||
|
||||
cd "$backup"
|
||||
|
@ -6,8 +6,24 @@ cd "$DIR"
|
||||
|
||||
sh update-pot.sh
|
||||
|
||||
#check for errors
|
||||
if [ $? -ne 0 ]; then
|
||||
cd "$backup"
|
||||
echo "Failed"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
rm -rf ../builds
|
||||
|
||||
bzr builddeb --source --native --build-dir ../builds/temp --result-dir ../builds
|
||||
|
||||
#check for errors
|
||||
if [ $? -ne 0 ]; then
|
||||
cd "$backup"
|
||||
echo "Failed"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
ls -l ../builds
|
||||
|
||||
cd "$backup"
|
||||
|
14
push.sh
14
push.sh
@ -6,9 +6,23 @@ cd "$DIR"
|
||||
|
||||
sh build-source.sh
|
||||
|
||||
#check for errors
|
||||
if [ $? -ne 0 ]; then
|
||||
cd "$backup"
|
||||
echo "Failed"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Pushing new revisions to launchpad..."
|
||||
bzr push lp:~teejee2008/timeshift/trunk
|
||||
|
||||
#check for errors
|
||||
if [ $? -ne 0 ]; then
|
||||
cd "$backup"
|
||||
echo "Failed"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cd "$backup"
|
||||
|
||||
|
||||
|
@ -530,7 +530,7 @@ public class Main : GLib.Object{
|
||||
}
|
||||
}
|
||||
|
||||
public bool is_live_system(){
|
||||
public bool live_system(){
|
||||
return (root_device == null);
|
||||
}
|
||||
|
||||
@ -1845,8 +1845,6 @@ public class Main : GLib.Object{
|
||||
|
||||
snapshot_list.clear();
|
||||
|
||||
if (is_snapshot_device_online() == false){ return false; }
|
||||
|
||||
string path = mount_point_backup + "/timeshift/snapshots";
|
||||
|
||||
if (dir_exists(path)){
|
||||
@ -1890,12 +1888,11 @@ public class Main : GLib.Object{
|
||||
|
||||
foreach(PartitionInfo pi in partition_list){
|
||||
//root_device and home_device will be detected by detect_system_devices()
|
||||
|
||||
if (pi.mount_point == "/mnt/timeshift"){
|
||||
if (pi.mount_point_list.contains("/mnt/timeshift")){
|
||||
snapshot_device = pi;
|
||||
}
|
||||
if (pi.is_mounted){
|
||||
pi.dist_info = DistInfo.get_dist_info(pi.mount_point).full_name();
|
||||
pi.dist_info = DistInfo.get_dist_info(pi.mount_point_list[0]).full_name();
|
||||
}
|
||||
}
|
||||
if (partition_list.size == 0){
|
||||
@ -1936,24 +1933,29 @@ public class Main : GLib.Object{
|
||||
log_error (std_err);
|
||||
}
|
||||
else{
|
||||
string dev_root = "";
|
||||
string dev_home = "";
|
||||
|
||||
foreach(string line in std_out.split("\n")){
|
||||
if (line.contains(" / ")){
|
||||
string dev = line.split(" ")[0].strip();
|
||||
foreach(PartitionInfo p in partition_list){
|
||||
if (p.device == dev){
|
||||
root_device = p;
|
||||
break;
|
||||
}
|
||||
}
|
||||
dev_root = line.split(" ")[0].strip();
|
||||
}
|
||||
else if (line.contains(" /home ")){
|
||||
string dev = line.split(" ")[0].strip();
|
||||
foreach(PartitionInfo p in partition_list){
|
||||
if (p.device == dev){
|
||||
home_device = p;
|
||||
break;
|
||||
}
|
||||
}
|
||||
dev_home = line.split(" ")[0].strip();
|
||||
}
|
||||
}
|
||||
|
||||
foreach(PartitionInfo p in partition_list){
|
||||
if (p.device == dev_root){
|
||||
root_device = p;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
foreach(PartitionInfo p in partition_list){
|
||||
if (p.device == dev_home){
|
||||
home_device = p;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2105,7 +2107,7 @@ public class Main : GLib.Object{
|
||||
string std_err;
|
||||
int ret_val;
|
||||
|
||||
if (is_live_system()) { return false; }
|
||||
if (live_system()) { return false; }
|
||||
|
||||
try{
|
||||
string temp_file = get_temp_file_path();
|
||||
@ -2152,9 +2154,9 @@ public class Main : GLib.Object{
|
||||
|
||||
|
||||
public PartitionInfo? get_backup_device(){
|
||||
var list = get_mounted_partitions();
|
||||
var list = get_mounted_partitions_using_df();
|
||||
foreach(PartitionInfo info in list){
|
||||
if (info.mount_point == "/mnt/timeshift"){
|
||||
if (info.mount_point_list.contains("/mnt/timeshift")){
|
||||
return info;
|
||||
}
|
||||
}
|
||||
@ -2176,8 +2178,8 @@ public class Main : GLib.Object{
|
||||
message = "%s ".printf(snapshot_device.free) + _("free");
|
||||
message = message.strip();
|
||||
|
||||
if (!is_live_system()){
|
||||
if (is_snapshot_device_online() == false){
|
||||
if (!live_system()){
|
||||
if (!backup_device_online()){
|
||||
message = _("Backup device not available!");
|
||||
status_code = -1;
|
||||
}
|
||||
@ -2213,10 +2215,10 @@ public class Main : GLib.Object{
|
||||
return is_supported;
|
||||
}
|
||||
|
||||
public bool is_snapshot_device_online(){
|
||||
public bool backup_device_online(){
|
||||
//check if mounted
|
||||
foreach(PartitionInfo info in get_mounted_partitions()){
|
||||
if (info.mount_point == mount_point_backup){
|
||||
foreach(PartitionInfo info in get_mounted_partitions_using_df()){
|
||||
if (info.mount_point_list.contains(mount_point_backup)){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -2224,13 +2226,12 @@ public class Main : GLib.Object{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public long calculate_size_of_first_snapshot(){
|
||||
|
||||
if (this.first_snapshot_size > 0){
|
||||
return this.first_snapshot_size;
|
||||
}
|
||||
else if (is_live_system()){
|
||||
else if (live_system()){
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -438,7 +438,7 @@ class MainWindow : Gtk.Window{
|
||||
|
||||
snapshot_device_original = App.snapshot_device;
|
||||
|
||||
if (App.is_live_system()){
|
||||
if (App.live_system()){
|
||||
btn_backup.sensitive = false;
|
||||
btn_settings.sensitive = false;
|
||||
btn_view_app_logs.sensitive = false;
|
||||
@ -455,7 +455,7 @@ class MainWindow : Gtk.Window{
|
||||
|
||||
update_ui(false);
|
||||
|
||||
if (App.is_live_system()){
|
||||
if (App.live_system()){
|
||||
statusbar_message(_("Checking backup device..."));
|
||||
}
|
||||
else{
|
||||
@ -575,7 +575,7 @@ class MainWindow : Gtk.Window{
|
||||
|
||||
case -1:
|
||||
string msg = _("The backup device is not set or unavailable.") + "\n";
|
||||
msg += _("Scheduled snapshots will be disabled.");
|
||||
msg += _("Scheduled snapshots will be disabled.") + "\n";
|
||||
msg += _("Do you want to select another device?");
|
||||
|
||||
var dialog = new Gtk.MessageDialog.with_markup(null, Gtk.DialogFlags.MODAL, Gtk.MessageType.INFO, Gtk.ButtonsType.OK_CANCEL, msg);
|
||||
@ -958,7 +958,7 @@ class MainWindow : Gtk.Window{
|
||||
|
||||
//take a snapshot if current system is being restored -----------------
|
||||
|
||||
if (!App.is_live_system() && (App.restore_target.device == App.root_device.device) && (App.restore_target.uuid == App.root_device.uuid)){
|
||||
if (!App.live_system() && (App.restore_target.device == App.root_device.device) && (App.restore_target.uuid == App.root_device.uuid)){
|
||||
|
||||
string msg = _("Do you want to take a snapshot of the current system before restoring the selected snapshot?");
|
||||
|
||||
@ -1258,7 +1258,7 @@ class MainWindow : Gtk.Window{
|
||||
|
||||
//status - scheduled snapshots -----------
|
||||
|
||||
if (App.is_live_system()){
|
||||
if (App.live_system()){
|
||||
img_status_scheduled.file = img_dot_green;
|
||||
lbl_status_scheduled.label = _("Running from Live CD/USB");
|
||||
lbl_status_scheduled.set_tooltip_text(_("TimeShift is running in a live system"));
|
||||
|
@ -921,7 +921,7 @@ public class SettingsWindow : Gtk.Dialog{
|
||||
iterExists = store.iter_next (ref iter);
|
||||
}
|
||||
|
||||
if (!App.is_live_system()){
|
||||
if (!App.live_system()){
|
||||
App.is_scheduled = switch_schedule.active;
|
||||
}
|
||||
}
|
||||
|
485
src/Utility.vala
485
src/Utility.vala
@ -23,8 +23,6 @@
|
||||
|
||||
using Gtk;
|
||||
using Json;
|
||||
|
||||
/*
|
||||
using TeeJee.Logging;
|
||||
using TeeJee.FileSystem;
|
||||
using TeeJee.DiskPartition;
|
||||
@ -35,11 +33,8 @@ using TeeJee.Multimedia;
|
||||
using TeeJee.System;
|
||||
using TeeJee.Misc;
|
||||
|
||||
/*
|
||||
extern void exit(int exit_code);
|
||||
|
||||
public static int main (string[] args) {
|
||||
return 0;
|
||||
}
|
||||
*/
|
||||
|
||||
namespace TeeJee.Logging{
|
||||
@ -344,21 +339,34 @@ namespace TeeJee.DiskPartition{
|
||||
public string uuid = "";
|
||||
public string available = "";
|
||||
public string used_percent = "";
|
||||
public string mount_point = "";
|
||||
public string dist_info = "";
|
||||
public Gee.ArrayList<string> mount_point_list;
|
||||
|
||||
public PartitionInfo(){
|
||||
mount_point_list = new Gee.ArrayList<string>();
|
||||
}
|
||||
|
||||
public string description(){
|
||||
string s = "";
|
||||
s += device;
|
||||
s += (type.length > 0) ? " ~ " + type : "";
|
||||
s += (used.length > 0) ? " ~ " + used + " / " + size + " used (" + used_percent + ")" : "";
|
||||
s += (used.length > 0) ? " ~ " + used + " / " + size + " GB used (" + used_percent + ")" : "";
|
||||
return s;
|
||||
}
|
||||
|
||||
public string description_device(){
|
||||
public string description_full(){
|
||||
string s = "";
|
||||
s += device;
|
||||
s += (uuid.length == 0) ? "" : ", UUID=" + uuid;
|
||||
s += (uuid.length > 0) ? " ~ " + uuid : "";
|
||||
s += (type.length > 0) ? " ~ " + type : "";
|
||||
s += (used.length > 0) ? " ~ " + used + " / " + size + " GB used (" + used_percent + ")" : "";
|
||||
|
||||
string mps = "";
|
||||
foreach(string mp in mount_point_list){
|
||||
mps += mp + " ";
|
||||
}
|
||||
s += (mps.length > 0) ? " ~ " + mps.strip() : "";
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
@ -373,13 +381,13 @@ namespace TeeJee.DiskPartition{
|
||||
|
||||
public string size{
|
||||
owned get{
|
||||
return (size_mb == 0) ? "" : "%.1f GB".printf(size_mb/1024.0);
|
||||
return (size_mb == 0) ? "" : "%.1f".printf(size_mb/1024.0);
|
||||
}
|
||||
}
|
||||
|
||||
public string used{
|
||||
owned get{
|
||||
return (used_mb == 0) ? "" : "%.1f GB".printf(used_mb/1024.0);
|
||||
return (used_mb == 0) ? "" : "%.1f".printf(used_mb/1024.0);
|
||||
}
|
||||
}
|
||||
|
||||
@ -391,7 +399,7 @@ namespace TeeJee.DiskPartition{
|
||||
|
||||
public bool is_mounted{
|
||||
get{
|
||||
return (mount_point.length > 0);
|
||||
return (mount_point_list.size > 0);
|
||||
}
|
||||
}
|
||||
|
||||
@ -446,65 +454,11 @@ namespace TeeJee.DiskPartition{
|
||||
}
|
||||
}
|
||||
|
||||
public PartitionInfo get_partition_info(string path){
|
||||
|
||||
public Gee.ArrayList<PartitionInfo?> get_mounted_partitions_using_df(bool exclude_unknown = true){
|
||||
|
||||
/* Returns partition info for specified path or device name */
|
||||
|
||||
PartitionInfo info = new PartitionInfo();
|
||||
|
||||
string std_out = "";
|
||||
string std_err = "";
|
||||
int exit_code = execute_command_script_sync("df -T -BM \"" + path + "\"| uniq -w 12", out std_out, out std_err);
|
||||
if (exit_code != 0){ return info; }
|
||||
|
||||
string[] lines = std_out.split("\n");
|
||||
|
||||
int k = 1;
|
||||
if (lines.length == 3){
|
||||
foreach(string part in lines[1].split(" ")){
|
||||
|
||||
if (part.strip().length == 0){ continue; }
|
||||
|
||||
switch(k++){
|
||||
case 1:
|
||||
info.device = part.strip();
|
||||
break;
|
||||
case 2:
|
||||
info.type = part.strip();
|
||||
break;
|
||||
case 3:
|
||||
info.size_mb = long.parse(part.strip().replace("M",""));
|
||||
break;
|
||||
case 4:
|
||||
info.used_mb = long.parse(part.strip().replace("M",""));
|
||||
break;
|
||||
case 5:
|
||||
info.available = part.strip();
|
||||
break;
|
||||
case 6:
|
||||
info.used_percent = part.strip();
|
||||
break;
|
||||
case 7:
|
||||
info.mount_point = part.strip();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach(PartitionInfo pi in get_all_partitions()){
|
||||
if (pi.device == info.device){
|
||||
info.label = pi.label;
|
||||
info.uuid = pi.uuid;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
public Gee.ArrayList<PartitionInfo?> get_mounted_partitions(){
|
||||
|
||||
/* Returns list of mounted partitions */
|
||||
/* Returns list of mounted partitions using 'df' command
|
||||
Populates device, type, size, used and mount_point_list */
|
||||
|
||||
var list = new Gee.ArrayList<PartitionInfo?>();
|
||||
|
||||
@ -514,6 +468,23 @@ namespace TeeJee.DiskPartition{
|
||||
|
||||
if (exit_code != 0){ return list; }
|
||||
|
||||
if (exit_code != 0){
|
||||
log_error ("Failed to get list of partitions");
|
||||
return list; //return empty list
|
||||
}
|
||||
|
||||
/*
|
||||
sample output
|
||||
-----------------
|
||||
Filesystem Type 1M-blocks Used Available Use% Mounted on
|
||||
/dev/sda3 ext4 25070M 19508M 4282M 83% /
|
||||
none tmpfs 1M 0M 1M 0% /sys/fs/cgroup
|
||||
udev devtmpfs 3903M 1M 3903M 1% /dev
|
||||
tmpfs tmpfs 789M 1M 788M 1% /run
|
||||
none tmpfs 5M 0M 5M 0% /run/lock
|
||||
/dev/sda3 ext4 25070M 19508M 4282M 83% /mnt/timeshift
|
||||
*/
|
||||
|
||||
string[] lines = std_out.split("\n");
|
||||
|
||||
int line_num = 0;
|
||||
@ -522,69 +493,197 @@ namespace TeeJee.DiskPartition{
|
||||
if (++line_num == 1) { continue; }
|
||||
if (line.strip().length == 0) { continue; }
|
||||
|
||||
PartitionInfo info = new PartitionInfo();
|
||||
PartitionInfo pi = new PartitionInfo();
|
||||
|
||||
//parse & populate fields ------------------
|
||||
|
||||
int k = 1;
|
||||
foreach(string part in line.split(" ")){
|
||||
foreach(string val in line.split(" ")){
|
||||
|
||||
if (part.strip().length == 0){ continue; }
|
||||
if (val.strip().length == 0){ continue; }
|
||||
|
||||
switch(k++){
|
||||
case 1:
|
||||
info.device = part.strip();
|
||||
pi.device = val.strip();
|
||||
break;
|
||||
case 2:
|
||||
info.type = part.strip();
|
||||
pi.type = val.strip();
|
||||
break;
|
||||
case 3:
|
||||
info.size_mb = long.parse(part.strip().replace("M",""));
|
||||
pi.size_mb = long.parse(val.strip().replace("M",""));
|
||||
break;
|
||||
case 4:
|
||||
info.used_mb = long.parse(part.strip().replace("M",""));
|
||||
pi.used_mb = long.parse(val.strip().replace("M",""));
|
||||
break;
|
||||
case 5:
|
||||
info.available = part.strip();
|
||||
pi.available = val.strip();
|
||||
break;
|
||||
case 6:
|
||||
info.used_percent = part.strip();
|
||||
pi.used_percent = val.strip();
|
||||
break;
|
||||
case 7:
|
||||
info.mount_point = part.strip();
|
||||
string mount_point = val.strip();
|
||||
if (!pi.mount_point_list.contains(mount_point)){
|
||||
pi.mount_point_list.add(mount_point);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
list.add(info);
|
||||
|
||||
//exclude unknown devices
|
||||
if (exclude_unknown){
|
||||
if (!(pi.device.has_prefix("/dev/sd") || pi.device.has_prefix("/dev/hd") || pi.device.has_prefix("/dev/mapper/"))) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
//check for duplicates
|
||||
bool found = false;
|
||||
foreach(PartitionInfo pm in list){
|
||||
if (pm.device == pi.device){
|
||||
//add mount points and continue
|
||||
foreach(string mount_point in pi.mount_point_list){
|
||||
if (!pm.mount_point_list.contains(mount_point)){
|
||||
pm.mount_point_list.add(mount_point);
|
||||
}
|
||||
}
|
||||
found = true;
|
||||
//don't break
|
||||
}
|
||||
}
|
||||
|
||||
//add to list
|
||||
if (!found){
|
||||
list.add(pi);
|
||||
}
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
public Gee.ArrayList<PartitionInfo?> get_all_partitions(){
|
||||
|
||||
public Gee.ArrayList<PartitionInfo?> get_mounted_partitions_using_mount(bool exclude_unknown = true){
|
||||
|
||||
/* Returns list of mounted/unmounted, physical/LVM partitions */
|
||||
/* Returns list of mounted partitions using 'mount' command
|
||||
Populates device, type and mount_point_list */
|
||||
|
||||
var list = new Gee.ArrayList<PartitionInfo?>();
|
||||
|
||||
string std_out = "";
|
||||
string std_err = "";
|
||||
|
||||
int exit_code = execute_command_script_sync("mount", out std_out, out std_err);
|
||||
|
||||
if (exit_code != 0){
|
||||
log_error ("Failed to get list of partitions");
|
||||
return list; //return empty list
|
||||
}
|
||||
|
||||
/*
|
||||
sample output
|
||||
-----------------
|
||||
/dev/sda3 on / type ext4 (rw,errors=remount-ro)
|
||||
proc on /proc type proc (rw,noexec,nosuid,nodev)
|
||||
sysfs on /sys type sysfs (rw,noexec,nosuid,nodev)
|
||||
none on /sys/fs/cgroup type tmpfs (rw)
|
||||
none on /sys/fs/fuse/connections type fusectl (rw)
|
||||
*/
|
||||
|
||||
foreach(string line in std_out.split("\n")){
|
||||
|
||||
if (line.strip().length == 0) { continue; }
|
||||
|
||||
PartitionInfo pi = new PartitionInfo();
|
||||
|
||||
//parse & populate fields ------------------
|
||||
|
||||
int k = 1;
|
||||
foreach(string val in line.split(" ")){
|
||||
if (val.strip().length == 0){ continue; }
|
||||
switch(k++){
|
||||
case 1:
|
||||
pi.device = val.strip();
|
||||
break;
|
||||
case 2:
|
||||
//'on' ignore
|
||||
break;
|
||||
case 3:
|
||||
string mount_point = val.strip();
|
||||
if (!pi.mount_point_list.contains(mount_point)){
|
||||
pi.mount_point_list.add(mount_point);
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
//'type' ignore
|
||||
break;
|
||||
case 5:
|
||||
pi.type = val.strip();
|
||||
break;
|
||||
default:
|
||||
//ignore
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//exclude unknown devices
|
||||
if (exclude_unknown){
|
||||
if (!(pi.device.has_prefix("/dev/sd") || pi.device.has_prefix("/dev/hd") || pi.device.has_prefix("/dev/mapper/"))) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
//check for duplicates
|
||||
bool found = false;
|
||||
foreach(PartitionInfo pm in list){
|
||||
if (pm.device == pi.device){
|
||||
//add mount points and continue
|
||||
foreach(string mount_point in pi.mount_point_list){
|
||||
if (!pm.mount_point_list.contains(mount_point)){
|
||||
pm.mount_point_list.add(mount_point);
|
||||
}
|
||||
}
|
||||
found = true;
|
||||
//don't break
|
||||
}
|
||||
}
|
||||
|
||||
//add to list
|
||||
if (!found){
|
||||
list.add(pi);
|
||||
}
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
public Gee.ArrayList<PartitionInfo?> get_partitions_using_blkid(bool exclude_unknown = true){
|
||||
|
||||
/* Returns list of mounted/unmounted, physical/LVM partitions
|
||||
* Populates device, uuid, type and label */
|
||||
|
||||
var list = new Gee.ArrayList<PartitionInfo?>();
|
||||
var list_mounted = get_mounted_partitions();
|
||||
|
||||
string cmd = "";
|
||||
|
||||
string std_out;
|
||||
string std_err;
|
||||
int ret_val;
|
||||
Regex rex;
|
||||
MatchInfo match;
|
||||
|
||||
ret_val = execute_command_script_sync("/sbin/blkid", out std_out, out std_err);
|
||||
|
||||
if (ret_val != 0){
|
||||
log_error ("Failed to get list of partitions");
|
||||
return list; //return empty list
|
||||
}
|
||||
|
||||
/*
|
||||
sample output
|
||||
-----------------
|
||||
/dev/sda1: LABEL="System Reserved" UUID="F476B08076B04560" TYPE="ntfs"
|
||||
/dev/sda2: LABEL="windows" UUID="BE00B6DB00B69A3B" TYPE="ntfs"
|
||||
/dev/sda3: UUID="03f3f35d-71fa-4dff-b740-9cca19e7555f" TYPE="ext4"
|
||||
*/
|
||||
|
||||
try{
|
||||
|
||||
cmd = "/sbin/blkid";
|
||||
ret_val = execute_command_script_sync(cmd, out std_out, out std_err);
|
||||
|
||||
if (ret_val != 0){
|
||||
log_error ("Failed to get list of partitions");
|
||||
log_error (std_err);
|
||||
return list_mounted; //return list of mounted devices
|
||||
}
|
||||
|
||||
foreach(string line in std_out.split("\n")){
|
||||
if (line.strip().length == 0) { continue; }
|
||||
|
||||
@ -592,16 +691,16 @@ namespace TeeJee.DiskPartition{
|
||||
|
||||
pi.device = line.split(":")[0].strip();
|
||||
|
||||
if (pi.device.length == 0) {
|
||||
continue;
|
||||
if (pi.device.length == 0) { continue; }
|
||||
|
||||
//exclude unknown devices
|
||||
if (exclude_unknown){
|
||||
if (!(pi.device.has_prefix("/dev/sd") || pi.device.has_prefix("/dev/hd") || pi.device.has_prefix("/dev/mapper/"))) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (pi.device.has_prefix("/dev/sd") || pi.device.has_prefix("/dev/hd") || pi.device.has_prefix("/dev/mapper/")) {
|
||||
//ok
|
||||
}
|
||||
else{
|
||||
continue;
|
||||
}
|
||||
//parse & populate fields ------------------
|
||||
|
||||
rex = new Regex("""LABEL=\"([^\"]*)\"""");
|
||||
if (rex.match (line, 0, out match)){
|
||||
@ -618,17 +717,25 @@ namespace TeeJee.DiskPartition{
|
||||
pi.type = match.fetch(1).strip();
|
||||
}
|
||||
|
||||
//get usage info
|
||||
foreach(PartitionInfo pm in list_mounted){
|
||||
//check for duplicates
|
||||
bool found = false;
|
||||
foreach(PartitionInfo pm in list){
|
||||
if (pm.device == pi.device){
|
||||
pi.size_mb = pm.size_mb;
|
||||
pi.used_mb = pm.used_mb;
|
||||
pi.used_percent = pm.used_percent;
|
||||
pi.mount_point = pm.mount_point;
|
||||
//add mount points and continue
|
||||
foreach(string mount_point in pi.mount_point_list){
|
||||
if (!pm.mount_point_list.contains(mount_point)){
|
||||
pm.mount_point_list.add(mount_point);
|
||||
}
|
||||
}
|
||||
found = true;
|
||||
//don't break
|
||||
}
|
||||
}
|
||||
|
||||
list.add(pi);
|
||||
//add to list
|
||||
if (!found){
|
||||
list.add(pi);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch(Error e){
|
||||
@ -637,7 +744,118 @@ namespace TeeJee.DiskPartition{
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
|
||||
public Gee.ArrayList<PartitionInfo?> get_all_partitions(bool exclude_unknown = true, bool get_usage = true){
|
||||
|
||||
/* Returns list of mounted/unmounted, physical/logical partitions */
|
||||
|
||||
var list = new Gee.ArrayList<PartitionInfo?>();
|
||||
|
||||
// get initial list --------
|
||||
|
||||
var list_blkid = get_partitions_using_blkid(exclude_unknown);
|
||||
|
||||
foreach (PartitionInfo pi in list_blkid){
|
||||
list.add(pi);
|
||||
}
|
||||
|
||||
// add more devices ----------
|
||||
|
||||
var list_mount = get_mounted_partitions_using_mount(exclude_unknown);
|
||||
|
||||
foreach (PartitionInfo pm in list_mount){
|
||||
bool found = false;
|
||||
|
||||
foreach (PartitionInfo pi in list){
|
||||
if (pi.device == pm.device){
|
||||
//add more mount points
|
||||
foreach(string mount_point in pm.mount_point_list){
|
||||
if (!pi.mount_point_list.contains(mount_point)){
|
||||
pi.mount_point_list.add(mount_point);
|
||||
}
|
||||
}
|
||||
found = true;
|
||||
//don't break
|
||||
}
|
||||
}
|
||||
|
||||
if(!found){
|
||||
list.add(pm);
|
||||
}
|
||||
}
|
||||
|
||||
// get usage info -------------
|
||||
|
||||
if (get_usage){
|
||||
|
||||
var list_df = get_mounted_partitions_using_df(exclude_unknown);
|
||||
|
||||
for(int k = 0; k < list.size; k++){
|
||||
PartitionInfo pi = list[k];
|
||||
foreach(PartitionInfo pm in list_df){
|
||||
if (pm.device == pi.device){
|
||||
pi.size_mb = pm.size_mb;
|
||||
pi.used_mb = pm.used_mb;
|
||||
pi.used_percent = pm.used_percent;
|
||||
|
||||
foreach(string mount_point in pm.mount_point_list){
|
||||
if (!pi.mount_point_list.contains(mount_point)){
|
||||
pi.mount_point_list.add(mount_point);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
public PartitionInfo refresh_partition_usage_info(PartitionInfo pi){
|
||||
|
||||
/* Updates and returns the given PartitionInfo object */
|
||||
|
||||
string std_out = "";
|
||||
string std_err = "";
|
||||
|
||||
int exit_code = execute_command_script_sync("df -T -BM \"" + pi.device + "\"| uniq -w 12", out std_out, out std_err);
|
||||
|
||||
if (exit_code != 0){
|
||||
return pi;
|
||||
}
|
||||
|
||||
string[] lines = std_out.split("\n");
|
||||
|
||||
int k = 1;
|
||||
if (lines.length == 3){
|
||||
foreach(string part in lines[1].split(" ")){
|
||||
|
||||
if (part.strip().length == 0){ continue; }
|
||||
|
||||
switch(k++){
|
||||
case 3:
|
||||
pi.size_mb = long.parse(part.strip().replace("M",""));
|
||||
break;
|
||||
case 4:
|
||||
pi.used_mb = long.parse(part.strip().replace("M",""));
|
||||
break;
|
||||
case 5:
|
||||
pi.available = part.strip();
|
||||
break;
|
||||
case 6:
|
||||
pi.used_percent = part.strip();
|
||||
break;
|
||||
default:
|
||||
//ignore
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return pi;
|
||||
}
|
||||
|
||||
|
||||
public bool mount(string device, string mount_point, string mount_options = ""){
|
||||
|
||||
/* Mounts specified device at specified mount point.
|
||||
@ -658,24 +876,24 @@ namespace TeeJee.DiskPartition{
|
||||
|
||||
//check if mounted
|
||||
bool mounted = false;
|
||||
foreach(PartitionInfo info in get_mounted_partitions()){
|
||||
foreach(PartitionInfo info in get_mounted_partitions_using_df()){
|
||||
|
||||
if (info.mount_point == mount_point && info.device == device){
|
||||
if (info.mount_point_list.contains(mount_point) && info.device == device){
|
||||
//device is already mounted at mount point
|
||||
mounted = true;
|
||||
break;
|
||||
}
|
||||
else if (info.mount_point == mount_point && info.device != device){
|
||||
else if (info.mount_point_list.contains(mount_point) && info.device != device){
|
||||
//another device is mounted at mount point - unmount it -------
|
||||
cmd = "sudo umount \"%s\"".printf(mount_point);
|
||||
Process.spawn_command_line_sync(cmd, out std_out, out std_err, out ret_val);
|
||||
if (ret_val != 0){
|
||||
log_error ("Failed to unmount device '%s' from mount point '%s'".printf(info.device, info.mount_point));
|
||||
log_error ("Failed to unmount device '%s' from mount point '%s'".printf(info.device, mount_point));
|
||||
log_error (std_err);
|
||||
return false;
|
||||
}
|
||||
else{
|
||||
log_msg ("Unmounted device '%s' from mount point '%s'".printf(info.device, info.mount_point));
|
||||
log_msg ("Unmounted device '%s' from mount point '%s'".printf(info.device, mount_point));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -717,10 +935,10 @@ namespace TeeJee.DiskPartition{
|
||||
|
||||
try{
|
||||
//check if mounted and unmount
|
||||
foreach(PartitionInfo info in get_mounted_partitions()){
|
||||
if (info.mount_point == mount_point){
|
||||
foreach(PartitionInfo info in get_mounted_partitions_using_df()){
|
||||
if (info.mount_point_list.contains(mount_point)){
|
||||
|
||||
log_msg(_("Unmounting device") + " '%s' ".printf(info.device) + _("from") + " '%s'".printf(info.mount_point));
|
||||
log_msg(_("Unmounting device") + " '%s' ".printf(info.device) + _("from") + " '%s'".printf(mount_point));
|
||||
|
||||
//sync before unmount
|
||||
cmd = "sync";
|
||||
@ -761,7 +979,7 @@ namespace TeeJee.DiskPartition{
|
||||
Process.spawn_command_line_sync(cmd, out std_out, out std_err, out ret_val);
|
||||
|
||||
if (ret_val != 0){
|
||||
log_error (_("Failed to unmount device") + " '%s' ".printf(info.device) + _("from") + " '%s'".printf(info.mount_point));
|
||||
log_error (_("Failed to unmount device") + " '%s' ".printf(info.device) + _("from") + " '%s'".printf(mount_point));
|
||||
log_error (std_err);
|
||||
quit_app = true;
|
||||
}
|
||||
@ -788,6 +1006,7 @@ namespace TeeJee.DiskPartition{
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public Gee.ArrayList<DeviceInfo> get_block_devices(){
|
||||
|
||||
/* Returns a list of all storage devices including vendor and model number */
|
||||
@ -924,7 +1143,7 @@ namespace TeeJee.ProcessManagement{
|
||||
}
|
||||
}
|
||||
|
||||
public bool execute_command_async (string cmd){
|
||||
public bool execute_command_script_async (string cmd){
|
||||
|
||||
/* Creates a temporary bash script with given commands and executes it asynchronously
|
||||
* Return value indicates if script was started successfully */
|
||||
@ -1561,28 +1780,28 @@ namespace TeeJee.System{
|
||||
|
||||
path = get_cmd_path ("exo-open");
|
||||
if ((path != null)&&(path != "")){
|
||||
return execute_command_async ("exo-open \"" + dir_path + "\"");
|
||||
return execute_command_script_async ("exo-open \"" + dir_path + "\"");
|
||||
}
|
||||
|
||||
path = get_cmd_path ("nemo");
|
||||
if ((path != null)&&(path != "")){
|
||||
return execute_command_async ("nemo \"" + dir_path + "\"");
|
||||
return execute_command_script_async ("nemo \"" + dir_path + "\"");
|
||||
}
|
||||
|
||||
path = get_cmd_path ("nautilus");
|
||||
if ((path != null)&&(path != "")){
|
||||
return execute_command_async ("nautilus \"" + dir_path + "\"");
|
||||
return execute_command_script_async ("nautilus \"" + dir_path + "\"");
|
||||
}
|
||||
|
||||
path = get_cmd_path ("thunar");
|
||||
if ((path != null)&&(path != "")){
|
||||
return execute_command_async ("thunar \"" + dir_path + "\"");
|
||||
return execute_command_script_async ("thunar \"" + dir_path + "\"");
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public int exo_open_textfile (string txt){
|
||||
public bool exo_open_textfile (string txt){
|
||||
|
||||
/* Tries to open the given text file in a text editor */
|
||||
|
||||
@ -1590,15 +1809,15 @@ namespace TeeJee.System{
|
||||
|
||||
path = get_cmd_path ("exo-open");
|
||||
if ((path != null)&&(path != "")){
|
||||
return execute_command_sync ("exo-open \"" + txt + "\"");
|
||||
return execute_command_script_async ("exo-open \"" + txt + "\"");
|
||||
}
|
||||
|
||||
path = get_cmd_path ("gedit");
|
||||
if ((path != null)&&(path != "")){
|
||||
return execute_command_sync ("gedit --new-document \"" + txt + "\"");
|
||||
return execute_command_script_async ("gedit --new-document \"" + txt + "\"");
|
||||
}
|
||||
|
||||
return -1;
|
||||
return false;
|
||||
}
|
||||
|
||||
public int notify_send (string title, string message, int durationMillis, string urgency){
|
||||
|
@ -18,19 +18,16 @@ long_line_column=80
|
||||
|
||||
[files]
|
||||
current_page=4
|
||||
FILE_NAME_0=40439;Vala;0;16;1;1;0;%2Fhome%2Fteejee%2Fprojects%2Ftimeshift%2Fsrc%2FMain.vala;0;4
|
||||
FILE_NAME_1=23471;Vala;0;16;1;1;0;%2Fhome%2Fteejee%2Fprojects%2Ftimeshift%2Fsrc%2FMainWindow.vala;0;4
|
||||
FILE_NAME_2=1060;Vala;0;16;1;1;0;%2Fhome%2Fteejee%2Fprojects%2Ftimeshift%2Fsrc%2FSettingsWindow.vala;0;4
|
||||
FILE_NAME_0=53968;Vala;0;16;1;1;0;%2Fhome%2Fteejee%2Fprojects%2Ftimeshift%2Fsrc%2FMain.vala;0;4
|
||||
FILE_NAME_1=19193;Vala;0;16;1;1;0;%2Fhome%2Fteejee%2Fprojects%2Ftimeshift%2Fsrc%2FMainWindow.vala;0;4
|
||||
FILE_NAME_2=28267;Vala;0;16;1;1;0;%2Fhome%2Fteejee%2Fprojects%2Ftimeshift%2Fsrc%2FSettingsWindow.vala;0;4
|
||||
FILE_NAME_3=25774;Vala;0;16;1;1;0;%2Fhome%2Fteejee%2Fprojects%2Ftimeshift%2Fsrc%2FRestoreWindow.vala;0;4
|
||||
FILE_NAME_4=15252;Vala;0;16;1;1;0;%2Fhome%2Fteejee%2Fprojects%2Ftimeshift%2Fsrc%2FUtility.vala;0;4
|
||||
FILE_NAME_4=21728;Vala;0;16;1;1;0;%2Fhome%2Fteejee%2Fprojects%2Ftimeshift%2Fsrc%2FUtility.vala;0;4
|
||||
FILE_NAME_5=708;Make;0;16;1;1;0;%2Fhome%2Fteejee%2Fprojects%2Ftimeshift%2Fsrc%2Fmakefile;0;4
|
||||
FILE_NAME_6=410;Conf;0;16;1;1;0;%2Fhome%2Fteejee%2Fprojects%2Ftimeshift%2Fdebian%2Fcontrol;0;4
|
||||
FILE_NAME_7=172;None;0;16;1;1;0;%2Fhome%2Fteejee%2Fprojects%2Ftimeshift%2Fdebian%2Fchangelog;0;4
|
||||
FILE_NAME_8=559;Sh;0;16;1;1;0;%2Fhome%2Fteejee%2Fprojects%2Ftimeshift%2Finstaller%2Finstall.sh;0;4
|
||||
FILE_NAME_9=402;Sh;0;16;1;1;0;%2Fhome%2Fteejee%2Fprojects%2Ftimeshift%2Fbuild-installer.sh;0;4
|
||||
FILE_NAME_10=370;Sh;0;16;1;1;0;%2Fhome%2Fteejee%2Fprojects%2Ftimeshift%2Fupdate-pot.sh;0;4
|
||||
FILE_NAME_11=0;Sh;0;16;1;1;0;%2Fhome%2Fteejee%2Fprojects%2Ftimeshift%2Fpush.sh;0;4
|
||||
FILE_NAME_12=1066;Vala;0;16;1;1;0;%2Fhome%2Fteejee%2Fprojects%2Ftimeshift%2Fsrc%2FExcludeMessageWindow.vala;0;4
|
||||
FILE_NAME_8=1691;Vala;0;16;1;1;0;%2Fhome%2Fteejee%2Fprojects%2Ftimeshift%2Fsrc%2FExcludeMessageWindow.vala;0;4
|
||||
FILE_NAME_9=1413;Vala;0;16;1;1;0;%2Fhome%2Fteejee%2Fprojects%2Futility%2FUtility.vala;0;4
|
||||
|
||||
[VTE]
|
||||
last_dir=/home/teejee
|
||||
|
@ -8,4 +8,10 @@ echo "Updating translation templates..."
|
||||
|
||||
xgettext --language=C --keyword=_ --copyright-holder='Tony George (teejee2008@gmail.com)' --package-name='timeshift' --package-version='1.1' --msgid-bugs-address='teejee2008@gmail.com' --escape --sort-output -o timeshift.pot src/*.vala
|
||||
|
||||
#check for errors
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Failed"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cd "$backup"
|
||||
|
Loading…
Reference in New Issue
Block a user