summaryrefslogtreecommitdiffstats
path: root/tails_installer/utils.py
blob: bc460f93c400306a6ce4c6ec1c2991e5fce381b7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
# -*- coding: utf-8 -*-

import os
import re
import subprocess
import shutil
import stat
import sys
from tails_installer import _
from tails_installer.config import config

if 'linux' in sys.platform:
    from gi.repository import GLib

def _to_unicode(obj, encoding='utf-8'):
    if hasattr(obj, 'toUtf8'): # PyQt4.QtCore.QString
        obj = str(obj.toUtf8())
    if isinstance(obj, basestring):
        if not isinstance(obj, unicode):
            obj = unicode(obj, encoding)
    return obj

def unicode_to_utf8(string):
    if isinstance(string, unicode):
        return string.encode('utf-8')
    return string

def unicode_to_filesystemencoding(string):
    if isinstance(string, unicode):
        return string.encode(sys.getfilesystemencoding(), 'replace')
    return string

def extract_file_content_from_iso(iso_path, path):
    """ Return the content of that file read from inside self.iso """

    cmd = ['isoinfo', '-R', '-i', unicode_to_utf8(iso_path),
           '-x', unicode_to_utf8(path)]

    proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    out, err = proc.communicate()
    out = unicode_to_utf8(out)
    err = unicode_to_utf8(err)
    if proc.returncode:
        raise Exception(_("There was a problem executing `%s`."
                          "%s\n%s" % (cmd, out, err)))
    return out

def iso_is_live_system(iso_path):
    """ Return true iff a Live system is detected inside the iso_path file """
    if sys.platform == 'win32':
        return True
    version = extract_file_content_from_iso(iso_path, '/.disk/info')
    return version.startswith('Debian GNU/Linux')

def _dir_size(source):
    total_size = os.path.getsize(source)
    for item in os.listdir(source):
        itempath = os.path.join(source, item)
        if os.path.isfile(itempath):
            total_size += os.path.getsize(itempath)
        elif os.path.isdir(itempath):
            total_size += _dir_size(itempath)
    return total_size

def _move_if_exists(src, dest):
    if os.path.exists(src):
        shutil.move(src, dest)

def _unlink_if_exists(path):
    if os.path.exists(path):
        os.unlink(path)

def _set_liberal_perms_recursive(destination):
    def _set_liberal_perms(arg, dirname, fnames):
        if dirname == 'lost+found':
            return
        os.chmod(dirname, 0755)
        for f in fnames:
            if f == 'lost+found':
                continue
            file = os.path.join(dirname, f)
            if os.path.isdir(file):
                os.chmod(file, 0755)
            elif os.path.isfile(file):
                os.chmod(file, 0644)
    os.path.walk(destination, _set_liberal_perms, None)

def underlying_physical_device(path):
    """ Returns the physical block device UDI on which the specified file is
    stored (e.g. /org/freedesktop/UDisks2/block_devices/sdb).
    """
    rawdev = os.stat(path)[stat.ST_DEV]
    from gi.repository import UDisks
    udisksclient = UDisks.Client.new_sync()
    block = udisksclient.get_block_for_dev(rawdev)
    drive = udisksclient.get_drive_for_block(block)
    parentblock = udisksclient.get_block_for_drive(drive, get_physical=False)
    return parentblock.get_object_path()

def _format_bytes_in_gb(value):
    return '%0.1f GB' % (value / 10.0**9)


def MiB_to_bytes(size_in_MiB):
    return size_in_MiB * 1024**2


def _get_datadir():
    script_path = os.path.abspath(sys.argv[0])
    if not script_path.startswith('/usr/'):
        if os.path.exists('data/tails-installer.ui'):
            return('data')
    elif script_path.startswith('/usr/local/'):
        return('/usr/local/share/tails-installer')
    else:
        return('/usr/share/tails-installer')

def get_open_write_fd(block):
    (fd_index, fd_list) = block.call_open_for_restore_sync(
        arg_options=GLib.Variant('a{sv}', None)
    )
    fd = fd_list.get(fd_index.get_handle())
    if fd == -1:
        raise Exception(_("Could not open device for writing."))
    return fd

def write_to_block_device(block, string):
    fd = get_open_write_fd(block)
    os.write(fd, string)
    os.fsync(fd)
    os.close(fd)

def is_running_from_tails():
    try:
        path = config['tails_vendor_path']
        search_vendor = "^Vendor:\s+Tails$"
        with open(path, "r") as file_to_read:
            for line in file_to_read:
                if re.search(search_vendor, line):
                    return True
            return False
    except IOError:
        return False