Merge branch 'qtgui' basic ftrs for create/open

Create is quite good, but has no support for automatic-key-on-usb
Open is very raw, it only supports opening while explicitly choosing
where to get the key from

Python wrapper for tomb is in a distinct library, called "tomblib":
it currently supports tomb, basic undertaker, and parsing output
messages
This commit is contained in:
boyska 2012-01-29 19:18:41 +01:00
commit a6da0dbb93
30 changed files with 2303 additions and 39 deletions

12
src/HACKING.txt Normal file
View File

@ -0,0 +1,12 @@
### Code organization:
* tomblib: a library that wraps on tomb. Meant to be used by various scripts, and every UI
* qt / wx / whatever: directory for different gui implementations
### QT project:
status: only create wizard
the graphical part is done through create.ui, which can be edited by designer
The UI should be (if possible) completely autocontained in this .ui file, and no code (or very few) should be added to make it work.
* ATM, some code has been added for the "password don't match" part.
* Some code need to be added to make the filedialog work

View File

@ -1,5 +1,5 @@
bin_SCRIPTS = tomb tomb-open
bin_SCRIPTS = tomb tomb-open undertaker
bin_PROGRAMS = tomb-status

5
src/pytomb/.gitignore vendored Normal file
View File

@ -0,0 +1,5 @@
.*.swp
*.pyc
*.egg-info
build
dist

BIN
src/pytomb/.wrapper.py.swp Executable file

Binary file not shown.

11
src/pytomb/setup.py Normal file
View File

@ -0,0 +1,11 @@
from setuptools import setup
setup(
name = 'TombLib',
version = '1.1',
packages = ['tomblib'],
test_suite = 'nose.collector'
)

0
src/pytomb/tomblib/__init__.py Executable file
View File

View File

@ -0,0 +1,34 @@
'''
Utilities to analyze tomb output
'''
import re
#found: [m] followed by some ID (usually "found") inside square brackets, then
#something else, then a space, then the content
_found_regex = re.compile(r'^\[m\]\[([^]]+)\] +(([^:]+)://(.+))$')
#generic: programname, then some identifiers in square (or round) brackets,
#then maybe something else, then a space, then the context
_generic_regex = re.compile(r'^[a-z-]+ [[(]([^]]+)[\])] +(.+)$')
types = {'E':'error', 'W':'warning', 'D':'debug', '*':'success'}
def parse_line(line):
'''Analyze a single line.
Return None if no standard format is detected, a dict otherwise.
The fields 'type' and 'content' are always in the dict; 'content' may be
empty
'type' can be 'error', 'progress'
'''
match = _found_regex.match(line)
if match:
return { 'type': types.get(match.group(1)) or match.group(1),
'content': match.group(2), 'scheme': match.group(3),
'path': match.group(4) }
match = _generic_regex.search(line)
if match:
return { 'type': types.get(match.group(1)) or match.group(1),
'content': match.group(2) }
return None

View File

@ -0,0 +1,52 @@
from tomblib.parser import *
class TestWrong:
def test_short(self):
'''short format is not supported anymore'''
assert parse_line('[!] foo') is None
def test_colors(self):
'''parsing while using colors should fail'''
parse = parse_line('\033[32mundertaker [W] url protocol not recognized: nonscheme')
assert parse is None
def test_no_spaces_in_programname(self):
parse = parse_line('tomb open [W] url protocol not recognized: nonscheme')
assert parse is None
class TestFound:
def test_simple(self):
parse = parse_line('[m][found] scheme:///and/path')
assert parse is not None
assert parse['type'] == 'found'
assert parse['content'] == 'scheme:///and/path'
assert 'scheme' in parse
assert parse['scheme'] == 'scheme'
assert 'path' in parse
assert parse['path'] == '/and/path'
class TestGeneric:
def test_simple(self):
parse = parse_line('undertaker [W] url protocol not recognized: nonscheme')
assert parse is not None
assert parse['type'] == 'warning'
assert parse['content'] == 'url protocol not recognized: nonscheme'
def test_debug(self):
parse = parse_line('undertaker [D] url protocol not recognized: nonscheme')
assert parse is not None
assert parse['type'] == 'debug'
assert parse['content'] == 'url protocol not recognized: nonscheme'
def test_success(self):
parse = parse_line('undertaker (*) url protocol not recognized: nonscheme')
assert parse is not None
assert parse['type'] == 'success'
assert parse['content'] == 'url protocol not recognized: nonscheme'
def test_dash(self):
parse = parse_line('tomb-open [W] url protocol not recognized: nonscheme')
assert parse is not None
assert parse['type'] == 'warning'
assert parse['content'] == 'url protocol not recognized: nonscheme'

View File

@ -0,0 +1,91 @@
'''
Module structure:
this contain a class, which is indeed just a collection of functions
(the methods are all static).
It's meant to behave in a way which is similar to the command line, for
Notes: consider moving to a more typical usage (instantiate, then use method)
to make it more configurable (ie set the tomb executable path).
'''
import subprocess
class Tomb(object):
'''
This is just a collection of static methods, so you should NOT instantiate
The methods are meant to resemble the command line interface as much as
possible
There is no support to things like threading, multiprocessing, whatever.
If you want to interact asynchronously with tomb, just do it in a separate
layer.
'''
tombexec = 'tomb'
def _check_exec_path(self):
'''Checks, using which, if tomb is available.
Returns None on error, the path on success.
'''
try:
path = subprocess.check_output(['which', 'tomb'])
except subprocess.CalledProcessError:
return None
return path
@classmethod
def check(cls, command, stdout=None, stderr=None, no_color=True, ignore_swap=False):
args = [command]
if no_color:
args += ['--no-color']
if ignore_swap:
args += ['--ignore-swap']
try:
subprocess.check_call([cls.tombexec, 'check'] + args, stdout=stdout, stderr=stderr)
except subprocess.CalledProcessError:
return False
return True
@classmethod
def create(cls, tombpath, tombsize,keypath, stdout=None, stderr=None,
no_color=True, ignore_swap=False):
'''If keypath is None, it will be created adjacent to the tomb.
This is unsafe, and you should NOT do it.
Note that this will invoke pinentry
no_color is supported as an option for short-lived retrocompatibility:
it will be removed as soon as no-color will be integrated
'''
args = [tombpath, '-s', tombsize]
if keypath is not None:
args += ['-k', keypath]
if no_color:
args += ['--no-color']
if ignore_swap:
args += ['--ignore-swap']
try:
subprocess.check_call([cls.tombexec, 'create'] + args, stdout=stdout, stderr=stderr)
except subprocess.CalledProcessError:
return False
return True
@classmethod
def open(cls, tombpath,keypath=None, no_color=True, ignore_swap=False):
args = [tombpath]
if keypath is not None:
args += ['-k', keypath]
if no_color:
args += ['--no-color']
if ignore_swap:
args += ['--ignore-swap']
try:
subprocess.check_call([cls.tombexec, 'open'] + args)
except subprocess.CalledProcessError:
return False
return True
if __name__ == '__main__':
#Debug stuff. Also useful for an example
print Tomb.create('/tmp/a.tomb', '10', '/tmp/akey')

View File

@ -0,0 +1,79 @@
import subprocess
from tempfile import NamedTemporaryFile
import parser
class Undertaker(object):
'''
This is similar to Tomb class, and provides a wrapper on undertaker.
TODO:
* methods for automagical scan
* output parsing, giving meaningful output
Due to the non-interactive nature of undertaker, it's simpler than Tomb
'''
undertakerexec = 'undertaker'
@classmethod
def check(cls, paths):
'''Will check if there are keys available there, as in --path
paths can be a string (one address), or a list of
'''
#TODO: more solid check: something like
if type(paths) is not str:
out = []
for p in paths:
try:
res = cls.check(p)
except:
continue
else:
if res:
out.extend(res)
return out
buf = NamedTemporaryFile()
try:
subprocess.check_call([cls.undertakerexec, paths, '--batch',
'--path'], stderr=buf)
except subprocess.CalledProcessError as exc:
return False
out = []
buf.seek(0)
for line in buf:
ret = parser.parse_line(line)
if ret and ret['type'] == 'found':
out.append(ret['content'])
return out
@classmethod
def get(cls, paths):
'''
Similar to check, but truly get the key content.
If paths is iterable, stop at the first successful path
'''
if type(paths) is not str:
for p in paths:
try:
res = cls.get(p)
except:
continue
else:
if res:
return res
buf = NamedTemporaryFile()
try:
subprocess.check_call([cls.undertakerexec, paths, '--batch'],
stdout=buf)
except subprocess.CalledProcessError:
return False
buf.seek(0)
return buf.read()
if __name__ == '__main__':
Undertaker.undertakerexec = '/home/davide/coding/projects/tomb/src/undertaker'
print Undertaker.get('near:///home/davide/Desktop/testing.tomb')

6
src/qt/.gitignore vendored Normal file
View File

@ -0,0 +1,6 @@
.*.swp
*.pyc
TombQt.egg-info
build
dist
disk

23
src/qt/Makefile Normal file
View File

@ -0,0 +1,23 @@
TARGETS_OPEN=tombqt/ui_open_tombfile.py tombqt/ui_open_keymethod.py tombqt/ui_open_success.py
TARGETS=tombqt/ui_create.py $(TARGETS_OPEN)
all: $(TARGETS)
test_create: tombqt/ui_create.py
python2 -3 tombqt/create.py
test_open: $(TARGETS_OPEN)
python2 -3 tombqt/open.py
tombqt/ui_create.py: tombqt/create.ui
pyuic4 create.ui -o tombqt/ui_create.py
tombqt/ui_open_tombfile.py: tombqt/open_tombfile.ui
pyuic4 tombqt/open_tombfile.ui -o tombqt/ui_open_tombfile.py
tombqt/ui_open_keymethod.py: tombqt/open_keymethod.ui
pyuic4 tombqt/open_keymethod.ui -o tombqt/ui_open_keymethod.py
tombqt/ui_open_success.py: tombqt/open_success.ui
pyuic4 tombqt/open_success.ui -o tombqt/ui_open_success.py
clean:
rm $(TARGETS)
.PHONY: test clean

9
src/qt/notes.txt Normal file
View File

@ -0,0 +1,9 @@
Some conventions:
.ui files are designers files
Sometimes it's necessary to create custom widget to extend the functionality
given by designer in a clean way. These files should be called ui_whatever.py
.ui files must be "compiled" using pyuic4. This should be done with make, but
won't be right now. So, for the moment, I'll keep compiled files directly in
the sources, for easiness.

52
src/qt/setup.py Normal file
View File

@ -0,0 +1,52 @@
import os
import glob
from setuptools import setup
from StringIO import StringIO
from distutils import log
from distutils.core import Command
from distutils.dep_util import newer
class build_ui(Command):
# Stolen from picard
description = "build Qt UI files"
user_options = []
def initialize_options(self):
pass
def finalize_options(self):
pass
def run(self):
from PyQt4 import uic
for uifile in glob.glob("tombqt/*.ui"):
pyfile = "ui_%s.py" % os.path.splitext(os.path.basename(uifile))[0]
pyfile = os.path.join('tombqt', pyfile)
if newer(uifile, pyfile):
log.info("compiling %s -> %s", uifile, pyfile)
tmp = StringIO()
uic.compileUi(uifile, tmp)
source = tmp.getvalue()
f = open(pyfile, "w")
f.write(source)
f.close()
setup(
name = 'TombQt',
version = '0.1',
packages = ['tombqt'],
cmdclass = {
'build_ui': build_ui
},
entry_points = {
'gui_scripts': [
'tomb-qt-create = tombqt.create:run_create_wizard',
'tomb-qt-open = tombqt.open:run_open_wizard'
]
}
)

View File

134
src/qt/tombqt/create.py Executable file
View File

@ -0,0 +1,134 @@
import sys, os
from PyQt4.QtGui import QApplication, QWizard
from PyQt4 import QtCore
from PyQt4 import QtGui
from ui_create import Ui_Wizard
if __name__ == '__main__':
parentdir = sys.path[0].split(os.sep)[:-1]
sys.path.append(os.sep.join(parentdir))
from tomblib.tomb import Tomb
from worker import TombCreateThread
try:
_fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
_fromUtf8 = lambda s: s
class TombCreateWizard(QWizard):
def __init__(self, *args, **kwargs):
QWizard.__init__(self, *args, **kwargs)
self.ui = ui = Ui_Wizard()
ui.setupUi(self)
#instance attributes:
self.ignore_swap = False
self._tomb_check = False #ugly; it's used by check_progress_complete
ui.wizardPage_tomb_location.registerField('tombpath*',
ui.lineEdit_tombpath) #required field, note the *
ui.wizardPage_key_location.setCommitPage(True)
QtCore.QObject.connect(ui.button_tombpath,
QtCore.SIGNAL(_fromUtf8('clicked()')),
self.on_tomb_location_clicked)
QtCore.QObject.connect(self,
QtCore.SIGNAL(_fromUtf8('currentIdChanged(int)')),
self.on_change_page)
QtCore.QObject.connect(ui.radioButton_swapoff,
QtCore.SIGNAL(_fromUtf8('toggled(bool)')),
ui.wizardPage_check.completeChanged)
QtCore.QObject.connect(ui.radioButton_ignore,
QtCore.SIGNAL(_fromUtf8('toggled(bool)')),
ui.wizardPage_check.completeChanged)
def check_progress_complete(*args, **kwargs):
if self.ui.progressBar.value() == 100:
return True
return False
def check_is_solved():
if self._tomb_check:
return True
if self.ui.radioButton_swapoff.isChecked() or \
self.ui.radioButton_ignore.isChecked():
return True
return False
self.ui.wizardPage_progress.isComplete = check_progress_complete
self.ui.wizardPage_check.isComplete = check_is_solved
self.ui.groupBox_swap.setVisible(False)
self.finished.connect(self.on_finish)
def _keyloc(self):
keyloc = None
if self.ui.radioButton_usb.isChecked():
print 'Warning: it is not supported'
raise NotImplementedError
elif self.ui.radioButton_near.isChecked():
print 'going near'
keyloc = None
else:
keyloc = self.ui.lineEdit_custom.text()
if not keyloc:
raise ValueError
return keyloc
def on_tomb_location_clicked(self, *args, **kwargs):
filename = QtGui.QFileDialog.getSaveFileName(self, 'Create Tomb',
filter="Tomb(*.tomb)")
self.ui.lineEdit_tombpath.setText(filename)
def on_change_page(self, pagenumber):
if self.currentPage() == self.ui.wizardPage_progress:
self.create_tomb()
if self.currentPage() == self.ui.wizardPage_check:
self.check_requisite()
def on_finish(self, finishedint):
if self.currentPage() != self.ui.wizardPage_end:
#there has been an error
return
if self.ui.checkBox_open.isChecked():
Tomb.open(self.ui.lineEdit_tombpath.text(), self._keyloc())
def on_thread_creation_finished(self):
if self.thread.get_success():
self.ui.progressBar.setValue(100)
else:
self.ui.progressBar.setEnabled(False)
self.ui.label_progress.setText('Error while creating the tomb!')
self.ui.wizardPage_progress.setFinalPage(True)
self.ui.wizardPage_progress.completeChanged.emit()
def create_tomb(self):
self.thread = TombCreateThread(self.ui.lineEdit_tombpath.text(),
str(self.ui.spinBox_size.value()), self._keyloc(),
no_color=False, ignore_swap=self.ui.radioButton_ignore.isChecked())
self.thread.finished.connect(self.on_thread_creation_finished)
self.thread.terminated.connect(self.on_thread_creation_finished)
self.thread.line_received.connect(self.ui.textBrowser_log.append)
def err_append_to_log(text):
self.ui.textBrowser_log.append('Error: <strong>' + text +
'</strong>')
self.thread.error_received.connect(err_append_to_log)
self.thread.start()
def check_requisite(self):
self._tomb_check = check = Tomb.check('create', no_color=False)
self.ui.wizardPage_check.completeChanged.emit()
if check:
self.ui.label_check.setText('Everything seems fine!')
return
self.ui.label_check.setText('Some error occurred')
if Tomb.check('create', no_color=False, ignore_swap=True): # swap is the only error
self.ui.groupBox_swap.setVisible(True)
#TODO: support swapoff
#TODO: calculate the amount of ram available vs swap used
self.ui.radioButton_swapoff.setEnabled(False)
self.ui.label_swapoff.setEnabled(False)
def run_create_wizard():
app = QApplication(sys.argv)
window = TombCreateWizard()
window.show()
sys.exit(app.exec_())
if __name__ == '__main__':
run_create_wizard()

553
src/qt/tombqt/create.ui Executable file
View File

@ -0,0 +1,553 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Wizard</class>
<widget class="QWizard" name="Wizard">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>710</width>
<height>368</height>
</rect>
</property>
<property name="windowTitle">
<string>Wizard</string>
</property>
<property name="options">
<set>QWizard::HaveHelpButton|QWizard::IndependentPages</set>
</property>
<widget class="QWizardPage" name="wizardPage_intro">
<property name="title">
<string>Tomb</string>
</property>
<property name="subTitle">
<string>tomb creation</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>This wizard will guide you to the creation of a tomb.&lt;br&gt; It will be fun!</string>
</property>
<property name="textFormat">
<enum>Qt::RichText</enum>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWizardPage" name="wizardPage_check">
<property name="title">
<string>Requirements check</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_12">
<item>
<widget class="QLabel" name="label_check">
<property name="text">
<string>Checking...</string>
</property>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_swap">
<property name="enabled">
<bool>true</bool>
</property>
<property name="title">
<string>Swap error</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_13">
<item>
<widget class="QLabel" name="label_7">
<property name="text">
<string>It seems that you have swap activated. It is very dangerous, since you could leave LOT of traces on your computer UNencrypted. You have some options:</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_swapoff">
<item>
<widget class="QRadioButton" name="radioButton_swapoff">
<property name="text">
<string>Swapoff</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_6">
<item>
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Maximum</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="label_swapoff">
<property name="text">
<string>Note: swapoff could take a long time, and, in case the memory is not enough, could even make your system crash. Your system seems to have %freeram%MB free</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_11">
<item>
<widget class="QRadioButton" name="radioButton_ignore">
<property name="text">
<string>Ignore</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_7">
<item>
<spacer name="horizontalSpacer_4">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Maximum</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="label_9">
<property name="text">
<string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'DejaVu Sans'; font-size:10pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Note:&lt;/span&gt; You should use this only if you are sure that your swap is encrypted, or that you are using compcache.&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;If this is not the case, DON'T select this, as it is &lt;span style=&quot; font-weight:600;&quot;&gt;VERY DANGEROUS &lt;/span&gt;to use encryption with swap activated&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<widget class="QWizardPage" name="wizardPage_tomb_size">
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>Please enter tomb size. Digging the tomb will require some time: usually, one minute per GB, but your mileage may vary. &lt;br&gt;Keep in mind that resizing it in the future is still NOT implemented</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="label_3">
<property name="text">
<string>Enter tomb size, in MB. 1GB=1000MB)</string>
</property>
<property name="buddy">
<cstring>spinBox_size</cstring>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="spinBox_size">
<property name="minimum">
<number>10</number>
</property>
<property name="maximum">
<number>100000</number>
</property>
<property name="value">
<number>100</number>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<widget class="QWizardPage" name="wizardPage_tomb_location">
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="QLabel" name="label_4">
<property name="text">
<string>Where do you want your tomb to be digged?</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
<property name="buddy">
<cstring>lineEdit_tombpath</cstring>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLineEdit" name="lineEdit_tombpath">
<property name="frame">
<bool>true</bool>
</property>
<property name="placeholderText">
<string>/path/to/file.tomb</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="button_tombpath">
<property name="text">
<string>Open file</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<widget class="QWizardPage" name="wizardPage_key_location">
<property name="title">
<string>Key creation</string>
</property>
<property name="subTitle">
<string>Choose the location for your key</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_6">
<item>
<widget class="QLabel" name="label_5">
<property name="text">
<string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Now, you have to decide where to put the &lt;span style=&quot; font-weight:600;&quot;&gt;key&lt;/span&gt; for your tomb&lt;br /&gt;You should not leave your key at the door, as this will lower security A LOT&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Also, the keyfile is very small (less than a KB), so disk space is not an issue&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="textFormat">
<enum>Qt::RichText</enum>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_5">
<item>
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<widget class="QRadioButton" name="radioButton_usb">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>On a USB pen (best security)</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Maximum</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="label_6">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>If you choose to do so, do not insert it NOW. Do it when you are asked to do so</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
<item>
<widget class="QRadioButton" name="radioButton_near">
<property name="toolTip">
<string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;It will be created as a regular file in the same directory of your tomb.&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;It is much easier to use, but also much more &lt;span style=&quot; font-style:italic;&quot;&gt;insecure&lt;/span&gt;: all your security will be guaranteed by your &lt;span style=&quot; font-weight:600;&quot;&gt;password&lt;/span&gt;. If you really want to do this, choose a strong password (lot of random/non-dictionary words, spaces, numbers, odd characters)&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Near to the tomb itself (this is BAD)</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="radioButton_custom">
<property name="text">
<string>Specify location</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Maximum</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLineEdit" name="lineEdit_custom">
<property name="enabled">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButton_custom">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Choose location</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QLabel" name="label_11">
<property name="text">
<string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Help: &lt;/span&gt;the key file is very small, so disk usage is not an issue&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWizardPage" name="wizardPage_progress">
<property name="title">
<string>Creating</string>
</property>
<property name="subTitle">
<string>Please wait</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_9">
<item>
<layout class="QVBoxLayout" name="verticalLayout_7">
<item>
<widget class="QProgressBar" name="progressBar">
<property name="value">
<number>0</number>
</property>
<property name="textVisible">
<bool>true</bool>
</property>
<property name="invertedAppearance">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_5">
<item>
<widget class="QLabel" name="label_progress">
<property name="text">
<string>Creating tomb, please wait...</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
<item>
<widget class="QTextBrowser" name="textBrowser_log">
<property name="documentTitle">
<string>Log</string>
</property>
<property name="html">
<string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;title&gt;Log&lt;/title&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'DejaVu Sans'; font-size:10pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'Sans Serif'; font-size:9pt; font-weight:600;&quot;&gt;Log&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt; font-weight:600;&quot;&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWizardPage" name="wizardPage_end">
<layout class="QVBoxLayout" name="verticalLayout_8">
<item>
<widget class="QLabel" name="label_10">
<property name="text">
<string>You successfully created the tomb!</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="checkBox_open">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Open the just-created tomb NOW!</string>
</property>
<property name="checked">
<bool>false</bool>
</property>
<property name="tristate">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
<resources/>
<connections>
<connection>
<sender>radioButton_custom</sender>
<signal>toggled(bool)</signal>
<receiver>lineEdit_custom</receiver>
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>91</x>
<y>56</y>
</hint>
<hint type="destinationlabel">
<x>53</x>
<y>56</y>
</hint>
</hints>
</connection>
<connection>
<sender>radioButton_custom</sender>
<signal>toggled(bool)</signal>
<receiver>pushButton_custom</receiver>
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>98</x>
<y>56</y>
</hint>
<hint type="destinationlabel">
<x>98</x>
<y>56</y>
</hint>
</hints>
</connection>
<connection>
<sender>Wizard</sender>
<signal>currentIdChanged(int)</signal>
<receiver>label_11</receiver>
<slot>hide()</slot>
<hints>
<hint type="sourcelabel">
<x>181</x>
<y>335</y>
</hint>
<hint type="destinationlabel">
<x>99</x>
<y>60</y>
</hint>
</hints>
</connection>
<connection>
<sender>Wizard</sender>
<signal>helpRequested()</signal>
<receiver>label_11</receiver>
<slot>show()</slot>
<hints>
<hint type="sourcelabel">
<x>135</x>
<y>356</y>
</hint>
<hint type="destinationlabel">
<x>99</x>
<y>60</y>
</hint>
</hints>
</connection>
</connections>
<slots>
<slot>check_passwords_equal()</slot>
</slots>
</ui>

109
src/qt/tombqt/open.py Normal file
View File

@ -0,0 +1,109 @@
import sys
from PyQt4 import QtCore, QtGui
from ui_open_tombfile import Ui_tombfile
from ui_open_keymethod import Ui_keymethod
from ui_open_success import Ui_success
from tomblib.tomb import Tomb
from tomblib.undertaker import Undertaker
try:
_fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
_fromUtf8 = lambda s: s
class TombfilePage(QtGui.QWizardPage):
def __init__(self, *args, **kwargs):
QtGui.QWizardPage.__init__(self, *args)
self.ui = Ui_tombfile()
self.ui.setupUi(self)
if 'tombfile' in kwargs and kwargs['tombfile'] is not None:
self.ui.tomb_line.setText(kwargs['tombfile'])
self.ui.tomb_browse.clicked.connect(self.on_tomb_location_clicked)
def on_tomb_location_clicked(self, *args, **kwargs):
filename = QtGui.QFileDialog.getOpenFileName(self, 'Select Tomb',
filter="Tomb (*.tomb)")
self.ui.tomb_line.setText(filename)
class MethodPage(QtGui.QWizardPage):
def __init__(self, *args, **kwargs):
QtGui.QWizardPage.__init__(self, *args, **kwargs)
self.ui = Ui_keymethod()
self.ui.setupUi(self)
self.group = group = QtGui.QButtonGroup()
for radio in self.children():
if type(radio) == QtGui.QRadioButton:
group.addButton(radio)
def initializePage(self):
self.found = Undertaker.check( str('near://' + self.wizard().get_tombfile()) ) or []
box = self.ui.radio_layout
for key in self.found:
radio = QtGui.QRadioButton('Automatically found: ' + key, parent=self)
radio.setChecked(True)
radio.setProperty('path', key)
box.insertWidget(0, radio)
self.group.addButton(radio)
def nextId(self):
'''Virtual method reimplemented to decide next page'''
if self.ui.fs.isChecked():
keyfile = QtGui.QFileDialog.getOpenFileName(self.wizard(), 'Key file',
filter="Tomb keys (*.tomb.key);;Buried keys (*.jpeg)")
if keyfile:
#TODO: check if this really is a success :)
if Tomb.open(self.wizard().get_tombfile(), keyfile): #bugs when wrong password
return TombOpenWizard.SUCCESS_PAGE
#else: #TODO: should alert the user that we failed
return TombOpenWizard.METHOD_PAGE
if self.ui.usb.isChecked():
return TombOpenWizard.USB_PAGE
print self.group.checkedButton().property('path').toPyObject()
return TombOpenWizard.SUCCESS_PAGE
class SuccessPage(QtGui.QWizardPage):
def __init__(self, *args, **kwargs):
QtGui.QWizardPage.__init__(self, *args, **kwargs)
self.ui = Ui_success()
self.ui.setupUi(self)
class TombOpenWizard(QtGui.QWizard):
TOMBFILE_PAGE=1
METHOD_PAGE=2
SUCCESS_PAGE=99
USB_PAGE=20
def __init__(self, *args, **kwargs):
QtGui.QWizard.__init__(self, *args)
self.setPage(TombOpenWizard.TOMBFILE_PAGE,
TombfilePage(self, tombfile = kwargs['tombfile']
if 'tombfile' in kwargs else None))
self.setPage(TombOpenWizard.METHOD_PAGE, MethodPage(self))
self.setPage(TombOpenWizard.SUCCESS_PAGE, SuccessPage(self))
if 'tombfile' in kwargs and kwargs['tombfile'] is not None:
self.setStartId(TombOpenWizard.METHOD_PAGE)
def get_tombfile(self):
page = self.page(TombOpenWizard.TOMBFILE_PAGE)
return page.ui.tomb_line.text()
def run_open_wizard():
app = QtGui.QApplication(sys.argv)
window = TombOpenWizard(tombfile=sys.argv[1] if len(sys.argv) > 1 else None)
window.show()
sys.exit(app.exec_())
if __name__ == '__main__':
Undertaker.undertakerexec = '/home/davide/coding/projects/tomb/src/undertaker'
run_open_wizard()

239
src/qt/tombqt/open.ui Normal file
View File

@ -0,0 +1,239 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Dialog</class>
<widget class="QDialog" name="Dialog">
<property name="windowTitle">
<string>Tomb open</string>
</property>
<property name="toolTip">
<string>Open a tomb file; this will require a passphrase</string>
</property>
<property name="autoFillBackground">
<bool>false</bool>
</property>
<property name="sizeGripEnabled">
<bool>true</bool>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'DejaVu Sans'; font-size:10pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:14pt; font-weight:600;&quot;&gt;Opening %tombname%&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="textFormat">
<enum>Qt::RichText</enum>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Maximum</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>Size: %tombsize%</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>25</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>Opening key</string>
</property>
<property name="flat">
<bool>false</bool>
</property>
<property name="checkable">
<bool>false</bool>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLabel" name="label_3">
<property name="text">
<string>Key found in %autokeypath%</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButton">
<property name="toolTip">
<string>Select a key to open the tomb</string>
</property>
<property name="text">
<string>Choose another key</string>
</property>
<property name="autoDefault">
<bool>true</bool>
</property>
<property name="default">
<bool>false</bool>
</property>
<property name="flat">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Preferred</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="label_4">
<property name="text">
<string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'DejaVu Sans'; font-size:10pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;HELP&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;To open a tomb, you need both:&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; 1. a key, which is a file with secret information.&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; 2. a passphrase&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;This dialog will help you choose the keyfile. We try hard to find the key, but if we can't found the right one, choose it yourself using the button&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Help|QDialogButtonBox::Open</set>
</property>
<property name="centerButtons">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>Dialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>578</x>
<y>751</y>
</hint>
<hint type="destinationlabel">
<x>529</x>
<y>381</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>Dialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>447</x>
<y>735</y>
</hint>
<hint type="destinationlabel">
<x>279</x>
<y>326</y>
</hint>
</hints>
</connection>
<connection>
<sender>Dialog</sender>
<signal>created()</signal>
<receiver>label_4</receiver>
<slot>hide()</slot>
<hints>
<hint type="sourcelabel">
<x>141</x>
<y>756</y>
</hint>
<hint type="destinationlabel">
<x>136</x>
<y>692</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>helpRequested()</signal>
<receiver>label_4</receiver>
<slot>hide()</slot>
<hints>
<hint type="sourcelabel">
<x>39</x>
<y>738</y>
</hint>
<hint type="destinationlabel">
<x>71</x>
<y>676</y>
</hint>
</hints>
</connection>
</connections>
<slots>
<signal>created()</signal>
</slots>
</ui>

View File

@ -0,0 +1,147 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Dialog</class>
<widget class="QDialog" name="Dialog">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
<property name="modal">
<bool>true</bool>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'DejaVu Sans'; font-size:10pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:12pt; font-weight:600;&quot;&gt;Auto-search&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="textFormat">
<enum>Qt::RichText</enum>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Expanding</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_radio">
<item>
<layout class="QVBoxLayout" name="verticalLayout_custom">
<item>
<widget class="QRadioButton" name="radioButton">
<property name="text">
<string>Custom location</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_custom_input">
<item>
<widget class="QLineEdit" name="lineEdit">
<property name="readOnly">
<bool>false</bool>
</property>
<property name="placeholderText">
<string>/path/to/keyfile</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButton">
<property name="text">
<string>Choose file</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
</layout>
</item>
<item>
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Expanding</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>Dialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>247</x>
<y>604</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>Dialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>315</x>
<y>604</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@ -0,0 +1,84 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>keymethod</class>
<widget class="QWizardPage" name="keymethod">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>480</width>
<height>640</height>
</rect>
</property>
<property name="windowTitle">
<string>WizardPage</string>
</property>
<property name="title">
<string>Choose key</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>265</height>
</size>
</property>
</spacer>
</item>
<item>
<layout class="QVBoxLayout" name="radio_layout">
<item>
<widget class="QRadioButton" name="fs">
<property name="text">
<string>Filesystem</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="usb">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>USB drive</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="bluetooth">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Retrieve via bluetooth (advanced)</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>265</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>success</class>
<widget class="QWizardPage" name="success">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>480</width>
<height>640</height>
</rect>
</property>
<property name="windowTitle">
<string>WizardPage</string>
</property>
<property name="title">
<string>Tomb opened</string>
</property>
<property name="subTitle">
<string>success</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>You successfully opened the tomb</string>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@ -0,0 +1,79 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>tombfile</class>
<widget class="QWizardPage" name="tombfile">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>480</width>
<height>640</height>
</rect>
</property>
<property name="windowTitle">
<string>WizardPage</string>
</property>
<property name="title">
<string>Choose tomb</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>276</height>
</size>
</property>
</spacer>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Choose a tomb file on your filesystem</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLineEdit" name="tomb_line">
<property name="placeholderText">
<string>/path/to/your.tomb</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="tomb_browse">
<property name="text">
<string>Browse</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
<item>
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>276</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

282
src/qt/tombqt/ui_create.py Normal file
View File

@ -0,0 +1,282 @@
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'create.ui'
#
# Created: Thu Nov 3 00:16:51 2011
# by: PyQt4 UI code generator 4.8.6
#
# WARNING! All changes made in this file will be lost!
from PyQt4 import QtCore, QtGui
try:
_fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
_fromUtf8 = lambda s: s
class Ui_Wizard(object):
def setupUi(self, Wizard):
Wizard.setObjectName(_fromUtf8("Wizard"))
Wizard.resize(710, 368)
Wizard.setWindowTitle(QtGui.QApplication.translate("Wizard", "Wizard", None, QtGui.QApplication.UnicodeUTF8))
Wizard.setOptions(QtGui.QWizard.HaveHelpButton|QtGui.QWizard.IndependentPages)
self.wizardPage_intro = QtGui.QWizardPage()
self.wizardPage_intro.setTitle(QtGui.QApplication.translate("Wizard", "Tomb", None, QtGui.QApplication.UnicodeUTF8))
self.wizardPage_intro.setSubTitle(QtGui.QApplication.translate("Wizard", "tomb creation", None, QtGui.QApplication.UnicodeUTF8))
self.wizardPage_intro.setObjectName(_fromUtf8("wizardPage_intro"))
self.verticalLayout = QtGui.QVBoxLayout(self.wizardPage_intro)
self.verticalLayout.setObjectName(_fromUtf8("verticalLayout"))
self.label = QtGui.QLabel(self.wizardPage_intro)
self.label.setText(QtGui.QApplication.translate("Wizard", "This wizard will guide you to the creation of a tomb.<br> It will be fun!", None, QtGui.QApplication.UnicodeUTF8))
self.label.setTextFormat(QtCore.Qt.RichText)
self.label.setWordWrap(True)
self.label.setObjectName(_fromUtf8("label"))
self.verticalLayout.addWidget(self.label)
Wizard.addPage(self.wizardPage_intro)
self.wizardPage_check = QtGui.QWizardPage()
self.wizardPage_check.setTitle(QtGui.QApplication.translate("Wizard", "Requirements check", None, QtGui.QApplication.UnicodeUTF8))
self.wizardPage_check.setObjectName(_fromUtf8("wizardPage_check"))
self.verticalLayout_12 = QtGui.QVBoxLayout(self.wizardPage_check)
self.verticalLayout_12.setObjectName(_fromUtf8("verticalLayout_12"))
self.label_check = QtGui.QLabel(self.wizardPage_check)
self.label_check.setText(QtGui.QApplication.translate("Wizard", "Checking...", None, QtGui.QApplication.UnicodeUTF8))
self.label_check.setObjectName(_fromUtf8("label_check"))
self.verticalLayout_12.addWidget(self.label_check)
self.groupBox_swap = QtGui.QGroupBox(self.wizardPage_check)
self.groupBox_swap.setEnabled(True)
self.groupBox_swap.setTitle(QtGui.QApplication.translate("Wizard", "Swap error", None, QtGui.QApplication.UnicodeUTF8))
self.groupBox_swap.setObjectName(_fromUtf8("groupBox_swap"))
self.verticalLayout_13 = QtGui.QVBoxLayout(self.groupBox_swap)
self.verticalLayout_13.setObjectName(_fromUtf8("verticalLayout_13"))
self.label_7 = QtGui.QLabel(self.groupBox_swap)
self.label_7.setText(QtGui.QApplication.translate("Wizard", "It seems that you have swap activated. It is very dangerous, since you could leave LOT of traces on your computer UNencrypted. You have some options:", None, QtGui.QApplication.UnicodeUTF8))
self.label_7.setWordWrap(True)
self.label_7.setObjectName(_fromUtf8("label_7"))
self.verticalLayout_13.addWidget(self.label_7)
self.verticalLayout_swapoff = QtGui.QVBoxLayout()
self.verticalLayout_swapoff.setObjectName(_fromUtf8("verticalLayout_swapoff"))
self.radioButton_swapoff = QtGui.QRadioButton(self.groupBox_swap)
self.radioButton_swapoff.setText(QtGui.QApplication.translate("Wizard", "Swapoff", None, QtGui.QApplication.UnicodeUTF8))
self.radioButton_swapoff.setObjectName(_fromUtf8("radioButton_swapoff"))
self.verticalLayout_swapoff.addWidget(self.radioButton_swapoff)
self.horizontalLayout_6 = QtGui.QHBoxLayout()
self.horizontalLayout_6.setObjectName(_fromUtf8("horizontalLayout_6"))
spacerItem = QtGui.QSpacerItem(20, 20, QtGui.QSizePolicy.Maximum, QtGui.QSizePolicy.Minimum)
self.horizontalLayout_6.addItem(spacerItem)
self.label_swapoff = QtGui.QLabel(self.groupBox_swap)
self.label_swapoff.setText(QtGui.QApplication.translate("Wizard", "Note: swapoff could take a long time, and, in case the memory is not enough, could even make your system crash. Your system seems to have %freeram%MB free", None, QtGui.QApplication.UnicodeUTF8))
self.label_swapoff.setWordWrap(True)
self.label_swapoff.setObjectName(_fromUtf8("label_swapoff"))
self.horizontalLayout_6.addWidget(self.label_swapoff)
self.verticalLayout_swapoff.addLayout(self.horizontalLayout_6)
self.verticalLayout_13.addLayout(self.verticalLayout_swapoff)
self.verticalLayout_11 = QtGui.QVBoxLayout()
self.verticalLayout_11.setObjectName(_fromUtf8("verticalLayout_11"))
self.radioButton_ignore = QtGui.QRadioButton(self.groupBox_swap)
self.radioButton_ignore.setText(QtGui.QApplication.translate("Wizard", "Ignore", None, QtGui.QApplication.UnicodeUTF8))
self.radioButton_ignore.setObjectName(_fromUtf8("radioButton_ignore"))
self.verticalLayout_11.addWidget(self.radioButton_ignore)
self.horizontalLayout_7 = QtGui.QHBoxLayout()
self.horizontalLayout_7.setObjectName(_fromUtf8("horizontalLayout_7"))
spacerItem1 = QtGui.QSpacerItem(20, 20, QtGui.QSizePolicy.Maximum, QtGui.QSizePolicy.Minimum)
self.horizontalLayout_7.addItem(spacerItem1)
self.label_9 = QtGui.QLabel(self.groupBox_swap)
self.label_9.setText(QtGui.QApplication.translate("Wizard", "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/REC-html40/strict.dtd\">\n"
"<html><head><meta name=\"qrichtext\" content=\"1\" /><style type=\"text/css\">\n"
"p, li { white-space: pre-wrap; }\n"
"</style></head><body style=\" font-family:\'DejaVu Sans\'; font-size:10pt; font-weight:400; font-style:normal;\">\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><span style=\" font-weight:600;\">Note:</span> You should use this only if you are sure that your swap is encrypted, or that you are using compcache.</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">If this is not the case, DON\'T select this, as it is <span style=\" font-weight:600;\">VERY DANGEROUS </span>to use encryption with swap activated</p></body></html>", None, QtGui.QApplication.UnicodeUTF8))
self.label_9.setWordWrap(True)
self.label_9.setObjectName(_fromUtf8("label_9"))
self.horizontalLayout_7.addWidget(self.label_9)
self.verticalLayout_11.addLayout(self.horizontalLayout_7)
self.verticalLayout_13.addLayout(self.verticalLayout_11)
self.verticalLayout_12.addWidget(self.groupBox_swap)
Wizard.addPage(self.wizardPage_check)
self.wizardPage_tomb_size = QtGui.QWizardPage()
self.wizardPage_tomb_size.setObjectName(_fromUtf8("wizardPage_tomb_size"))
self.verticalLayout_2 = QtGui.QVBoxLayout(self.wizardPage_tomb_size)
self.verticalLayout_2.setObjectName(_fromUtf8("verticalLayout_2"))
self.label_2 = QtGui.QLabel(self.wizardPage_tomb_size)
self.label_2.setText(QtGui.QApplication.translate("Wizard", "Please enter tomb size. Digging the tomb will require some time: usually, one minute per GB, but your mileage may vary. <br>Keep in mind that resizing it in the future is still NOT implemented", None, QtGui.QApplication.UnicodeUTF8))
self.label_2.setWordWrap(True)
self.label_2.setObjectName(_fromUtf8("label_2"))
self.verticalLayout_2.addWidget(self.label_2)
self.horizontalLayout = QtGui.QHBoxLayout()
self.horizontalLayout.setObjectName(_fromUtf8("horizontalLayout"))
self.label_3 = QtGui.QLabel(self.wizardPage_tomb_size)
self.label_3.setText(QtGui.QApplication.translate("Wizard", "Enter tomb size, in MB. 1GB=1000MB)", None, QtGui.QApplication.UnicodeUTF8))
self.label_3.setObjectName(_fromUtf8("label_3"))
self.horizontalLayout.addWidget(self.label_3)
self.spinBox_size = QtGui.QSpinBox(self.wizardPage_tomb_size)
self.spinBox_size.setMinimum(10)
self.spinBox_size.setMaximum(100000)
self.spinBox_size.setProperty("value", 100)
self.spinBox_size.setObjectName(_fromUtf8("spinBox_size"))
self.horizontalLayout.addWidget(self.spinBox_size)
self.verticalLayout_2.addLayout(self.horizontalLayout)
Wizard.addPage(self.wizardPage_tomb_size)
self.wizardPage_tomb_location = QtGui.QWizardPage()
self.wizardPage_tomb_location.setObjectName(_fromUtf8("wizardPage_tomb_location"))
self.verticalLayout_3 = QtGui.QVBoxLayout(self.wizardPage_tomb_location)
self.verticalLayout_3.setObjectName(_fromUtf8("verticalLayout_3"))
self.label_4 = QtGui.QLabel(self.wizardPage_tomb_location)
self.label_4.setText(QtGui.QApplication.translate("Wizard", "Where do you want your tomb to be digged?", None, QtGui.QApplication.UnicodeUTF8))
self.label_4.setWordWrap(True)
self.label_4.setObjectName(_fromUtf8("label_4"))
self.verticalLayout_3.addWidget(self.label_4)
self.horizontalLayout_2 = QtGui.QHBoxLayout()
self.horizontalLayout_2.setObjectName(_fromUtf8("horizontalLayout_2"))
self.lineEdit_tombpath = QtGui.QLineEdit(self.wizardPage_tomb_location)
self.lineEdit_tombpath.setFrame(True)
self.lineEdit_tombpath.setPlaceholderText(QtGui.QApplication.translate("Wizard", "/path/to/file.tomb", None, QtGui.QApplication.UnicodeUTF8))
self.lineEdit_tombpath.setObjectName(_fromUtf8("lineEdit_tombpath"))
self.horizontalLayout_2.addWidget(self.lineEdit_tombpath)
self.button_tombpath = QtGui.QPushButton(self.wizardPage_tomb_location)
self.button_tombpath.setText(QtGui.QApplication.translate("Wizard", "Open file", None, QtGui.QApplication.UnicodeUTF8))
self.button_tombpath.setObjectName(_fromUtf8("button_tombpath"))
self.horizontalLayout_2.addWidget(self.button_tombpath)
self.verticalLayout_3.addLayout(self.horizontalLayout_2)
Wizard.addPage(self.wizardPage_tomb_location)
self.wizardPage_key_location = QtGui.QWizardPage()
self.wizardPage_key_location.setTitle(QtGui.QApplication.translate("Wizard", "Key creation", None, QtGui.QApplication.UnicodeUTF8))
self.wizardPage_key_location.setSubTitle(QtGui.QApplication.translate("Wizard", "Choose the location for your key", None, QtGui.QApplication.UnicodeUTF8))
self.wizardPage_key_location.setObjectName(_fromUtf8("wizardPage_key_location"))
self.verticalLayout_6 = QtGui.QVBoxLayout(self.wizardPage_key_location)
self.verticalLayout_6.setObjectName(_fromUtf8("verticalLayout_6"))
self.label_5 = QtGui.QLabel(self.wizardPage_key_location)
self.label_5.setText(QtGui.QApplication.translate("Wizard", "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/REC-html40/strict.dtd\">\n"
"<html><head><meta name=\"qrichtext\" content=\"1\" /><style type=\"text/css\">\n"
"p, li { white-space: pre-wrap; }\n"
"</style></head><body style=\" font-family:\'Sans Serif\'; font-size:9pt; font-weight:400; font-style:normal;\">\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">Now, you have to decide where to put the <span style=\" font-weight:600;\">key</span> for your tomb<br />You should not leave your key at the door, as this will lower security A LOT</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">Also, the keyfile is very small (less than a KB), so disk space is not an issue</p></body></html>", None, QtGui.QApplication.UnicodeUTF8))
self.label_5.setTextFormat(QtCore.Qt.RichText)
self.label_5.setWordWrap(True)
self.label_5.setObjectName(_fromUtf8("label_5"))
self.verticalLayout_6.addWidget(self.label_5)
self.verticalLayout_5 = QtGui.QVBoxLayout()
self.verticalLayout_5.setObjectName(_fromUtf8("verticalLayout_5"))
self.verticalLayout_4 = QtGui.QVBoxLayout()
self.verticalLayout_4.setObjectName(_fromUtf8("verticalLayout_4"))
self.radioButton_usb = QtGui.QRadioButton(self.wizardPage_key_location)
self.radioButton_usb.setEnabled(False)
self.radioButton_usb.setText(QtGui.QApplication.translate("Wizard", "On a USB pen (best security)", None, QtGui.QApplication.UnicodeUTF8))
self.radioButton_usb.setCheckable(True)
self.radioButton_usb.setChecked(False)
self.radioButton_usb.setObjectName(_fromUtf8("radioButton_usb"))
self.verticalLayout_4.addWidget(self.radioButton_usb)
self.horizontalLayout_4 = QtGui.QHBoxLayout()
self.horizontalLayout_4.setObjectName(_fromUtf8("horizontalLayout_4"))
spacerItem2 = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Maximum, QtGui.QSizePolicy.Minimum)
self.horizontalLayout_4.addItem(spacerItem2)
self.label_6 = QtGui.QLabel(self.wizardPage_key_location)
self.label_6.setEnabled(False)
self.label_6.setText(QtGui.QApplication.translate("Wizard", "If you choose to do so, do not insert it NOW. Do it when you are asked to do so", None, QtGui.QApplication.UnicodeUTF8))
self.label_6.setObjectName(_fromUtf8("label_6"))
self.horizontalLayout_4.addWidget(self.label_6)
self.verticalLayout_4.addLayout(self.horizontalLayout_4)
self.verticalLayout_5.addLayout(self.verticalLayout_4)
self.radioButton_near = QtGui.QRadioButton(self.wizardPage_key_location)
self.radioButton_near.setToolTip(QtGui.QApplication.translate("Wizard", "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/REC-html40/strict.dtd\">\n"
"<html><head><meta name=\"qrichtext\" content=\"1\" /><style type=\"text/css\">\n"
"p, li { white-space: pre-wrap; }\n"
"</style></head><body style=\" font-family:\'Sans Serif\'; font-size:9pt; font-weight:400; font-style:normal;\">\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">It will be created as a regular file in the same directory of your tomb.</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">It is much easier to use, but also much more <span style=\" font-style:italic;\">insecure</span>: all your security will be guaranteed by your <span style=\" font-weight:600;\">password</span>. If you really want to do this, choose a strong password (lot of random/non-dictionary words, spaces, numbers, odd characters)</p></body></html>", None, QtGui.QApplication.UnicodeUTF8))
self.radioButton_near.setText(QtGui.QApplication.translate("Wizard", "Near to the tomb itself (this is BAD)", None, QtGui.QApplication.UnicodeUTF8))
self.radioButton_near.setChecked(True)
self.radioButton_near.setObjectName(_fromUtf8("radioButton_near"))
self.verticalLayout_5.addWidget(self.radioButton_near)
self.radioButton_custom = QtGui.QRadioButton(self.wizardPage_key_location)
self.radioButton_custom.setText(QtGui.QApplication.translate("Wizard", "Specify location", None, QtGui.QApplication.UnicodeUTF8))
self.radioButton_custom.setObjectName(_fromUtf8("radioButton_custom"))
self.verticalLayout_5.addWidget(self.radioButton_custom)
self.verticalLayout_6.addLayout(self.verticalLayout_5)
self.horizontalLayout_3 = QtGui.QHBoxLayout()
self.horizontalLayout_3.setObjectName(_fromUtf8("horizontalLayout_3"))
spacerItem3 = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Maximum, QtGui.QSizePolicy.Minimum)
self.horizontalLayout_3.addItem(spacerItem3)
self.lineEdit_custom = QtGui.QLineEdit(self.wizardPage_key_location)
self.lineEdit_custom.setEnabled(False)
self.lineEdit_custom.setObjectName(_fromUtf8("lineEdit_custom"))
self.horizontalLayout_3.addWidget(self.lineEdit_custom)
self.pushButton_custom = QtGui.QPushButton(self.wizardPage_key_location)
self.pushButton_custom.setEnabled(False)
self.pushButton_custom.setText(QtGui.QApplication.translate("Wizard", "Choose location", None, QtGui.QApplication.UnicodeUTF8))
self.pushButton_custom.setObjectName(_fromUtf8("pushButton_custom"))
self.horizontalLayout_3.addWidget(self.pushButton_custom)
self.verticalLayout_6.addLayout(self.horizontalLayout_3)
self.label_11 = QtGui.QLabel(self.wizardPage_key_location)
self.label_11.setText(QtGui.QApplication.translate("Wizard", "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/REC-html40/strict.dtd\">\n"
"<html><head><meta name=\"qrichtext\" content=\"1\" /><style type=\"text/css\">\n"
"p, li { white-space: pre-wrap; }\n"
"</style></head><body style=\" font-family:\'Sans Serif\'; font-size:9pt; font-weight:400; font-style:normal;\">\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><span style=\" font-weight:600;\">Help: </span>the key file is very small, so disk usage is not an issue</p></body></html>", None, QtGui.QApplication.UnicodeUTF8))
self.label_11.setWordWrap(True)
self.label_11.setObjectName(_fromUtf8("label_11"))
self.verticalLayout_6.addWidget(self.label_11)
Wizard.addPage(self.wizardPage_key_location)
self.wizardPage_progress = QtGui.QWizardPage()
self.wizardPage_progress.setTitle(QtGui.QApplication.translate("Wizard", "Creating", None, QtGui.QApplication.UnicodeUTF8))
self.wizardPage_progress.setSubTitle(QtGui.QApplication.translate("Wizard", "Please wait", None, QtGui.QApplication.UnicodeUTF8))
self.wizardPage_progress.setObjectName(_fromUtf8("wizardPage_progress"))
self.verticalLayout_9 = QtGui.QVBoxLayout(self.wizardPage_progress)
self.verticalLayout_9.setObjectName(_fromUtf8("verticalLayout_9"))
self.verticalLayout_7 = QtGui.QVBoxLayout()
self.verticalLayout_7.setObjectName(_fromUtf8("verticalLayout_7"))
self.progressBar = QtGui.QProgressBar(self.wizardPage_progress)
self.progressBar.setProperty("value", 0)
self.progressBar.setTextVisible(True)
self.progressBar.setInvertedAppearance(False)
self.progressBar.setObjectName(_fromUtf8("progressBar"))
self.verticalLayout_7.addWidget(self.progressBar)
self.horizontalLayout_5 = QtGui.QHBoxLayout()
self.horizontalLayout_5.setObjectName(_fromUtf8("horizontalLayout_5"))
self.label_progress = QtGui.QLabel(self.wizardPage_progress)
self.label_progress.setText(QtGui.QApplication.translate("Wizard", "Creating tomb, please wait...", None, QtGui.QApplication.UnicodeUTF8))
self.label_progress.setObjectName(_fromUtf8("label_progress"))
self.horizontalLayout_5.addWidget(self.label_progress)
self.verticalLayout_7.addLayout(self.horizontalLayout_5)
self.verticalLayout_9.addLayout(self.verticalLayout_7)
self.textBrowser_log = QtGui.QTextBrowser(self.wizardPage_progress)
self.textBrowser_log.setDocumentTitle(QtGui.QApplication.translate("Wizard", "Log", None, QtGui.QApplication.UnicodeUTF8))
self.textBrowser_log.setHtml(QtGui.QApplication.translate("Wizard", "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/REC-html40/strict.dtd\">\n"
"<html><head><meta name=\"qrichtext\" content=\"1\" /><title>Log</title><style type=\"text/css\">\n"
"p, li { white-space: pre-wrap; }\n"
"</style></head><body style=\" font-family:\'DejaVu Sans\'; font-size:10pt; font-weight:400; font-style:normal;\">\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><span style=\" font-family:\'Sans Serif\'; font-size:9pt; font-weight:600;\">Log</span></p>\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:\'Sans Serif\'; font-size:9pt; font-weight:600;\"></p></body></html>", None, QtGui.QApplication.UnicodeUTF8))
self.textBrowser_log.setObjectName(_fromUtf8("textBrowser_log"))
self.verticalLayout_9.addWidget(self.textBrowser_log)
Wizard.addPage(self.wizardPage_progress)
self.wizardPage_end = QtGui.QWizardPage()
self.wizardPage_end.setObjectName(_fromUtf8("wizardPage_end"))
self.verticalLayout_8 = QtGui.QVBoxLayout(self.wizardPage_end)
self.verticalLayout_8.setObjectName(_fromUtf8("verticalLayout_8"))
self.label_10 = QtGui.QLabel(self.wizardPage_end)
self.label_10.setText(QtGui.QApplication.translate("Wizard", "You successfully created the tomb!", None, QtGui.QApplication.UnicodeUTF8))
self.label_10.setObjectName(_fromUtf8("label_10"))
self.verticalLayout_8.addWidget(self.label_10)
self.checkBox_open = QtGui.QCheckBox(self.wizardPage_end)
self.checkBox_open.setEnabled(False)
self.checkBox_open.setText(QtGui.QApplication.translate("Wizard", "Open the just-created tomb NOW!", None, QtGui.QApplication.UnicodeUTF8))
self.checkBox_open.setChecked(False)
self.checkBox_open.setTristate(False)
self.checkBox_open.setObjectName(_fromUtf8("checkBox_open"))
self.verticalLayout_8.addWidget(self.checkBox_open)
Wizard.addPage(self.wizardPage_end)
self.label_3.setBuddy(self.spinBox_size)
self.label_4.setBuddy(self.lineEdit_tombpath)
self.retranslateUi(Wizard)
QtCore.QObject.connect(self.radioButton_custom, QtCore.SIGNAL(_fromUtf8("toggled(bool)")), self.lineEdit_custom.setEnabled)
QtCore.QObject.connect(self.radioButton_custom, QtCore.SIGNAL(_fromUtf8("toggled(bool)")), self.pushButton_custom.setEnabled)
QtCore.QObject.connect(Wizard, QtCore.SIGNAL(_fromUtf8("currentIdChanged(int)")), self.label_11.hide)
QtCore.QObject.connect(Wizard, QtCore.SIGNAL(_fromUtf8("helpRequested()")), self.label_11.show)
QtCore.QMetaObject.connectSlotsByName(Wizard)
def retranslateUi(self, Wizard):
pass

View File

@ -0,0 +1,51 @@
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'tombqt/open_keymethod.ui'
#
# Created: Sat Jan 28 03:36:11 2012
# by: PyQt4 UI code generator 4.9
#
# WARNING! All changes made in this file will be lost!
from PyQt4 import QtCore, QtGui
try:
_fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
_fromUtf8 = lambda s: s
class Ui_keymethod(object):
def setupUi(self, keymethod):
keymethod.setObjectName(_fromUtf8("keymethod"))
keymethod.resize(480, 640)
self.verticalLayout = QtGui.QVBoxLayout(keymethod)
self.verticalLayout.setObjectName(_fromUtf8("verticalLayout"))
spacerItem = QtGui.QSpacerItem(20, 265, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding)
self.verticalLayout.addItem(spacerItem)
self.radio_layout = QtGui.QVBoxLayout()
self.radio_layout.setObjectName(_fromUtf8("radio_layout"))
self.fs = QtGui.QRadioButton(keymethod)
self.fs.setObjectName(_fromUtf8("fs"))
self.radio_layout.addWidget(self.fs)
self.usb = QtGui.QRadioButton(keymethod)
self.usb.setEnabled(False)
self.usb.setObjectName(_fromUtf8("usb"))
self.radio_layout.addWidget(self.usb)
self.bluetooth = QtGui.QRadioButton(keymethod)
self.bluetooth.setEnabled(False)
self.bluetooth.setObjectName(_fromUtf8("bluetooth"))
self.radio_layout.addWidget(self.bluetooth)
self.verticalLayout.addLayout(self.radio_layout)
spacerItem1 = QtGui.QSpacerItem(20, 265, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding)
self.verticalLayout.addItem(spacerItem1)
self.retranslateUi(keymethod)
QtCore.QMetaObject.connectSlotsByName(keymethod)
def retranslateUi(self, keymethod):
keymethod.setWindowTitle(QtGui.QApplication.translate("keymethod", "WizardPage", None, QtGui.QApplication.UnicodeUTF8))
keymethod.setTitle(QtGui.QApplication.translate("keymethod", "Choose key", None, QtGui.QApplication.UnicodeUTF8))
self.fs.setText(QtGui.QApplication.translate("keymethod", "Filesystem", None, QtGui.QApplication.UnicodeUTF8))
self.usb.setText(QtGui.QApplication.translate("keymethod", "USB drive", None, QtGui.QApplication.UnicodeUTF8))
self.bluetooth.setText(QtGui.QApplication.translate("keymethod", "Retrieve via bluetooth (advanced)", None, QtGui.QApplication.UnicodeUTF8))

View File

@ -0,0 +1,35 @@
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'tombqt/open_success.ui'
#
# Created: Mon Jan 23 23:06:38 2012
# by: PyQt4 UI code generator 4.9
#
# WARNING! All changes made in this file will be lost!
from PyQt4 import QtCore, QtGui
try:
_fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
_fromUtf8 = lambda s: s
class Ui_success(object):
def setupUi(self, success):
success.setObjectName(_fromUtf8("success"))
success.resize(480, 640)
self.verticalLayout = QtGui.QVBoxLayout(success)
self.verticalLayout.setObjectName(_fromUtf8("verticalLayout"))
self.label = QtGui.QLabel(success)
self.label.setObjectName(_fromUtf8("label"))
self.verticalLayout.addWidget(self.label)
self.retranslateUi(success)
QtCore.QMetaObject.connectSlotsByName(success)
def retranslateUi(self, success):
success.setWindowTitle(QtGui.QApplication.translate("success", "WizardPage", None, QtGui.QApplication.UnicodeUTF8))
success.setTitle(QtGui.QApplication.translate("success", "Tomb opened", None, QtGui.QApplication.UnicodeUTF8))
success.setSubTitle(QtGui.QApplication.translate("success", "success", None, QtGui.QApplication.UnicodeUTF8))
self.label.setText(QtGui.QApplication.translate("success", "You successfully opened the tomb", None, QtGui.QApplication.UnicodeUTF8))

View File

@ -0,0 +1,52 @@
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'tombqt/open_tombfile.ui'
#
# Created: Tue Jan 24 00:49:10 2012
# by: PyQt4 UI code generator 4.9
#
# WARNING! All changes made in this file will be lost!
from PyQt4 import QtCore, QtGui
try:
_fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
_fromUtf8 = lambda s: s
class Ui_tombfile(object):
def setupUi(self, tombfile):
tombfile.setObjectName(_fromUtf8("tombfile"))
tombfile.resize(480, 640)
self.verticalLayout_2 = QtGui.QVBoxLayout(tombfile)
self.verticalLayout_2.setObjectName(_fromUtf8("verticalLayout_2"))
spacerItem = QtGui.QSpacerItem(20, 276, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding)
self.verticalLayout_2.addItem(spacerItem)
self.verticalLayout = QtGui.QVBoxLayout()
self.verticalLayout.setObjectName(_fromUtf8("verticalLayout"))
self.label = QtGui.QLabel(tombfile)
self.label.setObjectName(_fromUtf8("label"))
self.verticalLayout.addWidget(self.label)
self.horizontalLayout = QtGui.QHBoxLayout()
self.horizontalLayout.setObjectName(_fromUtf8("horizontalLayout"))
self.tomb_line = QtGui.QLineEdit(tombfile)
self.tomb_line.setObjectName(_fromUtf8("tomb_line"))
self.horizontalLayout.addWidget(self.tomb_line)
self.tomb_browse = QtGui.QPushButton(tombfile)
self.tomb_browse.setObjectName(_fromUtf8("tomb_browse"))
self.horizontalLayout.addWidget(self.tomb_browse)
self.verticalLayout.addLayout(self.horizontalLayout)
self.verticalLayout_2.addLayout(self.verticalLayout)
spacerItem1 = QtGui.QSpacerItem(20, 276, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding)
self.verticalLayout_2.addItem(spacerItem1)
self.retranslateUi(tombfile)
QtCore.QMetaObject.connectSlotsByName(tombfile)
def retranslateUi(self, tombfile):
tombfile.setWindowTitle(QtGui.QApplication.translate("tombfile", "WizardPage", None, QtGui.QApplication.UnicodeUTF8))
tombfile.setTitle(QtGui.QApplication.translate("tombfile", "Choose tomb", None, QtGui.QApplication.UnicodeUTF8))
self.label.setText(QtGui.QApplication.translate("tombfile", "Choose a tomb file on your filesystem", None, QtGui.QApplication.UnicodeUTF8))
self.tomb_line.setPlaceholderText(QtGui.QApplication.translate("tombfile", "/path/to/your.tomb", None, QtGui.QApplication.UnicodeUTF8))
self.tomb_browse.setText(QtGui.QApplication.translate("tombfile", "Browse", None, QtGui.QApplication.UnicodeUTF8))

62
src/qt/tombqt/worker.py Normal file
View File

@ -0,0 +1,62 @@
import sys,os
import time
from tempfile import NamedTemporaryFile
from PyQt4 import QtCore
parentdir = sys.path[0].split(os.sep)[:-1]
sys.path.append(os.sep.join(parentdir))
from tomblib.tomb import Tomb
from tomblib.parser import parse_line
class TombCreateThread(QtCore.QThread):
line_received = QtCore.pyqtSignal(QtCore.QString)
error_received = QtCore.pyqtSignal(QtCore.QString)
def __init__(self, tombpath, size, keypath, **opts):
QtCore.QThread.__init__(self)
self.tombpath = tombpath
self.size = size
self.keypath = keypath
self.opts = opts
self.err_thread = TombOutputThread()
self.err_thread.line_received.connect(self.line_received)
self.err_thread.error_received.connect(self.error_received)
def run(self):
self.err_thread.start()
self.status = Tomb.create(str(self.tombpath), str(self.size),
self.keypath, stderr=self.err_thread.buffer, **self.opts)
# self.err_thread.terminate()
def get_success(self):
return self.status
class TombOutputThread(QtCore.QThread):
line_received = QtCore.pyqtSignal(QtCore.QString)
error_received = QtCore.pyqtSignal(QtCore.QString)
progressed = QtCore.pyqtSignal(int) #value in percent
def __init__(self):
QtCore.QThread.__init__(self)
self.buffer = NamedTemporaryFile()
def run(self):
while True:
where = self.buffer.tell()
line = self.buffer.readline()
if not line:
time.sleep(1)
self.buffer.seek(where)
else:
#ansi color escapes messes this up, but it'ok anyway
self.line_received.emit(line)
self.parse_line(line)
def parse_line(self, line):
#This could be simplified, and s/search/match, if --no-color supported
#see #59
#TODO: this should be moved to tomblib.parse
parsed = parse_line(line)
if parsed and parsed['type'] == 'error':
self.error_received.emit(parsed.content)

View File

@ -48,8 +48,8 @@ PATH=/sbin:/bin:/usr/sbin:/usr/bin
function _msg() {
local command="print -P"
local progname="$fg[magenta]${TOMBEXEC##*/}$fg[reset_color]"
local message="$fg_bold[normal]$fg_no_bold[normal]${2}$fg[reset_color]"
local progname="$fg[magenta]${TOMBEXEC##*/}$reset_color"
local message="$fg_bold[normal]$fg_no_bold[normal]${2}$reset_color"
local -i returncode
case "$1" in
@ -57,19 +57,19 @@ function _msg() {
command+=" -n"; pchars=" > "; pcolor="yellow"
;;
message)
pchars=" . "; pcolor="white"; message="$fg_no_bold[$pcolor]${2}$fg[reset_color]"
pchars=" . "; pcolor="white"; message="$fg_no_bold[$pcolor]${2}$reset_color"
;;
verbose)
pchars="[D]"; pcolor="blue"
;;
success)
pchars="(*)"; pcolor="green"; message="$fg_no_bold[$pcolor]${2}$fg[reset_color]"
pchars="(*)"; pcolor="green"; message="$fg_no_bold[$pcolor]${2}$reset_color"
;;
warning)
pchars="[W]"; pcolor="yellow"; message="$fg_no_bold[$pcolor]${2}$fg[reset_color]"
pchars="[W]"; pcolor="yellow"; message="$fg_no_bold[$pcolor]${2}$reset_color"
;;
failure)
pchars="[E]"; pcolor="red"; message="$fg_no_bold[$pcolor]${2}$fg[reset_color]"
pchars="[E]"; pcolor="red"; message="$fg_no_bold[$pcolor]${2}$reset_color"
returncode=1
;;
*)
@ -78,7 +78,7 @@ function _msg() {
returncode=127
;;
esac
${=command} "${progname} $fg_bold[$pcolor]$pchars$fg[reset_color] ${message}$color[reset_color]" >&2
${=command} "${progname} $fg_bold[$pcolor]$pchars$reset_color ${message}$color[reset_color]" >&2
return $returncode
}
function _message say()
@ -298,8 +298,20 @@ EOF
return 0
}
# }}}
# }}}
# {{{ - TOMB USAGE
check_command() {
#generic checks; useful for interaction, to check if there are problems
#before wasting user's time
if ! option_is_set --ignore-swap; then
if [[ $1 == 'create' || $1 == 'open' ]]; then
if ! check_swap; then
error "Swap activated. Disable it with swapoff, or use --ignore-swap"
exit 1
fi
fi
fi
}
usage() {
cat <<EOF
@ -1591,19 +1603,19 @@ main() {
# to add some options? Well, keep in mind that an option CAN'T
# have differente meanings/behaviour in different subcommands.
# For example, "-s" means "size" and accept an argument. If you are tempted to add
# an option "-s" (that means, for example "silent", and doesn't accept an argument)
# DON'T DO IT!
# For example, "-s" means "size" and accept an argument. If you are tempted to add
# an option "-s" (that means, for example "silent", and doesn't accept an argument)
# DON'T DO IT!
# There are two reasons for that:
# There are two reasons for that:
# I. usability; user expect that "-s" is "size"
# II. Option parsing WILL EXPLODE if you do this kind of bad things
# (it will say "option defined more than once, and he's right")
# II. Option parsing WILL EXPLODE if you do this kind of bad things
# (it will say "option defined more than once, and he's right")
#
# If you want to use the same option in multiple commands then
# you can only use the non-abbreviated long-option version like:
# -force and NOT -f
main_opts=(q -quiet=q D -debug=D h -help=h v -version=v -no-color)
main_opts=(q -quiet=q D -debug=D h -help=h v -version=v -no-color)
subcommands_opts[__default]=""
subcommands_opts[open]="f n -nohook=n k: -key=k o: -mount-options=o"
subcommands_opts[mount]=${subcommands_opts[open]}
@ -1624,6 +1636,7 @@ main() {
subcommands_opts[source]=""
subcommands_opts[status]=""
subcommands_opts[resize]="s: -size=s k: -key=k"
subcommands_opts[check]="-ignore-swap"
# subcommands_opts[translate]=""
### Detect subcommand
@ -1635,7 +1648,20 @@ main() {
done
local -a oldstar
oldstar=($argv)
zparseopts -M -E -D -Adiscardme ${every_opts}
#### detect early: useful for --optiion-parsing
zparseopts -M -D -Adiscardme ${every_opts}
if [[ -n ${(k)discardme[--option-parsing]} ]]; then
echo $1
if [[ -n "$1" ]]; then
return 1
fi
return 0
fi
unset discardme
if ! zparseopts -M -E -D -Adiscardme ${every_opts}; then
error "error parsing"
return 127
fi
unset discardme
subcommand=$1
if [[ -z $subcommand ]]; then
@ -1723,14 +1749,13 @@ main() {
_warning "steghide not installed. Cannot bury your key"
return 1
fi
encode_key ${CMD2} ${CMD3}
;;
encode_key $PARAM[1] $PARAM[2] ;;
exhume)
if [ "$STEGHIDE" = 0 ]; then
_warning "steghide not installed. Cannot exhume your key"
return 1
fi
decode_key ${CMD2}
decode_key $PARAM[1]
;;
resize)
check_priv
@ -1740,8 +1765,9 @@ main() {
'source') return 0 ;;
install) check_priv ; install_tomb ;;
askpass) ask_password ${CMD2} ${CMD3} ;;
mktemp) safe_dir ${CMD2} ;;
mktemp) safe_dir $PARAM[1] ;;
translate) generate_translatable_strings ;;
check) check_command $PARAM[1] ;;
__default)
cat <<EOF
Tomb $VERSION - a strong and gentle undertaker for your secrets
@ -1770,8 +1796,9 @@ EOF
# {{{ RUNTIME
check_bin
main $@
if [[ $? != 0 ]]; then #this "if" seems useless, but avoid source tomb source from exiting
exit $?
ret=$?
if [[ $ret != 0 ]]; then #this "if" seems useless, but avoid source tomb source from exiting
exit $ret
fi
# }}}

View File

@ -32,21 +32,21 @@ TRAPSTOP() die "STOP signal caught, undertaker aborting."
# first of all source the tomb core functions
which tomb > /dev/null
if [[ $? != 0 ]]; then
print "$fg[red][!]$fg[white] Tomb command not found, operation aborted."; exit 1
print "$fg[red][!]$fg[white] Tomb command not found, operation aborted." >&2; exit 1
fi
key_found() {
# $1 is "url"
if option_is_set --machine-parseable; then
print -n '[m]'
if option_is_set --batch; then
print -n '[m]' >&2
fi
print "$fg[white][found] $1"
print "$fg[white][found] $1" >&2
}
function undertaker_scheme() {
zparseopts -D -print-path=print_path
zparseopts -D -path=print_path
local scheme
scheme=$1
@ -60,7 +60,7 @@ function undertaker_scheme() {
act "access to bluetooth protocol requested"
which obexftp &> /dev/null
if [[ $? != 0 ]]; then
error "obexftp not found, needed for bluetooth: operation aborted."
_warning "obexftp not found, needed for bluetooth: operation aborted."
return 64
fi
keytmp=`safe_dir undertaker`
@ -95,10 +95,10 @@ function undertaker_scheme() {
file)
if ! [[ -f $keypath ]]; then
error "Invalid path $keypath"
_warning "Invalid path $keypath"
return 1
fi
if [[ -n $print_path ]]; then
if option_is_set --path; then
key_found $scheme://$keypath;
else
< $keypath
@ -122,7 +122,7 @@ function undertaker_scheme() {
#It implements automounting using udisks; udisks is a (recently)
#new technology, so we can't rely on it being present
if ! which udisks &> /dev/null; then
error 'udisks not found'
_warning 'udisks not found'
exit 64
fi
while true; do
@ -149,7 +149,7 @@ function undertaker_scheme() {
*)
if ! which undertaker-$scheme &> /dev/null; then
error "url protocol not recognized: $scheme"
_warning "url protocol not recognized: $scheme"
return 64
fi
undertaker-$scheme ${print_path[@]} ${scheme}://$keypath
@ -162,13 +162,14 @@ function main() {
typeset -A opts
zparseopts -M -E -D -Aopts -poll -path -batch
if ! [ $1 ] ; then
error "an argument is missing, the undertaker is confused"
act "usage: undertaker [options] url://host:path/to/tomb.key"
print "[W] an argument is missing, the undertaker is confused" >&2
print "usage: undertaker [options] url://host:path/to/tomb.key" >&2
exit 1;
fi
local -a tomb_opts
if [[ -n ${(k)opts[--batch]} ]]; then
tomb_opts+='--batch'
tomb_opts+='--no-color'
tomb_opts+='--quiet'
fi
local -a under_opts
if [[ -n ${(k)opts[--path]} ]]; then
@ -178,13 +179,14 @@ function main() {
for a in ${(k)opts}; do
backupopts[$a]=${opts[$a]}
done
source tomb ${tomb_opts[@]} source
source tomb ${tomb_opts[@]} source
TOMBEXEC=undertaker
for a in ${(k)backupopts}; do
opts[$a]=${backupopts[$a]}
done
check_bin
notice "Undertaker will look for $1"
_success "Undertaker will look for $1"
ARG1=${1}
scheme=${ARG1%://*}