Commit 948374d6 authored by Irene "Tissy" Pirrotta's avatar Irene "Tissy" Pirrotta
Browse files

add other common files, qt folder and some file in it.

parent 502a267e
This diff is collapsed.
# Back In Time
# Copyright (C) 2008-2019 Oprea Dan, Bart de Koning, Richard Bailey, Germar Reitze
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
import os
import fcntl
import errno
import logger
import tools
class ApplicationInstance:
"""
Class used to handle one application instance mechanism.
Args:
pidFile (str): full path of file used to save pid and procname
autoExit (bool): automatically call sys.exit if there is an other
instance running
flock (bool): use file-locks to make sure only one instance
is checking at the same time
"""
def __init__(self, pidFile, autoExit = True, flock = False):
self.pidFile = pidFile
self.pid = 0
self.procname = ''
self.flock = None
if flock:
self.flockExclusiv()
if autoExit:
if self.check(True):
self.startApplication()
def __del__(self):
self.flockUnlock()
def check(self, autoExit = False):
"""
Check if the current application is already running
Args:
autoExit (bool): automatically call sys.exit if there is an other
instance running
Returns:
bool: ``True`` if this is the only application
instance
"""
#check if the pidfile exists
if not os.path.isfile(self.pidFile):
return True
self.pid, self.procname = self.readPidFile()
#check if the process with specified by pid exists
if 0 == self.pid:
return True
if not tools.processAlive(self.pid):
return True
#check if the process has the same procname
#check cmdline for backwards compatibility
if self.procname and \
self.procname != tools.processName(self.pid) and \
self.procname != tools.processCmdline(self.pid):
return True
if autoExit:
#exit the application
print("The application is already running !")
exit(0) #exit raise an exception so don't put it in a try/except block
return False
def busy(self):
"""
Check if one application with this instance is currently running.
Returns:
bool: ``True`` if an other instance is currently running.
"""
return not self.check()
def startApplication(self):
"""
Called when the single instance starts to save its pid
"""
pid = os.getpid()
procname = tools.processName(pid)
try:
with open(self.pidFile, 'wt') as f:
f.write('{}\n{}'.format(pid, procname))
except OSError as e:
logger.error('Failed to write PID file %s: [%s] %s' %(e.filename, e.errno, e.strerror))
self.flockUnlock()
def exitApplication(self):
"""
Called when the single instance exit (remove pid file)
"""
try:
os.remove(self.pidFile)
except:
pass
def flockExclusiv(self):
"""
Create an exclusive lock to block a second instance while
the first instance is starting.
"""
try:
self.flock = open(self.pidFile + '.flock', 'w')
fcntl.flock(self.flock, fcntl.LOCK_EX)
except OSError as e:
logger.error('Failed to write flock file %s: [%s] %s' %(e.filename, e.errno, e.strerror))
def flockUnlock(self):
"""
Remove the exclusive lock. Second instance can now continue
but should find it self to be obsolete.
"""
if self.flock:
fcntl.fcntl(self.flock, fcntl.LOCK_UN)
self.flock.close()
try:
os.remove(self.flock.name)
except:
#an other instance was faster
#race condition while using 'if os.path.exists(...)'
pass
self.flock = None
def readPidFile(self):
"""
Read the pid and procname from the file
Returns:
tuple: tuple of (pid(int), procname(str))
"""
pid = 0
procname = ''
try:
with open(self.pidFile, 'rt') as f:
data = f.read()
data = data.split('\n', 1)
if data[0].isdigit():
pid = int(data[0])
if len(data) > 1:
procname = data[1].strip('\n')
except OSError as e:
logger.warning('Failed to read PID and process name from %s: [%s] %s' %(e.filename, e.errno, e.strerror))
except ValueError as e:
logger.warning('Failed to extract PID and process name from %s: %s'
%(self.pidFile, str(e)))
return (pid, procname)
if __name__ == '__main__':
import time
#create application instance
appInstance = ApplicationInstance('/tmp/myapp.pid')
#do something here
print("Start MyApp")
time.sleep(5) #sleep 5 seconds
print("End MyApp")
#remove pid file
appInstance.exitApplication()
# Copyright (C) 2012-2019 Germar Reitze
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
import os
import sys
try:
import gtk
except:
pass
import password
import password_ipc
import tools
import config
if __name__ == '__main__':
"""
return password.
"""
cfg = config.Config()
tools.envLoad(cfg.cronEnvFile())
profile_id = os.getenv('ASKPASS_PROFILE_ID', '1')
mode = os.getenv('ASKPASS_MODE', 'local')
if mode == 'USER':
prompt = os.getenv('ASKPASS_PROMPT', None)
pw = password.Password(cfg)
print(pw.passwordFromUser(None, prompt = prompt))
sys.exit(0)
temp_file = os.getenv('ASKPASS_TEMP')
if temp_file is None:
#normal mode, get password from module password
pw = password.Password(cfg)
print(pw.password(None, profile_id, mode))
sys.exit(0)
#temp mode
fifo = password_ipc.FIFO(temp_file)
pw = fifo.read(5)
if pw:
print(pw)
#!/bin/sh
# Back In Time
# Copyright (C) 2008-2019 Oprea Dan, Bart de Koning, Richard Bailey, Germar Reitze
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
CUR_PATH="$(dirname $(readlink -m $0))"
if [ -f "${CUR_PATH}/backintime.py" ]; then
APP_PATH=$CUR_PATH
else
APP_PATH=$(readlink -m "${CUR_PATH}/../share/backintime/common")
fi
python3 -Es $APP_PATH/backintime.py "$@"
#!/bin/sh
# Back In Time
# Copyright (C) 2008-2019 Oprea Dan, Bart de Koning, Richard Bailey, Germar Reitze
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#fixing gray window error
#https://launchpad.net/bugs/1493020
export QT_GRAPHICSSYSTEM="native"
CUR_PATH="$(dirname $(readlink -m $0))"
if [ -f "${CUR_PATH}/askpass.py" ]; then
APP_PATH=$CUR_PATH
else
APP_PATH=$(readlink -m "${CUR_PATH}/../share/backintime/common")
fi
python3 -Es $APP_PATH/askpass.py "$@"
[Desktop Entry]
Version=1.0
Name=Backintime Password Cache
Exec=/bin/sh -c "backintime pw-cache start 2>&1 >/dev/null"
Comment=Cache passwords for non-interactive Backintime cronjobs
Icon=gtk-save
Terminal=false
Type=Application
This diff is collapsed.
#extract profile and config arguments
_bit_extr_opts()
{
local c=0 last="" opts=""
while [[ $c -le ${COMP_CWORD} ]]; do
case "${last}" in
--profile|--profile-id|--config)
if [[ ${COMP_WORDS[$c]} != -* ]]; then
opts="${opts} ${last} ${COMP_WORDS[$c]}"
fi ;;
esac
last=${COMP_WORDS[$c]}
c=$[$c+1]
done
echo "${opts}"
}
#return a list of all snapshots
_bit_snapshots_list()
{
backintime$(_bit_extr_opts) --quiet snapshots-list | awk '{print $2}'
}
_backintime()
{
local cur prev actions opts pw_cache_commands
local cur_action='' pos_action=0 c=0
COMPREPLY=()
cur="${COMP_WORDS[COMP_CWORD]}"
prev="${COMP_WORDS[COMP_CWORD-1]}"
opts="--profile --profile-id --quiet --config --version --license \
--help --debug --checksum --no-crontab --keep-mount --delete \
--local-backup --no-local-backup --only-new --share-path"
actions="backup backup-job snapshots-path snapshots-list \
snapshots-list-path last-snapshot last-snapshot-path unmount \
benchmark-cipher pw-cache decode remove restore check-config \
smart-remove shutdown"
pw_cache_commands="start stop restart reload status"
#extract the current action
while [[ $c -le $[${COMP_CWORD} - 1] ]]; do
case ${actions} in
*"${COMP_WORDS[$c]}"*)
cur_action="${COMP_WORDS[$c]}"
pos_action=${c}
break ;;
esac
c=$[${c}+1]
done
case "${cur_action}" in
restore)
if [[ ${cur} != -* ]]; then
#which positional argument is $cur?
case $[${COMP_CWORD}-${pos_action}] in
#first arg is a filename
1) _filedir
return 0
;;
#second arg is a dirname
2) _filedir -d
return 0
;;
#third arg is snapshot-id
3) COMPREPLY=( $(compgen -W "$(_bit_snapshots_list)" -- ${cur}) )
return 0
;;
esac
fi
;;
remove|remove-and-do-not-ask-again)
if [[ ${cur} != -* ]]; then
#snapshot-ids
COMPREPLY=( $(compgen -W "$(_bit_snapshots_list)" -- ${cur}) )
return 0
else
#other args
COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
return 0
fi
;;
esac
case "${prev}" in
--config|decode|restore|--share-path)
if [[ ${cur} != -* ]]; then
_filedir
return 0
fi ;;
pw-cache)
if [[ ${cur} != -* ]]; then
COMPREPLY=( $(compgen -W "${pw_cache_commands}" -- ${cur}) )
return 0
fi ;;
*)
if [[ -z "${cur_action}" ]]; then
opts="${opts} ${actions}"
fi
COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
return 0
;;
esac
}
complete -F _backintime backintime
complete -F _backintime backintime-qt
#!/usr/bin/env python3
# Copyright (C) 2015-2019 Germar Reitze
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
import sys
if sys.stdout.isatty():
HEADER = '\033[95m'
OKBLUE = '\033[94m'
OKGREEN = '\033[92m'
WARNING = '\033[93m'
FAIL = '\033[91m'
ENDC = '\033[0m'
BOLD = '\033[1m'
UNDERLINE = '\033[4m'
else:
HEADER = ''
OKBLUE = ''
OKGREEN = ''
WARNING = ''
FAIL = ''
ENDC = ''
BOLD = ''
UNDERLINE = ''
# -*- coding: utf-8 -*-
# Back In Time
# Copyright (C) 2012-2019 Germar Reitze
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
import os
import sys
import tools
import snapshots
import bcolors
def restore(cfg, snapshot_id = None, what = None, where = None, **kwargs):
if what is None:
what = input('File to restore: ')
what = tools.preparePath(os.path.abspath(os.path.expanduser(what)))
if where is None:
where = input('Restore to (empty for original path): ')
if where:
where = tools.preparePath(os.path.abspath(os.path.expanduser(where)))
snapshotsList = snapshots.listSnapshots(cfg)
sid = selectSnapshot(snapshotsList, cfg, snapshot_id, 'SnapshotID to restore')
print('')
RestoreDialog(cfg, sid, what, where, **kwargs).run()
def remove(cfg, snapshot_ids = None, force = None):
snapshotsList = snapshots.listSnapshots(cfg)
if not snapshot_ids:
snapshot_ids = (None,)
sids = [selectSnapshot(snapshotsList, cfg, sid, 'SnapshotID to remove') for sid in snapshot_ids]
if not force:
print('Do you really want to remove this snapshots?')
[print(sid.displayName) for sid in sids]
if not 'yes' == input('(no/yes): '):
return
s = snapshots.Snapshots(cfg)
[s.remove(sid) for sid in sids]
def checkConfig(cfg, crontab = True):
import mount
from exceptions import MountException
def announceTest():
print()
print(frame(test))
def failed():
print(test + ': ' + bcolors.FAIL + 'failed' + bcolors.ENDC)
def okay():
print(test + ': ' + bcolors.OKGREEN + 'done' + bcolors.ENDC)
def errorHandler(msg):
print(bcolors.WARNING + 'WARNING: ' + bcolors.ENDC + msg)
cfg.setErrorHandler(errorHandler)
mode = cfg.snapshotsMode()
if cfg.SNAPSHOT_MODES[mode][0] is not None:
#preMountCheck
test = 'Run mount tests'
announceTest()
mnt = mount.Mount(cfg = cfg, tmp_mount = True)
try:
mnt.preMountCheck(mode = mode, first_run = True)
except MountException as ex:
failed()
print(str(ex))
return False
okay()
#okay, lets try to mount
test = 'Mount'
announceTest()
try:
hash_id = mnt.mount(mode = mode, check = False)
except MountException as ex:
failed()
print(str(ex))
return False
okay()
test = 'Check/prepair snapshot path'
announceTest()
snapshots_path = cfg.snapshotsPath(mode = mode, tmp_mount = True)
if not cfg.setSnapshotsPath(snapshots_path, mode = mode):
failed()
return False
okay()
#umount
if not cfg.SNAPSHOT_MODES[mode][0] is None:
test = 'Unmount'
announceTest()
try:
mnt.umount(hash_id = hash_id)
except MountException as ex:
failed()
print(str(ex))
return False
okay()
test = 'Check config'
announceTest()
if not cfg.checkConfig():
failed()
return False
okay()
if crontab:
test = 'Install crontab'
announceTest()
if not cfg.setupCron():
failed()
return False
okay()
return True
def selectSnapshot(snapshotsList, cfg, snapshot_id = None, msg = 'SnapshotID'):
"""
check if given snapshot is valid. If not print a list of all
snapshots and ask to choose one
"""
len_snapshots = len(snapshotsList)
if not snapshot_id is None:
try:
sid = snapshots.SID(snapshot_id, cfg)
if sid in snapshotsList:
return sid
else:
print('SnapshotID %s not found.' % snapshot_id)
except ValueError:
try:
index = int(snapshot_id)
return snapshotsList[index]
except (ValueError, IndexError):
print('Invalid SnaphotID index: %s' % snapshot_id)
snapshot_id = None