From 2c73bbce277bc1f3e2b18edb5f20e282bded4770 Mon Sep 17 00:00:00 2001 From: Papoteur Date: Sun, 4 Mar 2018 15:39:39 +0100 Subject: Use call through DBUS for operation needing root privileges --- lib/isodumper.py | 157 ++++++++++++++----------------------------------------- lib/raw_write.py | 140 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 179 insertions(+), 118 deletions(-) create mode 100755 lib/raw_write.py (limited to 'lib') diff --git a/lib/isodumper.py b/lib/isodumper.py index 6388854..d44a42f 100755 --- a/lib/isodumper.py +++ b/lib/isodumper.py @@ -53,6 +53,8 @@ import gettext from gettext import gettext as _ from subprocess import call, Popen, PIPE import dbus +from pydbus import SystemBus +from gi.repository import GLib class NoUDisks2(Exception): @@ -212,6 +214,11 @@ class IsoDumper(object): self.progress.setDisabled() self.refreshbt.setEnabled() + def onProgress(self, frac): + self.logger(_('Wrote: {}% '.format(frac))) + self.progress.setValue(frac) + self.dialog.pollEvent() + def raw_format(self, usb_path, fstype, label): self.operation=True if os.geteuid() > 0: @@ -251,11 +258,9 @@ class IsoDumper(object): self.logger(_('Backup to:')+' '+dest) self.raw_write(source, dest, self.deviceSize) if self.returncode==0: - self.success() - + self.success() def do_write(self): - self.returncode = 0 self.writebt.setDisabled() self.devicelist.setDisabled() self.formatbt.setDisabled() @@ -283,124 +288,39 @@ class IsoDumper(object): return self.ima.setDisabled() self.writebt.setDisabled() - self.do_umount(target) - if self.returncode != 1: - # Writing step - #Dump mode - self.returncode=0 - b=os.path.getsize(source) - self.raw_write(source, target, b) - if self.returncode == 0: + # TODO Appel via DBus + self.progress.setLabel(_('Writing {source} to {target}').format(source=source.split('/')[-1],target=target.split('/')[-1])) + self.logger(_('Executing copy from ')+source+_(' to ')+target) + print(_('Writing {source} to {target}').format(source=source.split('/')[-1],target=target.split('/')[-1])) + bus = SystemBus() + iface = bus.get("org.mageia.Magiback","Isodumper") + print('DBus ouvert') + success, message = iface.do_unmount(target) + if success: + #Writing step + #Dump mode + print("Partitions démontées") + iface.do_write(source, target) + print("Ecriture en cours") + while iface.progress < 100 : + print(iface.progress, iface.done) + self.progress.setValue(iface.progress) + time.sleep(1) + #loop = GLib.MainLoop() + #loop.run() + success, message = iface.end() + if success: + self.logger(_('Image ')+source.split('/')[-1]+_(' successfully written to ')+target) + self.logger(_('Bytes written: ')+str(b)) self.check_write(target, b) self.success() + else: + self.emergency(message) else: + self.emergency(message) self.restore() else: self.restore() - def do_umount(self, target): - mounts = self.get_mounted(target) - if mounts: - self.logger(_('Unmounting all partitions of ')+target+':') - for mount in mounts: - self.logger(_('Trying to unmount ')+mount[0]+'...') - try: - retcode = call('umount '+mount[0], shell=True) - if retcode == 32: - message = _('Partition %s is busy')%mount[0] - self.logger(message) - self.emergency(message) - elif retcode< 0: - message = _('Error, umount ')+mount[0]+_(' was terminated by signal ')+str(retcode) - self.logger(message) - self.emergency(message) - elif retcode == 0: - self.logger(mount[0]+_(' successfully unmounted')) - else: - message = _('Error, umount ')+mount[0]+_(' returned ')+str(retcode) - self.logger(message) - self.emergency(message) - except OSError as e: - message = _('Execution failed: ')+str(e) - self.logger(message) - self.emergency(message) - - def get_mounted(self, target): - try: - lines = [line.strip("\n").split(" ") for line in open ("/etc/mtab", "r").readlines()] - return [mount for mount in lines if mount[0].startswith(target)] - except: - message = _('Could not read mtab !') - self.logger(message) - self.emergency(message) - - def raw_write(self, source, target, b): - self.operation=True - bs=4096*128 - try: - ifc=io.open(source, "rb",1) - except: - message = _('Reading error.')+ source - self.logger(message) - self.emergency(message) - return - else: - try: - ofc= io.open(target, 'wb',0) - except: - message = _("You don't have permission to write to the device") +" "+ target - self.logger(message) - self.emergency(message) - self.close() - else: - self.progress.setLabel(_('Writing ')+source.split('/')[-1]+_(' to ')+target.split('/')[-1]) - self.logger(_('Executing copy from ')+source+_(' to ')+target) - steps=list(range(0, b+1, int(b/100))) - steps.append(b) - indice=1 - written=0 - ncuts=int(b/bs) - while ncuts <= 100: - bs=int(bs/2) - ncuts=int(b/bs) - for i in range(0,int(ncuts)+1): - try: - buf=ifc.read(bs) - except: - message = _("Reading error.") - self.logger(message) - self.emergency(message) - return - try: - ofc.write(buf) - except: - message = _("Writing error.") - self.logger(message) - self.emergency(message) - return - written+=len(buf) - if written > steps[indice]: - if indice%1==0: - self.logger(_('Wrote: ')+str(indice)+'% '+str(written)+' bytes') - self.progress.setValue(indice) - self.dialog.pollEvent() - indice +=1 - try: - os.fsync(ofc) - except: - message = _("Writing error.") - self.logger(message) - self.emergency(message) - return - self.progress.setValue(100) - self.logger(_('Image ')+source.split('/')[-1]+_(' successfully written to ')+target) - self.logger(_('Bytes written: ')+str(written)) - try: - ofc.close() - except: - message = _("Writing error.") - self.logger(message) - self.emergency(message) - ifc.close() def check_write(self, target, b): import hashlib @@ -547,10 +467,11 @@ NTFS or ext. You can specify a volume name and the format in a new dialog box. +# +# Modifications 2013 from papoteur +# and Geiger David +# +# 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 St, Fifth Floor, Boston, MA 02110-1301, USA. + +########### +# imports # +########### +#import locale +import os +import io +import gettext +from gettext import gettext as _ +import pydbus + +class Dumper(object): + + def do_write(self,source,dev): + target = dev.split('(')[1].split(')')[0] + self.do_umount(target) + # Writing step + #Dump mode + self.returncode=0 + b=os.path.getsize(source) + self.operation=True + bs=4096*128 + try: + ifc=io.open(source, "rb",1) + except: + message = _('Reading error.')+ source + self.logger(message) + return False,message + else: + try: + ofc= io.open(target, 'wb',0) + except: + message = _("You don't have permission to write to the device {}").format(target) + self.logger(message) + return False,message + else: + self.progress.setLabel(_('Writing {source} to {target}').format(source=source.split('/')[-1],target=target.split('/')[-1]) + self.logger(_('Executing copy from ')+source+_(' to ')+target) + steps=list(range(0, b+1, int(b/100))) + steps.append(b) + indice=1 + written=0 + ncuts=int(b/bs) + while ncuts <= 100: + bs=int(bs/2) + ncuts=int(b/bs) + for i in range(0,int(ncuts)+1): + try: + buf=ifc.read(bs) + except: + message = _("Reading error.") + self.logger(message) + return False, message + try: + ofc.write(buf) + except: + message = _("Writing error.") + self.logger(message) + return False, message + written+=len(buf) + if written > steps[indice]: + if indice%1==0: + self.logger(_('Wrote: ')+str(indice)+'% '+str(written)+' bytes') + self.sendProgress(indice) + self.dialog.pollEvent() + indice +=1 + try: + os.fsync(ofc) + except: + message = _("Writing error.") + self.logger(message) + return False,message + self.progress.setValue(100) + self.logger(_('Image ')+source.split('/')[-1]+_(' successfully written to ')+target) + self.logger(_('Bytes written: ')+str(written)) + try: + ofc.close() + except: + message = _("Writing error.") + self.logger(message) + ifc.close() + return True, _("Succes") + + def do_umount(self, target): + try: + lines = [line.strip("\n").split(" ") for line in open ("/etc/mtab", "r").readlines()] + mounts = [mount for mount in lines if mount[0].startswith(target)] + except: + message = _('Could not read mtab !') + self.logger(message) + return False, message + if mounts: + self.logger(_('Unmounting all partitions of ')+target+':') + for mount in mounts: + self.logger(_('Trying to unmount ')+mount[0]+'...') + try: + retcode = call('umount '+mount[0], shell=True) + if retcode == 32: + message = _('Partition %s is busy')%mount[0] + elif retcode< 0: + message = _('Error, umount ')+mount[0]+_(' was terminated by signal ')+str(retcode) + elif retcode == 0: + message=_('{} successfully unmounted').format(mount[0]) + else: + message = _('Error, umount {} returned ').format(str(retcode)) + except OSError as e: + message = _('Execution failed: {}').format(str(e)) + return retcode, message + + def __init__(self): + gettext.bindtextdomain(APP, DIR) + gettext.textdomain(APP) + + # Operation running + self.operation=False + -- cgit v1.2.1