~teejee2008/timeshift/trunk

« back to all changes in this revision

Viewing changes to src/Utility.vala

  • Committer: Tony George
  • Date: 2013-10-24 15:11:55 UTC
  • Revision ID: teejee2008@gmail.com-20131024151155-3phu9mo26k2oflxq
Improved detection of disk partitions

Show diffs side-by-side

added added

removed removed

Lines of Context:
23
23
 
24
24
using Gtk;
25
25
using Json;
26
 
 
27
 
/*
28
26
using TeeJee.Logging;
29
27
using TeeJee.FileSystem;
30
28
using TeeJee.DiskPartition;
35
33
using TeeJee.System;
36
34
using TeeJee.Misc;
37
35
 
 
36
/*
38
37
extern void exit(int exit_code);
39
 
 
40
 
public static int main (string[] args) {
41
 
        return 0;
42
 
}
43
38
*/
44
39
 
45
40
namespace TeeJee.Logging{
344
339
                public string uuid = "";
345
340
                public string available = "";
346
341
                public string used_percent = "";
347
 
                public string mount_point = "";
348
342
                public string dist_info = "";
 
343
                public Gee.ArrayList<string> mount_point_list;
 
344
                
 
345
                public PartitionInfo(){
 
346
                        mount_point_list = new Gee.ArrayList<string>();
 
347
                }
349
348
                
350
349
                public string description(){
351
350
                        string s = "";
352
351
                        s += device;
353
352
                        s += (type.length > 0) ? " ~ " + type : "";
354
 
                        s += (used.length > 0) ? " ~ " + used + " / " + size + " used (" + used_percent + ")" : "";
 
353
                        s += (used.length > 0) ? " ~ " + used + " / " + size + " GB used (" + used_percent + ")" : "";
355
354
                        return s;
356
355
                }
357
356
                
358
 
                public string description_device(){
 
357
                public string description_full(){
359
358
                        string s = "";
360
359
                        s += device;
361
 
                        s += (uuid.length == 0) ? "" : ", UUID=" + uuid;
 
360
                        s += (uuid.length > 0) ? " ~ " + uuid : "";
 
361
                        s += (type.length > 0) ? " ~ " + type : "";
 
362
                        s += (used.length > 0) ? " ~ " + used + " / " + size + " GB used (" + used_percent + ")" : "";
 
363
                        
 
364
                        string mps = "";
 
365
                        foreach(string mp in mount_point_list){
 
366
                                mps += mp + " ";
 
367
                        }
 
368
                        s += (mps.length > 0) ? " ~ " + mps.strip() : "";
 
369
                        
362
370
                        return s;
363
371
                }
364
372
                
373
381
                
374
382
                public string size{
375
383
                        owned get{
376
 
                                return (size_mb == 0) ? "" : "%.1f GB".printf(size_mb/1024.0);
 
384
                                return (size_mb == 0) ? "" : "%.1f".printf(size_mb/1024.0);
377
385
                        }
378
386
                }
379
387
                
380
388
                public string used{
381
389
                        owned get{
382
 
                                return (used_mb == 0) ? "" : "%.1f GB".printf(used_mb/1024.0);
 
390
                                return (used_mb == 0) ? "" : "%.1f".printf(used_mb/1024.0);
383
391
                        }
384
392
                }
385
393
                
391
399
                
392
400
                public bool is_mounted{
393
401
                        get{
394
 
                                return (mount_point.length > 0);
 
402
                                return (mount_point_list.size > 0);
395
403
                        }
396
404
                }
397
405
                
446
454
                }
447
455
        }
448
456
 
449
 
        public PartitionInfo get_partition_info(string path){
450
 
                
451
 
                /* Returns partition info for specified path or device name */
452
 
 
453
 
                PartitionInfo info = new PartitionInfo();
454
 
                
455
 
                string std_out = "";
456
 
                string std_err = "";
457
 
                int exit_code = execute_command_script_sync("df -T -BM \"" + path + "\"| uniq -w 12", out std_out, out std_err);
458
 
                if (exit_code != 0){ return info; }
459
 
 
460
 
                string[] lines = std_out.split("\n");
461
 
 
462
 
                int k = 1;
463
 
                if (lines.length == 3){
464
 
                        foreach(string part in lines[1].split(" ")){
465
 
                                
466
 
                                if (part.strip().length == 0){ continue; }
467
 
                                
468
 
                                switch(k++){
469
 
                                        case 1:
470
 
                                                info.device = part.strip();
471
 
                                                break;
472
 
                                        case 2:
473
 
                                                info.type = part.strip();
474
 
                                                break;
475
 
                                        case 3:
476
 
                                                info.size_mb = long.parse(part.strip().replace("M",""));
477
 
                                                break;
478
 
                                        case 4:
479
 
                                                info.used_mb = long.parse(part.strip().replace("M",""));
480
 
                                                break;
481
 
                                        case 5:
482
 
                                                info.available = part.strip();
483
 
                                                break;
484
 
                                        case 6:
485
 
                                                info.used_percent = part.strip();
486
 
                                                break;
487
 
                                        case 7:
488
 
                                                info.mount_point = part.strip();
489
 
                                                break;
490
 
                                }
491
 
                        }
492
 
                }
493
 
 
494
 
                foreach(PartitionInfo pi in get_all_partitions()){
495
 
                        if (pi.device == info.device){
496
 
                                info.label = pi.label;
497
 
                                info.uuid = pi.uuid;
498
 
                                break;
499
 
                        }
500
 
                }
501
 
                
502
 
                return info;
503
 
        }
504
 
 
505
 
        public Gee.ArrayList<PartitionInfo?> get_mounted_partitions(){
506
 
                
507
 
                /* Returns list of mounted partitions */
 
457
 
 
458
        public Gee.ArrayList<PartitionInfo?> get_mounted_partitions_using_df(bool exclude_unknown = true){
 
459
                
 
460
                /* Returns list of mounted partitions using 'df' command 
 
461
                   Populates device, type, size, used and mount_point_list */
508
462
                 
509
463
                var list = new Gee.ArrayList<PartitionInfo?>();
510
464
                
514
468
                
515
469
                if (exit_code != 0){ return list; }
516
470
                
 
471
                if (exit_code != 0){ 
 
472
                        log_error ("Failed to get list of partitions");
 
473
                        return list; //return empty list
 
474
                }
 
475
                
 
476
                /*
 
477
                sample output
 
478
                -----------------
 
479
                Filesystem     Type     1M-blocks    Used Available Use% Mounted on
 
480
                /dev/sda3      ext4        25070M  19508M     4282M  83% /
 
481
                none           tmpfs           1M      0M        1M   0% /sys/fs/cgroup
 
482
                udev           devtmpfs     3903M      1M     3903M   1% /dev
 
483
                tmpfs          tmpfs         789M      1M      788M   1% /run
 
484
                none           tmpfs           5M      0M        5M   0% /run/lock
 
485
                /dev/sda3      ext4        25070M  19508M     4282M  83% /mnt/timeshift
 
486
                */
 
487
                
517
488
                string[] lines = std_out.split("\n");
518
489
 
519
490
                int line_num = 0;
522
493
                        if (++line_num == 1) { continue; }
523
494
                        if (line.strip().length == 0) { continue; }
524
495
                        
525
 
                        PartitionInfo info = new PartitionInfo();
 
496
                        PartitionInfo pi = new PartitionInfo();
 
497
                        
 
498
                        //parse & populate fields ------------------
526
499
                        
527
500
                        int k = 1;
528
 
                        foreach(string part in line.split(" ")){
 
501
                        foreach(string val in line.split(" ")){
529
502
                                
530
 
                                if (part.strip().length == 0){ continue; }
 
503
                                if (val.strip().length == 0){ continue; }
531
504
 
532
505
                                switch(k++){
533
506
                                        case 1:
534
 
                                                info.device = part.strip();
 
507
                                                pi.device = val.strip();
535
508
                                                break;
536
509
                                        case 2:
537
 
                                                info.type = part.strip();
 
510
                                                pi.type = val.strip();
538
511
                                                break;
539
512
                                        case 3:
540
 
                                                info.size_mb = long.parse(part.strip().replace("M",""));
 
513
                                                pi.size_mb = long.parse(val.strip().replace("M",""));
541
514
                                                break;
542
515
                                        case 4:
543
 
                                                info.used_mb = long.parse(part.strip().replace("M",""));
 
516
                                                pi.used_mb = long.parse(val.strip().replace("M",""));
544
517
                                                break;
545
518
                                        case 5:
546
 
                                                info.available = part.strip();
 
519
                                                pi.available = val.strip();
547
520
                                                break;
548
521
                                        case 6:
549
 
                                                info.used_percent = part.strip();
 
522
                                                pi.used_percent = val.strip();
550
523
                                                break;
551
524
                                        case 7:
552
 
                                                info.mount_point = part.strip();
553
 
                                                break;
554
 
                                }
555
 
                        }
556
 
 
557
 
                        list.add(info);
558
 
                }
559
 
                
 
525
                                                string mount_point = val.strip();
 
526
                                                if (!pi.mount_point_list.contains(mount_point)){
 
527
                                                        pi.mount_point_list.add(mount_point);
 
528
                                                }
 
529
                                                break;
 
530
                                }
 
531
                        }
 
532
                        
 
533
                        //exclude unknown devices
 
534
                        if (exclude_unknown){
 
535
                                if (!(pi.device.has_prefix("/dev/sd") || pi.device.has_prefix("/dev/hd") || pi.device.has_prefix("/dev/mapper/"))) { 
 
536
                                        continue;
 
537
                                }
 
538
                        }
 
539
                        
 
540
                        //check for duplicates
 
541
                        bool found = false;
 
542
                        foreach(PartitionInfo pm in list){
 
543
                                if (pm.device == pi.device){
 
544
                                        //add mount points and continue
 
545
                                        foreach(string mount_point in pi.mount_point_list){
 
546
                                                if (!pm.mount_point_list.contains(mount_point)){
 
547
                                                        pm.mount_point_list.add(mount_point);
 
548
                                                }
 
549
                                        }
 
550
                                        found = true;
 
551
                                        //don't break
 
552
                                }
 
553
                        }
 
554
                        
 
555
                        //add to list
 
556
                        if (!found){
 
557
                                list.add(pi);
 
558
                        }
 
559
                }
 
560
                
 
561
                return list;
 
562
        }
 
563
 
 
564
        public Gee.ArrayList<PartitionInfo?> get_mounted_partitions_using_mount(bool exclude_unknown = true){
 
565
                
 
566
                /* Returns list of mounted partitions using 'mount' command 
 
567
                   Populates device, type and mount_point_list */
 
568
 
 
569
                var list = new Gee.ArrayList<PartitionInfo?>();
 
570
                
 
571
                string std_out = "";
 
572
                string std_err = "";
 
573
                
 
574
                int exit_code = execute_command_script_sync("mount", out std_out, out std_err);
 
575
 
 
576
                if (exit_code != 0){ 
 
577
                        log_error ("Failed to get list of partitions");
 
578
                        return list; //return empty list
 
579
                }
 
580
                
 
581
                /*
 
582
                sample output
 
583
                -----------------
 
584
                /dev/sda3 on / type ext4 (rw,errors=remount-ro)
 
585
                proc on /proc type proc (rw,noexec,nosuid,nodev)
 
586
                sysfs on /sys type sysfs (rw,noexec,nosuid,nodev)
 
587
                none on /sys/fs/cgroup type tmpfs (rw)
 
588
                none on /sys/fs/fuse/connections type fusectl (rw)
 
589
                */
 
590
                                
 
591
                foreach(string line in std_out.split("\n")){
 
592
 
 
593
                        if (line.strip().length == 0) { continue; }
 
594
                        
 
595
                        PartitionInfo pi = new PartitionInfo();
 
596
 
 
597
                        //parse & populate fields ------------------
 
598
                                                        
 
599
                        int k = 1;
 
600
                        foreach(string val in line.split(" ")){
 
601
                                if (val.strip().length == 0){ continue; }
 
602
                                switch(k++){
 
603
                                        case 1:
 
604
                                                pi.device = val.strip();
 
605
                                                break;
 
606
                                        case 2:
 
607
                                                //'on' ignore
 
608
                                                break;
 
609
                                        case 3:
 
610
                                                string mount_point = val.strip();
 
611
                                                if (!pi.mount_point_list.contains(mount_point)){
 
612
                                                        pi.mount_point_list.add(mount_point);
 
613
                                                }
 
614
                                                break;
 
615
                                        case 4:
 
616
                                                //'type' ignore
 
617
                                                break;
 
618
                                        case 5:
 
619
                                                pi.type = val.strip();
 
620
                                                break;
 
621
                                        default:
 
622
                                                //ignore
 
623
                                                break;
 
624
                                }
 
625
                        }
 
626
                        
 
627
                        //exclude unknown devices
 
628
                        if (exclude_unknown){
 
629
                                if (!(pi.device.has_prefix("/dev/sd") || pi.device.has_prefix("/dev/hd") || pi.device.has_prefix("/dev/mapper/"))) { 
 
630
                                        continue;
 
631
                                }
 
632
                        }
 
633
 
 
634
                        //check for duplicates
 
635
                        bool found = false;
 
636
                        foreach(PartitionInfo pm in list){
 
637
                                if (pm.device == pi.device){
 
638
                                        //add mount points and continue
 
639
                                        foreach(string mount_point in pi.mount_point_list){
 
640
                                                if (!pm.mount_point_list.contains(mount_point)){
 
641
                                                        pm.mount_point_list.add(mount_point);
 
642
                                                }
 
643
                                        }
 
644
                                        found = true;
 
645
                                        //don't break
 
646
                                }
 
647
                        }
 
648
                        
 
649
                        //add to list
 
650
                        if (!found){
 
651
                                list.add(pi);
 
652
                        }
 
653
                }
 
654
 
560
655
                return list;
561
656
        }
562
657
        
563
 
        public Gee.ArrayList<PartitionInfo?> get_all_partitions(){
 
658
        public Gee.ArrayList<PartitionInfo?> get_partitions_using_blkid(bool exclude_unknown = true){
564
659
                
565
 
                /* Returns list of mounted/unmounted, physical/LVM partitions */
 
660
                /* Returns list of mounted/unmounted, physical/LVM partitions 
 
661
                 * Populates device, uuid, type and label */
566
662
                
567
663
                var list = new Gee.ArrayList<PartitionInfo?>();
568
 
                var list_mounted = get_mounted_partitions();
569
 
                
570
 
                string cmd = "";
 
664
 
571
665
                string std_out;
572
666
                string std_err;
573
667
                int ret_val;
574
668
                Regex rex;
575
669
                MatchInfo match;
576
670
                        
 
671
                ret_val = execute_command_script_sync("/sbin/blkid", out std_out, out std_err);
 
672
                
 
673
                if (ret_val != 0){
 
674
                        log_error ("Failed to get list of partitions");
 
675
                        return list; //return empty list
 
676
                }
 
677
                        
 
678
                /*
 
679
                sample output
 
680
                -----------------
 
681
                /dev/sda1: LABEL="System Reserved" UUID="F476B08076B04560" TYPE="ntfs" 
 
682
                /dev/sda2: LABEL="windows" UUID="BE00B6DB00B69A3B" TYPE="ntfs" 
 
683
                /dev/sda3: UUID="03f3f35d-71fa-4dff-b740-9cca19e7555f" TYPE="ext4"
 
684
                */
 
685
                
577
686
                try{
578
 
                        
579
 
                        cmd = "/sbin/blkid";
580
 
                        ret_val = execute_command_script_sync(cmd, out std_out, out std_err);
581
 
                        
582
 
                        if (ret_val != 0){
583
 
                                log_error ("Failed to get list of partitions");
584
 
                                log_error (std_err);
585
 
                                return list_mounted; //return list of mounted devices
586
 
                        }
587
 
 
588
687
                        foreach(string line in std_out.split("\n")){
589
688
                                if (line.strip().length == 0) { continue; }
590
689
                                
592
691
                                
593
692
                                pi.device = line.split(":")[0].strip();
594
693
                                
595
 
                                if (pi.device.length == 0) { 
596
 
                                        continue; 
597
 
                                }
598
 
                                
599
 
                                if (pi.device.has_prefix("/dev/sd") || pi.device.has_prefix("/dev/hd") || pi.device.has_prefix("/dev/mapper/")) { 
600
 
                                        //ok
601
 
                                }
602
 
                                else{
603
 
                                        continue; 
604
 
                                }
 
694
                                if (pi.device.length == 0) { continue; }
 
695
                                
 
696
                                //exclude unknown devices
 
697
                                if (exclude_unknown){
 
698
                                        if (!(pi.device.has_prefix("/dev/sd") || pi.device.has_prefix("/dev/hd") || pi.device.has_prefix("/dev/mapper/"))) { 
 
699
                                                continue;
 
700
                                        }
 
701
                                }
 
702
                                
 
703
                                //parse & populate fields ------------------
605
704
                                
606
705
                                rex = new Regex("""LABEL=\"([^\"]*)\"""");
607
706
                                if (rex.match (line, 0, out match)){
618
717
                                        pi.type = match.fetch(1).strip();
619
718
                                }
620
719
                                
621
 
                                //get usage info 
622
 
                                foreach(PartitionInfo pm in list_mounted){
 
720
                                //check for duplicates
 
721
                                bool found = false;
 
722
                                foreach(PartitionInfo pm in list){
 
723
                                        if (pm.device == pi.device){
 
724
                                                //add mount points and continue
 
725
                                                foreach(string mount_point in pi.mount_point_list){
 
726
                                                        if (!pm.mount_point_list.contains(mount_point)){
 
727
                                                                pm.mount_point_list.add(mount_point);
 
728
                                                        }
 
729
                                                }
 
730
                                                found = true;
 
731
                                                //don't break
 
732
                                        }
 
733
                                }
 
734
                                
 
735
                                //add to list
 
736
                                if (!found){
 
737
                                        list.add(pi);
 
738
                                }
 
739
                        }
 
740
                }
 
741
                catch(Error e){
 
742
                log_error (e.message);
 
743
            }
 
744
 
 
745
                return list;
 
746
        }
 
747
 
 
748
        public Gee.ArrayList<PartitionInfo?> get_all_partitions(bool exclude_unknown = true, bool get_usage = true){
 
749
                
 
750
                /* Returns list of mounted/unmounted, physical/logical partitions */
 
751
                
 
752
                var list = new Gee.ArrayList<PartitionInfo?>();
 
753
 
 
754
                // get initial list --------
 
755
                
 
756
                var list_blkid = get_partitions_using_blkid(exclude_unknown);
 
757
                
 
758
                foreach (PartitionInfo pi in list_blkid){
 
759
                        list.add(pi);
 
760
                }
 
761
                
 
762
                // add more devices ----------
 
763
 
 
764
                var list_mount = get_mounted_partitions_using_mount(exclude_unknown);
 
765
                
 
766
                foreach (PartitionInfo pm in list_mount){
 
767
                        bool found = false;
 
768
                        
 
769
                        foreach (PartitionInfo pi in list){
 
770
                                if (pi.device == pm.device){
 
771
                                        //add more mount points
 
772
                                        foreach(string mount_point in pm.mount_point_list){
 
773
                                                if (!pi.mount_point_list.contains(mount_point)){
 
774
                                                        pi.mount_point_list.add(mount_point);
 
775
                                                }
 
776
                                        }
 
777
                                        found = true;
 
778
                                        //don't break
 
779
                                }
 
780
                        }
 
781
                        
 
782
                        if(!found){
 
783
                                list.add(pm);
 
784
                        }
 
785
                }
 
786
                
 
787
                // get usage info -------------
 
788
 
 
789
                if (get_usage){
 
790
                        
 
791
                        var list_df = get_mounted_partitions_using_df(exclude_unknown);
 
792
 
 
793
                        for(int k = 0; k < list.size; k++){
 
794
                                PartitionInfo pi = list[k];
 
795
                                foreach(PartitionInfo pm in list_df){
623
796
                                        if (pm.device == pi.device){
624
797
                                                pi.size_mb = pm.size_mb;
625
798
                                                pi.used_mb = pm.used_mb;
626
799
                                                pi.used_percent = pm.used_percent;
627
 
                                                pi.mount_point = pm.mount_point;
 
800
                                                
 
801
                                                foreach(string mount_point in pm.mount_point_list){
 
802
                                                        if (!pi.mount_point_list.contains(mount_point)){
 
803
                                                                pi.mount_point_list.add(mount_point);
 
804
                                                        }
 
805
                                                }
628
806
                                        }
629
807
                                }
630
 
                                
631
 
                                list.add(pi);
632
808
                        }
633
809
                }
634
 
                catch(Error e){
635
 
                log_error (e.message);
636
 
            }
637
 
 
 
810
                
638
811
                return list;
639
812
        }
640
 
        
 
813
 
 
814
        public PartitionInfo refresh_partition_usage_info(PartitionInfo pi){
 
815
                
 
816
                /* Updates and returns the given PartitionInfo object */
 
817
 
 
818
                string std_out = "";
 
819
                string std_err = "";
 
820
                
 
821
                int exit_code = execute_command_script_sync("df -T -BM \"" + pi.device + "\"| uniq -w 12", out std_out, out std_err);
 
822
                
 
823
                if (exit_code != 0){ 
 
824
                        return pi; 
 
825
                }
 
826
 
 
827
                string[] lines = std_out.split("\n");
 
828
 
 
829
                int k = 1;
 
830
                if (lines.length == 3){
 
831
                        foreach(string part in lines[1].split(" ")){
 
832
                                
 
833
                                if (part.strip().length == 0){ continue; }
 
834
                                
 
835
                                switch(k++){
 
836
                                        case 3:
 
837
                                                pi.size_mb = long.parse(part.strip().replace("M",""));
 
838
                                                break;
 
839
                                        case 4:
 
840
                                                pi.used_mb = long.parse(part.strip().replace("M",""));
 
841
                                                break;
 
842
                                        case 5:
 
843
                                                pi.available = part.strip();
 
844
                                                break;
 
845
                                        case 6:
 
846
                                                pi.used_percent = part.strip();
 
847
                                                break;
 
848
                                        default:
 
849
                                                //ignore
 
850
                                                break;
 
851
                                }
 
852
                        }
 
853
                }
 
854
 
 
855
                return pi;
 
856
        }
 
857
 
 
858
 
641
859
        public bool mount(string device, string mount_point, string mount_options = ""){
642
860
                
643
861
                /* Mounts specified device at specified mount point.
658
876
 
659
877
                        //check if mounted
660
878
                        bool mounted = false;
661
 
                        foreach(PartitionInfo info in get_mounted_partitions()){
 
879
                        foreach(PartitionInfo info in get_mounted_partitions_using_df()){
662
880
 
663
 
                                if (info.mount_point == mount_point && info.device == device){
 
881
                                if (info.mount_point_list.contains(mount_point) && info.device == device){
664
882
                                        //device is already mounted at mount point
665
883
                                        mounted = true;
666
884
                                        break;
667
885
                                }
668
 
                                else if (info.mount_point == mount_point && info.device != device){
 
886
                                else if (info.mount_point_list.contains(mount_point) && info.device != device){
669
887
                                        //another device is mounted at mount point - unmount it -------
670
888
                                        cmd = "sudo umount \"%s\"".printf(mount_point);
671
889
                                        Process.spawn_command_line_sync(cmd, out std_out, out std_err, out ret_val);
672
890
                                        if (ret_val != 0){
673
 
                                                log_error ("Failed to unmount device '%s' from mount point '%s'".printf(info.device, info.mount_point));
 
891
                                                log_error ("Failed to unmount device '%s' from mount point '%s'".printf(info.device, mount_point));
674
892
                                                log_error (std_err);
675
893
                                                return false;
676
894
                                        }
677
895
                                        else{
678
 
                                                log_msg ("Unmounted device '%s' from mount point '%s'".printf(info.device, info.mount_point));
 
896
                                                log_msg ("Unmounted device '%s' from mount point '%s'".printf(info.device, mount_point));
679
897
                                        }
680
898
                                }
681
899
                        }
717
935
                
718
936
                try{
719
937
                        //check if mounted and unmount
720
 
                        foreach(PartitionInfo info in get_mounted_partitions()){
721
 
                                if (info.mount_point == mount_point){
 
938
                        foreach(PartitionInfo info in get_mounted_partitions_using_df()){
 
939
                                if (info.mount_point_list.contains(mount_point)){
722
940
                                        
723
 
                                        log_msg(_("Unmounting device") + " '%s' ".printf(info.device) + _("from") + " '%s'".printf(info.mount_point));
 
941
                                        log_msg(_("Unmounting device") + " '%s' ".printf(info.device) + _("from") + " '%s'".printf(mount_point));
724
942
                                        
725
943
                                        //sync before unmount
726
944
                                        cmd = "sync";
761
979
                                                                        Process.spawn_command_line_sync(cmd, out std_out, out std_err, out ret_val);
762
980
                                                                        
763
981
                                                                        if (ret_val != 0){
764
 
                                                                                log_error (_("Failed to unmount device") + " '%s' ".printf(info.device) + _("from") + " '%s'".printf(info.mount_point));
 
982
                                                                                log_error (_("Failed to unmount device") + " '%s' ".printf(info.device) + _("from") + " '%s'".printf(mount_point));
765
983
                                                                                log_error (std_err);
766
984
                                                                                quit_app = true;
767
985
                                                                        }
788
1006
                
789
1007
                return true;
790
1008
        }
 
1009
        
791
1010
        public Gee.ArrayList<DeviceInfo> get_block_devices(){
792
1011
                
793
1012
                /* Returns a list of all storage devices including vendor and model number */
924
1143
            }
925
1144
        }
926
1145
 
927
 
        public bool execute_command_async (string cmd){
 
1146
        public bool execute_command_script_async (string cmd){
928
1147
                                
929
1148
                /* Creates a temporary bash script with given commands and executes it asynchronously 
930
1149
                 * Return value indicates if script was started successfully */
1561
1780
                
1562
1781
                path = get_cmd_path ("exo-open");
1563
1782
                if ((path != null)&&(path != "")){
1564
 
                        return execute_command_async ("exo-open \"" + dir_path + "\"");
 
1783
                        return execute_command_script_async ("exo-open \"" + dir_path + "\"");
1565
1784
                }
1566
1785
 
1567
1786
                path = get_cmd_path ("nemo");
1568
1787
                if ((path != null)&&(path != "")){
1569
 
                        return execute_command_async ("nemo \"" + dir_path + "\"");
 
1788
                        return execute_command_script_async ("nemo \"" + dir_path + "\"");
1570
1789
                }
1571
1790
                
1572
1791
                path = get_cmd_path ("nautilus");
1573
1792
                if ((path != null)&&(path != "")){
1574
 
                        return execute_command_async ("nautilus \"" + dir_path + "\"");
 
1793
                        return execute_command_script_async ("nautilus \"" + dir_path + "\"");
1575
1794
                }
1576
1795
                
1577
1796
                path = get_cmd_path ("thunar");
1578
1797
                if ((path != null)&&(path != "")){
1579
 
                        return execute_command_async ("thunar \"" + dir_path + "\"");
 
1798
                        return execute_command_script_async ("thunar \"" + dir_path + "\"");
1580
1799
                }
1581
1800
 
1582
1801
                return false;
1583
1802
        }
1584
1803
 
1585
 
        public int exo_open_textfile (string txt){
 
1804
        public bool exo_open_textfile (string txt){
1586
1805
                                
1587
1806
                /* Tries to open the given text file in a text editor */
1588
1807
                
1590
1809
                
1591
1810
                path = get_cmd_path ("exo-open");
1592
1811
                if ((path != null)&&(path != "")){
1593
 
                        return execute_command_sync ("exo-open \"" + txt + "\"");
 
1812
                        return execute_command_script_async ("exo-open \"" + txt + "\"");
1594
1813
                }
1595
1814
 
1596
1815
                path = get_cmd_path ("gedit");
1597
1816
                if ((path != null)&&(path != "")){
1598
 
                        return execute_command_sync ("gedit --new-document \"" + txt + "\"");
 
1817
                        return execute_command_script_async ("gedit --new-document \"" + txt + "\"");
1599
1818
                }
1600
1819
 
1601
 
                return -1;
 
1820
                return false;
1602
1821
        }
1603
1822
 
1604
1823
        public int notify_send (string title, string message, int durationMillis, string urgency){